aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net')
-rw-r--r--drivers/s390/net/Kconfig2
-rw-r--r--drivers/s390/net/qeth_core.h17
-rw-r--r--drivers/s390/net/qeth_core_main.c26
-rw-r--r--drivers/s390/net/qeth_l2_main.c173
-rw-r--r--drivers/s390/net/qeth_l3_main.c189
5 files changed, 262 insertions, 145 deletions
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 977bb4d4ed15..456b18743397 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -100,6 +100,6 @@ config QETH_IPV6
100 100
101config CCWGROUP 101config CCWGROUP
102 tristate 102 tristate
103 default (LCS || CTCM || QETH) 103 default (LCS || CTCM || QETH || CLAW)
104 104
105endmenu 105endmenu
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index d1257768be90..6be43eb126b4 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -676,6 +676,7 @@ enum qeth_discipline_id {
676}; 676};
677 677
678struct qeth_discipline { 678struct qeth_discipline {
679 void (*start_poll)(struct ccw_device *, int, unsigned long);
679 qdio_handler_t *input_handler; 680 qdio_handler_t *input_handler;
680 qdio_handler_t *output_handler; 681 qdio_handler_t *output_handler;
681 int (*recover)(void *ptr); 682 int (*recover)(void *ptr);
@@ -702,6 +703,16 @@ struct qeth_skb_data {
702#define QETH_SKB_MAGIC 0x71657468 703#define QETH_SKB_MAGIC 0x71657468
703#define QETH_SIGA_CC2_RETRIES 3 704#define QETH_SIGA_CC2_RETRIES 3
704 705
706struct qeth_rx {
707 int b_count;
708 int b_index;
709 struct qdio_buffer_element *b_element;
710 int e_offset;
711 int qdio_err;
712};
713
714#define QETH_NAPI_WEIGHT 128
715
705struct qeth_card { 716struct qeth_card {
706 struct list_head list; 717 struct list_head list;
707 enum qeth_card_states state; 718 enum qeth_card_states state;
@@ -749,6 +760,8 @@ struct qeth_card {
749 debug_info_t *debug; 760 debug_info_t *debug;
750 struct mutex conf_mutex; 761 struct mutex conf_mutex;
751 struct mutex discipline_mutex; 762 struct mutex discipline_mutex;
763 struct napi_struct napi;
764 struct qeth_rx rx;
752}; 765};
753 766
754struct qeth_card_list_struct { 767struct qeth_card_list_struct {
@@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
831 struct qdio_buffer *, struct qdio_buffer_element **, int *, 844 struct qdio_buffer *, struct qdio_buffer_element **, int *,
832 struct qeth_hdr **); 845 struct qeth_hdr **);
833void qeth_schedule_recovery(struct qeth_card *); 846void qeth_schedule_recovery(struct qeth_card *);
847void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
848void qeth_qdio_input_handler(struct ccw_device *,
849 unsigned int, unsigned int, int,
850 int, unsigned long);
834void qeth_qdio_output_handler(struct ccw_device *, unsigned int, 851void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
835 int, int, int, unsigned long); 852 int, int, int, unsigned long);
836void qeth_clear_ipacmd_list(struct qeth_card *); 853void qeth_clear_ipacmd_list(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3a5a18a0fc28..764267062601 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
2911 } 2911 }
2912} 2912}
2913 2913
2914void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
2915 unsigned long card_ptr)
2916{
2917 struct qeth_card *card = (struct qeth_card *)card_ptr;
2918
2919 if (card->dev)
2920 napi_schedule(&card->napi);
2921}
2922EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
2923
2924void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
2925 unsigned int queue, int first_element, int count,
2926 unsigned long card_ptr)
2927{
2928 struct qeth_card *card = (struct qeth_card *)card_ptr;
2929
2930 if (qdio_err)
2931 qeth_schedule_recovery(card);
2932}
2933EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
2934
2914void qeth_qdio_output_handler(struct ccw_device *ccwdev, 2935void qeth_qdio_output_handler(struct ccw_device *ccwdev,
2915 unsigned int qdio_error, int __queue, int first_element, 2936 unsigned int qdio_error, int __queue, int first_element,
2916 int count, unsigned long card_ptr) 2937 int count, unsigned long card_ptr)
@@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
3843 init_data.no_output_qs = card->qdio.no_out_queues; 3864 init_data.no_output_qs = card->qdio.no_out_queues;
3844 init_data.input_handler = card->discipline.input_handler; 3865 init_data.input_handler = card->discipline.input_handler;
3845 init_data.output_handler = card->discipline.output_handler; 3866 init_data.output_handler = card->discipline.output_handler;
3867 init_data.queue_start_poll = card->discipline.start_poll;
3846 init_data.int_parm = (unsigned long) card; 3868 init_data.int_parm = (unsigned long) card;
3847 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3869 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3848 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3870 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
@@ -4513,8 +4535,8 @@ static struct {
4513/* 20 */{"queue 1 buffer usage"}, 4535/* 20 */{"queue 1 buffer usage"},
4514 {"queue 2 buffer usage"}, 4536 {"queue 2 buffer usage"},
4515 {"queue 3 buffer usage"}, 4537 {"queue 3 buffer usage"},
4516 {"rx handler time"}, 4538 {"rx poll time"},
4517 {"rx handler count"}, 4539 {"rx poll count"},
4518 {"rx do_QDIO time"}, 4540 {"rx do_QDIO time"},
4519 {"rx do_QDIO count"}, 4541 {"rx do_QDIO count"},
4520 {"tx handler time"}, 4542 {"tx handler time"},
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 830d63524d61..01c3c1f77879 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -407,29 +407,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
407 return rc; 407 return rc;
408} 408}
409 409
410static void qeth_l2_process_inbound_buffer(struct qeth_card *card, 410static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
411 struct qeth_qdio_buffer *buf, int index) 411 int budget, int *done)
412{ 412{
413 struct qdio_buffer_element *element; 413 int work_done = 0;
414 struct sk_buff *skb; 414 struct sk_buff *skb;
415 struct qeth_hdr *hdr; 415 struct qeth_hdr *hdr;
416 int offset;
417 unsigned int len; 416 unsigned int len;
418 417
419 /* get first element of current buffer */ 418 *done = 0;
420 element = (struct qdio_buffer_element *)&buf->buffer->element[0]; 419 BUG_ON(!budget);
421 offset = 0; 420 while (budget) {
422 if (card->options.performance_stats) 421 skb = qeth_core_get_next_skb(card,
423 card->perf_stats.bufs_rec++; 422 card->qdio.in_q->bufs[card->rx.b_index].buffer,
424 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, 423 &card->rx.b_element, &card->rx.e_offset, &hdr);
425 &offset, &hdr))) { 424 if (!skb) {
426 skb->dev = card->dev; 425 *done = 1;
427 /* is device UP ? */ 426 break;
428 if (!(card->dev->flags & IFF_UP)) {
429 dev_kfree_skb_any(skb);
430 continue;
431 } 427 }
432 428 skb->dev = card->dev;
433 switch (hdr->hdr.l2.id) { 429 switch (hdr->hdr.l2.id) {
434 case QETH_HEADER_TYPE_LAYER2: 430 case QETH_HEADER_TYPE_LAYER2:
435 skb->pkt_type = PACKET_HOST; 431 skb->pkt_type = PACKET_HOST;
@@ -441,7 +437,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
441 if (skb->protocol == htons(ETH_P_802_2)) 437 if (skb->protocol == htons(ETH_P_802_2))
442 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; 438 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
443 len = skb->len; 439 len = skb->len;
444 netif_rx(skb); 440 netif_receive_skb(skb);
445 break; 441 break;
446 case QETH_HEADER_TYPE_OSN: 442 case QETH_HEADER_TYPE_OSN:
447 if (card->info.type == QETH_CARD_TYPE_OSN) { 443 if (card->info.type == QETH_CARD_TYPE_OSN) {
@@ -459,9 +455,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
459 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); 455 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
460 continue; 456 continue;
461 } 457 }
458 work_done++;
459 budget--;
462 card->stats.rx_packets++; 460 card->stats.rx_packets++;
463 card->stats.rx_bytes += len; 461 card->stats.rx_bytes += len;
464 } 462 }
463 return work_done;
464}
465
466static int qeth_l2_poll(struct napi_struct *napi, int budget)
467{
468 struct qeth_card *card = container_of(napi, struct qeth_card, napi);
469 int work_done = 0;
470 struct qeth_qdio_buffer *buffer;
471 int done;
472 int new_budget = budget;
473
474 if (card->options.performance_stats) {
475 card->perf_stats.inbound_cnt++;
476 card->perf_stats.inbound_start_time = qeth_get_micros();
477 }
478
479 while (1) {
480 if (!card->rx.b_count) {
481 card->rx.qdio_err = 0;
482 card->rx.b_count = qdio_get_next_buffers(
483 card->data.ccwdev, 0, &card->rx.b_index,
484 &card->rx.qdio_err);
485 if (card->rx.b_count <= 0) {
486 card->rx.b_count = 0;
487 break;
488 }
489 card->rx.b_element =
490 &card->qdio.in_q->bufs[card->rx.b_index]
491 .buffer->element[0];
492 card->rx.e_offset = 0;
493 }
494
495 while (card->rx.b_count) {
496 buffer = &card->qdio.in_q->bufs[card->rx.b_index];
497 if (!(card->rx.qdio_err &&
498 qeth_check_qdio_errors(card, buffer->buffer,
499 card->rx.qdio_err, "qinerr")))
500 work_done += qeth_l2_process_inbound_buffer(
501 card, new_budget, &done);
502 else
503 done = 1;
504
505 if (done) {
506 if (card->options.performance_stats)
507 card->perf_stats.bufs_rec++;
508 qeth_put_buffer_pool_entry(card,
509 buffer->pool_entry);
510 qeth_queue_input_buffer(card, card->rx.b_index);
511 card->rx.b_count--;
512 if (card->rx.b_count) {
513 card->rx.b_index =
514 (card->rx.b_index + 1) %
515 QDIO_MAX_BUFFERS_PER_Q;
516 card->rx.b_element =
517 &card->qdio.in_q
518 ->bufs[card->rx.b_index]
519 .buffer->element[0];
520 card->rx.e_offset = 0;
521 }
522 }
523
524 if (work_done >= budget)
525 goto out;
526 else
527 new_budget = budget - work_done;
528 }
529 }
530
531 napi_complete(napi);
532 if (qdio_start_irq(card->data.ccwdev, 0))
533 napi_schedule(&card->napi);
534out:
535 if (card->options.performance_stats)
536 card->perf_stats.inbound_time += qeth_get_micros() -
537 card->perf_stats.inbound_start_time;
538 return work_done;
465} 539}
466 540
467static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, 541static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
@@ -755,49 +829,10 @@ tx_drop:
755 return NETDEV_TX_OK; 829 return NETDEV_TX_OK;
756} 830}
757 831
758static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
759 unsigned int qdio_err, unsigned int queue,
760 int first_element, int count, unsigned long card_ptr)
761{
762 struct net_device *net_dev;
763 struct qeth_card *card;
764 struct qeth_qdio_buffer *buffer;
765 int index;
766 int i;
767
768 card = (struct qeth_card *) card_ptr;
769 net_dev = card->dev;
770 if (card->options.performance_stats) {
771 card->perf_stats.inbound_cnt++;
772 card->perf_stats.inbound_start_time = qeth_get_micros();
773 }
774 if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
775 QETH_CARD_TEXT(card, 1, "qdinchk");
776 QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element,
777 count);
778 QETH_CARD_TEXT_(card, 1, "%04X", queue);
779 qeth_schedule_recovery(card);
780 return;
781 }
782 for (i = first_element; i < (first_element + count); ++i) {
783 index = i % QDIO_MAX_BUFFERS_PER_Q;
784 buffer = &card->qdio.in_q->bufs[index];
785 if (!(qdio_err &&
786 qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
787 "qinerr")))
788 qeth_l2_process_inbound_buffer(card, buffer, index);
789 /* clear buffer and give back to hardware */
790 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
791 qeth_queue_input_buffer(card, index);
792 }
793 if (card->options.performance_stats)
794 card->perf_stats.inbound_time += qeth_get_micros() -
795 card->perf_stats.inbound_start_time;
796}
797
798static int qeth_l2_open(struct net_device *dev) 832static int qeth_l2_open(struct net_device *dev)
799{ 833{
800 struct qeth_card *card = dev->ml_priv; 834 struct qeth_card *card = dev->ml_priv;
835 int rc = 0;
801 836
802 QETH_CARD_TEXT(card, 4, "qethopen"); 837 QETH_CARD_TEXT(card, 4, "qethopen");
803 if (card->state != CARD_STATE_SOFTSETUP) 838 if (card->state != CARD_STATE_SOFTSETUP)
@@ -814,18 +849,24 @@ static int qeth_l2_open(struct net_device *dev)
814 849
815 if (!card->lan_online && netif_carrier_ok(dev)) 850 if (!card->lan_online && netif_carrier_ok(dev))
816 netif_carrier_off(dev); 851 netif_carrier_off(dev);
817 return 0; 852 if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
853 napi_enable(&card->napi);
854 napi_schedule(&card->napi);
855 } else
856 rc = -EIO;
857 return rc;
818} 858}
819 859
820
821static int qeth_l2_stop(struct net_device *dev) 860static int qeth_l2_stop(struct net_device *dev)
822{ 861{
823 struct qeth_card *card = dev->ml_priv; 862 struct qeth_card *card = dev->ml_priv;
824 863
825 QETH_CARD_TEXT(card, 4, "qethstop"); 864 QETH_CARD_TEXT(card, 4, "qethstop");
826 netif_tx_disable(dev); 865 netif_tx_disable(dev);
827 if (card->state == CARD_STATE_UP) 866 if (card->state == CARD_STATE_UP) {
828 card->state = CARD_STATE_SOFTSETUP; 867 card->state = CARD_STATE_SOFTSETUP;
868 napi_disable(&card->napi);
869 }
829 return 0; 870 return 0;
830} 871}
831 872
@@ -836,8 +877,9 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
836 INIT_LIST_HEAD(&card->vid_list); 877 INIT_LIST_HEAD(&card->vid_list);
837 INIT_LIST_HEAD(&card->mc_list); 878 INIT_LIST_HEAD(&card->mc_list);
838 card->options.layer2 = 1; 879 card->options.layer2 = 1;
880 card->discipline.start_poll = qeth_qdio_start_poll;
839 card->discipline.input_handler = (qdio_handler_t *) 881 card->discipline.input_handler = (qdio_handler_t *)
840 qeth_l2_qdio_input_handler; 882 qeth_qdio_input_handler;
841 card->discipline.output_handler = (qdio_handler_t *) 883 card->discipline.output_handler = (qdio_handler_t *)
842 qeth_qdio_output_handler; 884 qeth_qdio_output_handler;
843 card->discipline.recover = qeth_l2_recover; 885 card->discipline.recover = qeth_l2_recover;
@@ -923,6 +965,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
923 card->info.broadcast_capable = 1; 965 card->info.broadcast_capable = 1;
924 qeth_l2_request_initial_mac(card); 966 qeth_l2_request_initial_mac(card);
925 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 967 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
968 netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
926 return register_netdev(card->dev); 969 return register_netdev(card->dev);
927} 970}
928 971
@@ -955,6 +998,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
955 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); 998 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
956 999
957 card->state = CARD_STATE_HARDSETUP; 1000 card->state = CARD_STATE_HARDSETUP;
1001 memset(&card->rx, 0, sizeof(struct qeth_rx));
958 qeth_print_status_message(card); 1002 qeth_print_status_message(card);
959 1003
960 /* softsetup */ 1004 /* softsetup */
@@ -1086,9 +1130,6 @@ static int qeth_l2_recover(void *ptr)
1086 card->use_hard_stop = 1; 1130 card->use_hard_stop = 1;
1087 __qeth_l2_set_offline(card->gdev, 1); 1131 __qeth_l2_set_offline(card->gdev, 1);
1088 rc = __qeth_l2_set_online(card->gdev, 1); 1132 rc = __qeth_l2_set_online(card->gdev, 1);
1089 /* don't run another scheduled recovery */
1090 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1091 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1092 if (!rc) 1133 if (!rc)
1093 dev_info(&card->gdev->dev, 1134 dev_info(&card->gdev->dev,
1094 "Device successfully recovered!\n"); 1135 "Device successfully recovered!\n");
@@ -1099,6 +1140,8 @@ static int qeth_l2_recover(void *ptr)
1099 dev_warn(&card->gdev->dev, "The qeth device driver " 1140 dev_warn(&card->gdev->dev, "The qeth device driver "
1100 "failed to recover an error on the device\n"); 1141 "failed to recover an error on the device\n");
1101 } 1142 }
1143 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1144 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1102 return 0; 1145 return 0;
1103} 1146}
1104 1147
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index e22ae248f613..5b79f573bd93 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
103 103
104void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) 104void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
105{ 105{
106 sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" 106 sprintf(buf, "%pI6", addr);
107 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
108 addr[0], addr[1], addr[2], addr[3],
109 addr[4], addr[5], addr[6], addr[7],
110 addr[8], addr[9], addr[10], addr[11],
111 addr[12], addr[13], addr[14], addr[15]);
112} 107}
113 108
114int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) 109int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
@@ -2112,51 +2107,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
2112 return vlan_id; 2107 return vlan_id;
2113} 2108}
2114 2109
2115static void qeth_l3_process_inbound_buffer(struct qeth_card *card, 2110static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
2116 struct qeth_qdio_buffer *buf, int index) 2111 int budget, int *done)
2117{ 2112{
2118 struct qdio_buffer_element *element; 2113 int work_done = 0;
2119 struct sk_buff *skb; 2114 struct sk_buff *skb;
2120 struct qeth_hdr *hdr; 2115 struct qeth_hdr *hdr;
2121 int offset;
2122 __u16 vlan_tag = 0; 2116 __u16 vlan_tag = 0;
2123 unsigned int len; 2117 unsigned int len;
2124 /* get first element of current buffer */
2125 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
2126 offset = 0;
2127 if (card->options.performance_stats)
2128 card->perf_stats.bufs_rec++;
2129 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
2130 &offset, &hdr))) {
2131 skb->dev = card->dev;
2132 /* is device UP ? */
2133 if (!(card->dev->flags & IFF_UP)) {
2134 dev_kfree_skb_any(skb);
2135 continue;
2136 }
2137 2118
2119 *done = 0;
2120 BUG_ON(!budget);
2121 while (budget) {
2122 skb = qeth_core_get_next_skb(card,
2123 card->qdio.in_q->bufs[card->rx.b_index].buffer,
2124 &card->rx.b_element, &card->rx.e_offset, &hdr);
2125 if (!skb) {
2126 *done = 1;
2127 break;
2128 }
2129 skb->dev = card->dev;
2138 switch (hdr->hdr.l3.id) { 2130 switch (hdr->hdr.l3.id) {
2139 case QETH_HEADER_TYPE_LAYER3: 2131 case QETH_HEADER_TYPE_LAYER3:
2140 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); 2132 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
2141 len = skb->len; 2133 len = skb->len;
2142 if (vlan_tag && !card->options.sniffer) 2134 if (vlan_tag && !card->options.sniffer)
2143 if (card->vlangrp) 2135 if (card->vlangrp)
2144 vlan_hwaccel_rx(skb, card->vlangrp, 2136 vlan_gro_receive(&card->napi,
2145 vlan_tag); 2137 card->vlangrp, vlan_tag, skb);
2146 else { 2138 else {
2147 dev_kfree_skb_any(skb); 2139 dev_kfree_skb_any(skb);
2148 continue; 2140 continue;
2149 } 2141 }
2150 else 2142 else
2151 netif_rx(skb); 2143 napi_gro_receive(&card->napi, skb);
2152 break; 2144 break;
2153 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ 2145 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
2154 skb->pkt_type = PACKET_HOST; 2146 skb->pkt_type = PACKET_HOST;
2155 skb->protocol = eth_type_trans(skb, skb->dev); 2147 skb->protocol = eth_type_trans(skb, skb->dev);
2156 if (card->options.checksum_type == NO_CHECKSUMMING)
2157 skb->ip_summed = CHECKSUM_UNNECESSARY;
2158 else
2159 skb->ip_summed = CHECKSUM_NONE;
2160 len = skb->len; 2148 len = skb->len;
2161 netif_receive_skb(skb); 2149 netif_receive_skb(skb);
2162 break; 2150 break;
@@ -2166,10 +2154,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2166 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); 2154 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
2167 continue; 2155 continue;
2168 } 2156 }
2169 2157 work_done++;
2158 budget--;
2170 card->stats.rx_packets++; 2159 card->stats.rx_packets++;
2171 card->stats.rx_bytes += len; 2160 card->stats.rx_bytes += len;
2172 } 2161 }
2162 return work_done;
2163}
2164
2165static int qeth_l3_poll(struct napi_struct *napi, int budget)
2166{
2167 struct qeth_card *card = container_of(napi, struct qeth_card, napi);
2168 int work_done = 0;
2169 struct qeth_qdio_buffer *buffer;
2170 int done;
2171 int new_budget = budget;
2172
2173 if (card->options.performance_stats) {
2174 card->perf_stats.inbound_cnt++;
2175 card->perf_stats.inbound_start_time = qeth_get_micros();
2176 }
2177
2178 while (1) {
2179 if (!card->rx.b_count) {
2180 card->rx.qdio_err = 0;
2181 card->rx.b_count = qdio_get_next_buffers(
2182 card->data.ccwdev, 0, &card->rx.b_index,
2183 &card->rx.qdio_err);
2184 if (card->rx.b_count <= 0) {
2185 card->rx.b_count = 0;
2186 break;
2187 }
2188 card->rx.b_element =
2189 &card->qdio.in_q->bufs[card->rx.b_index]
2190 .buffer->element[0];
2191 card->rx.e_offset = 0;
2192 }
2193
2194 while (card->rx.b_count) {
2195 buffer = &card->qdio.in_q->bufs[card->rx.b_index];
2196 if (!(card->rx.qdio_err &&
2197 qeth_check_qdio_errors(card, buffer->buffer,
2198 card->rx.qdio_err, "qinerr")))
2199 work_done += qeth_l3_process_inbound_buffer(
2200 card, new_budget, &done);
2201 else
2202 done = 1;
2203
2204 if (done) {
2205 if (card->options.performance_stats)
2206 card->perf_stats.bufs_rec++;
2207 qeth_put_buffer_pool_entry(card,
2208 buffer->pool_entry);
2209 qeth_queue_input_buffer(card, card->rx.b_index);
2210 card->rx.b_count--;
2211 if (card->rx.b_count) {
2212 card->rx.b_index =
2213 (card->rx.b_index + 1) %
2214 QDIO_MAX_BUFFERS_PER_Q;
2215 card->rx.b_element =
2216 &card->qdio.in_q
2217 ->bufs[card->rx.b_index]
2218 .buffer->element[0];
2219 card->rx.e_offset = 0;
2220 }
2221 }
2222
2223 if (work_done >= budget)
2224 goto out;
2225 else
2226 new_budget = budget - work_done;
2227 }
2228 }
2229
2230 napi_complete(napi);
2231 if (qdio_start_irq(card->data.ccwdev, 0))
2232 napi_schedule(&card->napi);
2233out:
2234 if (card->options.performance_stats)
2235 card->perf_stats.inbound_time += qeth_get_micros() -
2236 card->perf_stats.inbound_start_time;
2237 return work_done;
2173} 2238}
2174 2239
2175static int qeth_l3_verify_vlan_dev(struct net_device *dev, 2240static int qeth_l3_verify_vlan_dev(struct net_device *dev,
@@ -3103,6 +3168,7 @@ tx_drop:
3103static int qeth_l3_open(struct net_device *dev) 3168static int qeth_l3_open(struct net_device *dev)
3104{ 3169{
3105 struct qeth_card *card = dev->ml_priv; 3170 struct qeth_card *card = dev->ml_priv;
3171 int rc = 0;
3106 3172
3107 QETH_CARD_TEXT(card, 4, "qethopen"); 3173 QETH_CARD_TEXT(card, 4, "qethopen");
3108 if (card->state != CARD_STATE_SOFTSETUP) 3174 if (card->state != CARD_STATE_SOFTSETUP)
@@ -3113,7 +3179,12 @@ static int qeth_l3_open(struct net_device *dev)
3113 3179
3114 if (!card->lan_online && netif_carrier_ok(dev)) 3180 if (!card->lan_online && netif_carrier_ok(dev))
3115 netif_carrier_off(dev); 3181 netif_carrier_off(dev);
3116 return 0; 3182 if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
3183 napi_enable(&card->napi);
3184 napi_schedule(&card->napi);
3185 } else
3186 rc = -EIO;
3187 return rc;
3117} 3188}
3118 3189
3119static int qeth_l3_stop(struct net_device *dev) 3190static int qeth_l3_stop(struct net_device *dev)
@@ -3122,8 +3193,10 @@ static int qeth_l3_stop(struct net_device *dev)
3122 3193
3123 QETH_CARD_TEXT(card, 4, "qethstop"); 3194 QETH_CARD_TEXT(card, 4, "qethstop");
3124 netif_tx_disable(dev); 3195 netif_tx_disable(dev);
3125 if (card->state == CARD_STATE_UP) 3196 if (card->state == CARD_STATE_UP) {
3126 card->state = CARD_STATE_SOFTSETUP; 3197 card->state = CARD_STATE_SOFTSETUP;
3198 napi_disable(&card->napi);
3199 }
3127 return 0; 3200 return 0;
3128} 3201}
3129 3202
@@ -3293,57 +3366,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
3293 card->dev->gso_max_size = 15 * PAGE_SIZE; 3366 card->dev->gso_max_size = 15 * PAGE_SIZE;
3294 3367
3295 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 3368 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
3369 netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
3296 return register_netdev(card->dev); 3370 return register_netdev(card->dev);
3297} 3371}
3298 3372
3299static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
3300 unsigned int qdio_err, unsigned int queue, int first_element,
3301 int count, unsigned long card_ptr)
3302{
3303 struct net_device *net_dev;
3304 struct qeth_card *card;
3305 struct qeth_qdio_buffer *buffer;
3306 int index;
3307 int i;
3308
3309 card = (struct qeth_card *) card_ptr;
3310 net_dev = card->dev;
3311 if (card->options.performance_stats) {
3312 card->perf_stats.inbound_cnt++;
3313 card->perf_stats.inbound_start_time = qeth_get_micros();
3314 }
3315 if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
3316 QETH_CARD_TEXT(card, 1, "qdinchk");
3317 QETH_CARD_TEXT_(card, 1, "%04X%04X",
3318 first_element, count);
3319 QETH_CARD_TEXT_(card, 1, "%04X", queue);
3320 qeth_schedule_recovery(card);
3321 return;
3322 }
3323 for (i = first_element; i < (first_element + count); ++i) {
3324 index = i % QDIO_MAX_BUFFERS_PER_Q;
3325 buffer = &card->qdio.in_q->bufs[index];
3326 if (!(qdio_err &&
3327 qeth_check_qdio_errors(card, buffer->buffer,
3328 qdio_err, "qinerr")))
3329 qeth_l3_process_inbound_buffer(card, buffer, index);
3330 /* clear buffer and give back to hardware */
3331 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
3332 qeth_queue_input_buffer(card, index);
3333 }
3334 if (card->options.performance_stats)
3335 card->perf_stats.inbound_time += qeth_get_micros() -
3336 card->perf_stats.inbound_start_time;
3337}
3338
3339static int qeth_l3_probe_device(struct ccwgroup_device *gdev) 3373static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
3340{ 3374{
3341 struct qeth_card *card = dev_get_drvdata(&gdev->dev); 3375 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3342 3376
3343 qeth_l3_create_device_attributes(&gdev->dev); 3377 qeth_l3_create_device_attributes(&gdev->dev);
3344 card->options.layer2 = 0; 3378 card->options.layer2 = 0;
3379 card->discipline.start_poll = qeth_qdio_start_poll;
3345 card->discipline.input_handler = (qdio_handler_t *) 3380 card->discipline.input_handler = (qdio_handler_t *)
3346 qeth_l3_qdio_input_handler; 3381 qeth_qdio_input_handler;
3347 card->discipline.output_handler = (qdio_handler_t *) 3382 card->discipline.output_handler = (qdio_handler_t *)
3348 qeth_qdio_output_handler; 3383 qeth_qdio_output_handler;
3349 card->discipline.recover = qeth_l3_recover; 3384 card->discipline.recover = qeth_l3_recover;
@@ -3402,6 +3437,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3402 } 3437 }
3403 3438
3404 card->state = CARD_STATE_HARDSETUP; 3439 card->state = CARD_STATE_HARDSETUP;
3440 memset(&card->rx, 0, sizeof(struct qeth_rx));
3405 qeth_print_status_message(card); 3441 qeth_print_status_message(card);
3406 3442
3407 /* softsetup */ 3443 /* softsetup */
@@ -3538,9 +3574,6 @@ static int qeth_l3_recover(void *ptr)
3538 card->use_hard_stop = 1; 3574 card->use_hard_stop = 1;
3539 __qeth_l3_set_offline(card->gdev, 1); 3575 __qeth_l3_set_offline(card->gdev, 1);
3540 rc = __qeth_l3_set_online(card->gdev, 1); 3576 rc = __qeth_l3_set_online(card->gdev, 1);
3541 /* don't run another scheduled recovery */
3542 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3543 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
3544 if (!rc) 3577 if (!rc)
3545 dev_info(&card->gdev->dev, 3578 dev_info(&card->gdev->dev,
3546 "Device successfully recovered!\n"); 3579 "Device successfully recovered!\n");
@@ -3551,6 +3584,8 @@ static int qeth_l3_recover(void *ptr)
3551 dev_warn(&card->gdev->dev, "The qeth device driver " 3584 dev_warn(&card->gdev->dev, "The qeth device driver "
3552 "failed to recover an error on the device\n"); 3585 "failed to recover an error on the device\n");
3553 } 3586 }
3587 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3588 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
3554 return 0; 3589 return 0;
3555} 3590}
3556 3591