diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 00:04:44 -0400 |
commit | f8965467f366fd18f01feafb5db10512d7b4422c (patch) | |
tree | 3706a9cd779859271ca61b85c63a1bc3f82d626e /drivers/s390/net | |
parent | a26272e5200765691e67d6780e52b32498fdb659 (diff) | |
parent | 2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits)
qlcnic: adding co maintainer
ixgbe: add support for active DA cables
ixgbe: dcb, do not tag tc_prio_control frames
ixgbe: fix ixgbe_tx_is_paused logic
ixgbe: always enable vlan strip/insert when DCB is enabled
ixgbe: remove some redundant code in setting FCoE FIP filter
ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp
ixgbe: fix header len when unsplit packet overflows to data buffer
ipv6: Never schedule DAD timer on dead address
ipv6: Use POSTDAD state
ipv6: Use state_lock to protect ifa state
ipv6: Replace inet6_ifaddr->dead with state
cxgb4: notify upper drivers if the device is already up when they load
cxgb4: keep interrupts available when the ports are brought down
cxgb4: fix initial addition of MAC address
cnic: Return SPQ credit to bnx2x after ring setup and shutdown.
cnic: Convert cnic_local_flags to atomic ops.
can: Fix SJA1000 command register writes on SMP systems
bridge: fix build for CONFIG_SYSFS disabled
ARCNET: Limit com20020 PCI ID matches for SOHARD cards
...
Fix up various conflicts with pcmcia tree drivers/net/
{pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and
wireless/orinoco/spectrum_cs.c} and feature removal
(Documentation/feature-removal-schedule.txt).
Also fix a non-content conflict due to pm_qos_requirement getting
renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/ctcm_main.c | 6 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_mpc.c | 6 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 3 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 32 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 237 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_mpc.h | 10 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 151 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 47 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 108 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 244 |
10 files changed, 523 insertions, 321 deletions
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index e35713dd0504..4ecafbf91211 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c | |||
@@ -1364,8 +1364,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, | |||
1364 | 1364 | ||
1365 | ch->protocol = priv->protocol; | 1365 | ch->protocol = priv->protocol; |
1366 | if (IS_MPC(priv)) { | 1366 | if (IS_MPC(priv)) { |
1367 | ch->discontact_th = (struct th_header *) | 1367 | ch->discontact_th = kzalloc(TH_HEADER_LENGTH, gfp_type()); |
1368 | kzalloc(TH_HEADER_LENGTH, gfp_type()); | ||
1369 | if (ch->discontact_th == NULL) | 1368 | if (ch->discontact_th == NULL) |
1370 | goto nomem_return; | 1369 | goto nomem_return; |
1371 | 1370 | ||
@@ -1379,8 +1378,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, | |||
1379 | } else | 1378 | } else |
1380 | ccw_num = 8; | 1379 | ccw_num = 8; |
1381 | 1380 | ||
1382 | ch->ccw = (struct ccw1 *) | 1381 | ch->ccw = kzalloc(ccw_num * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); |
1383 | kzalloc(ccw_num * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); | ||
1384 | if (ch->ccw == NULL) | 1382 | if (ch->ccw == NULL) |
1385 | goto nomem_return; | 1383 | goto nomem_return; |
1386 | 1384 | ||
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 5978b390153f..87c24d2936d6 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c | |||
@@ -669,8 +669,7 @@ static void ctcmpc_send_sweep_resp(struct channel *rch) | |||
669 | goto done; | 669 | goto done; |
670 | } | 670 | } |
671 | 671 | ||
672 | header = (struct th_sweep *) | 672 | header = kmalloc(sizeof(struct th_sweep), gfp_type()); |
673 | kmalloc(sizeof(struct th_sweep), gfp_type()); | ||
674 | 673 | ||
675 | if (!header) { | 674 | if (!header) { |
676 | dev_kfree_skb_any(sweep_skb); | 675 | dev_kfree_skb_any(sweep_skb); |
@@ -1191,8 +1190,7 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb) | |||
1191 | skb_pull(pskb, new_len); /* point to next PDU */ | 1190 | skb_pull(pskb, new_len); /* point to next PDU */ |
1192 | } | 1191 | } |
1193 | } else { | 1192 | } else { |
1194 | mpcginfo = (struct mpcg_info *) | 1193 | mpcginfo = kmalloc(sizeof(struct mpcg_info), gfp_type()); |
1195 | kmalloc(sizeof(struct mpcg_info), gfp_type()); | ||
1196 | if (mpcginfo == NULL) | 1194 | if (mpcginfo == NULL) |
1197 | goto done; | 1195 | goto done; |
1198 | 1196 | ||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 9b19ea13b4d8..0f19d540b655 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -1238,8 +1238,7 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) | |||
1238 | ipm = lcs_check_addr_entry(card, im4, buf); | 1238 | ipm = lcs_check_addr_entry(card, im4, buf); |
1239 | if (ipm != NULL) | 1239 | if (ipm != NULL) |
1240 | continue; /* Address already in list. */ | 1240 | continue; /* Address already in list. */ |
1241 | ipm = (struct lcs_ipm_list *) | 1241 | ipm = kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); |
1242 | kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); | ||
1243 | if (ipm == NULL) { | 1242 | if (ipm == NULL) { |
1244 | pr_info("Not enough memory to add" | 1243 | pr_info("Not enough memory to add" |
1245 | " new multicast entry!\n"); | 1244 | " new multicast entry!\n"); |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index fcd005aad989..7a44c38aaf65 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -179,25 +179,23 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, | |||
179 | ((prot == QETH_PROT_IPV6) ? \ | 179 | ((prot == QETH_PROT_IPV6) ? \ |
180 | qeth_is_enabled6(c, f) : qeth_is_enabled(c, f)) | 180 | qeth_is_enabled6(c, f) : qeth_is_enabled(c, f)) |
181 | 181 | ||
182 | #define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101 | 182 | #define QETH_IDX_FUNC_LEVEL_OSD 0x0101 |
183 | #define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101 | ||
184 | #define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 | 183 | #define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 |
185 | #define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 | 184 | #define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 |
186 | 185 | ||
187 | #define QETH_MODELLIST_ARRAY \ | 186 | #define QETH_MODELLIST_ARRAY \ |
188 | {{0x1731, 0x01, 0x1732, 0x01, QETH_CARD_TYPE_OSAE, 1, \ | 187 | {{0x1731, 0x01, 0x1732, QETH_CARD_TYPE_OSD, QETH_MAX_QUEUES, 0}, \ |
189 | QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ | 188 | {0x1731, 0x05, 0x1732, QETH_CARD_TYPE_IQD, QETH_MAX_QUEUES, 0x103}, \ |
190 | QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ | 189 | {0x1731, 0x06, 0x1732, QETH_CARD_TYPE_OSN, QETH_MAX_QUEUES, 0}, \ |
191 | QETH_MAX_QUEUES, 0}, \ | 190 | {0x1731, 0x02, 0x1732, QETH_CARD_TYPE_OSM, QETH_MAX_QUEUES, 0}, \ |
192 | {0x1731, 0x05, 0x1732, 0x05, QETH_CARD_TYPE_IQD, 0, \ | 191 | {0x1731, 0x02, 0x1732, QETH_CARD_TYPE_OSX, QETH_MAX_QUEUES, 0}, \ |
193 | QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \ | 192 | {0, 0, 0, 0, 0, 0} } |
194 | QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \ | 193 | #define QETH_CU_TYPE_IND 0 |
195 | QETH_MAX_QUEUES, 0x103}, \ | 194 | #define QETH_CU_MODEL_IND 1 |
196 | {0x1731, 0x06, 0x1732, 0x06, QETH_CARD_TYPE_OSN, 0, \ | 195 | #define QETH_DEV_TYPE_IND 2 |
197 | QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ | 196 | #define QETH_DEV_MODEL_IND 3 |
198 | QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ | 197 | #define QETH_QUEUE_NO_IND 4 |
199 | QETH_MAX_QUEUES, 0}, \ | 198 | #define QETH_MULTICAST_IND 5 |
200 | {0, 0, 0, 0, 0, 0, 0, 0, 0} } | ||
201 | 199 | ||
202 | #define QETH_REAL_CARD 1 | 200 | #define QETH_REAL_CARD 1 |
203 | #define QETH_VLAN_CARD 2 | 201 | #define QETH_VLAN_CARD 2 |
@@ -351,7 +349,7 @@ enum qeth_header_ids { | |||
351 | #define QETH_HDR_EXT_SRC_MAC_ADDR 0x08 | 349 | #define QETH_HDR_EXT_SRC_MAC_ADDR 0x08 |
352 | #define QETH_HDR_EXT_CSUM_HDR_REQ 0x10 | 350 | #define QETH_HDR_EXT_CSUM_HDR_REQ 0x10 |
353 | #define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20 | 351 | #define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20 |
354 | #define QETH_HDR_EXT_UDP_TSO 0x40 /*bit off for TCP*/ | 352 | #define QETH_HDR_EXT_UDP 0x40 /*bit off for TCP*/ |
355 | 353 | ||
356 | static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale) | 354 | static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale) |
357 | { | 355 | { |
@@ -630,6 +628,7 @@ struct qeth_card_info { | |||
630 | int unique_id; | 628 | int unique_id; |
631 | struct qeth_card_blkt blkt; | 629 | struct qeth_card_blkt blkt; |
632 | __u32 csum_mask; | 630 | __u32 csum_mask; |
631 | __u32 tx_csum_mask; | ||
633 | enum qeth_ipa_promisc_modes promisc_mode; | 632 | enum qeth_ipa_promisc_modes promisc_mode; |
634 | }; | 633 | }; |
635 | 634 | ||
@@ -739,6 +738,7 @@ struct qeth_card { | |||
739 | atomic_t force_alloc_skb; | 738 | atomic_t force_alloc_skb; |
740 | struct service_level qeth_service_level; | 739 | struct service_level qeth_service_level; |
741 | struct qdio_ssqd_desc ssqd; | 740 | struct qdio_ssqd_desc ssqd; |
741 | struct mutex conf_mutex; | ||
742 | }; | 742 | }; |
743 | 743 | ||
744 | struct qeth_card_list_struct { | 744 | struct qeth_card_list_struct { |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 28f71349fdec..13ef46b9d388 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -53,7 +53,7 @@ struct kmem_cache *qeth_core_header_cache; | |||
53 | EXPORT_SYMBOL_GPL(qeth_core_header_cache); | 53 | EXPORT_SYMBOL_GPL(qeth_core_header_cache); |
54 | 54 | ||
55 | static struct device *qeth_core_root_dev; | 55 | static struct device *qeth_core_root_dev; |
56 | static unsigned int known_devices[][10] = QETH_MODELLIST_ARRAY; | 56 | static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY; |
57 | static struct lock_class_key qdio_out_skb_queue_key; | 57 | static struct lock_class_key qdio_out_skb_queue_key; |
58 | 58 | ||
59 | static void qeth_send_control_data_cb(struct qeth_channel *, | 59 | static void qeth_send_control_data_cb(struct qeth_channel *, |
@@ -111,21 +111,29 @@ static inline const char *qeth_get_cardname(struct qeth_card *card) | |||
111 | { | 111 | { |
112 | if (card->info.guestlan) { | 112 | if (card->info.guestlan) { |
113 | switch (card->info.type) { | 113 | switch (card->info.type) { |
114 | case QETH_CARD_TYPE_OSAE: | 114 | case QETH_CARD_TYPE_OSD: |
115 | return " Guest LAN QDIO"; | 115 | return " Guest LAN QDIO"; |
116 | case QETH_CARD_TYPE_IQD: | 116 | case QETH_CARD_TYPE_IQD: |
117 | return " Guest LAN Hiper"; | 117 | return " Guest LAN Hiper"; |
118 | case QETH_CARD_TYPE_OSM: | ||
119 | return " Guest LAN QDIO - OSM"; | ||
120 | case QETH_CARD_TYPE_OSX: | ||
121 | return " Guest LAN QDIO - OSX"; | ||
118 | default: | 122 | default: |
119 | return " unknown"; | 123 | return " unknown"; |
120 | } | 124 | } |
121 | } else { | 125 | } else { |
122 | switch (card->info.type) { | 126 | switch (card->info.type) { |
123 | case QETH_CARD_TYPE_OSAE: | 127 | case QETH_CARD_TYPE_OSD: |
124 | return " OSD Express"; | 128 | return " OSD Express"; |
125 | case QETH_CARD_TYPE_IQD: | 129 | case QETH_CARD_TYPE_IQD: |
126 | return " HiperSockets"; | 130 | return " HiperSockets"; |
127 | case QETH_CARD_TYPE_OSN: | 131 | case QETH_CARD_TYPE_OSN: |
128 | return " OSN QDIO"; | 132 | return " OSN QDIO"; |
133 | case QETH_CARD_TYPE_OSM: | ||
134 | return " OSM QDIO"; | ||
135 | case QETH_CARD_TYPE_OSX: | ||
136 | return " OSX QDIO"; | ||
129 | default: | 137 | default: |
130 | return " unknown"; | 138 | return " unknown"; |
131 | } | 139 | } |
@@ -138,16 +146,20 @@ const char *qeth_get_cardname_short(struct qeth_card *card) | |||
138 | { | 146 | { |
139 | if (card->info.guestlan) { | 147 | if (card->info.guestlan) { |
140 | switch (card->info.type) { | 148 | switch (card->info.type) { |
141 | case QETH_CARD_TYPE_OSAE: | 149 | case QETH_CARD_TYPE_OSD: |
142 | return "GuestLAN QDIO"; | 150 | return "GuestLAN QDIO"; |
143 | case QETH_CARD_TYPE_IQD: | 151 | case QETH_CARD_TYPE_IQD: |
144 | return "GuestLAN Hiper"; | 152 | return "GuestLAN Hiper"; |
153 | case QETH_CARD_TYPE_OSM: | ||
154 | return "GuestLAN OSM"; | ||
155 | case QETH_CARD_TYPE_OSX: | ||
156 | return "GuestLAN OSX"; | ||
145 | default: | 157 | default: |
146 | return "unknown"; | 158 | return "unknown"; |
147 | } | 159 | } |
148 | } else { | 160 | } else { |
149 | switch (card->info.type) { | 161 | switch (card->info.type) { |
150 | case QETH_CARD_TYPE_OSAE: | 162 | case QETH_CARD_TYPE_OSD: |
151 | switch (card->info.link_type) { | 163 | switch (card->info.link_type) { |
152 | case QETH_LINK_TYPE_FAST_ETH: | 164 | case QETH_LINK_TYPE_FAST_ETH: |
153 | return "OSD_100"; | 165 | return "OSD_100"; |
@@ -172,6 +184,10 @@ const char *qeth_get_cardname_short(struct qeth_card *card) | |||
172 | return "HiperSockets"; | 184 | return "HiperSockets"; |
173 | case QETH_CARD_TYPE_OSN: | 185 | case QETH_CARD_TYPE_OSN: |
174 | return "OSN"; | 186 | return "OSN"; |
187 | case QETH_CARD_TYPE_OSM: | ||
188 | return "OSM_1000"; | ||
189 | case QETH_CARD_TYPE_OSX: | ||
190 | return "OSX_10GIG"; | ||
175 | default: | 191 | default: |
176 | return "unknown"; | 192 | return "unknown"; |
177 | } | 193 | } |
@@ -419,7 +435,8 @@ void qeth_clear_ipacmd_list(struct qeth_card *card) | |||
419 | } | 435 | } |
420 | EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list); | 436 | EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list); |
421 | 437 | ||
422 | static int qeth_check_idx_response(unsigned char *buffer) | 438 | static int qeth_check_idx_response(struct qeth_card *card, |
439 | unsigned char *buffer) | ||
423 | { | 440 | { |
424 | if (!buffer) | 441 | if (!buffer) |
425 | return 0; | 442 | return 0; |
@@ -434,6 +451,12 @@ static int qeth_check_idx_response(unsigned char *buffer) | |||
434 | QETH_DBF_TEXT(TRACE, 2, "ckidxres"); | 451 | QETH_DBF_TEXT(TRACE, 2, "ckidxres"); |
435 | QETH_DBF_TEXT(TRACE, 2, " idxterm"); | 452 | QETH_DBF_TEXT(TRACE, 2, " idxterm"); |
436 | QETH_DBF_TEXT_(TRACE, 2, " rc%d", -EIO); | 453 | QETH_DBF_TEXT_(TRACE, 2, " rc%d", -EIO); |
454 | if (buffer[4] == 0xf6) { | ||
455 | dev_err(&card->gdev->dev, | ||
456 | "The qeth device is not configured " | ||
457 | "for the OSI layer required by z/VM\n"); | ||
458 | return -EPERM; | ||
459 | } | ||
437 | return -EIO; | 460 | return -EIO; |
438 | } | 461 | } |
439 | return 0; | 462 | return 0; |
@@ -528,18 +551,19 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel, | |||
528 | struct qeth_ipa_cmd *cmd; | 551 | struct qeth_ipa_cmd *cmd; |
529 | unsigned long flags; | 552 | unsigned long flags; |
530 | int keep_reply; | 553 | int keep_reply; |
554 | int rc = 0; | ||
531 | 555 | ||
532 | QETH_DBF_TEXT(TRACE, 4, "sndctlcb"); | 556 | QETH_DBF_TEXT(TRACE, 4, "sndctlcb"); |
533 | 557 | ||
534 | card = CARD_FROM_CDEV(channel->ccwdev); | 558 | card = CARD_FROM_CDEV(channel->ccwdev); |
535 | if (qeth_check_idx_response(iob->data)) { | 559 | rc = qeth_check_idx_response(card, iob->data); |
560 | switch (rc) { | ||
561 | case 0: | ||
562 | break; | ||
563 | case -EIO: | ||
536 | qeth_clear_ipacmd_list(card); | 564 | qeth_clear_ipacmd_list(card); |
537 | if (((iob->data[2] & 0xc0) == 0xc0) && iob->data[4] == 0xf6) | 565 | qeth_schedule_recovery(card); |
538 | dev_err(&card->gdev->dev, | 566 | default: |
539 | "The qeth device is not configured " | ||
540 | "for the OSI layer required by z/VM\n"); | ||
541 | else | ||
542 | qeth_schedule_recovery(card); | ||
543 | goto out; | 567 | goto out; |
544 | } | 568 | } |
545 | 569 | ||
@@ -606,7 +630,7 @@ static int qeth_setup_channel(struct qeth_channel *channel) | |||
606 | 630 | ||
607 | QETH_DBF_TEXT(SETUP, 2, "setupch"); | 631 | QETH_DBF_TEXT(SETUP, 2, "setupch"); |
608 | for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) { | 632 | for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) { |
609 | channel->iob[cnt].data = (char *) | 633 | channel->iob[cnt].data = |
610 | kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL); | 634 | kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL); |
611 | if (channel->iob[cnt].data == NULL) | 635 | if (channel->iob[cnt].data == NULL) |
612 | break; | 636 | break; |
@@ -719,7 +743,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb) | |||
719 | QETH_DBF_TEXT(TRACE, 2, "CGENCHK"); | 743 | QETH_DBF_TEXT(TRACE, 2, "CGENCHK"); |
720 | dev_warn(&cdev->dev, "The qeth device driver " | 744 | dev_warn(&cdev->dev, "The qeth device driver " |
721 | "failed to recover an error on the device\n"); | 745 | "failed to recover an error on the device\n"); |
722 | QETH_DBF_MESSAGE(2, "%s check on device dstat=x%x, cstat=x%x ", | 746 | QETH_DBF_MESSAGE(2, "%s check on device dstat=x%x, cstat=x%x\n", |
723 | dev_name(&cdev->dev), dstat, cstat); | 747 | dev_name(&cdev->dev), dstat, cstat); |
724 | print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET, | 748 | print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET, |
725 | 16, 1, irb, 64, 1); | 749 | 16, 1, irb, 64, 1); |
@@ -998,9 +1022,8 @@ static void qeth_clean_channel(struct qeth_channel *channel) | |||
998 | kfree(channel->iob[cnt].data); | 1022 | kfree(channel->iob[cnt].data); |
999 | } | 1023 | } |
1000 | 1024 | ||
1001 | static int qeth_is_1920_device(struct qeth_card *card) | 1025 | static void qeth_get_channel_path_desc(struct qeth_card *card) |
1002 | { | 1026 | { |
1003 | int single_queue = 0; | ||
1004 | struct ccw_device *ccwdev; | 1027 | struct ccw_device *ccwdev; |
1005 | struct channelPath_dsc { | 1028 | struct channelPath_dsc { |
1006 | u8 flags; | 1029 | u8 flags; |
@@ -1013,17 +1036,25 @@ static int qeth_is_1920_device(struct qeth_card *card) | |||
1013 | u8 chpp; | 1036 | u8 chpp; |
1014 | } *chp_dsc; | 1037 | } *chp_dsc; |
1015 | 1038 | ||
1016 | QETH_DBF_TEXT(SETUP, 2, "chk_1920"); | 1039 | QETH_DBF_TEXT(SETUP, 2, "chp_desc"); |
1017 | 1040 | ||
1018 | ccwdev = card->data.ccwdev; | 1041 | ccwdev = card->data.ccwdev; |
1019 | chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); | 1042 | chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); |
1020 | if (chp_dsc != NULL) { | 1043 | if (chp_dsc != NULL) { |
1021 | /* CHPP field bit 6 == 1 -> single queue */ | 1044 | /* CHPP field bit 6 == 1 -> single queue */ |
1022 | single_queue = ((chp_dsc->chpp & 0x02) == 0x02); | 1045 | if ((chp_dsc->chpp & 0x02) == 0x02) |
1046 | card->qdio.no_out_queues = 1; | ||
1047 | card->info.func_level = 0x4100 + chp_dsc->desc; | ||
1023 | kfree(chp_dsc); | 1048 | kfree(chp_dsc); |
1024 | } | 1049 | } |
1025 | QETH_DBF_TEXT_(SETUP, 2, "rc:%x", single_queue); | 1050 | if (card->qdio.no_out_queues == 1) { |
1026 | return single_queue; | 1051 | card->qdio.default_out_queue = 0; |
1052 | dev_info(&card->gdev->dev, | ||
1053 | "Priority Queueing not supported\n"); | ||
1054 | } | ||
1055 | QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); | ||
1056 | QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); | ||
1057 | return; | ||
1027 | } | 1058 | } |
1028 | 1059 | ||
1029 | static void qeth_init_qdio_info(struct qeth_card *card) | 1060 | static void qeth_init_qdio_info(struct qeth_card *card) |
@@ -1100,6 +1131,7 @@ static int qeth_setup_card(struct qeth_card *card) | |||
1100 | spin_lock_init(&card->lock); | 1131 | spin_lock_init(&card->lock); |
1101 | spin_lock_init(&card->ip_lock); | 1132 | spin_lock_init(&card->ip_lock); |
1102 | spin_lock_init(&card->thread_mask_lock); | 1133 | spin_lock_init(&card->thread_mask_lock); |
1134 | mutex_init(&card->conf_mutex); | ||
1103 | card->thread_start_mask = 0; | 1135 | card->thread_start_mask = 0; |
1104 | card->thread_allowed_mask = 0; | 1136 | card->thread_allowed_mask = 0; |
1105 | card->thread_running_mask = 0; | 1137 | card->thread_running_mask = 0; |
@@ -1170,18 +1202,17 @@ static int qeth_determine_card_type(struct qeth_card *card) | |||
1170 | 1202 | ||
1171 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; | 1203 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; |
1172 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; | 1204 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; |
1173 | while (known_devices[i][4]) { | 1205 | while (known_devices[i][QETH_DEV_MODEL_IND]) { |
1174 | if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) && | 1206 | if ((CARD_RDEV(card)->id.dev_type == |
1175 | (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) { | 1207 | known_devices[i][QETH_DEV_TYPE_IND]) && |
1176 | card->info.type = known_devices[i][4]; | 1208 | (CARD_RDEV(card)->id.dev_model == |
1177 | card->qdio.no_out_queues = known_devices[i][8]; | 1209 | known_devices[i][QETH_DEV_MODEL_IND])) { |
1178 | card->info.is_multicast_different = known_devices[i][9]; | 1210 | card->info.type = known_devices[i][QETH_DEV_MODEL_IND]; |
1179 | if (qeth_is_1920_device(card)) { | 1211 | card->qdio.no_out_queues = |
1180 | dev_info(&card->gdev->dev, | 1212 | known_devices[i][QETH_QUEUE_NO_IND]; |
1181 | "Priority Queueing not supported\n"); | 1213 | card->info.is_multicast_different = |
1182 | card->qdio.no_out_queues = 1; | 1214 | known_devices[i][QETH_MULTICAST_IND]; |
1183 | card->qdio.default_out_queue = 0; | 1215 | qeth_get_channel_path_desc(card); |
1184 | } | ||
1185 | return 0; | 1216 | return 0; |
1186 | } | 1217 | } |
1187 | i++; | 1218 | i++; |
@@ -1399,22 +1430,20 @@ static void qeth_init_tokens(struct qeth_card *card) | |||
1399 | 1430 | ||
1400 | static void qeth_init_func_level(struct qeth_card *card) | 1431 | static void qeth_init_func_level(struct qeth_card *card) |
1401 | { | 1432 | { |
1402 | if (card->ipato.enabled) { | 1433 | switch (card->info.type) { |
1403 | if (card->info.type == QETH_CARD_TYPE_IQD) | 1434 | case QETH_CARD_TYPE_IQD: |
1404 | card->info.func_level = | 1435 | if (card->ipato.enabled) |
1405 | QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT; | ||
1406 | else | ||
1407 | card->info.func_level = | ||
1408 | QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT; | ||
1409 | } else { | ||
1410 | if (card->info.type == QETH_CARD_TYPE_IQD) | ||
1411 | /*FIXME:why do we have same values for dis and ena for | ||
1412 | osae??? */ | ||
1413 | card->info.func_level = | 1436 | card->info.func_level = |
1414 | QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT; | 1437 | QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT; |
1415 | else | 1438 | else |
1416 | card->info.func_level = | 1439 | card->info.func_level = |
1417 | QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT; | 1440 | QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT; |
1441 | break; | ||
1442 | case QETH_CARD_TYPE_OSD: | ||
1443 | card->info.func_level = QETH_IDX_FUNC_LEVEL_OSD; | ||
1444 | break; | ||
1445 | default: | ||
1446 | break; | ||
1418 | } | 1447 | } |
1419 | } | 1448 | } |
1420 | 1449 | ||
@@ -1561,7 +1590,7 @@ static void qeth_idx_write_cb(struct qeth_channel *channel, | |||
1561 | card = CARD_FROM_CDEV(channel->ccwdev); | 1590 | card = CARD_FROM_CDEV(channel->ccwdev); |
1562 | 1591 | ||
1563 | if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { | 1592 | if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { |
1564 | if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19) | 1593 | if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == QETH_IDX_ACT_ERR_EXCL) |
1565 | dev_err(&card->write.ccwdev->dev, | 1594 | dev_err(&card->write.ccwdev->dev, |
1566 | "The adapter is used exclusively by another " | 1595 | "The adapter is used exclusively by another " |
1567 | "host\n"); | 1596 | "host\n"); |
@@ -1597,27 +1626,35 @@ static void qeth_idx_read_cb(struct qeth_channel *channel, | |||
1597 | } | 1626 | } |
1598 | 1627 | ||
1599 | card = CARD_FROM_CDEV(channel->ccwdev); | 1628 | card = CARD_FROM_CDEV(channel->ccwdev); |
1600 | if (qeth_check_idx_response(iob->data)) | 1629 | if (qeth_check_idx_response(card, iob->data)) |
1601 | goto out; | 1630 | goto out; |
1602 | 1631 | ||
1603 | if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { | 1632 | if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) { |
1604 | if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19) | 1633 | switch (QETH_IDX_ACT_CAUSE_CODE(iob->data)) { |
1634 | case QETH_IDX_ACT_ERR_EXCL: | ||
1605 | dev_err(&card->write.ccwdev->dev, | 1635 | dev_err(&card->write.ccwdev->dev, |
1606 | "The adapter is used exclusively by another " | 1636 | "The adapter is used exclusively by another " |
1607 | "host\n"); | 1637 | "host\n"); |
1608 | else | 1638 | break; |
1639 | case QETH_IDX_ACT_ERR_AUTH: | ||
1640 | dev_err(&card->read.ccwdev->dev, | ||
1641 | "Setting the device online failed because of " | ||
1642 | "insufficient LPAR authorization\n"); | ||
1643 | break; | ||
1644 | default: | ||
1609 | QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel:" | 1645 | QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel:" |
1610 | " negative reply\n", | 1646 | " negative reply\n", |
1611 | dev_name(&card->read.ccwdev->dev)); | 1647 | dev_name(&card->read.ccwdev->dev)); |
1648 | } | ||
1612 | goto out; | 1649 | goto out; |
1613 | } | 1650 | } |
1614 | 1651 | ||
1615 | /** | 1652 | /** |
1616 | * temporary fix for microcode bug | 1653 | * * temporary fix for microcode bug |
1617 | * to revert it,replace OR by AND | 1654 | * * to revert it,replace OR by AND |
1618 | */ | 1655 | * */ |
1619 | if ((!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) || | 1656 | if ((!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) || |
1620 | (card->info.type == QETH_CARD_TYPE_OSAE)) | 1657 | (card->info.type == QETH_CARD_TYPE_OSD)) |
1621 | card->info.portname_required = 1; | 1658 | card->info.portname_required = 1; |
1622 | 1659 | ||
1623 | memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2); | 1660 | memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2); |
@@ -1826,7 +1863,7 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card) | |||
1826 | return 1500; | 1863 | return 1500; |
1827 | case QETH_CARD_TYPE_IQD: | 1864 | case QETH_CARD_TYPE_IQD: |
1828 | return card->info.max_mtu; | 1865 | return card->info.max_mtu; |
1829 | case QETH_CARD_TYPE_OSAE: | 1866 | case QETH_CARD_TYPE_OSD: |
1830 | switch (card->info.link_type) { | 1867 | switch (card->info.link_type) { |
1831 | case QETH_LINK_TYPE_HSTR: | 1868 | case QETH_LINK_TYPE_HSTR: |
1832 | case QETH_LINK_TYPE_LANE_TR: | 1869 | case QETH_LINK_TYPE_LANE_TR: |
@@ -1834,6 +1871,9 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card) | |||
1834 | default: | 1871 | default: |
1835 | return 1492; | 1872 | return 1492; |
1836 | } | 1873 | } |
1874 | case QETH_CARD_TYPE_OSM: | ||
1875 | case QETH_CARD_TYPE_OSX: | ||
1876 | return 1492; | ||
1837 | default: | 1877 | default: |
1838 | return 1500; | 1878 | return 1500; |
1839 | } | 1879 | } |
@@ -1844,8 +1884,10 @@ static inline int qeth_get_max_mtu_for_card(int cardtype) | |||
1844 | switch (cardtype) { | 1884 | switch (cardtype) { |
1845 | 1885 | ||
1846 | case QETH_CARD_TYPE_UNKNOWN: | 1886 | case QETH_CARD_TYPE_UNKNOWN: |
1847 | case QETH_CARD_TYPE_OSAE: | 1887 | case QETH_CARD_TYPE_OSD: |
1848 | case QETH_CARD_TYPE_OSN: | 1888 | case QETH_CARD_TYPE_OSN: |
1889 | case QETH_CARD_TYPE_OSM: | ||
1890 | case QETH_CARD_TYPE_OSX: | ||
1849 | return 61440; | 1891 | return 61440; |
1850 | case QETH_CARD_TYPE_IQD: | 1892 | case QETH_CARD_TYPE_IQD: |
1851 | return 57344; | 1893 | return 57344; |
@@ -1883,7 +1925,9 @@ static inline int qeth_get_mtu_outof_framesize(int framesize) | |||
1883 | static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu) | 1925 | static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu) |
1884 | { | 1926 | { |
1885 | switch (card->info.type) { | 1927 | switch (card->info.type) { |
1886 | case QETH_CARD_TYPE_OSAE: | 1928 | case QETH_CARD_TYPE_OSD: |
1929 | case QETH_CARD_TYPE_OSM: | ||
1930 | case QETH_CARD_TYPE_OSX: | ||
1887 | return ((mtu >= 576) && (mtu <= 61440)); | 1931 | return ((mtu >= 576) && (mtu <= 61440)); |
1888 | case QETH_CARD_TYPE_IQD: | 1932 | case QETH_CARD_TYPE_IQD: |
1889 | return ((mtu >= 576) && | 1933 | return ((mtu >= 576) && |
@@ -1934,6 +1978,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
1934 | card->info.link_type = link_type; | 1978 | card->info.link_type = link_type; |
1935 | } else | 1979 | } else |
1936 | card->info.link_type = 0; | 1980 | card->info.link_type = 0; |
1981 | QETH_DBF_TEXT_(SETUP, 2, "link%d", link_type); | ||
1937 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); | 1982 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); |
1938 | return 0; | 1983 | return 0; |
1939 | } | 1984 | } |
@@ -1977,6 +2022,7 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
1977 | unsigned long data) | 2022 | unsigned long data) |
1978 | { | 2023 | { |
1979 | struct qeth_cmd_buffer *iob; | 2024 | struct qeth_cmd_buffer *iob; |
2025 | int rc = 0; | ||
1980 | 2026 | ||
1981 | QETH_DBF_TEXT(SETUP, 2, "ulpstpcb"); | 2027 | QETH_DBF_TEXT(SETUP, 2, "ulpstpcb"); |
1982 | 2028 | ||
@@ -1984,8 +2030,15 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
1984 | memcpy(&card->token.ulp_connection_r, | 2030 | memcpy(&card->token.ulp_connection_r, |
1985 | QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data), | 2031 | QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data), |
1986 | QETH_MPC_TOKEN_LENGTH); | 2032 | QETH_MPC_TOKEN_LENGTH); |
2033 | if (!strncmp("00S", QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data), | ||
2034 | 3)) { | ||
2035 | QETH_DBF_TEXT(SETUP, 2, "olmlimit"); | ||
2036 | dev_err(&card->gdev->dev, "A connection could not be " | ||
2037 | "established because of an OLM limit\n"); | ||
2038 | rc = -EMLINK; | ||
2039 | } | ||
1987 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); | 2040 | QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); |
1988 | return 0; | 2041 | return rc; |
1989 | } | 2042 | } |
1990 | 2043 | ||
1991 | static int qeth_ulp_setup(struct qeth_card *card) | 2044 | static int qeth_ulp_setup(struct qeth_card *card) |
@@ -2238,7 +2291,9 @@ static void qeth_print_status_no_portname(struct qeth_card *card) | |||
2238 | void qeth_print_status_message(struct qeth_card *card) | 2291 | void qeth_print_status_message(struct qeth_card *card) |
2239 | { | 2292 | { |
2240 | switch (card->info.type) { | 2293 | switch (card->info.type) { |
2241 | case QETH_CARD_TYPE_OSAE: | 2294 | case QETH_CARD_TYPE_OSD: |
2295 | case QETH_CARD_TYPE_OSM: | ||
2296 | case QETH_CARD_TYPE_OSX: | ||
2242 | /* VM will use a non-zero first character | 2297 | /* VM will use a non-zero first character |
2243 | * to indicate a HiperSockets like reporting | 2298 | * to indicate a HiperSockets like reporting |
2244 | * of the level OSA sets the first character to zero | 2299 | * of the level OSA sets the first character to zero |
@@ -2545,9 +2600,11 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, | |||
2545 | QETH_DBF_TEXT(TRACE, 3, "quyadpcb"); | 2600 | QETH_DBF_TEXT(TRACE, 3, "quyadpcb"); |
2546 | 2601 | ||
2547 | cmd = (struct qeth_ipa_cmd *) data; | 2602 | cmd = (struct qeth_ipa_cmd *) data; |
2548 | if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) | 2603 | if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) { |
2549 | card->info.link_type = | 2604 | card->info.link_type = |
2550 | cmd->data.setadapterparms.data.query_cmds_supp.lan_type; | 2605 | cmd->data.setadapterparms.data.query_cmds_supp.lan_type; |
2606 | QETH_DBF_TEXT_(SETUP, 2, "lnk %d", card->info.link_type); | ||
2607 | } | ||
2551 | card->options.adp.supported_funcs = | 2608 | card->options.adp.supported_funcs = |
2552 | cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds; | 2609 | cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds; |
2553 | return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); | 2610 | return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); |
@@ -2937,7 +2994,8 @@ EXPORT_SYMBOL_GPL(qeth_qdio_output_handler); | |||
2937 | int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, | 2994 | int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, |
2938 | int ipv, int cast_type) | 2995 | int ipv, int cast_type) |
2939 | { | 2996 | { |
2940 | if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE)) | 2997 | if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD || |
2998 | card->info.type == QETH_CARD_TYPE_OSX)) | ||
2941 | return card->qdio.default_out_queue; | 2999 | return card->qdio.default_out_queue; |
2942 | switch (card->qdio.no_out_queues) { | 3000 | switch (card->qdio.no_out_queues) { |
2943 | case 4: | 3001 | case 4: |
@@ -3499,13 +3557,14 @@ int qeth_set_access_ctrl_online(struct qeth_card *card) | |||
3499 | 3557 | ||
3500 | QETH_DBF_TEXT(TRACE, 4, "setactlo"); | 3558 | QETH_DBF_TEXT(TRACE, 4, "setactlo"); |
3501 | 3559 | ||
3502 | if (card->info.type == QETH_CARD_TYPE_OSAE && | 3560 | if ((card->info.type == QETH_CARD_TYPE_OSD || |
3503 | qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) { | 3561 | card->info.type == QETH_CARD_TYPE_OSX) && |
3562 | qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) { | ||
3504 | rc = qeth_setadpparms_set_access_ctrl(card, | 3563 | rc = qeth_setadpparms_set_access_ctrl(card, |
3505 | card->options.isolation); | 3564 | card->options.isolation); |
3506 | if (rc) { | 3565 | if (rc) { |
3507 | QETH_DBF_MESSAGE(3, | 3566 | QETH_DBF_MESSAGE(3, |
3508 | "IPA(SET_ACCESS_CTRL,%s,%d) sent failed", | 3567 | "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n", |
3509 | card->gdev->dev.kobj.name, | 3568 | card->gdev->dev.kobj.name, |
3510 | rc); | 3569 | rc); |
3511 | } | 3570 | } |
@@ -3845,9 +3904,16 @@ static void qeth_core_free_card(struct qeth_card *card) | |||
3845 | } | 3904 | } |
3846 | 3905 | ||
3847 | static struct ccw_device_id qeth_ids[] = { | 3906 | static struct ccw_device_id qeth_ids[] = { |
3848 | {CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE}, | 3907 | {CCW_DEVICE_DEVTYPE(0x1731, 0x01, 0x1732, 0x01), |
3849 | {CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD}, | 3908 | .driver_info = QETH_CARD_TYPE_OSD}, |
3850 | {CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN}, | 3909 | {CCW_DEVICE_DEVTYPE(0x1731, 0x05, 0x1732, 0x05), |
3910 | .driver_info = QETH_CARD_TYPE_IQD}, | ||
3911 | {CCW_DEVICE_DEVTYPE(0x1731, 0x06, 0x1732, 0x06), | ||
3912 | .driver_info = QETH_CARD_TYPE_OSN}, | ||
3913 | {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x03), | ||
3914 | .driver_info = QETH_CARD_TYPE_OSM}, | ||
3915 | {CCW_DEVICE_DEVTYPE(0x1731, 0x02, 0x1732, 0x02), | ||
3916 | .driver_info = QETH_CARD_TYPE_OSX}, | ||
3851 | {}, | 3917 | {}, |
3852 | }; | 3918 | }; |
3853 | MODULE_DEVICE_TABLE(ccw, qeth_ids); | 3919 | MODULE_DEVICE_TABLE(ccw, qeth_ids); |
@@ -4251,25 +4317,25 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
4251 | goto err_card; | 4317 | goto err_card; |
4252 | } | 4318 | } |
4253 | 4319 | ||
4254 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 4320 | if (card->info.type == QETH_CARD_TYPE_OSN) |
4255 | rc = qeth_core_create_osn_attributes(dev); | 4321 | rc = qeth_core_create_osn_attributes(dev); |
4256 | if (rc) | 4322 | else |
4257 | goto err_card; | 4323 | rc = qeth_core_create_device_attributes(dev); |
4324 | if (rc) | ||
4325 | goto err_card; | ||
4326 | switch (card->info.type) { | ||
4327 | case QETH_CARD_TYPE_OSN: | ||
4328 | case QETH_CARD_TYPE_OSM: | ||
4258 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); | 4329 | rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); |
4259 | if (rc) { | 4330 | if (rc) |
4260 | qeth_core_remove_osn_attributes(dev); | 4331 | goto err_attr; |
4261 | goto err_card; | ||
4262 | } | ||
4263 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 4332 | rc = card->discipline.ccwgdriver->probe(card->gdev); |
4264 | if (rc) { | ||
4265 | qeth_core_free_discipline(card); | ||
4266 | qeth_core_remove_osn_attributes(dev); | ||
4267 | goto err_card; | ||
4268 | } | ||
4269 | } else { | ||
4270 | rc = qeth_core_create_device_attributes(dev); | ||
4271 | if (rc) | 4333 | if (rc) |
4272 | goto err_card; | 4334 | goto err_disc; |
4335 | case QETH_CARD_TYPE_OSD: | ||
4336 | case QETH_CARD_TYPE_OSX: | ||
4337 | default: | ||
4338 | break; | ||
4273 | } | 4339 | } |
4274 | 4340 | ||
4275 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); | 4341 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); |
@@ -4279,6 +4345,13 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) | |||
4279 | qeth_determine_capabilities(card); | 4345 | qeth_determine_capabilities(card); |
4280 | return 0; | 4346 | return 0; |
4281 | 4347 | ||
4348 | err_disc: | ||
4349 | qeth_core_free_discipline(card); | ||
4350 | err_attr: | ||
4351 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
4352 | qeth_core_remove_osn_attributes(dev); | ||
4353 | else | ||
4354 | qeth_core_remove_device_attributes(dev); | ||
4282 | err_card: | 4355 | err_card: |
4283 | qeth_core_free_card(card); | 4356 | qeth_core_free_card(card); |
4284 | err_dev: | 4357 | err_dev: |
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 104a3351e02b..f9ed24de7514 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h | |||
@@ -48,9 +48,11 @@ extern unsigned char IPA_PDU_HEADER[]; | |||
48 | 48 | ||
49 | enum qeth_card_types { | 49 | enum qeth_card_types { |
50 | QETH_CARD_TYPE_UNKNOWN = 0, | 50 | QETH_CARD_TYPE_UNKNOWN = 0, |
51 | QETH_CARD_TYPE_OSAE = 10, | 51 | QETH_CARD_TYPE_OSD = 1, |
52 | QETH_CARD_TYPE_IQD = 1234, | 52 | QETH_CARD_TYPE_IQD = 5, |
53 | QETH_CARD_TYPE_OSN = 11, | 53 | QETH_CARD_TYPE_OSN = 6, |
54 | QETH_CARD_TYPE_OSM = 3, | ||
55 | QETH_CARD_TYPE_OSX = 2, | ||
54 | }; | 56 | }; |
55 | 57 | ||
56 | #define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18 | 58 | #define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18 |
@@ -614,6 +616,8 @@ extern unsigned char IDX_ACTIVATE_WRITE[]; | |||
614 | #define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08] & 3) == 2) | 616 | #define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08] & 3) == 2) |
615 | #define QETH_IDX_REPLY_LEVEL(buffer) (buffer + 0x12) | 617 | #define QETH_IDX_REPLY_LEVEL(buffer) (buffer + 0x12) |
616 | #define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09] | 618 | #define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09] |
619 | #define QETH_IDX_ACT_ERR_EXCL 0x19 | ||
620 | #define QETH_IDX_ACT_ERR_AUTH 0x1E | ||
617 | 621 | ||
618 | #define PDU_ENCAPSULATION(buffer) \ | 622 | #define PDU_ENCAPSULATION(buffer) \ |
619 | (buffer + *(buffer + (*(buffer + 0x0b)) + \ | 623 | (buffer + *(buffer + (*(buffer + 0x0b)) + \ |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 25dfd5abd19b..2eb022ff2610 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -122,23 +122,32 @@ static ssize_t qeth_dev_portno_store(struct device *dev, | |||
122 | struct qeth_card *card = dev_get_drvdata(dev); | 122 | struct qeth_card *card = dev_get_drvdata(dev); |
123 | char *tmp; | 123 | char *tmp; |
124 | unsigned int portno, limit; | 124 | unsigned int portno, limit; |
125 | int rc = 0; | ||
125 | 126 | ||
126 | if (!card) | 127 | if (!card) |
127 | return -EINVAL; | 128 | return -EINVAL; |
128 | 129 | ||
130 | mutex_lock(&card->conf_mutex); | ||
129 | if ((card->state != CARD_STATE_DOWN) && | 131 | if ((card->state != CARD_STATE_DOWN) && |
130 | (card->state != CARD_STATE_RECOVER)) | 132 | (card->state != CARD_STATE_RECOVER)) { |
131 | return -EPERM; | 133 | rc = -EPERM; |
134 | goto out; | ||
135 | } | ||
132 | 136 | ||
133 | portno = simple_strtoul(buf, &tmp, 16); | 137 | portno = simple_strtoul(buf, &tmp, 16); |
134 | if (portno > QETH_MAX_PORTNO) | 138 | if (portno > QETH_MAX_PORTNO) { |
135 | return -EINVAL; | 139 | rc = -EINVAL; |
140 | goto out; | ||
141 | } | ||
136 | limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt); | 142 | limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt); |
137 | if (portno > limit) | 143 | if (portno > limit) { |
138 | return -EINVAL; | 144 | rc = -EINVAL; |
139 | 145 | goto out; | |
146 | } | ||
140 | card->info.portno = portno; | 147 | card->info.portno = portno; |
141 | return count; | 148 | out: |
149 | mutex_unlock(&card->conf_mutex); | ||
150 | return rc ? rc : count; | ||
142 | } | 151 | } |
143 | 152 | ||
144 | static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store); | 153 | static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store); |
@@ -165,18 +174,23 @@ static ssize_t qeth_dev_portname_store(struct device *dev, | |||
165 | { | 174 | { |
166 | struct qeth_card *card = dev_get_drvdata(dev); | 175 | struct qeth_card *card = dev_get_drvdata(dev); |
167 | char *tmp; | 176 | char *tmp; |
168 | int i; | 177 | int i, rc = 0; |
169 | 178 | ||
170 | if (!card) | 179 | if (!card) |
171 | return -EINVAL; | 180 | return -EINVAL; |
172 | 181 | ||
182 | mutex_lock(&card->conf_mutex); | ||
173 | if ((card->state != CARD_STATE_DOWN) && | 183 | if ((card->state != CARD_STATE_DOWN) && |
174 | (card->state != CARD_STATE_RECOVER)) | 184 | (card->state != CARD_STATE_RECOVER)) { |
175 | return -EPERM; | 185 | rc = -EPERM; |
186 | goto out; | ||
187 | } | ||
176 | 188 | ||
177 | tmp = strsep((char **) &buf, "\n"); | 189 | tmp = strsep((char **) &buf, "\n"); |
178 | if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) | 190 | if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) { |
179 | return -EINVAL; | 191 | rc = -EINVAL; |
192 | goto out; | ||
193 | } | ||
180 | 194 | ||
181 | card->info.portname[0] = strlen(tmp); | 195 | card->info.portname[0] = strlen(tmp); |
182 | /* for beauty reasons */ | 196 | /* for beauty reasons */ |
@@ -184,8 +198,9 @@ static ssize_t qeth_dev_portname_store(struct device *dev, | |||
184 | card->info.portname[i] = ' '; | 198 | card->info.portname[i] = ' '; |
185 | strcpy(card->info.portname + 1, tmp); | 199 | strcpy(card->info.portname + 1, tmp); |
186 | ASCEBC(card->info.portname + 1, 8); | 200 | ASCEBC(card->info.portname + 1, 8); |
187 | 201 | out: | |
188 | return count; | 202 | mutex_unlock(&card->conf_mutex); |
203 | return rc ? rc : count; | ||
189 | } | 204 | } |
190 | 205 | ||
191 | static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, | 206 | static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, |
@@ -215,20 +230,25 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
215 | { | 230 | { |
216 | struct qeth_card *card = dev_get_drvdata(dev); | 231 | struct qeth_card *card = dev_get_drvdata(dev); |
217 | char *tmp; | 232 | char *tmp; |
233 | int rc = 0; | ||
218 | 234 | ||
219 | if (!card) | 235 | if (!card) |
220 | return -EINVAL; | 236 | return -EINVAL; |
221 | 237 | ||
238 | mutex_lock(&card->conf_mutex); | ||
222 | if ((card->state != CARD_STATE_DOWN) && | 239 | if ((card->state != CARD_STATE_DOWN) && |
223 | (card->state != CARD_STATE_RECOVER)) | 240 | (card->state != CARD_STATE_RECOVER)) { |
224 | return -EPERM; | 241 | rc = -EPERM; |
242 | goto out; | ||
243 | } | ||
225 | 244 | ||
226 | /* check if 1920 devices are supported , | 245 | /* check if 1920 devices are supported , |
227 | * if though we have to permit priority queueing | 246 | * if though we have to permit priority queueing |
228 | */ | 247 | */ |
229 | if (card->qdio.no_out_queues == 1) { | 248 | if (card->qdio.no_out_queues == 1) { |
230 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; | 249 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; |
231 | return -EPERM; | 250 | rc = -EPERM; |
251 | goto out; | ||
232 | } | 252 | } |
233 | 253 | ||
234 | tmp = strsep((char **) &buf, "\n"); | 254 | tmp = strsep((char **) &buf, "\n"); |
@@ -251,10 +271,11 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
251 | } else if (!strcmp(tmp, "no_prio_queueing")) { | 271 | } else if (!strcmp(tmp, "no_prio_queueing")) { |
252 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; | 272 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; |
253 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; | 273 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; |
254 | } else { | 274 | } else |
255 | return -EINVAL; | 275 | rc = -EINVAL; |
256 | } | 276 | out: |
257 | return count; | 277 | mutex_unlock(&card->conf_mutex); |
278 | return rc ? rc : count; | ||
258 | } | 279 | } |
259 | 280 | ||
260 | static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, | 281 | static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, |
@@ -277,14 +298,17 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, | |||
277 | struct qeth_card *card = dev_get_drvdata(dev); | 298 | struct qeth_card *card = dev_get_drvdata(dev); |
278 | char *tmp; | 299 | char *tmp; |
279 | int cnt, old_cnt; | 300 | int cnt, old_cnt; |
280 | int rc; | 301 | int rc = 0; |
281 | 302 | ||
282 | if (!card) | 303 | if (!card) |
283 | return -EINVAL; | 304 | return -EINVAL; |
284 | 305 | ||
306 | mutex_lock(&card->conf_mutex); | ||
285 | if ((card->state != CARD_STATE_DOWN) && | 307 | if ((card->state != CARD_STATE_DOWN) && |
286 | (card->state != CARD_STATE_RECOVER)) | 308 | (card->state != CARD_STATE_RECOVER)) { |
287 | return -EPERM; | 309 | rc = -EPERM; |
310 | goto out; | ||
311 | } | ||
288 | 312 | ||
289 | old_cnt = card->qdio.in_buf_pool.buf_count; | 313 | old_cnt = card->qdio.in_buf_pool.buf_count; |
290 | cnt = simple_strtoul(buf, &tmp, 10); | 314 | cnt = simple_strtoul(buf, &tmp, 10); |
@@ -293,7 +317,9 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, | |||
293 | if (old_cnt != cnt) { | 317 | if (old_cnt != cnt) { |
294 | rc = qeth_realloc_buffer_pool(card, cnt); | 318 | rc = qeth_realloc_buffer_pool(card, cnt); |
295 | } | 319 | } |
296 | return count; | 320 | out: |
321 | mutex_unlock(&card->conf_mutex); | ||
322 | return rc ? rc : count; | ||
297 | } | 323 | } |
298 | 324 | ||
299 | static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, | 325 | static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, |
@@ -337,25 +363,27 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, | |||
337 | { | 363 | { |
338 | struct qeth_card *card = dev_get_drvdata(dev); | 364 | struct qeth_card *card = dev_get_drvdata(dev); |
339 | char *tmp; | 365 | char *tmp; |
340 | int i; | 366 | int i, rc = 0; |
341 | 367 | ||
342 | if (!card) | 368 | if (!card) |
343 | return -EINVAL; | 369 | return -EINVAL; |
344 | 370 | ||
371 | mutex_lock(&card->conf_mutex); | ||
345 | i = simple_strtoul(buf, &tmp, 16); | 372 | i = simple_strtoul(buf, &tmp, 16); |
346 | if ((i == 0) || (i == 1)) { | 373 | if ((i == 0) || (i == 1)) { |
347 | if (i == card->options.performance_stats) | 374 | if (i == card->options.performance_stats) |
348 | return count; | 375 | goto out;; |
349 | card->options.performance_stats = i; | 376 | card->options.performance_stats = i; |
350 | if (i == 0) | 377 | if (i == 0) |
351 | memset(&card->perf_stats, 0, | 378 | memset(&card->perf_stats, 0, |
352 | sizeof(struct qeth_perf_stats)); | 379 | sizeof(struct qeth_perf_stats)); |
353 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; | 380 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; |
354 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; | 381 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; |
355 | } else { | 382 | } else |
356 | return -EINVAL; | 383 | rc = -EINVAL; |
357 | } | 384 | out: |
358 | return count; | 385 | mutex_unlock(&card->conf_mutex); |
386 | return rc ? rc : count; | ||
359 | } | 387 | } |
360 | 388 | ||
361 | static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, | 389 | static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, |
@@ -377,15 +405,17 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
377 | { | 405 | { |
378 | struct qeth_card *card = dev_get_drvdata(dev); | 406 | struct qeth_card *card = dev_get_drvdata(dev); |
379 | char *tmp; | 407 | char *tmp; |
380 | int i, rc; | 408 | int i, rc = 0; |
381 | enum qeth_discipline_id newdis; | 409 | enum qeth_discipline_id newdis; |
382 | 410 | ||
383 | if (!card) | 411 | if (!card) |
384 | return -EINVAL; | 412 | return -EINVAL; |
385 | 413 | ||
386 | if (((card->state != CARD_STATE_DOWN) && | 414 | mutex_lock(&card->conf_mutex); |
387 | (card->state != CARD_STATE_RECOVER))) | 415 | if (card->state != CARD_STATE_DOWN) { |
388 | return -EPERM; | 416 | rc = -EPERM; |
417 | goto out; | ||
418 | } | ||
389 | 419 | ||
390 | i = simple_strtoul(buf, &tmp, 16); | 420 | i = simple_strtoul(buf, &tmp, 16); |
391 | switch (i) { | 421 | switch (i) { |
@@ -396,12 +426,13 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
396 | newdis = QETH_DISCIPLINE_LAYER2; | 426 | newdis = QETH_DISCIPLINE_LAYER2; |
397 | break; | 427 | break; |
398 | default: | 428 | default: |
399 | return -EINVAL; | 429 | rc = -EINVAL; |
430 | goto out; | ||
400 | } | 431 | } |
401 | 432 | ||
402 | if (card->options.layer2 == newdis) { | 433 | if (card->options.layer2 == newdis) |
403 | return count; | 434 | goto out; |
404 | } else { | 435 | else { |
405 | if (card->discipline.ccwgdriver) { | 436 | if (card->discipline.ccwgdriver) { |
406 | card->discipline.ccwgdriver->remove(card->gdev); | 437 | card->discipline.ccwgdriver->remove(card->gdev); |
407 | qeth_core_free_discipline(card); | 438 | qeth_core_free_discipline(card); |
@@ -410,12 +441,12 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
410 | 441 | ||
411 | rc = qeth_core_load_discipline(card, newdis); | 442 | rc = qeth_core_load_discipline(card, newdis); |
412 | if (rc) | 443 | if (rc) |
413 | return rc; | 444 | goto out; |
414 | 445 | ||
415 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 446 | rc = card->discipline.ccwgdriver->probe(card->gdev); |
416 | if (rc) | 447 | out: |
417 | return rc; | 448 | mutex_unlock(&card->conf_mutex); |
418 | return count; | 449 | return rc ? rc : count; |
419 | } | 450 | } |
420 | 451 | ||
421 | static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, | 452 | static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, |
@@ -454,13 +485,13 @@ static ssize_t qeth_dev_isolation_store(struct device *dev, | |||
454 | char *tmp, *curtoken; | 485 | char *tmp, *curtoken; |
455 | curtoken = (char *) buf; | 486 | curtoken = (char *) buf; |
456 | 487 | ||
457 | if (!card) { | 488 | if (!card) |
458 | rc = -EINVAL; | 489 | return -EINVAL; |
459 | goto out; | ||
460 | } | ||
461 | 490 | ||
491 | mutex_lock(&card->conf_mutex); | ||
462 | /* check for unknown, too, in case we do not yet know who we are */ | 492 | /* check for unknown, too, in case we do not yet know who we are */ |
463 | if (card->info.type != QETH_CARD_TYPE_OSAE && | 493 | if (card->info.type != QETH_CARD_TYPE_OSD && |
494 | card->info.type != QETH_CARD_TYPE_OSX && | ||
464 | card->info.type != QETH_CARD_TYPE_UNKNOWN) { | 495 | card->info.type != QETH_CARD_TYPE_UNKNOWN) { |
465 | rc = -EOPNOTSUPP; | 496 | rc = -EOPNOTSUPP; |
466 | dev_err(&card->gdev->dev, "Adapter does not " | 497 | dev_err(&card->gdev->dev, "Adapter does not " |
@@ -491,6 +522,7 @@ static ssize_t qeth_dev_isolation_store(struct device *dev, | |||
491 | rc = ipa_rc; | 522 | rc = ipa_rc; |
492 | } | 523 | } |
493 | out: | 524 | out: |
525 | mutex_unlock(&card->conf_mutex); | ||
494 | return rc; | 526 | return rc; |
495 | } | 527 | } |
496 | 528 | ||
@@ -510,22 +542,25 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card, | |||
510 | const char *buf, size_t count, int *value, int max_value) | 542 | const char *buf, size_t count, int *value, int max_value) |
511 | { | 543 | { |
512 | char *tmp; | 544 | char *tmp; |
513 | int i; | 545 | int i, rc = 0; |
514 | 546 | ||
515 | if (!card) | 547 | if (!card) |
516 | return -EINVAL; | 548 | return -EINVAL; |
517 | 549 | ||
550 | mutex_lock(&card->conf_mutex); | ||
518 | if ((card->state != CARD_STATE_DOWN) && | 551 | if ((card->state != CARD_STATE_DOWN) && |
519 | (card->state != CARD_STATE_RECOVER)) | 552 | (card->state != CARD_STATE_RECOVER)) { |
520 | return -EPERM; | 553 | rc = -EPERM; |
521 | 554 | goto out; | |
555 | } | ||
522 | i = simple_strtoul(buf, &tmp, 10); | 556 | i = simple_strtoul(buf, &tmp, 10); |
523 | if (i <= max_value) { | 557 | if (i <= max_value) |
524 | *value = i; | 558 | *value = i; |
525 | } else { | 559 | else |
526 | return -EINVAL; | 560 | rc = -EINVAL; |
527 | } | 561 | out: |
528 | return count; | 562 | mutex_unlock(&card->conf_mutex); |
563 | return rc ? rc : count; | ||
529 | } | 564 | } |
530 | 565 | ||
531 | static ssize_t qeth_dev_blkt_total_show(struct device *dev, | 566 | static ssize_t qeth_dev_blkt_total_show(struct device *dev, |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 6a801dc3bf8e..d43f57a4ac66 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -56,7 +56,9 @@ static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
56 | rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); | 56 | rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); |
57 | break; | 57 | break; |
58 | case SIOC_QETH_GET_CARD_TYPE: | 58 | case SIOC_QETH_GET_CARD_TYPE: |
59 | if ((card->info.type == QETH_CARD_TYPE_OSAE) && | 59 | if ((card->info.type == QETH_CARD_TYPE_OSD || |
60 | card->info.type == QETH_CARD_TYPE_OSM || | ||
61 | card->info.type == QETH_CARD_TYPE_OSX) && | ||
60 | !card->info.guestlan) | 62 | !card->info.guestlan) |
61 | return 1; | 63 | return 1; |
62 | return 0; | 64 | return 0; |
@@ -309,6 +311,10 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | |||
309 | struct qeth_vlan_vid *id; | 311 | struct qeth_vlan_vid *id; |
310 | 312 | ||
311 | QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid); | 313 | QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid); |
314 | if (card->info.type == QETH_CARD_TYPE_OSM) { | ||
315 | QETH_DBF_TEXT(TRACE, 3, "aidOSM"); | ||
316 | return; | ||
317 | } | ||
312 | if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { | 318 | if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { |
313 | QETH_DBF_TEXT(TRACE, 3, "aidREC"); | 319 | QETH_DBF_TEXT(TRACE, 3, "aidREC"); |
314 | return; | 320 | return; |
@@ -329,6 +335,10 @@ static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
329 | struct qeth_card *card = dev->ml_priv; | 335 | struct qeth_card *card = dev->ml_priv; |
330 | 336 | ||
331 | QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid); | 337 | QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid); |
338 | if (card->info.type == QETH_CARD_TYPE_OSM) { | ||
339 | QETH_DBF_TEXT(TRACE, 3, "kidOSM"); | ||
340 | return; | ||
341 | } | ||
332 | if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { | 342 | if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { |
333 | QETH_DBF_TEXT(TRACE, 3, "kidREC"); | 343 | QETH_DBF_TEXT(TRACE, 3, "kidREC"); |
334 | return; | 344 | return; |
@@ -559,8 +569,10 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) | |||
559 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | 569 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
560 | } | 570 | } |
561 | 571 | ||
562 | if ((card->info.type == QETH_CARD_TYPE_IQD) || | 572 | if (card->info.type == QETH_CARD_TYPE_IQD || |
563 | (card->info.guestlan)) { | 573 | card->info.type == QETH_CARD_TYPE_OSM || |
574 | card->info.type == QETH_CARD_TYPE_OSX || | ||
575 | card->info.guestlan) { | ||
564 | rc = qeth_setadpparms_change_macaddr(card); | 576 | rc = qeth_setadpparms_change_macaddr(card); |
565 | if (rc) { | 577 | if (rc) { |
566 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " | 578 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " |
@@ -589,8 +601,10 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
589 | return -EOPNOTSUPP; | 601 | return -EOPNOTSUPP; |
590 | } | 602 | } |
591 | 603 | ||
592 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 604 | if (card->info.type == QETH_CARD_TYPE_OSN || |
593 | QETH_DBF_TEXT(TRACE, 3, "setmcOSN"); | 605 | card->info.type == QETH_CARD_TYPE_OSM || |
606 | card->info.type == QETH_CARD_TYPE_OSX) { | ||
607 | QETH_DBF_TEXT(TRACE, 3, "setmcTYP"); | ||
594 | return -EOPNOTSUPP; | 608 | return -EOPNOTSUPP; |
595 | } | 609 | } |
596 | QETH_DBF_TEXT_(TRACE, 3, "%s", CARD_BUS_ID(card)); | 610 | QETH_DBF_TEXT_(TRACE, 3, "%s", CARD_BUS_ID(card)); |
@@ -608,7 +622,6 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
608 | static void qeth_l2_set_multicast_list(struct net_device *dev) | 622 | static void qeth_l2_set_multicast_list(struct net_device *dev) |
609 | { | 623 | { |
610 | struct qeth_card *card = dev->ml_priv; | 624 | struct qeth_card *card = dev->ml_priv; |
611 | struct dev_addr_list *dm; | ||
612 | struct netdev_hw_addr *ha; | 625 | struct netdev_hw_addr *ha; |
613 | 626 | ||
614 | if (card->info.type == QETH_CARD_TYPE_OSN) | 627 | if (card->info.type == QETH_CARD_TYPE_OSN) |
@@ -620,8 +633,8 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) | |||
620 | return; | 633 | return; |
621 | qeth_l2_del_all_mc(card); | 634 | qeth_l2_del_all_mc(card); |
622 | spin_lock_bh(&card->mclock); | 635 | spin_lock_bh(&card->mclock); |
623 | for (dm = dev->mc_list; dm; dm = dm->next) | 636 | netdev_for_each_mc_addr(ha, dev) |
624 | qeth_l2_add_mc(card, dm->da_addr, 0); | 637 | qeth_l2_add_mc(card, ha->addr, 0); |
625 | 638 | ||
626 | netdev_for_each_uc_addr(ha, dev) | 639 | netdev_for_each_uc_addr(ha, dev) |
627 | qeth_l2_add_mc(card, ha->addr, 1); | 640 | qeth_l2_add_mc(card, ha->addr, 1); |
@@ -886,9 +899,6 @@ static const struct net_device_ops qeth_l2_netdev_ops = { | |||
886 | static int qeth_l2_setup_netdev(struct qeth_card *card) | 899 | static int qeth_l2_setup_netdev(struct qeth_card *card) |
887 | { | 900 | { |
888 | switch (card->info.type) { | 901 | switch (card->info.type) { |
889 | case QETH_CARD_TYPE_OSAE: | ||
890 | card->dev = alloc_etherdev(0); | ||
891 | break; | ||
892 | case QETH_CARD_TYPE_IQD: | 902 | case QETH_CARD_TYPE_IQD: |
893 | card->dev = alloc_netdev(0, "hsi%d", ether_setup); | 903 | card->dev = alloc_netdev(0, "hsi%d", ether_setup); |
894 | break; | 904 | break; |
@@ -925,6 +935,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
925 | enum qeth_card_states recover_flag; | 935 | enum qeth_card_states recover_flag; |
926 | 936 | ||
927 | BUG_ON(!card); | 937 | BUG_ON(!card); |
938 | mutex_lock(&card->conf_mutex); | ||
928 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 939 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
929 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 940 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
930 | 941 | ||
@@ -957,18 +968,21 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
957 | dev_warn(&card->gdev->dev, | 968 | dev_warn(&card->gdev->dev, |
958 | "The LAN is offline\n"); | 969 | "The LAN is offline\n"); |
959 | card->lan_online = 0; | 970 | card->lan_online = 0; |
960 | return 0; | 971 | goto out; |
961 | } | 972 | } |
962 | rc = -ENODEV; | 973 | rc = -ENODEV; |
963 | goto out_remove; | 974 | goto out_remove; |
964 | } else | 975 | } else |
965 | card->lan_online = 1; | 976 | card->lan_online = 1; |
966 | 977 | ||
967 | if (card->info.type != QETH_CARD_TYPE_OSN) { | 978 | if ((card->info.type == QETH_CARD_TYPE_OSD) || |
979 | (card->info.type == QETH_CARD_TYPE_OSX)) | ||
968 | /* configure isolation level */ | 980 | /* configure isolation level */ |
969 | qeth_set_access_ctrl_online(card); | 981 | qeth_set_access_ctrl_online(card); |
982 | |||
983 | if (card->info.type != QETH_CARD_TYPE_OSN && | ||
984 | card->info.type != QETH_CARD_TYPE_OSM) | ||
970 | qeth_l2_process_vlans(card, 0); | 985 | qeth_l2_process_vlans(card, 0); |
971 | } | ||
972 | 986 | ||
973 | netif_tx_disable(card->dev); | 987 | netif_tx_disable(card->dev); |
974 | 988 | ||
@@ -996,6 +1010,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
996 | } | 1010 | } |
997 | /* let user_space know that device is online */ | 1011 | /* let user_space know that device is online */ |
998 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 1012 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
1013 | out: | ||
1014 | mutex_unlock(&card->conf_mutex); | ||
999 | return 0; | 1015 | return 0; |
1000 | 1016 | ||
1001 | out_remove: | 1017 | out_remove: |
@@ -1008,6 +1024,7 @@ out_remove: | |||
1008 | card->state = CARD_STATE_RECOVER; | 1024 | card->state = CARD_STATE_RECOVER; |
1009 | else | 1025 | else |
1010 | card->state = CARD_STATE_DOWN; | 1026 | card->state = CARD_STATE_DOWN; |
1027 | mutex_unlock(&card->conf_mutex); | ||
1011 | return rc; | 1028 | return rc; |
1012 | } | 1029 | } |
1013 | 1030 | ||
@@ -1023,6 +1040,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1023 | int rc = 0, rc2 = 0, rc3 = 0; | 1040 | int rc = 0, rc2 = 0, rc3 = 0; |
1024 | enum qeth_card_states recover_flag; | 1041 | enum qeth_card_states recover_flag; |
1025 | 1042 | ||
1043 | mutex_lock(&card->conf_mutex); | ||
1026 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 1044 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
1027 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 1045 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
1028 | 1046 | ||
@@ -1041,6 +1059,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1041 | card->state = CARD_STATE_RECOVER; | 1059 | card->state = CARD_STATE_RECOVER; |
1042 | /* let user_space know that device is offline */ | 1060 | /* let user_space know that device is offline */ |
1043 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 1061 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
1062 | mutex_unlock(&card->conf_mutex); | ||
1044 | return 0; | 1063 | return 0; |
1045 | } | 1064 | } |
1046 | 1065 | ||
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index fc6ca1da8b98..61adae21a464 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -54,16 +54,16 @@ int qeth_l3_set_large_send(struct qeth_card *card, | |||
54 | if (card->options.large_send == QETH_LARGE_SEND_TSO) { | 54 | if (card->options.large_send == QETH_LARGE_SEND_TSO) { |
55 | if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) { | 55 | if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) { |
56 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG | | 56 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG | |
57 | NETIF_F_HW_CSUM; | 57 | NETIF_F_IP_CSUM; |
58 | } else { | 58 | } else { |
59 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | | 59 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | |
60 | NETIF_F_HW_CSUM); | 60 | NETIF_F_IP_CSUM); |
61 | card->options.large_send = QETH_LARGE_SEND_NO; | 61 | card->options.large_send = QETH_LARGE_SEND_NO; |
62 | rc = -EOPNOTSUPP; | 62 | rc = -EOPNOTSUPP; |
63 | } | 63 | } |
64 | } else { | 64 | } else { |
65 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | | 65 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | |
66 | NETIF_F_HW_CSUM); | 66 | NETIF_F_IP_CSUM); |
67 | card->options.large_send = QETH_LARGE_SEND_NO; | 67 | card->options.large_send = QETH_LARGE_SEND_NO; |
68 | } | 68 | } |
69 | return rc; | 69 | return rc; |
@@ -1108,6 +1108,13 @@ static int qeth_l3_default_setassparms_cb(struct qeth_card *card, | |||
1108 | card->info.csum_mask = cmd->data.setassparms.data.flags_32bit; | 1108 | card->info.csum_mask = cmd->data.setassparms.data.flags_32bit; |
1109 | QETH_DBF_TEXT_(TRACE, 3, "csum:%d", card->info.csum_mask); | 1109 | QETH_DBF_TEXT_(TRACE, 3, "csum:%d", card->info.csum_mask); |
1110 | } | 1110 | } |
1111 | if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM && | ||
1112 | cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) { | ||
1113 | card->info.tx_csum_mask = | ||
1114 | cmd->data.setassparms.data.flags_32bit; | ||
1115 | QETH_DBF_TEXT_(TRACE, 3, "tcsu:%d", card->info.tx_csum_mask); | ||
1116 | } | ||
1117 | |||
1111 | return 0; | 1118 | return 0; |
1112 | } | 1119 | } |
1113 | 1120 | ||
@@ -1536,6 +1543,28 @@ static int qeth_l3_start_ipa_checksum(struct qeth_card *card) | |||
1536 | return rc; | 1543 | return rc; |
1537 | } | 1544 | } |
1538 | 1545 | ||
1546 | static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card) | ||
1547 | { | ||
1548 | int rc = 0; | ||
1549 | |||
1550 | if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) | ||
1551 | return rc; | ||
1552 | rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, | ||
1553 | IPA_CMD_ASS_START, 0); | ||
1554 | if (rc) | ||
1555 | goto err_out; | ||
1556 | rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, | ||
1557 | IPA_CMD_ASS_ENABLE, card->info.tx_csum_mask); | ||
1558 | if (rc) | ||
1559 | goto err_out; | ||
1560 | dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n"); | ||
1561 | return rc; | ||
1562 | err_out: | ||
1563 | dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s " | ||
1564 | "failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card)); | ||
1565 | return rc; | ||
1566 | } | ||
1567 | |||
1539 | static int qeth_l3_start_ipa_tso(struct qeth_card *card) | 1568 | static int qeth_l3_start_ipa_tso(struct qeth_card *card) |
1540 | { | 1569 | { |
1541 | int rc; | 1570 | int rc; |
@@ -1578,6 +1607,7 @@ static int qeth_l3_start_ipassists(struct qeth_card *card) | |||
1578 | qeth_l3_start_ipa_ipv6(card); /* go on*/ | 1607 | qeth_l3_start_ipa_ipv6(card); /* go on*/ |
1579 | qeth_l3_start_ipa_broadcast(card); /* go on*/ | 1608 | qeth_l3_start_ipa_broadcast(card); /* go on*/ |
1580 | qeth_l3_start_ipa_checksum(card); /* go on*/ | 1609 | qeth_l3_start_ipa_checksum(card); /* go on*/ |
1610 | qeth_l3_start_ipa_tx_checksum(card); | ||
1581 | qeth_l3_start_ipa_tso(card); /* go on*/ | 1611 | qeth_l3_start_ipa_tso(card); /* go on*/ |
1582 | return 0; | 1612 | return 0; |
1583 | } | 1613 | } |
@@ -1929,7 +1959,7 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, | |||
1929 | in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid)); | 1959 | in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid)); |
1930 | if (!in6_dev) | 1960 | if (!in6_dev) |
1931 | return; | 1961 | return; |
1932 | for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next) { | 1962 | list_for_each_entry(ifa, &in6_dev->addr_list, if_list) { |
1933 | addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); | 1963 | addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6); |
1934 | if (addr) { | 1964 | if (addr) { |
1935 | memcpy(&addr->u.a6.addr, &ifa->addr, | 1965 | memcpy(&addr->u.a6.addr, &ifa->addr, |
@@ -2681,7 +2711,8 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2681 | rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); | 2711 | rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data); |
2682 | break; | 2712 | break; |
2683 | case SIOC_QETH_GET_CARD_TYPE: | 2713 | case SIOC_QETH_GET_CARD_TYPE: |
2684 | if ((card->info.type == QETH_CARD_TYPE_OSAE) && | 2714 | if ((card->info.type == QETH_CARD_TYPE_OSD || |
2715 | card->info.type == QETH_CARD_TYPE_OSX) && | ||
2685 | !card->info.guestlan) | 2716 | !card->info.guestlan) |
2686 | return 1; | 2717 | return 1; |
2687 | return 0; | 2718 | return 0; |
@@ -2817,6 +2848,21 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, | |||
2817 | } | 2848 | } |
2818 | } | 2849 | } |
2819 | 2850 | ||
2851 | static inline void qeth_l3_hdr_csum(struct qeth_card *card, | ||
2852 | struct qeth_hdr *hdr, struct sk_buff *skb) | ||
2853 | { | ||
2854 | struct iphdr *iph = ip_hdr(skb); | ||
2855 | |||
2856 | /* tcph->check contains already the pseudo hdr checksum | ||
2857 | * so just set the header flags | ||
2858 | */ | ||
2859 | if (iph->protocol == IPPROTO_UDP) | ||
2860 | hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_UDP; | ||
2861 | hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ; | ||
2862 | if (card->options.performance_stats) | ||
2863 | card->perf_stats.tx_csum++; | ||
2864 | } | ||
2865 | |||
2820 | static void qeth_tso_fill_header(struct qeth_card *card, | 2866 | static void qeth_tso_fill_header(struct qeth_card *card, |
2821 | struct qeth_hdr *qhdr, struct sk_buff *skb) | 2867 | struct qeth_hdr *qhdr, struct sk_buff *skb) |
2822 | { | 2868 | { |
@@ -2852,21 +2898,6 @@ static void qeth_tso_fill_header(struct qeth_card *card, | |||
2852 | } | 2898 | } |
2853 | } | 2899 | } |
2854 | 2900 | ||
2855 | static void qeth_tx_csum(struct sk_buff *skb) | ||
2856 | { | ||
2857 | __wsum csum; | ||
2858 | int offset; | ||
2859 | |||
2860 | skb_set_transport_header(skb, skb->csum_start - skb_headroom(skb)); | ||
2861 | offset = skb->csum_start - skb_headroom(skb); | ||
2862 | BUG_ON(offset >= skb_headlen(skb)); | ||
2863 | csum = skb_checksum(skb, offset, skb->len - offset, 0); | ||
2864 | |||
2865 | offset += skb->csum_offset; | ||
2866 | BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb)); | ||
2867 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); | ||
2868 | } | ||
2869 | |||
2870 | static inline int qeth_l3_tso_elements(struct sk_buff *skb) | 2901 | static inline int qeth_l3_tso_elements(struct sk_buff *skb) |
2871 | { | 2902 | { |
2872 | unsigned long tcpd = (unsigned long)tcp_hdr(skb) + | 2903 | unsigned long tcpd = (unsigned long)tcp_hdr(skb) + |
@@ -2923,12 +2954,6 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2923 | 2954 | ||
2924 | if (skb_is_gso(skb)) | 2955 | if (skb_is_gso(skb)) |
2925 | large_send = card->options.large_send; | 2956 | large_send = card->options.large_send; |
2926 | else | ||
2927 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
2928 | qeth_tx_csum(skb); | ||
2929 | if (card->options.performance_stats) | ||
2930 | card->perf_stats.tx_csum++; | ||
2931 | } | ||
2932 | 2957 | ||
2933 | if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) && | 2958 | if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) && |
2934 | (skb_shinfo(skb)->nr_frags == 0)) { | 2959 | (skb_shinfo(skb)->nr_frags == 0)) { |
@@ -3007,6 +3032,9 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3007 | cast_type); | 3032 | cast_type); |
3008 | hdr->hdr.l3.length = new_skb->len - data_offset; | 3033 | hdr->hdr.l3.length = new_skb->len - data_offset; |
3009 | } | 3034 | } |
3035 | |||
3036 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
3037 | qeth_l3_hdr_csum(card, hdr, new_skb); | ||
3010 | } | 3038 | } |
3011 | 3039 | ||
3012 | elems = qeth_get_elements_no(card, (void *)hdr, new_skb, | 3040 | elems = qeth_get_elements_no(card, (void *)hdr, new_skb, |
@@ -3132,10 +3160,25 @@ static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) | |||
3132 | return rc; | 3160 | return rc; |
3133 | } | 3161 | } |
3134 | 3162 | ||
3163 | static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data) | ||
3164 | { | ||
3165 | struct qeth_card *card = dev->ml_priv; | ||
3166 | |||
3167 | if (data) { | ||
3168 | if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) | ||
3169 | dev->features |= NETIF_F_IP_CSUM; | ||
3170 | else | ||
3171 | return -EPERM; | ||
3172 | } else | ||
3173 | dev->features &= ~NETIF_F_IP_CSUM; | ||
3174 | |||
3175 | return 0; | ||
3176 | } | ||
3177 | |||
3135 | static const struct ethtool_ops qeth_l3_ethtool_ops = { | 3178 | static const struct ethtool_ops qeth_l3_ethtool_ops = { |
3136 | .get_link = ethtool_op_get_link, | 3179 | .get_link = ethtool_op_get_link, |
3137 | .get_tx_csum = ethtool_op_get_tx_csum, | 3180 | .get_tx_csum = ethtool_op_get_tx_csum, |
3138 | .set_tx_csum = ethtool_op_set_tx_hw_csum, | 3181 | .set_tx_csum = qeth_l3_ethtool_set_tx_csum, |
3139 | .get_rx_csum = qeth_l3_ethtool_get_rx_csum, | 3182 | .get_rx_csum = qeth_l3_ethtool_get_rx_csum, |
3140 | .set_rx_csum = qeth_l3_ethtool_set_rx_csum, | 3183 | .set_rx_csum = qeth_l3_ethtool_set_rx_csum, |
3141 | .get_sg = ethtool_op_get_sg, | 3184 | .get_sg = ethtool_op_get_sg, |
@@ -3206,7 +3249,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { | |||
3206 | 3249 | ||
3207 | static int qeth_l3_setup_netdev(struct qeth_card *card) | 3250 | static int qeth_l3_setup_netdev(struct qeth_card *card) |
3208 | { | 3251 | { |
3209 | if (card->info.type == QETH_CARD_TYPE_OSAE) { | 3252 | if (card->info.type == QETH_CARD_TYPE_OSD || |
3253 | card->info.type == QETH_CARD_TYPE_OSX) { | ||
3210 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || | 3254 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || |
3211 | (card->info.link_type == QETH_LINK_TYPE_HSTR)) { | 3255 | (card->info.link_type == QETH_LINK_TYPE_HSTR)) { |
3212 | #ifdef CONFIG_TR | 3256 | #ifdef CONFIG_TR |
@@ -3336,6 +3380,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3336 | enum qeth_card_states recover_flag; | 3380 | enum qeth_card_states recover_flag; |
3337 | 3381 | ||
3338 | BUG_ON(!card); | 3382 | BUG_ON(!card); |
3383 | mutex_lock(&card->conf_mutex); | ||
3339 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 3384 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
3340 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 3385 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
3341 | 3386 | ||
@@ -3367,7 +3412,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3367 | dev_warn(&card->gdev->dev, | 3412 | dev_warn(&card->gdev->dev, |
3368 | "The LAN is offline\n"); | 3413 | "The LAN is offline\n"); |
3369 | card->lan_online = 0; | 3414 | card->lan_online = 0; |
3370 | return 0; | 3415 | goto out; |
3371 | } | 3416 | } |
3372 | rc = -ENODEV; | 3417 | rc = -ENODEV; |
3373 | goto out_remove; | 3418 | goto out_remove; |
@@ -3414,6 +3459,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3414 | } | 3459 | } |
3415 | /* let user_space know that device is online */ | 3460 | /* let user_space know that device is online */ |
3416 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 3461 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
3462 | out: | ||
3463 | mutex_unlock(&card->conf_mutex); | ||
3417 | return 0; | 3464 | return 0; |
3418 | out_remove: | 3465 | out_remove: |
3419 | card->use_hard_stop = 1; | 3466 | card->use_hard_stop = 1; |
@@ -3425,6 +3472,7 @@ out_remove: | |||
3425 | card->state = CARD_STATE_RECOVER; | 3472 | card->state = CARD_STATE_RECOVER; |
3426 | else | 3473 | else |
3427 | card->state = CARD_STATE_DOWN; | 3474 | card->state = CARD_STATE_DOWN; |
3475 | mutex_unlock(&card->conf_mutex); | ||
3428 | return rc; | 3476 | return rc; |
3429 | } | 3477 | } |
3430 | 3478 | ||
@@ -3440,6 +3488,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3440 | int rc = 0, rc2 = 0, rc3 = 0; | 3488 | int rc = 0, rc2 = 0, rc3 = 0; |
3441 | enum qeth_card_states recover_flag; | 3489 | enum qeth_card_states recover_flag; |
3442 | 3490 | ||
3491 | mutex_lock(&card->conf_mutex); | ||
3443 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 3492 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
3444 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 3493 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
3445 | 3494 | ||
@@ -3458,6 +3507,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3458 | card->state = CARD_STATE_RECOVER; | 3507 | card->state = CARD_STATE_RECOVER; |
3459 | /* let user_space know that device is offline */ | 3508 | /* let user_space know that device is offline */ |
3460 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 3509 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
3510 | mutex_unlock(&card->conf_mutex); | ||
3461 | return 0; | 3511 | return 0; |
3462 | } | 3512 | } |
3463 | 3513 | ||
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 25b3e7aae44f..fb5318b30e99 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -70,10 +70,10 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
70 | { | 70 | { |
71 | enum qeth_routing_types old_route_type = route->type; | 71 | enum qeth_routing_types old_route_type = route->type; |
72 | char *tmp; | 72 | char *tmp; |
73 | int rc; | 73 | int rc = 0; |
74 | 74 | ||
75 | tmp = strsep((char **) &buf, "\n"); | 75 | tmp = strsep((char **) &buf, "\n"); |
76 | 76 | mutex_lock(&card->conf_mutex); | |
77 | if (!strcmp(tmp, "no_router")) { | 77 | if (!strcmp(tmp, "no_router")) { |
78 | route->type = NO_ROUTER; | 78 | route->type = NO_ROUTER; |
79 | } else if (!strcmp(tmp, "primary_connector")) { | 79 | } else if (!strcmp(tmp, "primary_connector")) { |
@@ -87,7 +87,8 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
87 | } else if (!strcmp(tmp, "multicast_router")) { | 87 | } else if (!strcmp(tmp, "multicast_router")) { |
88 | route->type = MULTICAST_ROUTER; | 88 | route->type = MULTICAST_ROUTER; |
89 | } else { | 89 | } else { |
90 | return -EINVAL; | 90 | rc = -EINVAL; |
91 | goto out; | ||
91 | } | 92 | } |
92 | if (((card->state == CARD_STATE_SOFTSETUP) || | 93 | if (((card->state == CARD_STATE_SOFTSETUP) || |
93 | (card->state == CARD_STATE_UP)) && | 94 | (card->state == CARD_STATE_UP)) && |
@@ -97,7 +98,9 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
97 | else if (prot == QETH_PROT_IPV6) | 98 | else if (prot == QETH_PROT_IPV6) |
98 | rc = qeth_l3_setrouting_v6(card); | 99 | rc = qeth_l3_setrouting_v6(card); |
99 | } | 100 | } |
100 | return count; | 101 | out: |
102 | mutex_unlock(&card->conf_mutex); | ||
103 | return rc ? rc : count; | ||
101 | } | 104 | } |
102 | 105 | ||
103 | static ssize_t qeth_l3_dev_route4_store(struct device *dev, | 106 | static ssize_t qeth_l3_dev_route4_store(struct device *dev, |
@@ -157,22 +160,26 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, | |||
157 | { | 160 | { |
158 | struct qeth_card *card = dev_get_drvdata(dev); | 161 | struct qeth_card *card = dev_get_drvdata(dev); |
159 | char *tmp; | 162 | char *tmp; |
160 | int i; | 163 | int i, rc = 0; |
161 | 164 | ||
162 | if (!card) | 165 | if (!card) |
163 | return -EINVAL; | 166 | return -EINVAL; |
164 | 167 | ||
168 | mutex_lock(&card->conf_mutex); | ||
165 | if ((card->state != CARD_STATE_DOWN) && | 169 | if ((card->state != CARD_STATE_DOWN) && |
166 | (card->state != CARD_STATE_RECOVER)) | 170 | (card->state != CARD_STATE_RECOVER)) { |
167 | return -EPERM; | 171 | rc = -EPERM; |
172 | goto out; | ||
173 | } | ||
168 | 174 | ||
169 | i = simple_strtoul(buf, &tmp, 16); | 175 | i = simple_strtoul(buf, &tmp, 16); |
170 | if ((i == 0) || (i == 1)) | 176 | if ((i == 0) || (i == 1)) |
171 | card->options.fake_broadcast = i; | 177 | card->options.fake_broadcast = i; |
172 | else { | 178 | else |
173 | return -EINVAL; | 179 | rc = -EINVAL; |
174 | } | 180 | out: |
175 | return count; | 181 | mutex_unlock(&card->conf_mutex); |
182 | return rc ? rc : count; | ||
176 | } | 183 | } |
177 | 184 | ||
178 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, | 185 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, |
@@ -200,31 +207,35 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, | |||
200 | { | 207 | { |
201 | struct qeth_card *card = dev_get_drvdata(dev); | 208 | struct qeth_card *card = dev_get_drvdata(dev); |
202 | char *tmp; | 209 | char *tmp; |
210 | int rc = 0; | ||
203 | 211 | ||
204 | if (!card) | 212 | if (!card) |
205 | return -EINVAL; | 213 | return -EINVAL; |
206 | 214 | ||
215 | mutex_lock(&card->conf_mutex); | ||
207 | if ((card->state != CARD_STATE_DOWN) && | 216 | if ((card->state != CARD_STATE_DOWN) && |
208 | (card->state != CARD_STATE_RECOVER)) | 217 | (card->state != CARD_STATE_RECOVER)) { |
209 | return -EPERM; | 218 | rc = -EPERM; |
219 | goto out; | ||
220 | } | ||
210 | 221 | ||
211 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 222 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
212 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 223 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
213 | return -EINVAL; | 224 | rc = -EINVAL; |
225 | goto out; | ||
214 | } | 226 | } |
215 | 227 | ||
216 | tmp = strsep((char **) &buf, "\n"); | 228 | tmp = strsep((char **) &buf, "\n"); |
217 | 229 | ||
218 | if (!strcmp(tmp, "local")) { | 230 | if (!strcmp(tmp, "local")) |
219 | card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; | 231 | card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; |
220 | return count; | 232 | else if (!strcmp(tmp, "all_rings")) |
221 | } else if (!strcmp(tmp, "all_rings")) { | ||
222 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; | 233 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; |
223 | return count; | 234 | else |
224 | } else { | 235 | rc = -EINVAL; |
225 | return -EINVAL; | 236 | out: |
226 | } | 237 | mutex_unlock(&card->conf_mutex); |
227 | return count; | 238 | return rc ? rc : count; |
228 | } | 239 | } |
229 | 240 | ||
230 | static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, | 241 | static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, |
@@ -251,18 +262,22 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
251 | { | 262 | { |
252 | struct qeth_card *card = dev_get_drvdata(dev); | 263 | struct qeth_card *card = dev_get_drvdata(dev); |
253 | char *tmp; | 264 | char *tmp; |
254 | int i; | 265 | int i, rc = 0; |
255 | 266 | ||
256 | if (!card) | 267 | if (!card) |
257 | return -EINVAL; | 268 | return -EINVAL; |
258 | 269 | ||
270 | mutex_lock(&card->conf_mutex); | ||
259 | if ((card->state != CARD_STATE_DOWN) && | 271 | if ((card->state != CARD_STATE_DOWN) && |
260 | (card->state != CARD_STATE_RECOVER)) | 272 | (card->state != CARD_STATE_RECOVER)) { |
261 | return -EPERM; | 273 | rc = -EPERM; |
274 | goto out; | ||
275 | } | ||
262 | 276 | ||
263 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 277 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
264 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 278 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
265 | return -EINVAL; | 279 | rc = -EINVAL; |
280 | goto out; | ||
266 | } | 281 | } |
267 | 282 | ||
268 | i = simple_strtoul(buf, &tmp, 16); | 283 | i = simple_strtoul(buf, &tmp, 16); |
@@ -270,10 +285,11 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
270 | card->options.macaddr_mode = i? | 285 | card->options.macaddr_mode = i? |
271 | QETH_TR_MACADDR_CANONICAL : | 286 | QETH_TR_MACADDR_CANONICAL : |
272 | QETH_TR_MACADDR_NONCANONICAL; | 287 | QETH_TR_MACADDR_NONCANONICAL; |
273 | else { | 288 | else |
274 | return -EINVAL; | 289 | rc = -EINVAL; |
275 | } | 290 | out: |
276 | return count; | 291 | mutex_unlock(&card->conf_mutex); |
292 | return rc ? rc : count; | ||
277 | } | 293 | } |
278 | 294 | ||
279 | static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, | 295 | static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, |
@@ -297,11 +313,12 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
297 | struct qeth_card *card = dev_get_drvdata(dev); | 313 | struct qeth_card *card = dev_get_drvdata(dev); |
298 | enum qeth_checksum_types csum_type; | 314 | enum qeth_checksum_types csum_type; |
299 | char *tmp; | 315 | char *tmp; |
300 | int rc; | 316 | int rc = 0; |
301 | 317 | ||
302 | if (!card) | 318 | if (!card) |
303 | return -EINVAL; | 319 | return -EINVAL; |
304 | 320 | ||
321 | mutex_lock(&card->conf_mutex); | ||
305 | tmp = strsep((char **) &buf, "\n"); | 322 | tmp = strsep((char **) &buf, "\n"); |
306 | if (!strcmp(tmp, "sw_checksumming")) | 323 | if (!strcmp(tmp, "sw_checksumming")) |
307 | csum_type = SW_CHECKSUMMING; | 324 | csum_type = SW_CHECKSUMMING; |
@@ -309,13 +326,15 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
309 | csum_type = HW_CHECKSUMMING; | 326 | csum_type = HW_CHECKSUMMING; |
310 | else if (!strcmp(tmp, "no_checksumming")) | 327 | else if (!strcmp(tmp, "no_checksumming")) |
311 | csum_type = NO_CHECKSUMMING; | 328 | csum_type = NO_CHECKSUMMING; |
312 | else | 329 | else { |
313 | return -EINVAL; | 330 | rc = -EINVAL; |
331 | goto out; | ||
332 | } | ||
314 | 333 | ||
315 | rc = qeth_l3_set_rx_csum(card, csum_type); | 334 | rc = qeth_l3_set_rx_csum(card, csum_type); |
316 | if (rc) | 335 | out: |
317 | return rc; | 336 | mutex_unlock(&card->conf_mutex); |
318 | return count; | 337 | return rc ? rc : count; |
319 | } | 338 | } |
320 | 339 | ||
321 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, | 340 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, |
@@ -336,7 +355,7 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
336 | struct device_attribute *attr, const char *buf, size_t count) | 355 | struct device_attribute *attr, const char *buf, size_t count) |
337 | { | 356 | { |
338 | struct qeth_card *card = dev_get_drvdata(dev); | 357 | struct qeth_card *card = dev_get_drvdata(dev); |
339 | int ret; | 358 | int rc = 0; |
340 | unsigned long i; | 359 | unsigned long i; |
341 | 360 | ||
342 | if (!card) | 361 | if (!card) |
@@ -345,19 +364,24 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
345 | if (card->info.type != QETH_CARD_TYPE_IQD) | 364 | if (card->info.type != QETH_CARD_TYPE_IQD) |
346 | return -EPERM; | 365 | return -EPERM; |
347 | 366 | ||
367 | mutex_lock(&card->conf_mutex); | ||
348 | if ((card->state != CARD_STATE_DOWN) && | 368 | if ((card->state != CARD_STATE_DOWN) && |
349 | (card->state != CARD_STATE_RECOVER)) | 369 | (card->state != CARD_STATE_RECOVER)) { |
350 | return -EPERM; | 370 | rc = -EPERM; |
371 | goto out; | ||
372 | } | ||
351 | 373 | ||
352 | ret = strict_strtoul(buf, 16, &i); | 374 | rc = strict_strtoul(buf, 16, &i); |
353 | if (ret) | 375 | if (rc) { |
354 | return -EINVAL; | 376 | rc = -EINVAL; |
377 | goto out; | ||
378 | } | ||
355 | switch (i) { | 379 | switch (i) { |
356 | case 0: | 380 | case 0: |
357 | card->options.sniffer = i; | 381 | card->options.sniffer = i; |
358 | break; | 382 | break; |
359 | case 1: | 383 | case 1: |
360 | ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); | 384 | qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); |
361 | if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { | 385 | if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { |
362 | card->options.sniffer = i; | 386 | card->options.sniffer = i; |
363 | if (card->qdio.init_pool.buf_count != | 387 | if (card->qdio.init_pool.buf_count != |
@@ -366,11 +390,13 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
366 | QETH_IN_BUF_COUNT_MAX); | 390 | QETH_IN_BUF_COUNT_MAX); |
367 | break; | 391 | break; |
368 | } else | 392 | } else |
369 | return -EPERM; | 393 | rc = -EPERM; |
370 | default: /* fall through */ | 394 | default: /* fall through */ |
371 | return -EINVAL; | 395 | rc = -EINVAL; |
372 | } | 396 | } |
373 | return count; | 397 | out: |
398 | mutex_unlock(&card->conf_mutex); | ||
399 | return rc ? rc : count; | ||
374 | } | 400 | } |
375 | 401 | ||
376 | static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, | 402 | static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, |
@@ -412,12 +438,11 @@ static ssize_t qeth_l3_dev_large_send_store(struct device *dev, | |||
412 | else | 438 | else |
413 | return -EINVAL; | 439 | return -EINVAL; |
414 | 440 | ||
415 | if (card->options.large_send == type) | 441 | mutex_lock(&card->conf_mutex); |
416 | return count; | 442 | if (card->options.large_send != type) |
417 | rc = qeth_l3_set_large_send(card, type); | 443 | rc = qeth_l3_set_large_send(card, type); |
418 | if (rc) | 444 | mutex_unlock(&card->conf_mutex); |
419 | return rc; | 445 | return rc ? rc : count; |
420 | return count; | ||
421 | } | 446 | } |
422 | 447 | ||
423 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, | 448 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, |
@@ -455,13 +480,17 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
455 | { | 480 | { |
456 | struct qeth_card *card = dev_get_drvdata(dev); | 481 | struct qeth_card *card = dev_get_drvdata(dev); |
457 | char *tmp; | 482 | char *tmp; |
483 | int rc = 0; | ||
458 | 484 | ||
459 | if (!card) | 485 | if (!card) |
460 | return -EINVAL; | 486 | return -EINVAL; |
461 | 487 | ||
488 | mutex_lock(&card->conf_mutex); | ||
462 | if ((card->state != CARD_STATE_DOWN) && | 489 | if ((card->state != CARD_STATE_DOWN) && |
463 | (card->state != CARD_STATE_RECOVER)) | 490 | (card->state != CARD_STATE_RECOVER)) { |
464 | return -EPERM; | 491 | rc = -EPERM; |
492 | goto out; | ||
493 | } | ||
465 | 494 | ||
466 | tmp = strsep((char **) &buf, "\n"); | 495 | tmp = strsep((char **) &buf, "\n"); |
467 | if (!strcmp(tmp, "toggle")) { | 496 | if (!strcmp(tmp, "toggle")) { |
@@ -470,10 +499,11 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
470 | card->ipato.enabled = 1; | 499 | card->ipato.enabled = 1; |
471 | } else if (!strcmp(tmp, "0")) { | 500 | } else if (!strcmp(tmp, "0")) { |
472 | card->ipato.enabled = 0; | 501 | card->ipato.enabled = 0; |
473 | } else { | 502 | } else |
474 | return -EINVAL; | 503 | rc = -EINVAL; |
475 | } | 504 | out: |
476 | return count; | 505 | mutex_unlock(&card->conf_mutex); |
506 | return rc ? rc : count; | ||
477 | } | 507 | } |
478 | 508 | ||
479 | static QETH_DEVICE_ATTR(ipato_enable, enable, 0644, | 509 | static QETH_DEVICE_ATTR(ipato_enable, enable, 0644, |
@@ -497,10 +527,12 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
497 | { | 527 | { |
498 | struct qeth_card *card = dev_get_drvdata(dev); | 528 | struct qeth_card *card = dev_get_drvdata(dev); |
499 | char *tmp; | 529 | char *tmp; |
530 | int rc = 0; | ||
500 | 531 | ||
501 | if (!card) | 532 | if (!card) |
502 | return -EINVAL; | 533 | return -EINVAL; |
503 | 534 | ||
535 | mutex_lock(&card->conf_mutex); | ||
504 | tmp = strsep((char **) &buf, "\n"); | 536 | tmp = strsep((char **) &buf, "\n"); |
505 | if (!strcmp(tmp, "toggle")) { | 537 | if (!strcmp(tmp, "toggle")) { |
506 | card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; | 538 | card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; |
@@ -508,10 +540,10 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
508 | card->ipato.invert4 = 1; | 540 | card->ipato.invert4 = 1; |
509 | } else if (!strcmp(tmp, "0")) { | 541 | } else if (!strcmp(tmp, "0")) { |
510 | card->ipato.invert4 = 0; | 542 | card->ipato.invert4 = 0; |
511 | } else { | 543 | } else |
512 | return -EINVAL; | 544 | rc = -EINVAL; |
513 | } | 545 | mutex_unlock(&card->conf_mutex); |
514 | return count; | 546 | return rc ? rc : count; |
515 | } | 547 | } |
516 | 548 | ||
517 | static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644, | 549 | static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644, |
@@ -593,27 +625,28 @@ static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count, | |||
593 | struct qeth_ipato_entry *ipatoe; | 625 | struct qeth_ipato_entry *ipatoe; |
594 | u8 addr[16]; | 626 | u8 addr[16]; |
595 | int mask_bits; | 627 | int mask_bits; |
596 | int rc; | 628 | int rc = 0; |
597 | 629 | ||
630 | mutex_lock(&card->conf_mutex); | ||
598 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); | 631 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); |
599 | if (rc) | 632 | if (rc) |
600 | return rc; | 633 | goto out; |
601 | 634 | ||
602 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); | 635 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); |
603 | if (!ipatoe) { | 636 | if (!ipatoe) { |
604 | return -ENOMEM; | 637 | rc = -ENOMEM; |
638 | goto out; | ||
605 | } | 639 | } |
606 | ipatoe->proto = proto; | 640 | ipatoe->proto = proto; |
607 | memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16); | 641 | memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16); |
608 | ipatoe->mask_bits = mask_bits; | 642 | ipatoe->mask_bits = mask_bits; |
609 | 643 | ||
610 | rc = qeth_l3_add_ipato_entry(card, ipatoe); | 644 | rc = qeth_l3_add_ipato_entry(card, ipatoe); |
611 | if (rc) { | 645 | if (rc) |
612 | kfree(ipatoe); | 646 | kfree(ipatoe); |
613 | return rc; | 647 | out: |
614 | } | 648 | mutex_unlock(&card->conf_mutex); |
615 | 649 | return rc ? rc : count; | |
616 | return count; | ||
617 | } | 650 | } |
618 | 651 | ||
619 | static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev, | 652 | static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev, |
@@ -636,15 +669,14 @@ static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count, | |||
636 | { | 669 | { |
637 | u8 addr[16]; | 670 | u8 addr[16]; |
638 | int mask_bits; | 671 | int mask_bits; |
639 | int rc; | 672 | int rc = 0; |
640 | 673 | ||
674 | mutex_lock(&card->conf_mutex); | ||
641 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); | 675 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); |
642 | if (rc) | 676 | if (!rc) |
643 | return rc; | 677 | qeth_l3_del_ipato_entry(card, proto, addr, mask_bits); |
644 | 678 | mutex_unlock(&card->conf_mutex); | |
645 | qeth_l3_del_ipato_entry(card, proto, addr, mask_bits); | 679 | return rc ? rc : count; |
646 | |||
647 | return count; | ||
648 | } | 680 | } |
649 | 681 | ||
650 | static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev, | 682 | static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev, |
@@ -677,10 +709,12 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
677 | { | 709 | { |
678 | struct qeth_card *card = dev_get_drvdata(dev); | 710 | struct qeth_card *card = dev_get_drvdata(dev); |
679 | char *tmp; | 711 | char *tmp; |
712 | int rc = 0; | ||
680 | 713 | ||
681 | if (!card) | 714 | if (!card) |
682 | return -EINVAL; | 715 | return -EINVAL; |
683 | 716 | ||
717 | mutex_lock(&card->conf_mutex); | ||
684 | tmp = strsep((char **) &buf, "\n"); | 718 | tmp = strsep((char **) &buf, "\n"); |
685 | if (!strcmp(tmp, "toggle")) { | 719 | if (!strcmp(tmp, "toggle")) { |
686 | card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; | 720 | card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; |
@@ -688,10 +722,10 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
688 | card->ipato.invert6 = 1; | 722 | card->ipato.invert6 = 1; |
689 | } else if (!strcmp(tmp, "0")) { | 723 | } else if (!strcmp(tmp, "0")) { |
690 | card->ipato.invert6 = 0; | 724 | card->ipato.invert6 = 0; |
691 | } else { | 725 | } else |
692 | return -EINVAL; | 726 | rc = -EINVAL; |
693 | } | 727 | mutex_unlock(&card->conf_mutex); |
694 | return count; | 728 | return rc ? rc : count; |
695 | } | 729 | } |
696 | 730 | ||
697 | static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644, | 731 | static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644, |
@@ -813,15 +847,12 @@ static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count, | |||
813 | u8 addr[16] = {0, }; | 847 | u8 addr[16] = {0, }; |
814 | int rc; | 848 | int rc; |
815 | 849 | ||
850 | mutex_lock(&card->conf_mutex); | ||
816 | rc = qeth_l3_parse_vipae(buf, proto, addr); | 851 | rc = qeth_l3_parse_vipae(buf, proto, addr); |
817 | if (rc) | 852 | if (!rc) |
818 | return rc; | 853 | rc = qeth_l3_add_vipa(card, proto, addr); |
819 | 854 | mutex_unlock(&card->conf_mutex); | |
820 | rc = qeth_l3_add_vipa(card, proto, addr); | 855 | return rc ? rc : count; |
821 | if (rc) | ||
822 | return rc; | ||
823 | |||
824 | return count; | ||
825 | } | 856 | } |
826 | 857 | ||
827 | static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev, | 858 | static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev, |
@@ -845,13 +876,12 @@ static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count, | |||
845 | u8 addr[16]; | 876 | u8 addr[16]; |
846 | int rc; | 877 | int rc; |
847 | 878 | ||
879 | mutex_lock(&card->conf_mutex); | ||
848 | rc = qeth_l3_parse_vipae(buf, proto, addr); | 880 | rc = qeth_l3_parse_vipae(buf, proto, addr); |
849 | if (rc) | 881 | if (!rc) |
850 | return rc; | 882 | qeth_l3_del_vipa(card, proto, addr); |
851 | 883 | mutex_unlock(&card->conf_mutex); | |
852 | qeth_l3_del_vipa(card, proto, addr); | 884 | return rc ? rc : count; |
853 | |||
854 | return count; | ||
855 | } | 885 | } |
856 | 886 | ||
857 | static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev, | 887 | static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev, |
@@ -979,15 +1009,12 @@ static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count, | |||
979 | u8 addr[16] = {0, }; | 1009 | u8 addr[16] = {0, }; |
980 | int rc; | 1010 | int rc; |
981 | 1011 | ||
1012 | mutex_lock(&card->conf_mutex); | ||
982 | rc = qeth_l3_parse_rxipe(buf, proto, addr); | 1013 | rc = qeth_l3_parse_rxipe(buf, proto, addr); |
983 | if (rc) | 1014 | if (!rc) |
984 | return rc; | 1015 | rc = qeth_l3_add_rxip(card, proto, addr); |
985 | 1016 | mutex_unlock(&card->conf_mutex); | |
986 | rc = qeth_l3_add_rxip(card, proto, addr); | 1017 | return rc ? rc : count; |
987 | if (rc) | ||
988 | return rc; | ||
989 | |||
990 | return count; | ||
991 | } | 1018 | } |
992 | 1019 | ||
993 | static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev, | 1020 | static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev, |
@@ -1011,13 +1038,12 @@ static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count, | |||
1011 | u8 addr[16]; | 1038 | u8 addr[16]; |
1012 | int rc; | 1039 | int rc; |
1013 | 1040 | ||
1041 | mutex_lock(&card->conf_mutex); | ||
1014 | rc = qeth_l3_parse_rxipe(buf, proto, addr); | 1042 | rc = qeth_l3_parse_rxipe(buf, proto, addr); |
1015 | if (rc) | 1043 | if (!rc) |
1016 | return rc; | 1044 | qeth_l3_del_rxip(card, proto, addr); |
1017 | 1045 | mutex_unlock(&card->conf_mutex); | |
1018 | qeth_l3_del_rxip(card, proto, addr); | 1046 | return rc ? rc : count; |
1019 | |||
1020 | return count; | ||
1021 | } | 1047 | } |
1022 | 1048 | ||
1023 | static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev, | 1049 | static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev, |