diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe_ctlr.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 38 |
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 | } |
248 | unlock: | 248 | unlock: |
@@ -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 { |