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

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
...@@ -705,6 +705,7 @@ struct qeth_discipline { ...@@ -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 *, ...@@ -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);
......
...@@ -3216,8 +3216,10 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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)
{ {
......
...@@ -500,81 +500,6 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card, ...@@ -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) ...@@ -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 = { ...@@ -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,
......
...@@ -1829,81 +1829,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, ...@@ -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) ...@@ -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 = { ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment