aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorUrsula Braun <ursula.braun@de.ibm.com>2010-01-10 21:50:50 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-13 23:34:55 -0500
commit76b11f8e270f04851774ff64b16e29e5a43d3a1a (patch)
treed4e7666c766bd1fba5ef2219717f302faf3a21bf /drivers
parentab8932f3e8e07df92d6ce3fa41f5af0dda865429 (diff)
qeth: HiperSockets Network Traffic Analyzer
New feature to trace HiperSockets network traffic for debugging purposes. Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/net/qeth_core.h5
-rw-r--r--drivers/s390/net/qeth_core_main.c130
-rw-r--r--drivers/s390/net/qeth_core_mpc.h44
-rw-r--r--drivers/s390/net/qeth_core_sys.c8
-rw-r--r--drivers/s390/net/qeth_l2_main.c3
-rw-r--r--drivers/s390/net/qeth_l3.h2
-rw-r--r--drivers/s390/net/qeth_l3_main.c174
-rw-r--r--drivers/s390/net/qeth_l3_sys.c56
8 files changed, 336 insertions, 86 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index b232693378cd..a3ac4456e0b1 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -649,6 +649,7 @@ struct qeth_card_options {
649 int performance_stats; 649 int performance_stats;
650 int rx_sg_cb; 650 int rx_sg_cb;
651 enum qeth_ipa_isolation_modes isolation; 651 enum qeth_ipa_isolation_modes isolation;
652 int sniffer;
652}; 653};
653 654
654/* 655/*
@@ -737,6 +738,7 @@ struct qeth_card {
737 struct qeth_discipline discipline; 738 struct qeth_discipline discipline;
738 atomic_t force_alloc_skb; 739 atomic_t force_alloc_skb;
739 struct service_level qeth_service_level; 740 struct service_level qeth_service_level;
741 struct qdio_ssqd_desc ssqd;
740}; 742};
741 743
742struct qeth_card_list_struct { 744struct qeth_card_list_struct {
@@ -811,7 +813,8 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
811struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, 813struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
812 enum qeth_ipa_cmds, enum qeth_prot_versions); 814 enum qeth_ipa_cmds, enum qeth_prot_versions);
813int qeth_query_setadapterparms(struct qeth_card *); 815int qeth_query_setadapterparms(struct qeth_card *);
814int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *); 816int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
817 unsigned int, const char *);
815void qeth_queue_input_buffer(struct qeth_card *, int); 818void qeth_queue_input_buffer(struct qeth_card *, int);
816struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, 819struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
817 struct qdio_buffer *, struct qdio_buffer_element **, int *, 820 struct qdio_buffer *, struct qdio_buffer_element **, int *,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d34804d5ece1..2c8e9da8753f 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -269,6 +269,7 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
269 card->qdio.init_pool.buf_count = bufcnt; 269 card->qdio.init_pool.buf_count = bufcnt;
270 return qeth_alloc_buffer_pool(card); 270 return qeth_alloc_buffer_pool(card);
271} 271}
272EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
272 273
273static int qeth_issue_next_read(struct qeth_card *card) 274static int qeth_issue_next_read(struct qeth_card *card)
274{ 275{
@@ -350,8 +351,10 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
350 if (IS_IPA(iob->data)) { 351 if (IS_IPA(iob->data)) {
351 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data); 352 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
352 if (IS_IPA_REPLY(cmd)) { 353 if (IS_IPA_REPLY(cmd)) {
353 if (cmd->hdr.command < IPA_CMD_SETCCID || 354 if (cmd->hdr.command != IPA_CMD_SETCCID &&
354 cmd->hdr.command > IPA_CMD_MODCCID) 355 cmd->hdr.command != IPA_CMD_DELCCID &&
356 cmd->hdr.command != IPA_CMD_MODCCID &&
357 cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
355 qeth_issue_ipa_msg(cmd, 358 qeth_issue_ipa_msg(cmd,
356 cmd->hdr.return_code, card); 359 cmd->hdr.return_code, card);
357 return cmd; 360 return cmd;
@@ -1100,11 +1103,6 @@ static int qeth_setup_card(struct qeth_card *card)
1100 card->thread_running_mask = 0; 1103 card->thread_running_mask = 0;
1101 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread); 1104 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1102 INIT_LIST_HEAD(&card->ip_list); 1105 INIT_LIST_HEAD(&card->ip_list);
1103 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1104 if (!card->ip_tbd_list) {
1105 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1106 return -ENOMEM;
1107 }
1108 INIT_LIST_HEAD(card->ip_tbd_list); 1106 INIT_LIST_HEAD(card->ip_tbd_list);
1109 INIT_LIST_HEAD(&card->cmd_waiter_list); 1107 INIT_LIST_HEAD(&card->cmd_waiter_list);
1110 init_waitqueue_head(&card->wait_q); 1108 init_waitqueue_head(&card->wait_q);
@@ -1138,21 +1136,30 @@ static struct qeth_card *qeth_alloc_card(void)
1138 QETH_DBF_TEXT(SETUP, 2, "alloccrd"); 1136 QETH_DBF_TEXT(SETUP, 2, "alloccrd");
1139 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL); 1137 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
1140 if (!card) 1138 if (!card)
1141 return NULL; 1139 goto out;
1142 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 1140 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
1143 if (qeth_setup_channel(&card->read)) { 1141 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1144 kfree(card); 1142 if (!card->ip_tbd_list) {
1145 return NULL; 1143 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1146 } 1144 goto out_card;
1147 if (qeth_setup_channel(&card->write)) {
1148 qeth_clean_channel(&card->read);
1149 kfree(card);
1150 return NULL;
1151 } 1145 }
1146 if (qeth_setup_channel(&card->read))
1147 goto out_ip;
1148 if (qeth_setup_channel(&card->write))
1149 goto out_channel;
1152 card->options.layer2 = -1; 1150 card->options.layer2 = -1;
1153 card->qeth_service_level.seq_print = qeth_core_sl_print; 1151 card->qeth_service_level.seq_print = qeth_core_sl_print;
1154 register_service_level(&card->qeth_service_level); 1152 register_service_level(&card->qeth_service_level);
1155 return card; 1153 return card;
1154
1155out_channel:
1156 qeth_clean_channel(&card->read);
1157out_ip:
1158 kfree(card->ip_tbd_list);
1159out_card:
1160 kfree(card);
1161out:
1162 return NULL;
1156} 1163}
1157 1164
1158static int qeth_determine_card_type(struct qeth_card *card) 1165static int qeth_determine_card_type(struct qeth_card *card)
@@ -2573,8 +2580,8 @@ int qeth_query_setadapterparms(struct qeth_card *card)
2573} 2580}
2574EXPORT_SYMBOL_GPL(qeth_query_setadapterparms); 2581EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
2575 2582
2576int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, 2583int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
2577 const char *dbftext) 2584 unsigned int qdio_error, const char *dbftext)
2578{ 2585{
2579 if (qdio_error) { 2586 if (qdio_error) {
2580 QETH_DBF_TEXT(TRACE, 2, dbftext); 2587 QETH_DBF_TEXT(TRACE, 2, dbftext);
@@ -2584,7 +2591,11 @@ int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2584 QETH_DBF_TEXT_(QERR, 2, " F14=%02X", 2591 QETH_DBF_TEXT_(QERR, 2, " F14=%02X",
2585 buf->element[14].flags & 0xff); 2592 buf->element[14].flags & 0xff);
2586 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error); 2593 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error);
2587 return 1; 2594 if ((buf->element[15].flags & 0xff) == 0x12) {
2595 card->stats.rx_dropped++;
2596 return 0;
2597 } else
2598 return 1;
2588 } 2599 }
2589 return 0; 2600 return 0;
2590} 2601}
@@ -2667,7 +2678,7 @@ static int qeth_handle_send_error(struct qeth_card *card,
2667 qdio_err = 1; 2678 qdio_err = 1;
2668 } 2679 }
2669 } 2680 }
2670 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr"); 2681 qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
2671 2682
2672 if (!qdio_err) 2683 if (!qdio_err)
2673 return QETH_SEND_ERROR_NONE; 2684 return QETH_SEND_ERROR_NONE;
@@ -3509,6 +3520,7 @@ void qeth_tx_timeout(struct net_device *dev)
3509{ 3520{
3510 struct qeth_card *card; 3521 struct qeth_card *card;
3511 3522
3523 QETH_DBF_TEXT(TRACE, 4, "txtimeo");
3512 card = dev->ml_priv; 3524 card = dev->ml_priv;
3513 card->stats.tx_errors++; 3525 card->stats.tx_errors++;
3514 qeth_schedule_recovery(card); 3526 qeth_schedule_recovery(card);
@@ -3847,9 +3859,7 @@ static int qeth_core_driver_group(const char *buf, struct device *root_dev,
3847 3859
3848int qeth_core_hardsetup_card(struct qeth_card *card) 3860int qeth_core_hardsetup_card(struct qeth_card *card)
3849{ 3861{
3850 struct qdio_ssqd_desc *ssqd;
3851 int retries = 0; 3862 int retries = 0;
3852 int mpno = 0;
3853 int rc; 3863 int rc;
3854 3864
3855 QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); 3865 QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
@@ -3882,31 +3892,6 @@ retriable:
3882 else 3892 else
3883 goto retry; 3893 goto retry;
3884 } 3894 }
3885
3886 rc = qeth_get_unitaddr(card);
3887 if (rc) {
3888 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3889 return rc;
3890 }
3891
3892 ssqd = kmalloc(sizeof(struct qdio_ssqd_desc), GFP_KERNEL);
3893 if (!ssqd) {
3894 rc = -ENOMEM;
3895 goto out;
3896 }
3897 rc = qdio_get_ssqd_desc(CARD_DDEV(card), ssqd);
3898 if (rc == 0)
3899 mpno = ssqd->pcnt;
3900 kfree(ssqd);
3901
3902 if (mpno)
3903 mpno = min(mpno - 1, QETH_MAX_PORTNO);
3904 if (card->info.portno > mpno) {
3905 QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d"
3906 "\n.", CARD_BUS_ID(card), card->info.portno);
3907 rc = -ENODEV;
3908 goto out;
3909 }
3910 qeth_init_tokens(card); 3895 qeth_init_tokens(card);
3911 qeth_init_func_level(card); 3896 qeth_init_func_level(card);
3912 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); 3897 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -3990,7 +3975,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
3990 struct qdio_buffer_element *element = *__element; 3975 struct qdio_buffer_element *element = *__element;
3991 int offset = *__offset; 3976 int offset = *__offset;
3992 struct sk_buff *skb = NULL; 3977 struct sk_buff *skb = NULL;
3993 int skb_len; 3978 int skb_len = 0;
3994 void *data_ptr; 3979 void *data_ptr;
3995 int data_len; 3980 int data_len;
3996 int headroom = 0; 3981 int headroom = 0;
@@ -4009,20 +3994,24 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
4009 *hdr = element->addr + offset; 3994 *hdr = element->addr + offset;
4010 3995
4011 offset += sizeof(struct qeth_hdr); 3996 offset += sizeof(struct qeth_hdr);
4012 if (card->options.layer2) { 3997 switch ((*hdr)->hdr.l2.id) {
4013 if (card->info.type == QETH_CARD_TYPE_OSN) { 3998 case QETH_HEADER_TYPE_LAYER2:
4014 skb_len = (*hdr)->hdr.osn.pdu_length; 3999 skb_len = (*hdr)->hdr.l2.pkt_length;
4015 headroom = sizeof(struct qeth_hdr); 4000 break;
4016 } else { 4001 case QETH_HEADER_TYPE_LAYER3:
4017 skb_len = (*hdr)->hdr.l2.pkt_length;
4018 }
4019 } else {
4020 skb_len = (*hdr)->hdr.l3.length; 4002 skb_len = (*hdr)->hdr.l3.length;
4021 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || 4003 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
4022 (card->info.link_type == QETH_LINK_TYPE_HSTR)) 4004 (card->info.link_type == QETH_LINK_TYPE_HSTR))
4023 headroom = TR_HLEN; 4005 headroom = TR_HLEN;
4024 else 4006 else
4025 headroom = ETH_HLEN; 4007 headroom = ETH_HLEN;
4008 break;
4009 case QETH_HEADER_TYPE_OSN:
4010 skb_len = (*hdr)->hdr.osn.pdu_length;
4011 headroom = sizeof(struct qeth_hdr);
4012 break;
4013 default:
4014 break;
4026 } 4015 }
4027 4016
4028 if (!skb_len) 4017 if (!skb_len)
@@ -4177,6 +4166,33 @@ void qeth_core_free_discipline(struct qeth_card *card)
4177 card->discipline.ccwgdriver = NULL; 4166 card->discipline.ccwgdriver = NULL;
4178} 4167}
4179 4168
4169static void qeth_determine_capabilities(struct qeth_card *card)
4170{
4171 int rc;
4172
4173 QETH_DBF_TEXT(SETUP, 2, "detcapab");
4174 rc = ccw_device_set_online(CARD_DDEV(card));
4175 if (rc) {
4176 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
4177 goto out;
4178 }
4179
4180 rc = qeth_get_unitaddr(card);
4181 if (rc) {
4182 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
4183 goto out_offline;
4184 }
4185
4186 rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
4187 if (rc)
4188 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
4189
4190out_offline:
4191 ccw_device_set_offline(CARD_DDEV(card));
4192out:
4193 return;
4194}
4195
4180static int qeth_core_probe_device(struct ccwgroup_device *gdev) 4196static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4181{ 4197{
4182 struct qeth_card *card; 4198 struct qeth_card *card;
@@ -4242,6 +4258,8 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4242 write_lock_irqsave(&qeth_core_card_list.rwlock, flags); 4258 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
4243 list_add_tail(&card->list, &qeth_core_card_list.list); 4259 list_add_tail(&card->list, &qeth_core_card_list.list);
4244 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); 4260 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
4261
4262 qeth_determine_capabilities(card);
4245 return 0; 4263 return 0;
4246 4264
4247err_card: 4265err_card:
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 1ba51152f667..104a3351e02b 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -156,6 +156,8 @@ enum qeth_ipa_return_codes {
156 IPA_RC_IP_TABLE_FULL = 0x0002, 156 IPA_RC_IP_TABLE_FULL = 0x0002,
157 IPA_RC_UNKNOWN_ERROR = 0x0003, 157 IPA_RC_UNKNOWN_ERROR = 0x0003,
158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004, 158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
159 IPA_RC_TRACE_ALREADY_ACTIVE = 0x0005,
160 IPA_RC_INVALID_FORMAT = 0x0006,
159 IPA_RC_DUP_IPV6_REMOTE = 0x0008, 161 IPA_RC_DUP_IPV6_REMOTE = 0x0008,
160 IPA_RC_DUP_IPV6_HOME = 0x0010, 162 IPA_RC_DUP_IPV6_HOME = 0x0010,
161 IPA_RC_UNREGISTERED_ADDR = 0x0011, 163 IPA_RC_UNREGISTERED_ADDR = 0x0011,
@@ -196,6 +198,11 @@ enum qeth_ipa_return_codes {
196 IPA_RC_INVALID_IP_VERSION2 = 0xf001, 198 IPA_RC_INVALID_IP_VERSION2 = 0xf001,
197 IPA_RC_FFFF = 0xffff 199 IPA_RC_FFFF = 0xffff
198}; 200};
201/* for DELIP */
202#define IPA_RC_IP_ADDRESS_NOT_DEFINED IPA_RC_PRIMARY_ALREADY_DEFINED
203/* for SET_DIAGNOSTIC_ASSIST */
204#define IPA_RC_INVALID_SUBCMD IPA_RC_IP_TABLE_FULL
205#define IPA_RC_HARDWARE_AUTH_ERROR IPA_RC_UNKNOWN_ERROR
199 206
200/* IPA function flags; each flag marks availability of respective function */ 207/* IPA function flags; each flag marks availability of respective function */
201enum qeth_ipa_funcs { 208enum qeth_ipa_funcs {
@@ -246,6 +253,7 @@ enum qeth_ipa_setadp_cmd {
246 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L, 253 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
247 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L, 254 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
248 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, 255 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
256 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
249 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, 257 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
250}; 258};
251enum qeth_ipa_mac_ops { 259enum qeth_ipa_mac_ops {
@@ -424,6 +432,40 @@ struct qeth_create_destroy_address {
424 __u8 unique_id[8]; 432 __u8 unique_id[8];
425} __attribute__ ((packed)); 433} __attribute__ ((packed));
426 434
435/* SET DIAGNOSTIC ASSIST IPA Command: *************************************/
436
437enum qeth_diags_cmds {
438 QETH_DIAGS_CMD_QUERY = 0x0001,
439 QETH_DIAGS_CMD_TRAP = 0x0002,
440 QETH_DIAGS_CMD_TRACE = 0x0004,
441 QETH_DIAGS_CMD_NOLOG = 0x0008,
442 QETH_DIAGS_CMD_DUMP = 0x0010,
443};
444
445enum qeth_diags_trace_types {
446 QETH_DIAGS_TYPE_HIPERSOCKET = 0x02,
447};
448
449enum qeth_diags_trace_cmds {
450 QETH_DIAGS_CMD_TRACE_ENABLE = 0x0001,
451 QETH_DIAGS_CMD_TRACE_DISABLE = 0x0002,
452 QETH_DIAGS_CMD_TRACE_MODIFY = 0x0004,
453 QETH_DIAGS_CMD_TRACE_REPLACE = 0x0008,
454 QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
455};
456
457struct qeth_ipacmd_diagass {
458 __u32 host_tod2;
459 __u32:32;
460 __u16 subcmd_len;
461 __u16:16;
462 __u32 subcmd;
463 __u8 type;
464 __u8 action;
465 __u16 options;
466 __u32:32;
467} __attribute__ ((packed));
468
427/* Header for each IPA command */ 469/* Header for each IPA command */
428struct qeth_ipacmd_hdr { 470struct qeth_ipacmd_hdr {
429 __u8 command; 471 __u8 command;
@@ -452,6 +494,7 @@ struct qeth_ipa_cmd {
452 struct qeth_create_destroy_address create_destroy_addr; 494 struct qeth_create_destroy_address create_destroy_addr;
453 struct qeth_ipacmd_setadpparms setadapterparms; 495 struct qeth_ipacmd_setadpparms setadapterparms;
454 struct qeth_set_routing setrtg; 496 struct qeth_set_routing setrtg;
497 struct qeth_ipacmd_diagass diagass;
455 } data; 498 } data;
456} __attribute__ ((packed)); 499} __attribute__ ((packed));
457 500
@@ -469,7 +512,6 @@ enum qeth_ipa_arp_return_codes {
469 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, 512 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
470}; 513};
471 514
472
473extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); 515extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
474extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); 516extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
475 517
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 9ff2b36fdc43..ac2239a4f133 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -118,7 +118,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
118{ 118{
119 struct qeth_card *card = dev_get_drvdata(dev); 119 struct qeth_card *card = dev_get_drvdata(dev);
120 char *tmp; 120 char *tmp;
121 unsigned int portno; 121 unsigned int portno, limit;
122 122
123 if (!card) 123 if (!card)
124 return -EINVAL; 124 return -EINVAL;
@@ -128,9 +128,11 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
128 return -EPERM; 128 return -EPERM;
129 129
130 portno = simple_strtoul(buf, &tmp, 16); 130 portno = simple_strtoul(buf, &tmp, 16);
131 if (portno > QETH_MAX_PORTNO) { 131 if (portno > QETH_MAX_PORTNO)
132 return -EINVAL;
133 limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
134 if (portno > limit)
132 return -EINVAL; 135 return -EINVAL;
133 }
134 136
135 card->info.portno = portno; 137 card->info.portno = portno;
136 return count; 138 return count;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 038299ae3feb..74ba388a159f 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -769,7 +769,8 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
769 index = i % QDIO_MAX_BUFFERS_PER_Q; 769 index = i % QDIO_MAX_BUFFERS_PER_Q;
770 buffer = &card->qdio.in_q->bufs[index]; 770 buffer = &card->qdio.in_q->bufs[index];
771 if (!(qdio_err && 771 if (!(qdio_err &&
772 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr"))) 772 qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
773 "qinerr")))
773 qeth_l2_process_inbound_buffer(card, buffer, index); 774 qeth_l2_process_inbound_buffer(card, buffer, index);
774 /* clear buffer and give back to hardware */ 775 /* clear buffer and give back to hardware */
775 qeth_put_buffer_pool_entry(card, buffer->pool_entry); 776 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
index 321988fa9f7d..8447d233d0b3 100644
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -13,6 +13,8 @@
13 13
14#include "qeth_core.h" 14#include "qeth_core.h"
15 15
16#define QETH_SNIFF_AVAIL 0x0008
17
16struct qeth_ipaddr { 18struct qeth_ipaddr {
17 struct list_head entry; 19 struct list_head entry;
18 enum qeth_ip_types type; 20 enum qeth_ip_types type;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index fd1b6ed3721f..337d03fb045d 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -242,6 +242,8 @@ static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
242 struct qeth_ipaddr *tmp, *t; 242 struct qeth_ipaddr *tmp, *t;
243 int found = 0; 243 int found = 0;
244 244
245 if (card->options.sniffer)
246 return 0;
245 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) { 247 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
246 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && 248 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
247 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) 249 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
@@ -457,6 +459,8 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
457 QETH_DBF_TEXT(TRACE, 2, "sdiplist"); 459 QETH_DBF_TEXT(TRACE, 2, "sdiplist");
458 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *)); 460 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
459 461
462 if (card->options.sniffer)
463 return;
460 spin_lock_irqsave(&card->ip_lock, flags); 464 spin_lock_irqsave(&card->ip_lock, flags);
461 tbd_list = card->ip_tbd_list; 465 tbd_list = card->ip_tbd_list;
462 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); 466 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
@@ -495,7 +499,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
495 spin_unlock_irqrestore(&card->ip_lock, flags); 499 spin_unlock_irqrestore(&card->ip_lock, flags);
496 rc = qeth_l3_deregister_addr_entry(card, addr); 500 rc = qeth_l3_deregister_addr_entry(card, addr);
497 spin_lock_irqsave(&card->ip_lock, flags); 501 spin_lock_irqsave(&card->ip_lock, flags);
498 if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED)) 502 if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
499 kfree(addr); 503 kfree(addr);
500 else 504 else
501 list_add_tail(&addr->entry, &card->ip_list); 505 list_add_tail(&addr->entry, &card->ip_list);
@@ -513,6 +517,8 @@ static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean,
513 unsigned long flags; 517 unsigned long flags;
514 518
515 QETH_DBF_TEXT(TRACE, 4, "clearip"); 519 QETH_DBF_TEXT(TRACE, 4, "clearip");
520 if (recover && card->options.sniffer)
521 return;
516 spin_lock_irqsave(&card->ip_lock, flags); 522 spin_lock_irqsave(&card->ip_lock, flags);
517 /* clear todo list */ 523 /* clear todo list */
518 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) { 524 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
@@ -1674,6 +1680,76 @@ static int qeth_l3_get_unique_id(struct qeth_card *card)
1674 return rc; 1680 return rc;
1675} 1681}
1676 1682
1683static int
1684qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
1685 unsigned long data)
1686{
1687 struct qeth_ipa_cmd *cmd;
1688 __u16 rc;
1689
1690 QETH_DBF_TEXT(SETUP, 2, "diastrcb");
1691
1692 cmd = (struct qeth_ipa_cmd *)data;
1693 rc = cmd->hdr.return_code;
1694 if (rc) {
1695 QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
1696 if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
1697 switch (rc) {
1698 case IPA_RC_HARDWARE_AUTH_ERROR:
1699 dev_warn(&card->gdev->dev, "The device is not "
1700 "authorized to run as a HiperSockets "
1701 "network traffic analyzer\n");
1702 break;
1703 case IPA_RC_TRACE_ALREADY_ACTIVE:
1704 dev_warn(&card->gdev->dev, "A HiperSockets "
1705 "network traffic analyzer is already "
1706 "active in the HiperSockets LAN\n");
1707 break;
1708 default:
1709 break;
1710 }
1711 }
1712 return 0;
1713 }
1714
1715 switch (cmd->data.diagass.action) {
1716 case QETH_DIAGS_CMD_TRACE_QUERY:
1717 break;
1718 case QETH_DIAGS_CMD_TRACE_DISABLE:
1719 card->info.promisc_mode = SET_PROMISC_MODE_OFF;
1720 dev_info(&card->gdev->dev, "The HiperSockets network traffic "
1721 "analyzer is deactivated\n");
1722 break;
1723 case QETH_DIAGS_CMD_TRACE_ENABLE:
1724 card->info.promisc_mode = SET_PROMISC_MODE_ON;
1725 dev_info(&card->gdev->dev, "The HiperSockets network traffic "
1726 "analyzer is activated\n");
1727 break;
1728 default:
1729 QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
1730 cmd->data.diagass.action, QETH_CARD_IFNAME(card));
1731 }
1732
1733 return 0;
1734}
1735
1736static int
1737qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
1738{
1739 struct qeth_cmd_buffer *iob;
1740 struct qeth_ipa_cmd *cmd;
1741
1742 QETH_DBF_TEXT(SETUP, 2, "diagtrac");
1743
1744 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
1745 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1746 cmd->data.diagass.subcmd_len = 16;
1747 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
1748 cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
1749 cmd->data.diagass.action = diags_cmd;
1750 return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
1751}
1752
1677static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, 1753static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
1678 struct net_device *dev) 1754 struct net_device *dev)
1679{ 1755{
@@ -1951,7 +2027,10 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
1951 case QETH_CAST_ANYCAST: 2027 case QETH_CAST_ANYCAST:
1952 case QETH_CAST_NOCAST: 2028 case QETH_CAST_NOCAST:
1953 default: 2029 default:
1954 skb->pkt_type = PACKET_HOST; 2030 if (card->options.sniffer)
2031 skb->pkt_type = PACKET_OTHERHOST;
2032 else
2033 skb->pkt_type = PACKET_HOST;
1955 memcpy(tg_addr, card->dev->dev_addr, 2034 memcpy(tg_addr, card->dev->dev_addr,
1956 card->dev->addr_len); 2035 card->dev->addr_len);
1957 } 2036 }
@@ -2007,7 +2086,6 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2007 int offset; 2086 int offset;
2008 __u16 vlan_tag = 0; 2087 __u16 vlan_tag = 0;
2009 unsigned int len; 2088 unsigned int len;
2010
2011 /* get first element of current buffer */ 2089 /* get first element of current buffer */
2012 element = (struct qdio_buffer_element *)&buf->buffer->element[0]; 2090 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
2013 offset = 0; 2091 offset = 0;
@@ -2026,7 +2104,7 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2026 case QETH_HEADER_TYPE_LAYER3: 2104 case QETH_HEADER_TYPE_LAYER3:
2027 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); 2105 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
2028 len = skb->len; 2106 len = skb->len;
2029 if (vlan_tag) 2107 if (vlan_tag && !card->options.sniffer)
2030 if (card->vlangrp) 2108 if (card->vlangrp)
2031 vlan_hwaccel_rx(skb, card->vlangrp, 2109 vlan_hwaccel_rx(skb, card->vlangrp,
2032 vlan_tag); 2110 vlan_tag);
@@ -2037,6 +2115,16 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2037 else 2115 else
2038 netif_rx(skb); 2116 netif_rx(skb);
2039 break; 2117 break;
2118 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
2119 skb->pkt_type = PACKET_HOST;
2120 skb->protocol = eth_type_trans(skb, skb->dev);
2121 if (card->options.checksum_type == NO_CHECKSUMMING)
2122 skb->ip_summed = CHECKSUM_UNNECESSARY;
2123 else
2124 skb->ip_summed = CHECKSUM_NONE;
2125 len = skb->len;
2126 netif_receive_skb(skb);
2127 break;
2040 default: 2128 default:
2041 dev_kfree_skb_any(skb); 2129 dev_kfree_skb_any(skb);
2042 QETH_DBF_TEXT(TRACE, 3, "inbunkno"); 2130 QETH_DBF_TEXT(TRACE, 3, "inbunkno");
@@ -2118,6 +2206,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2118 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 2206 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
2119 2207
2120 qeth_set_allowed_threads(card, 0, 1); 2208 qeth_set_allowed_threads(card, 0, 1);
2209 if (card->options.sniffer &&
2210 (card->info.promisc_mode == SET_PROMISC_MODE_ON))
2211 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2121 if (card->read.state == CH_STATE_UP && 2212 if (card->read.state == CH_STATE_UP &&
2122 card->write.state == CH_STATE_UP && 2213 card->write.state == CH_STATE_UP &&
2123 (card->state == CARD_STATE_UP)) { 2214 (card->state == CARD_STATE_UP)) {
@@ -2162,6 +2253,36 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2162 return rc; 2253 return rc;
2163} 2254}
2164 2255
2256/*
2257 * test for and Switch promiscuous mode (on or off)
2258 * either for guestlan or HiperSocket Sniffer
2259 */
2260static void
2261qeth_l3_handle_promisc_mode(struct qeth_card *card)
2262{
2263 struct net_device *dev = card->dev;
2264
2265 if (((dev->flags & IFF_PROMISC) &&
2266 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
2267 (!(dev->flags & IFF_PROMISC) &&
2268 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
2269 return;
2270
2271 if (card->info.guestlan) { /* Guestlan trace */
2272 if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2273 qeth_setadp_promisc_mode(card);
2274 } else if (card->options.sniffer && /* HiperSockets trace */
2275 qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
2276 if (dev->flags & IFF_PROMISC) {
2277 QETH_DBF_TEXT(TRACE, 3, "+promisc");
2278 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
2279 } else {
2280 QETH_DBF_TEXT(TRACE, 3, "-promisc");
2281 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2282 }
2283 }
2284}
2285
2165static void qeth_l3_set_multicast_list(struct net_device *dev) 2286static void qeth_l3_set_multicast_list(struct net_device *dev)
2166{ 2287{
2167 struct qeth_card *card = dev->ml_priv; 2288 struct qeth_card *card = dev->ml_priv;
@@ -2170,15 +2291,17 @@ static void qeth_l3_set_multicast_list(struct net_device *dev)
2170 if (qeth_threads_running(card, QETH_RECOVER_THREAD) && 2291 if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
2171 (card->state != CARD_STATE_UP)) 2292 (card->state != CARD_STATE_UP))
2172 return; 2293 return;
2173 qeth_l3_delete_mc_addresses(card); 2294 if (!card->options.sniffer) {
2174 qeth_l3_add_multicast_ipv4(card); 2295 qeth_l3_delete_mc_addresses(card);
2296 qeth_l3_add_multicast_ipv4(card);
2175#ifdef CONFIG_QETH_IPV6 2297#ifdef CONFIG_QETH_IPV6
2176 qeth_l3_add_multicast_ipv6(card); 2298 qeth_l3_add_multicast_ipv6(card);
2177#endif 2299#endif
2178 qeth_l3_set_ip_addr_list(card); 2300 qeth_l3_set_ip_addr_list(card);
2179 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) 2301 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2180 return; 2302 return;
2181 qeth_setadp_promisc_mode(card); 2303 }
2304 qeth_l3_handle_promisc_mode(card);
2182} 2305}
2183 2306
2184static const char *qeth_l3_arp_get_error_cause(int *rc) 2307static const char *qeth_l3_arp_get_error_cause(int *rc)
@@ -2778,8 +2901,9 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2778 int nr_frags; 2901 int nr_frags;
2779 2902
2780 if ((card->info.type == QETH_CARD_TYPE_IQD) && 2903 if ((card->info.type == QETH_CARD_TYPE_IQD) &&
2781 (skb->protocol != htons(ETH_P_IPV6)) && 2904 (((skb->protocol != htons(ETH_P_IPV6)) &&
2782 (skb->protocol != htons(ETH_P_IP))) 2905 (skb->protocol != htons(ETH_P_IP))) ||
2906 card->options.sniffer))
2783 goto tx_drop; 2907 goto tx_drop;
2784 2908
2785 if ((card->state != CARD_STATE_UP) || !card->lan_online) { 2909 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -3155,7 +3279,7 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
3155 index = i % QDIO_MAX_BUFFERS_PER_Q; 3279 index = i % QDIO_MAX_BUFFERS_PER_Q;
3156 buffer = &card->qdio.in_q->bufs[index]; 3280 buffer = &card->qdio.in_q->bufs[index];
3157 if (!(qdio_err && 3281 if (!(qdio_err &&
3158 qeth_check_qdio_errors(buffer->buffer, 3282 qeth_check_qdio_errors(card, buffer->buffer,
3159 qdio_err, "qinerr"))) 3283 qdio_err, "qinerr")))
3160 qeth_l3_process_inbound_buffer(card, buffer, index); 3284 qeth_l3_process_inbound_buffer(card, buffer, index);
3161 /* clear buffer and give back to hardware */ 3285 /* clear buffer and give back to hardware */
@@ -3250,20 +3374,22 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3250 goto out_remove; 3374 goto out_remove;
3251 } else 3375 } else
3252 card->lan_online = 1; 3376 card->lan_online = 1;
3253 qeth_l3_set_large_send(card, card->options.large_send);
3254 3377
3255 rc = qeth_l3_setadapter_parms(card); 3378 rc = qeth_l3_setadapter_parms(card);
3256 if (rc) 3379 if (rc)
3257 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 3380 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3258 rc = qeth_l3_start_ipassists(card); 3381 if (!card->options.sniffer) {
3259 if (rc) 3382 rc = qeth_l3_start_ipassists(card);
3260 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 3383 if (rc)
3261 rc = qeth_l3_setrouting_v4(card); 3384 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
3262 if (rc) 3385 qeth_l3_set_large_send(card, card->options.large_send);
3263 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); 3386 rc = qeth_l3_setrouting_v4(card);
3264 rc = qeth_l3_setrouting_v6(card); 3387 if (rc)
3265 if (rc) 3388 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
3266 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); 3389 rc = qeth_l3_setrouting_v6(card);
3390 if (rc)
3391 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
3392 }
3267 netif_tx_disable(card->dev); 3393 netif_tx_disable(card->dev);
3268 3394
3269 rc = qeth_init_qdio_queues(card); 3395 rc = qeth_init_qdio_queues(card);
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index 3360b0941aa1..3f08b11274ae 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -319,6 +319,61 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
319static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, 319static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
320 qeth_l3_dev_checksum_store); 320 qeth_l3_dev_checksum_store);
321 321
322static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
323 struct device_attribute *attr, char *buf)
324{
325 struct qeth_card *card = dev_get_drvdata(dev);
326
327 if (!card)
328 return -EINVAL;
329
330 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
331}
332
333static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
334 struct device_attribute *attr, const char *buf, size_t count)
335{
336 struct qeth_card *card = dev_get_drvdata(dev);
337 int ret;
338 unsigned long i;
339
340 if (!card)
341 return -EINVAL;
342
343 if (card->info.type != QETH_CARD_TYPE_IQD)
344 return -EPERM;
345
346 if ((card->state != CARD_STATE_DOWN) &&
347 (card->state != CARD_STATE_RECOVER))
348 return -EPERM;
349
350 ret = strict_strtoul(buf, 16, &i);
351 if (ret)
352 return -EINVAL;
353 switch (i) {
354 case 0:
355 card->options.sniffer = i;
356 break;
357 case 1:
358 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
359 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
360 card->options.sniffer = i;
361 if (card->qdio.init_pool.buf_count !=
362 QETH_IN_BUF_COUNT_MAX)
363 qeth_realloc_buffer_pool(card,
364 QETH_IN_BUF_COUNT_MAX);
365 break;
366 } else
367 return -EPERM;
368 default: /* fall through */
369 return -EINVAL;
370 }
371 return count;
372}
373
374static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
375 qeth_l3_dev_sniffer_store);
376
322static ssize_t qeth_l3_dev_large_send_show(struct device *dev, 377static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
323 struct device_attribute *attr, char *buf) 378 struct device_attribute *attr, char *buf)
324{ 379{
@@ -373,6 +428,7 @@ static struct attribute *qeth_l3_device_attrs[] = {
373 &dev_attr_broadcast_mode.attr, 428 &dev_attr_broadcast_mode.attr,
374 &dev_attr_canonical_macaddr.attr, 429 &dev_attr_canonical_macaddr.attr,
375 &dev_attr_checksumming.attr, 430 &dev_attr_checksumming.attr,
431 &dev_attr_sniffer.attr,
376 &dev_attr_large_send.attr, 432 &dev_attr_large_send.attr,
377 NULL, 433 NULL,
378}; 434};