aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/qeth_core_main.c36
-rw-r--r--drivers/s390/net/qeth_l2_main.c187
2 files changed, 117 insertions, 106 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index f407e3763432..e2fbfff53b50 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2021,10 +2021,36 @@ void qeth_prepare_control_data(struct qeth_card *card, int len,
2021} 2021}
2022EXPORT_SYMBOL_GPL(qeth_prepare_control_data); 2022EXPORT_SYMBOL_GPL(qeth_prepare_control_data);
2023 2023
2024/**
2025 * qeth_send_control_data() - send control command to the card
2026 * @card: qeth_card structure pointer
2027 * @len: size of the command buffer
2028 * @iob: qeth_cmd_buffer pointer
2029 * @reply_cb: callback function pointer
2030 * @cb_card: pointer to the qeth_card structure
2031 * @cb_reply: pointer to the qeth_reply structure
2032 * @cb_cmd: pointer to the original iob for non-IPA
2033 * commands, or to the qeth_ipa_cmd structure
2034 * for the IPA commands.
2035 * @reply_param: private pointer passed to the callback
2036 *
2037 * Returns the value of the `return_code' field of the response
2038 * block returned from the hardware, or other error indication.
2039 * Value of zero indicates successful execution of the command.
2040 *
2041 * Callback function gets called one or more times, with cb_cmd
2042 * pointing to the response returned by the hardware. Callback
2043 * function must return non-zero if more reply blocks are expected,
2044 * and zero if the last or only reply block is received. Callback
2045 * function can get the value of the reply_param pointer from the
2046 * field 'param' of the structure qeth_reply.
2047 */
2048
2024int qeth_send_control_data(struct qeth_card *card, int len, 2049int qeth_send_control_data(struct qeth_card *card, int len,
2025 struct qeth_cmd_buffer *iob, 2050 struct qeth_cmd_buffer *iob,
2026 int (*reply_cb)(struct qeth_card *, struct qeth_reply *, 2051 int (*reply_cb)(struct qeth_card *cb_card,
2027 unsigned long), 2052 struct qeth_reply *cb_reply,
2053 unsigned long cb_cmd),
2028 void *reply_param) 2054 void *reply_param)
2029{ 2055{
2030 int rc; 2056 int rc;
@@ -2932,6 +2958,12 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2932} 2958}
2933EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); 2959EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
2934 2960
2961/**
2962 * qeth_send_ipa_cmd() - send an IPA command
2963 *
2964 * See qeth_send_control_data() for explanation of the arguments.
2965 */
2966
2935int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, 2967int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2936 int (*reply_cb)(struct qeth_card *, struct qeth_reply*, 2968 int (*reply_cb)(struct qeth_card *, struct qeth_reply*,
2937 unsigned long), 2969 unsigned long),
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index d02cd1a67943..b7b9d5cbe4d5 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -27,10 +27,7 @@ static int qeth_l2_set_offline(struct ccwgroup_device *);
27static int qeth_l2_stop(struct net_device *); 27static int qeth_l2_stop(struct net_device *);
28static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); 28static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
29static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, 29static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
30 enum qeth_ipa_cmds, 30 enum qeth_ipa_cmds);
31 int (*reply_cb) (struct qeth_card *,
32 struct qeth_reply*,
33 unsigned long));
34static void qeth_l2_set_multicast_list(struct net_device *); 31static void qeth_l2_set_multicast_list(struct net_device *);
35static int qeth_l2_recover(void *); 32static int qeth_l2_recover(void *);
36static void qeth_bridgeport_query_support(struct qeth_card *card); 33static void qeth_bridgeport_query_support(struct qeth_card *card);
@@ -130,56 +127,68 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no)
130 return ndev; 127 return ndev;
131} 128}
132 129
133static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, 130static int qeth_setdel_makerc(struct qeth_card *card, int retcode)
134 struct qeth_reply *reply,
135 unsigned long data)
136{ 131{
137 struct qeth_ipa_cmd *cmd; 132 int rc;
138 __u8 *mac;
139 133
140 QETH_CARD_TEXT(card, 2, "L2Sgmacb"); 134 if (retcode)
141 cmd = (struct qeth_ipa_cmd *) data; 135 QETH_CARD_TEXT_(card, 2, "err%d", retcode);
142 mac = &cmd->data.setdelmac.mac[0]; 136 switch (retcode) {
143 /* MAC already registered, needed in couple/uncouple case */ 137 case IPA_RC_SUCCESS:
144 if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) { 138 rc = 0;
145 QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", 139 break;
146 mac, QETH_CARD_IFNAME(card)); 140 case IPA_RC_L2_UNSUPPORTED_CMD:
147 cmd->hdr.return_code = 0; 141 rc = -ENOSYS;
142 break;
143 case IPA_RC_L2_ADDR_TABLE_FULL:
144 rc = -ENOSPC;
145 break;
146 case IPA_RC_L2_DUP_MAC:
147 case IPA_RC_L2_DUP_LAYER3_MAC:
148 rc = -EEXIST;
149 break;
150 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
151 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
152 rc = -EPERM;
153 break;
154 case IPA_RC_L2_MAC_NOT_FOUND:
155 rc = -ENOENT;
156 break;
157 default:
158 rc = -EIO;
159 break;
148 } 160 }
149 if (cmd->hdr.return_code) 161 return rc;
150 QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n",
151 mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code);
152 return 0;
153} 162}
154 163
155static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) 164static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
156{ 165{
157 QETH_CARD_TEXT(card, 2, "L2Sgmac"); 166 int rc;
158 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
159 qeth_l2_send_setgroupmac_cb);
160}
161
162static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card,
163 struct qeth_reply *reply,
164 unsigned long data)
165{
166 struct qeth_ipa_cmd *cmd;
167 __u8 *mac;
168 167
169 QETH_CARD_TEXT(card, 2, "L2Dgmacb"); 168 QETH_CARD_TEXT(card, 2, "L2Sgmac");
170 cmd = (struct qeth_ipa_cmd *) data; 169 rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
171 mac = &cmd->data.setdelmac.mac[0]; 170 IPA_CMD_SETGMAC));
172 if (cmd->hdr.return_code) 171 if (rc == -EEXIST)
173 QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n", 172 QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n",
174 mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); 173 mac, QETH_CARD_IFNAME(card));
175 return 0; 174 else if (rc)
175 QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n",
176 mac, QETH_CARD_IFNAME(card), rc);
177 return rc;
176} 178}
177 179
178static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) 180static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
179{ 181{
182 int rc;
183
180 QETH_CARD_TEXT(card, 2, "L2Dgmac"); 184 QETH_CARD_TEXT(card, 2, "L2Dgmac");
181 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC, 185 rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
182 qeth_l2_send_delgroupmac_cb); 186 IPA_CMD_DELGMAC));
187 if (rc)
188 QETH_DBF_MESSAGE(2,
189 "Could not delete group MAC %pM on %s: %d\n",
190 mac, QETH_CARD_IFNAME(card), rc);
191 return rc;
183} 192}
184 193
185static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) 194static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
@@ -197,10 +206,11 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
197 mc->is_vmac = vmac; 206 mc->is_vmac = vmac;
198 207
199 if (vmac) { 208 if (vmac) {
200 rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, 209 rc = qeth_setdel_makerc(card,
201 NULL); 210 qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC));
202 } else { 211 } else {
203 rc = qeth_l2_send_setgroupmac(card, mac); 212 rc = qeth_setdel_makerc(card,
213 qeth_l2_send_setgroupmac(card, mac));
204 } 214 }
205 215
206 if (!rc) 216 if (!rc)
@@ -218,7 +228,7 @@ static void qeth_l2_del_all_mc(struct qeth_card *card, int del)
218 if (del) { 228 if (del) {
219 if (mc->is_vmac) 229 if (mc->is_vmac)
220 qeth_l2_send_setdelmac(card, mc->mc_addr, 230 qeth_l2_send_setdelmac(card, mc->mc_addr,
221 IPA_CMD_DELVMAC, NULL); 231 IPA_CMD_DELVMAC);
222 else 232 else
223 qeth_l2_send_delgroupmac(card, mc->mc_addr); 233 qeth_l2_send_delgroupmac(card, mc->mc_addr);
224 } 234 }
@@ -539,10 +549,7 @@ out:
539} 549}
540 550
541static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, 551static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
542 enum qeth_ipa_cmds ipacmd, 552 enum qeth_ipa_cmds ipacmd)
543 int (*reply_cb) (struct qeth_card *,
544 struct qeth_reply*,
545 unsigned long))
546{ 553{
547 struct qeth_ipa_cmd *cmd; 554 struct qeth_ipa_cmd *cmd;
548 struct qeth_cmd_buffer *iob; 555 struct qeth_cmd_buffer *iob;
@@ -552,78 +559,50 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
552 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 559 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
553 cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; 560 cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
554 memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); 561 memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
555 return qeth_send_ipa_cmd(card, iob, reply_cb, NULL); 562 return qeth_send_ipa_cmd(card, iob, NULL, NULL);
556} 563}
557 564
558static int qeth_l2_send_setmac_cb(struct qeth_card *card, 565static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
559 struct qeth_reply *reply,
560 unsigned long data)
561{ 566{
562 struct qeth_ipa_cmd *cmd; 567 int rc;
563 568
564 QETH_CARD_TEXT(card, 2, "L2Smaccb"); 569 QETH_CARD_TEXT(card, 2, "L2Setmac");
565 cmd = (struct qeth_ipa_cmd *) data; 570 rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
566 if (cmd->hdr.return_code) { 571 IPA_CMD_SETVMAC));
567 QETH_CARD_TEXT_(card, 2, "L2er%x", cmd->hdr.return_code); 572 if (rc == 0) {
573 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
574 memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN);
575 dev_info(&card->gdev->dev,
576 "MAC address %pM successfully registered on device %s\n",
577 card->dev->dev_addr, card->dev->name);
578 } else {
568 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; 579 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
569 switch (cmd->hdr.return_code) { 580 switch (rc) {
570 case IPA_RC_L2_DUP_MAC: 581 case -EEXIST:
571 case IPA_RC_L2_DUP_LAYER3_MAC:
572 dev_warn(&card->gdev->dev, 582 dev_warn(&card->gdev->dev,
573 "MAC address %pM already exists\n", 583 "MAC address %pM already exists\n", mac);
574 cmd->data.setdelmac.mac);
575 break; 584 break;
576 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: 585 case -EPERM:
577 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
578 dev_warn(&card->gdev->dev, 586 dev_warn(&card->gdev->dev,
579 "MAC address %pM is not authorized\n", 587 "MAC address %pM is not authorized\n", mac);
580 cmd->data.setdelmac.mac);
581 break;
582 default:
583 break; 588 break;
584 } 589 }
585 } else {
586 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
587 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
588 OSA_ADDR_LEN);
589 dev_info(&card->gdev->dev,
590 "MAC address %pM successfully registered on device %s\n",
591 card->dev->dev_addr, card->dev->name);
592 } 590 }
593 return 0; 591 return rc;
594}
595
596static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
597{
598 QETH_CARD_TEXT(card, 2, "L2Setmac");
599 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
600 qeth_l2_send_setmac_cb);
601}
602
603static int qeth_l2_send_delmac_cb(struct qeth_card *card,
604 struct qeth_reply *reply,
605 unsigned long data)
606{
607 struct qeth_ipa_cmd *cmd;
608
609 QETH_CARD_TEXT(card, 2, "L2Dmaccb");
610 cmd = (struct qeth_ipa_cmd *) data;
611 if (cmd->hdr.return_code) {
612 QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code);
613 return 0;
614 }
615 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
616
617 return 0;
618} 592}
619 593
620static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) 594static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
621{ 595{
596 int rc;
597
622 QETH_CARD_TEXT(card, 2, "L2Delmac"); 598 QETH_CARD_TEXT(card, 2, "L2Delmac");
623 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) 599 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
624 return 0; 600 return 0;
625 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, 601 rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
626 qeth_l2_send_delmac_cb); 602 IPA_CMD_DELVMAC));
603 if (rc == 0)
604 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
605 return rc;
627} 606}
628 607
629static int qeth_l2_request_initial_mac(struct qeth_card *card) 608static int qeth_l2_request_initial_mac(struct qeth_card *card)
@@ -687,7 +666,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
687 return -ERESTARTSYS; 666 return -ERESTARTSYS;
688 } 667 }
689 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); 668 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
690 if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) 669 if (!rc || (rc == -ENOENT))
691 rc = qeth_l2_send_setmac(card, addr->sa_data); 670 rc = qeth_l2_send_setmac(card, addr->sa_data);
692 return rc ? -EINVAL : 0; 671 return rc ? -EINVAL : 0;
693} 672}