Commit 81c11dd2 authored by Bhanu Prakash Gollapudi's avatar Bhanu Prakash Gollapudi Committed by James Bottomley

[SCSI] libfcoe: Support extra MAC descriptor to be used as FCoE MAC

Some switch implementations (eg., HP virtual connect FlexFabric) send two MAC
descriptors in FIP FLOGI response, with first MAC descriptor (granted_mac) used
as FPMA, and the second one (fcoe_mac) used as destination address for
sending/receiving FCoE packets. fip_mac continues to be used for FIP traffic.
This patch introduces fcoe_mac in fcoe_fcf structure. For regular switches,
both fcoe_mac and fip_mac will be the same. For the switches that send
additional MAC descriptor, fcoe_mac is updated.
Signed-off-by: default avatarBhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 73d67aa4
...@@ -242,7 +242,7 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) ...@@ -242,7 +242,7 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
printk(KERN_INFO "libfcoe: host%d: FIP selected " printk(KERN_INFO "libfcoe: host%d: FIP selected "
"Fibre-Channel Forwarder MAC %pM\n", "Fibre-Channel Forwarder MAC %pM\n",
fip->lp->host->host_no, sel->fcf_mac); fip->lp->host->host_no, sel->fcf_mac);
memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); memcpy(fip->dest_addr, sel->fcoe_mac, ETH_ALEN);
fip->map_dest = 0; fip->map_dest = 0;
} }
unlock: unlock:
...@@ -824,6 +824,7 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip, ...@@ -824,6 +824,7 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip,
memcpy(fcf->fcf_mac, memcpy(fcf->fcf_mac,
((struct fip_mac_desc *)desc)->fd_mac, ((struct fip_mac_desc *)desc)->fd_mac,
ETH_ALEN); ETH_ALEN);
memcpy(fcf->fcoe_mac, fcf->fcf_mac, ETH_ALEN);
if (!is_valid_ether_addr(fcf->fcf_mac)) { if (!is_valid_ether_addr(fcf->fcf_mac)) {
LIBFCOE_FIP_DBG(fip, LIBFCOE_FIP_DBG(fip,
"Invalid MAC addr %pM in FIP adv\n", "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,6 +1014,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
struct fip_desc *desc; struct fip_desc *desc;
struct fip_encaps *els; struct fip_encaps *els;
struct fcoe_dev_stats *stats; struct fcoe_dev_stats *stats;
struct fcoe_fcf *sel;
enum fip_desc_type els_dtype = 0; enum fip_desc_type els_dtype = 0;
u8 els_op; u8 els_op;
u8 sub; u8 sub;
...@@ -1040,7 +1042,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -1040,7 +1042,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
goto drop; goto drop;
/* Drop ELS if there are duplicate critical descriptors */ /* Drop ELS if there are duplicate critical descriptors */
if (desc->fip_dtype < 32) { if (desc->fip_dtype < 32) {
if (desc_mask & 1U << desc->fip_dtype) { if ((desc->fip_dtype != FIP_DT_MAC) &&
(desc_mask & 1U << desc->fip_dtype)) {
LIBFCOE_FIP_DBG(fip, "Duplicate Critical " LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
"Descriptors in FIP ELS\n"); "Descriptors in FIP ELS\n");
goto drop; goto drop;
...@@ -1049,17 +1052,32 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -1049,17 +1052,32 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
} }
switch (desc->fip_dtype) { switch (desc->fip_dtype) {
case FIP_DT_MAC: case FIP_DT_MAC:
sel = fip->sel_fcf;
if (desc_cnt == 1) { if (desc_cnt == 1) {
LIBFCOE_FIP_DBG(fip, "FIP descriptors " LIBFCOE_FIP_DBG(fip, "FIP descriptors "
"received out of order\n"); "received out of order\n");
goto drop; goto drop;
} }
/*
* Some switch implementations send two MAC descriptors,
* with first MAC(granted_mac) being the FPMA, and the
* second one(fcoe_mac) is used as destination address
* for sending/receiving FCoE packets. FIP traffic is
* sent using fip_mac. For regular switches, both
* fip_mac and fcoe_mac would be the same.
*/
if (desc_cnt == 2)
memcpy(granted_mac,
((struct fip_mac_desc *)desc)->fd_mac,
ETH_ALEN);
if (dlen != sizeof(struct fip_mac_desc)) if (dlen != sizeof(struct fip_mac_desc))
goto len_err; goto len_err;
memcpy(granted_mac,
((struct fip_mac_desc *)desc)->fd_mac, if ((desc_cnt == 3) && (sel))
ETH_ALEN); memcpy(sel->fcoe_mac,
((struct fip_mac_desc *)desc)->fd_mac,
ETH_ALEN);
break; break;
case FIP_DT_FLOGI: case FIP_DT_FLOGI:
case FIP_DT_FDISC: case FIP_DT_FDISC:
......
...@@ -165,7 +165,8 @@ struct fcoe_ctlr { ...@@ -165,7 +165,8 @@ struct fcoe_ctlr {
* @switch_name: WWN of switch from advertisement * @switch_name: WWN of switch from advertisement
* @fabric_name: WWN of fabric from advertisement * @fabric_name: WWN of fabric from advertisement
* @fc_map: FC_MAP value from advertisement * @fc_map: FC_MAP value from advertisement
* @fcf_mac: Ethernet address of the FCF * @fcf_mac: Ethernet address of the FCF for FIP traffic
* @fcoe_mac: Ethernet address of the FCF for FCoE traffic
* @vfid: virtual fabric ID * @vfid: virtual fabric ID
* @pri: selection priority, smaller values are better * @pri: selection priority, smaller values are better
* @flogi_sent: current FLOGI sent to this FCF * @flogi_sent: current FLOGI sent to this FCF
...@@ -188,6 +189,7 @@ struct fcoe_fcf { ...@@ -188,6 +189,7 @@ struct fcoe_fcf {
u32 fc_map; u32 fc_map;
u16 vfid; u16 vfid;
u8 fcf_mac[ETH_ALEN]; u8 fcf_mac[ETH_ALEN];
u8 fcoe_mac[ETH_ALEN];
u8 pri; u8 pri;
u8 flogi_sent; u8 flogi_sent;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment