aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/fcoe.c24
-rw-r--r--drivers/scsi/fcoe/libfcoe.c10
-rw-r--r--include/scsi/libfcoe.h2
3 files changed, 33 insertions, 3 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 04f500571d49..f2d16127bd0a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -238,6 +238,9 @@ void fcoe_netdev_cleanup(struct fcoe_softc *fc)
238 if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) 238 if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
239 dev_unicast_delete(fc->real_dev, 239 dev_unicast_delete(fc->real_dev,
240 fc->ctlr.data_src_addr, ETH_ALEN); 240 fc->ctlr.data_src_addr, ETH_ALEN);
241 if (fc->ctlr.spma)
242 dev_unicast_delete(fc->real_dev,
243 fc->ctlr.ctl_src_addr, ETH_ALEN);
241 dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); 244 dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
242 rtnl_unlock(); 245 rtnl_unlock();
243} 246}
@@ -257,6 +260,7 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
257 u64 wwnn, wwpn; 260 u64 wwnn, wwpn;
258 struct fcoe_softc *fc; 261 struct fcoe_softc *fc;
259 u8 flogi_maddr[ETH_ALEN]; 262 u8 flogi_maddr[ETH_ALEN];
263 struct netdev_hw_addr *ha;
260 264
261 /* Setup lport private data to point to fcoe softc */ 265 /* Setup lport private data to point to fcoe softc */
262 fc = lport_priv(lp); 266 fc = lport_priv(lp);
@@ -313,9 +317,23 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
313 skb_queue_head_init(&fc->fcoe_pending_queue); 317 skb_queue_head_init(&fc->fcoe_pending_queue);
314 fc->fcoe_pending_queue_active = 0; 318 fc->fcoe_pending_queue_active = 0;
315 319
320 /* look for SAN MAC address, if multiple SAN MACs exist, only
321 * use the first one for SPMA */
322 rcu_read_lock();
323 for_each_dev_addr(netdev, ha) {
324 if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
325 (is_valid_ether_addr(fc->ctlr.ctl_src_addr))) {
326 memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN);
327 fc->ctlr.spma = 1;
328 break;
329 }
330 }
331 rcu_read_unlock();
332
316 /* setup Source Mac Address */ 333 /* setup Source Mac Address */
317 memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr, 334 if (!fc->ctlr.spma)
318 fc->real_dev->addr_len); 335 memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
336 fc->real_dev->addr_len);
319 337
320 wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0); 338 wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
321 fc_set_wwnn(lp, wwnn); 339 fc_set_wwnn(lp, wwnn);
@@ -331,6 +349,8 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
331 rtnl_lock(); 349 rtnl_lock();
332 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); 350 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
333 dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN); 351 dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
352 if (fc->ctlr.spma)
353 dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr, ETH_ALEN);
334 rtnl_unlock(); 354 rtnl_unlock();
335 355
336 /* 356 /*
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index f410f4abb548..444a06bdb70b 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -198,6 +198,8 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
198 sol->fip.fip_subcode = FIP_SC_SOL; 198 sol->fip.fip_subcode = FIP_SC_SOL;
199 sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW); 199 sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
200 sol->fip.fip_flags = htons(FIP_FL_FPMA); 200 sol->fip.fip_flags = htons(FIP_FL_FPMA);
201 if (fip->spma)
202 sol->fip.fip_flags |= htons(FIP_FL_SPMA);
201 203
202 sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC; 204 sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
203 sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW; 205 sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
@@ -350,6 +352,8 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
350 kal->fip.fip_dl_len = htons((sizeof(kal->mac) + 352 kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
351 ports * sizeof(*vn)) / FIP_BPW); 353 ports * sizeof(*vn)) / FIP_BPW);
352 kal->fip.fip_flags = htons(FIP_FL_FPMA); 354 kal->fip.fip_flags = htons(FIP_FL_FPMA);
355 if (fip->spma)
356 kal->fip.fip_flags |= htons(FIP_FL_SPMA);
353 357
354 kal->mac.fd_desc.fip_dtype = FIP_DT_MAC; 358 kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
355 kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW; 359 kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
@@ -413,6 +417,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
413 cap->fip.fip_subcode = FIP_SC_REQ; 417 cap->fip.fip_subcode = FIP_SC_REQ;
414 cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW); 418 cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
415 cap->fip.fip_flags = htons(FIP_FL_FPMA); 419 cap->fip.fip_flags = htons(FIP_FL_FPMA);
420 if (fip->spma)
421 cap->fip.fip_flags |= htons(FIP_FL_SPMA);
416 422
417 cap->encaps.fd_desc.fip_dtype = dtype; 423 cap->encaps.fd_desc.fip_dtype = dtype;
418 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW; 424 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
@@ -421,8 +427,10 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
421 memset(mac, 0, sizeof(mac)); 427 memset(mac, 0, sizeof(mac));
422 mac->fd_desc.fip_dtype = FIP_DT_MAC; 428 mac->fd_desc.fip_dtype = FIP_DT_MAC;
423 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; 429 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
424 if (dtype != ELS_FLOGI) 430 if (dtype != FIP_DT_FLOGI)
425 memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); 431 memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
432 else if (fip->spma)
433 memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
426 434
427 skb->protocol = htons(ETH_P_802_3); 435 skb->protocol = htons(ETH_P_802_3);
428 skb_reset_mac_header(skb); 436 skb_reset_mac_header(skb);
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 666cc131732e..b2410605b740 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -73,6 +73,7 @@ enum fip_state {
73 * @link: current link status for libfc. 73 * @link: current link status for libfc.
74 * @last_link: last link state reported to libfc. 74 * @last_link: last link state reported to libfc.
75 * @map_dest: use the FC_MAP mode for destination MAC addresses. 75 * @map_dest: use the FC_MAP mode for destination MAC addresses.
76 * @spma: supports SPMA server-provided MACs mode
76 * @dest_addr: MAC address of the selected FC forwarder. 77 * @dest_addr: MAC address of the selected FC forwarder.
77 * @ctl_src_addr: the native MAC address of our local port. 78 * @ctl_src_addr: the native MAC address of our local port.
78 * @data_src_addr: the assigned MAC address for the local port after FLOGI. 79 * @data_src_addr: the assigned MAC address for the local port after FLOGI.
@@ -104,6 +105,7 @@ struct fcoe_ctlr {
104 u8 link; 105 u8 link;
105 u8 last_link; 106 u8 last_link;
106 u8 map_dest; 107 u8 map_dest;
108 u8 spma;
107 u8 dest_addr[ETH_ALEN]; 109 u8 dest_addr[ETH_ALEN];
108 u8 ctl_src_addr[ETH_ALEN]; 110 u8 ctl_src_addr[ETH_ALEN];
109 u8 data_src_addr[ETH_ALEN]; 111 u8 data_src_addr[ETH_ALEN];