aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe_ctlr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/fcoe_ctlr.c')
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index e7522dcc296e..249a106888d9 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -242,7 +242,7 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
242 printk(KERN_INFO "libfcoe: host%d: FIP selected " 242 printk(KERN_INFO "libfcoe: host%d: FIP selected "
243 "Fibre-Channel Forwarder MAC %pM\n", 243 "Fibre-Channel Forwarder MAC %pM\n",
244 fip->lp->host->host_no, sel->fcf_mac); 244 fip->lp->host->host_no, sel->fcf_mac);
245 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); 245 memcpy(fip->dest_addr, sel->fcoe_mac, ETH_ALEN);
246 fip->map_dest = 0; 246 fip->map_dest = 0;
247 } 247 }
248unlock: 248unlock:
@@ -824,6 +824,7 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
824 memcpy(fcf->fcf_mac, 824 memcpy(fcf->fcf_mac,
825 ((struct fip_mac_desc *)desc)->fd_mac, 825 ((struct fip_mac_desc *)desc)->fd_mac,
826 ETH_ALEN); 826 ETH_ALEN);
827 memcpy(fcf->fcoe_mac, fcf->fcf_mac, ETH_ALEN);
827 if (!is_valid_ether_addr(fcf->fcf_mac)) { 828 if (!is_valid_ether_addr(fcf->fcf_mac)) {
828 LIBFCOE_FIP_DBG(fip, 829 LIBFCOE_FIP_DBG(fip,
829 "Invalid MAC addr %pM in FIP adv\n", 830 "Invalid MAC addr %pM in FIP adv\n",
@@ -1013,6 +1014,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1013 struct fip_desc *desc; 1014 struct fip_desc *desc;
1014 struct fip_encaps *els; 1015 struct fip_encaps *els;
1015 struct fcoe_dev_stats *stats; 1016 struct fcoe_dev_stats *stats;
1017 struct fcoe_fcf *sel;
1016 enum fip_desc_type els_dtype = 0; 1018 enum fip_desc_type els_dtype = 0;
1017 u8 els_op; 1019 u8 els_op;
1018 u8 sub; 1020 u8 sub;
@@ -1040,7 +1042,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1040 goto drop; 1042 goto drop;
1041 /* Drop ELS if there are duplicate critical descriptors */ 1043 /* Drop ELS if there are duplicate critical descriptors */
1042 if (desc->fip_dtype < 32) { 1044 if (desc->fip_dtype < 32) {
1043 if (desc_mask & 1U << desc->fip_dtype) { 1045 if ((desc->fip_dtype != FIP_DT_MAC) &&
1046 (desc_mask & 1U << desc->fip_dtype)) {
1044 LIBFCOE_FIP_DBG(fip, "Duplicate Critical " 1047 LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
1045 "Descriptors in FIP ELS\n"); 1048 "Descriptors in FIP ELS\n");
1046 goto drop; 1049 goto drop;
@@ -1049,17 +1052,32 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1049 } 1052 }
1050 switch (desc->fip_dtype) { 1053 switch (desc->fip_dtype) {
1051 case FIP_DT_MAC: 1054 case FIP_DT_MAC:
1055 sel = fip->sel_fcf;
1052 if (desc_cnt == 1) { 1056 if (desc_cnt == 1) {
1053 LIBFCOE_FIP_DBG(fip, "FIP descriptors " 1057 LIBFCOE_FIP_DBG(fip, "FIP descriptors "
1054 "received out of order\n"); 1058 "received out of order\n");
1055 goto drop; 1059 goto drop;
1056 } 1060 }
1061 /*
1062 * Some switch implementations send two MAC descriptors,
1063 * with first MAC(granted_mac) being the FPMA, and the
1064 * second one(fcoe_mac) is used as destination address
1065 * for sending/receiving FCoE packets. FIP traffic is
1066 * sent using fip_mac. For regular switches, both
1067 * fip_mac and fcoe_mac would be the same.
1068 */
1069 if (desc_cnt == 2)
1070 memcpy(granted_mac,
1071 ((struct fip_mac_desc *)desc)->fd_mac,
1072 ETH_ALEN);
1057 1073
1058 if (dlen != sizeof(struct fip_mac_desc)) 1074 if (dlen != sizeof(struct fip_mac_desc))
1059 goto len_err; 1075 goto len_err;
1060 memcpy(granted_mac, 1076
1061 ((struct fip_mac_desc *)desc)->fd_mac, 1077 if ((desc_cnt == 3) && (sel))
1062 ETH_ALEN); 1078 memcpy(sel->fcoe_mac,
1079 ((struct fip_mac_desc *)desc)->fd_mac,
1080 ETH_ALEN);
1063 break; 1081 break;
1064 case FIP_DT_FLOGI: 1082 case FIP_DT_FLOGI:
1065 case FIP_DT_FDISC: 1083 case FIP_DT_FDISC:
@@ -1273,11 +1291,6 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
1273 * No Vx_Port description. Clear all NPIV ports, 1291 * No Vx_Port description. Clear all NPIV ports,
1274 * followed by physical port 1292 * followed by physical port
1275 */ 1293 */
1276 mutex_lock(&lport->lp_mutex);
1277 list_for_each_entry(vn_port, &lport->vports, list)
1278 fc_lport_reset(vn_port);
1279 mutex_unlock(&lport->lp_mutex);
1280
1281 mutex_lock(&fip->ctlr_mutex); 1294 mutex_lock(&fip->ctlr_mutex);
1282 per_cpu_ptr(lport->dev_stats, 1295 per_cpu_ptr(lport->dev_stats,
1283 get_cpu())->VLinkFailureCount++; 1296 get_cpu())->VLinkFailureCount++;
@@ -1285,6 +1298,11 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
1285 fcoe_ctlr_reset(fip); 1298 fcoe_ctlr_reset(fip);
1286 mutex_unlock(&fip->ctlr_mutex); 1299 mutex_unlock(&fip->ctlr_mutex);
1287 1300
1301 mutex_lock(&lport->lp_mutex);
1302 list_for_each_entry(vn_port, &lport->vports, list)
1303 fc_lport_reset(vn_port);
1304 mutex_unlock(&lport->lp_mutex);
1305
1288 fc_lport_reset(fip->lp); 1306 fc_lport_reset(fip->lp);
1289 fcoe_ctlr_solicit(fip, NULL); 1307 fcoe_ctlr_solicit(fip, NULL);
1290 } else { 1308 } else {