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: Julian Wiedmann <jwi@linux.vnet.ibm.com> Acked-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
942d6984aa
commit
d73ef32493
|
@ -705,6 +705,7 @@ struct qeth_discipline {
|
|||
void (*start_poll)(struct ccw_device *, int, unsigned long);
|
||||
qdio_handler_t *input_handler;
|
||||
qdio_handler_t *output_handler;
|
||||
int (*process_rx_buffer)(struct qeth_card *card, int budget, int *done);
|
||||
int (*recover)(void *ptr);
|
||||
int (*setup) (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 *,
|
||||
enum qeth_ipa_cmds, enum qeth_prot_versions);
|
||||
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 qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
|
||||
struct qeth_hdr **);
|
||||
void qeth_schedule_recovery(struct qeth_card *);
|
||||
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 *,
|
||||
unsigned int, unsigned int, int,
|
||||
int, unsigned long);
|
||||
|
|
|
@ -3216,8 +3216,10 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_hw_trap);
|
||||
|
||||
int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
|
||||
unsigned int qdio_error, const char *dbftext)
|
||||
static int qeth_check_qdio_errors(struct qeth_card *card,
|
||||
struct qdio_buffer *buf,
|
||||
unsigned int qdio_error,
|
||||
const char *dbftext)
|
||||
{
|
||||
if (qdio_error) {
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_check_qdio_errors);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void qeth_queue_input_buffer(struct qeth_card *card, int index)
|
||||
static void qeth_queue_input_buffer(struct qeth_card *card, int index)
|
||||
{
|
||||
struct qeth_qdio_q *queue = card->qdio.in_q;
|
||||
struct list_head *lh;
|
||||
|
@ -3319,7 +3311,15 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index)
|
|||
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,
|
||||
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);
|
||||
|
||||
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,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
|
|
|
@ -500,81 +500,6 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
|
|||
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)
|
||||
{
|
||||
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) *
|
||||
PAGE_SIZE;
|
||||
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);
|
||||
return register_netdev(card->dev);
|
||||
}
|
||||
|
@ -1357,6 +1282,7 @@ struct qeth_discipline qeth_l2_discipline = {
|
|||
.start_poll = qeth_qdio_start_poll,
|
||||
.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
|
||||
.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
|
||||
.process_rx_buffer = qeth_l2_process_inbound_buffer,
|
||||
.recover = qeth_l2_recover,
|
||||
.setup = qeth_l2_probe_device,
|
||||
.remove = qeth_l2_remove_device,
|
||||
|
|
|
@ -1829,81 +1829,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
|
|||
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,
|
||||
struct qeth_card *card)
|
||||
{
|
||||
|
@ -3105,7 +3030,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|||
PAGE_SIZE;
|
||||
|
||||
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);
|
||||
return register_netdev(card->dev);
|
||||
}
|
||||
|
@ -3394,6 +3319,7 @@ struct qeth_discipline qeth_l3_discipline = {
|
|||
.start_poll = qeth_qdio_start_poll,
|
||||
.input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
|
||||
.output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
|
||||
.process_rx_buffer = qeth_l3_process_inbound_buffer,
|
||||
.recover = qeth_l3_recover,
|
||||
.setup = qeth_l3_probe_device,
|
||||
.remove = qeth_l3_remove_device,
|
||||
|
|
Loading…
Reference in New Issue