diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 24 |
1 files changed, 22 insertions, 2 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 | /* |