Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d73ef324 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller
Browse files

s390/qeth: move NAPI poll routine to core



Identical code, we just need to call a layer-specific hook
to process any received buffer.

qeth_buffer_reclaim_work() is shuffled around to avoid a
forward declaration for qeth_queue_input_buffer().

Signed-off-by: default avatarJulian Wiedmann <jwi@linux.vnet.ibm.com>
Acked-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 942d6984
Loading
Loading
Loading
Loading
+2 −3
Original line number Original line Diff line number Diff line
@@ -705,6 +705,7 @@ struct qeth_discipline {
	void (*start_poll)(struct ccw_device *, int, unsigned long);
	void (*start_poll)(struct ccw_device *, int, unsigned long);
	qdio_handler_t *input_handler;
	qdio_handler_t *input_handler;
	qdio_handler_t *output_handler;
	qdio_handler_t *output_handler;
	int (*process_rx_buffer)(struct qeth_card *card, int budget, int *done);
	int (*recover)(void *ptr);
	int (*recover)(void *ptr);
	int (*setup) (struct ccwgroup_device *);
	int (*setup) (struct ccwgroup_device *);
	void (*remove) (struct ccwgroup_device *);
	void (*remove) (struct ccwgroup_device *);
@@ -909,14 +910,12 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
			enum qeth_ipa_cmds, enum qeth_prot_versions);
			enum qeth_ipa_cmds, enum qeth_prot_versions);
int qeth_query_setadapterparms(struct qeth_card *);
int qeth_query_setadapterparms(struct qeth_card *);
int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
		unsigned int, const char *);
void qeth_queue_input_buffer(struct qeth_card *, int);
struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
		struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
		struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
		struct qeth_hdr **);
		struct qeth_hdr **);
void qeth_schedule_recovery(struct qeth_card *);
void qeth_schedule_recovery(struct qeth_card *);
void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
int qeth_poll(struct napi_struct *napi, int budget);
void qeth_qdio_input_handler(struct ccw_device *,
void qeth_qdio_input_handler(struct ccw_device *,
		unsigned int, unsigned int, int,
		unsigned int, unsigned int, int,
		int, unsigned long);
		int, unsigned long);
+91 −14
Original line number Original line Diff line number Diff line
@@ -3216,8 +3216,10 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
}
}
EXPORT_SYMBOL_GPL(qeth_hw_trap);
EXPORT_SYMBOL_GPL(qeth_hw_trap);


int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
static int qeth_check_qdio_errors(struct qeth_card *card,
		unsigned int qdio_error, const char *dbftext)
				  struct qdio_buffer *buf,
				  unsigned int qdio_error,
				  const char *dbftext)
{
{
	if (qdio_error) {
	if (qdio_error) {
		QETH_CARD_TEXT(card, 2, dbftext);
		QETH_CARD_TEXT(card, 2, dbftext);
@@ -3234,18 +3236,8 @@ int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
	}
	}
	return 0;
	return 0;
}
}
EXPORT_SYMBOL_GPL(qeth_check_qdio_errors);


static void qeth_buffer_reclaim_work(struct work_struct *work)
static void qeth_queue_input_buffer(struct qeth_card *card, int index)
{
	struct qeth_card *card = container_of(work, struct qeth_card,
		buffer_reclaim_work.work);

	QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
	qeth_queue_input_buffer(card, card->reclaim_index);
}

void qeth_queue_input_buffer(struct qeth_card *card, int index)
{
{
	struct qeth_qdio_q *queue = card->qdio.in_q;
	struct qeth_qdio_q *queue = card->qdio.in_q;
	struct list_head *lh;
	struct list_head *lh;
@@ -3319,7 +3311,15 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index)
					  QDIO_MAX_BUFFERS_PER_Q;
					  QDIO_MAX_BUFFERS_PER_Q;
	}
	}
}
}
EXPORT_SYMBOL_GPL(qeth_queue_input_buffer);

static void qeth_buffer_reclaim_work(struct work_struct *work)
{
	struct qeth_card *card = container_of(work, struct qeth_card,
		buffer_reclaim_work.work);

	QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
	qeth_queue_input_buffer(card, card->reclaim_index);
}


static void qeth_handle_send_error(struct qeth_card *card,
static void qeth_handle_send_error(struct qeth_card *card,
		struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
		struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
@@ -5282,6 +5282,83 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
}
}
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);


int qeth_poll(struct napi_struct *napi, int budget)
{
	struct qeth_card *card = container_of(napi, struct qeth_card, napi);
	int work_done = 0;
	struct qeth_qdio_buffer *buffer;
	int done;
	int new_budget = budget;

	if (card->options.performance_stats) {
		card->perf_stats.inbound_cnt++;
		card->perf_stats.inbound_start_time = qeth_get_micros();
	}

	while (1) {
		if (!card->rx.b_count) {
			card->rx.qdio_err = 0;
			card->rx.b_count = qdio_get_next_buffers(
				card->data.ccwdev, 0, &card->rx.b_index,
				&card->rx.qdio_err);
			if (card->rx.b_count <= 0) {
				card->rx.b_count = 0;
				break;
			}
			card->rx.b_element =
				&card->qdio.in_q->bufs[card->rx.b_index]
				.buffer->element[0];
			card->rx.e_offset = 0;
		}

		while (card->rx.b_count) {
			buffer = &card->qdio.in_q->bufs[card->rx.b_index];
			if (!(card->rx.qdio_err &&
			    qeth_check_qdio_errors(card, buffer->buffer,
			    card->rx.qdio_err, "qinerr")))
				work_done +=
					card->discipline->process_rx_buffer(
						card, new_budget, &done);
			else
				done = 1;

			if (done) {
				if (card->options.performance_stats)
					card->perf_stats.bufs_rec++;
				qeth_put_buffer_pool_entry(card,
					buffer->pool_entry);
				qeth_queue_input_buffer(card, card->rx.b_index);
				card->rx.b_count--;
				if (card->rx.b_count) {
					card->rx.b_index =
						(card->rx.b_index + 1) %
						QDIO_MAX_BUFFERS_PER_Q;
					card->rx.b_element =
						&card->qdio.in_q
						->bufs[card->rx.b_index]
						.buffer->element[0];
					card->rx.e_offset = 0;
				}
			}

			if (work_done >= budget)
				goto out;
			else
				new_budget = budget - work_done;
		}
	}

	napi_complete(napi);
	if (qdio_start_irq(card->data.ccwdev, 0))
		napi_schedule(&card->napi);
out:
	if (card->options.performance_stats)
		card->perf_stats.inbound_time += qeth_get_micros() -
			card->perf_stats.inbound_start_time;
	return work_done;
}
EXPORT_SYMBOL_GPL(qeth_poll);

int qeth_setassparms_cb(struct qeth_card *card,
int qeth_setassparms_cb(struct qeth_card *card,
			struct qeth_reply *reply, unsigned long data)
			struct qeth_reply *reply, unsigned long data)
{
{
+2 −76
Original line number Original line Diff line number Diff line
@@ -500,81 +500,6 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
	return work_done;
	return work_done;
}
}


static int qeth_l2_poll(struct napi_struct *napi, int budget)
{
	struct qeth_card *card = container_of(napi, struct qeth_card, napi);
	int work_done = 0;
	struct qeth_qdio_buffer *buffer;
	int done;
	int new_budget = budget;

	if (card->options.performance_stats) {
		card->perf_stats.inbound_cnt++;
		card->perf_stats.inbound_start_time = qeth_get_micros();
	}

	while (1) {
		if (!card->rx.b_count) {
			card->rx.qdio_err = 0;
			card->rx.b_count = qdio_get_next_buffers(
				card->data.ccwdev, 0, &card->rx.b_index,
				&card->rx.qdio_err);
			if (card->rx.b_count <= 0) {
				card->rx.b_count = 0;
				break;
			}
			card->rx.b_element =
				&card->qdio.in_q->bufs[card->rx.b_index]
				.buffer->element[0];
			card->rx.e_offset = 0;
		}

		while (card->rx.b_count) {
			buffer = &card->qdio.in_q->bufs[card->rx.b_index];
			if (!(card->rx.qdio_err &&
			    qeth_check_qdio_errors(card, buffer->buffer,
			    card->rx.qdio_err, "qinerr")))
				work_done += qeth_l2_process_inbound_buffer(
					card, new_budget, &done);
			else
				done = 1;

			if (done) {
				if (card->options.performance_stats)
					card->perf_stats.bufs_rec++;
				qeth_put_buffer_pool_entry(card,
					buffer->pool_entry);
				qeth_queue_input_buffer(card, card->rx.b_index);
				card->rx.b_count--;
				if (card->rx.b_count) {
					card->rx.b_index =
						(card->rx.b_index + 1) %
						QDIO_MAX_BUFFERS_PER_Q;
					card->rx.b_element =
						&card->qdio.in_q
						->bufs[card->rx.b_index]
						.buffer->element[0];
					card->rx.e_offset = 0;
				}
			}

			if (work_done >= budget)
				goto out;
			else
				new_budget = budget - work_done;
		}
	}

	napi_complete(napi);
	if (qdio_start_irq(card->data.ccwdev, 0))
		napi_schedule(&card->napi);
out:
	if (card->options.performance_stats)
		card->perf_stats.inbound_time += qeth_get_micros() -
			card->perf_stats.inbound_start_time;
	return work_done;
}

static int qeth_l2_request_initial_mac(struct qeth_card *card)
static int qeth_l2_request_initial_mac(struct qeth_card *card)
{
{
	int rc = 0;
	int rc = 0;
@@ -1065,7 +990,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
				  PAGE_SIZE;
				  PAGE_SIZE;
	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
	netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
	netif_carrier_off(card->dev);
	netif_carrier_off(card->dev);
	return register_netdev(card->dev);
	return register_netdev(card->dev);
}
}
@@ -1357,6 +1282,7 @@ struct qeth_discipline qeth_l2_discipline = {
	.start_poll = qeth_qdio_start_poll,
	.start_poll = qeth_qdio_start_poll,
	.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
	.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
	.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
	.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
	.process_rx_buffer = qeth_l2_process_inbound_buffer,
	.recover = qeth_l2_recover,
	.recover = qeth_l2_recover,
	.setup = qeth_l2_probe_device,
	.setup = qeth_l2_probe_device,
	.remove = qeth_l2_remove_device,
	.remove = qeth_l2_remove_device,
+2 −76
Original line number Original line Diff line number Diff line
@@ -1829,81 +1829,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
	return work_done;
	return work_done;
}
}


static int qeth_l3_poll(struct napi_struct *napi, int budget)
{
	struct qeth_card *card = container_of(napi, struct qeth_card, napi);
	int work_done = 0;
	struct qeth_qdio_buffer *buffer;
	int done;
	int new_budget = budget;

	if (card->options.performance_stats) {
		card->perf_stats.inbound_cnt++;
		card->perf_stats.inbound_start_time = qeth_get_micros();
	}

	while (1) {
		if (!card->rx.b_count) {
			card->rx.qdio_err = 0;
			card->rx.b_count = qdio_get_next_buffers(
				card->data.ccwdev, 0, &card->rx.b_index,
				&card->rx.qdio_err);
			if (card->rx.b_count <= 0) {
				card->rx.b_count = 0;
				break;
			}
			card->rx.b_element =
				&card->qdio.in_q->bufs[card->rx.b_index]
				.buffer->element[0];
			card->rx.e_offset = 0;
		}

		while (card->rx.b_count) {
			buffer = &card->qdio.in_q->bufs[card->rx.b_index];
			if (!(card->rx.qdio_err &&
			    qeth_check_qdio_errors(card, buffer->buffer,
			    card->rx.qdio_err, "qinerr")))
				work_done += qeth_l3_process_inbound_buffer(
					card, new_budget, &done);
			else
				done = 1;

			if (done) {
				if (card->options.performance_stats)
					card->perf_stats.bufs_rec++;
				qeth_put_buffer_pool_entry(card,
					buffer->pool_entry);
				qeth_queue_input_buffer(card, card->rx.b_index);
				card->rx.b_count--;
				if (card->rx.b_count) {
					card->rx.b_index =
						(card->rx.b_index + 1) %
						QDIO_MAX_BUFFERS_PER_Q;
					card->rx.b_element =
						&card->qdio.in_q
						->bufs[card->rx.b_index]
						.buffer->element[0];
					card->rx.e_offset = 0;
				}
			}

			if (work_done >= budget)
				goto out;
			else
				new_budget = budget - work_done;
		}
	}

	napi_complete(napi);
	if (qdio_start_irq(card->data.ccwdev, 0))
		napi_schedule(&card->napi);
out:
	if (card->options.performance_stats)
		card->perf_stats.inbound_time += qeth_get_micros() -
			card->perf_stats.inbound_start_time;
	return work_done;
}

static int qeth_l3_verify_vlan_dev(struct net_device *dev,
static int qeth_l3_verify_vlan_dev(struct net_device *dev,
			struct qeth_card *card)
			struct qeth_card *card)
{
{
@@ -3105,7 +3030,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
				  PAGE_SIZE;
				  PAGE_SIZE;


	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
	netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
	netif_carrier_off(card->dev);
	netif_carrier_off(card->dev);
	return register_netdev(card->dev);
	return register_netdev(card->dev);
}
}
@@ -3394,6 +3319,7 @@ struct qeth_discipline qeth_l3_discipline = {
	.start_poll = qeth_qdio_start_poll,
	.start_poll = qeth_qdio_start_poll,
	.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
	.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
	.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
	.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
	.process_rx_buffer = qeth_l3_process_inbound_buffer,
	.recover = qeth_l3_recover,
	.recover = qeth_l3_recover,
	.setup = qeth_l3_probe_device,
	.setup = qeth_l3_probe_device,
	.remove = qeth_l3_remove_device,
	.remove = qeth_l3_remove_device,