aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-16 20:24:53 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-16 20:24:53 -0400
commit492b057c426e4aa747484958e18e9da29003985d (patch)
tree34e08c24618688d8bcc190523028b5f94cce0c0b /drivers/scsi/fcoe/fcoe.c
parent313485175da221c388f6a8ecf4c30062ba9bea17 (diff)
parent300df7dc89cc276377fc020704e34875d5c473b6 (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c197
1 files changed, 115 insertions, 82 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index e606b4829d44..c15878e88157 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -135,6 +135,58 @@ static struct scsi_host_template fcoe_shost_template = {
135}; 135};
136 136
137/** 137/**
138 * fcoe_fip_recv - handle a received FIP frame.
139 * @skb: the receive skb
140 * @dev: associated &net_device
141 * @ptype: the &packet_type structure which was used to register this handler.
142 * @orig_dev: original receive &net_device, in case @dev is a bond.
143 *
144 * Returns: 0 for success
145 */
146static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
147 struct packet_type *ptype,
148 struct net_device *orig_dev)
149{
150 struct fcoe_softc *fc;
151
152 fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
153 fcoe_ctlr_recv(&fc->ctlr, skb);
154 return 0;
155}
156
157/**
158 * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
159 * @fip: FCoE controller.
160 * @skb: FIP Packet.
161 */
162static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
163{
164 skb->dev = fcoe_from_ctlr(fip)->real_dev;
165 dev_queue_xmit(skb);
166}
167
168/**
169 * fcoe_update_src_mac() - Update Ethernet MAC filters.
170 * @fip: FCoE controller.
171 * @old: Unicast MAC address to delete if the MAC is non-zero.
172 * @new: Unicast MAC address to add.
173 *
174 * Remove any previously-set unicast MAC filter.
175 * Add secondary FCoE MAC address filter for our OUI.
176 */
177static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
178{
179 struct fcoe_softc *fc;
180
181 fc = fcoe_from_ctlr(fip);
182 rtnl_lock();
183 if (!is_zero_ether_addr(old))
184 dev_unicast_delete(fc->real_dev, old);
185 dev_unicast_add(fc->real_dev, new);
186 rtnl_unlock();
187}
188
189/**
138 * fcoe_lport_config() - sets up the fc_lport 190 * fcoe_lport_config() - sets up the fc_lport
139 * @lp: ptr to the fc_lport 191 * @lp: ptr to the fc_lport
140 * 192 *
@@ -167,6 +219,30 @@ static int fcoe_lport_config(struct fc_lport *lp)
167} 219}
168 220
169/** 221/**
222 * fcoe_netdev_cleanup() - clean up netdev configurations
223 * @fc: ptr to the fcoe_softc
224 */
225void fcoe_netdev_cleanup(struct fcoe_softc *fc)
226{
227 u8 flogi_maddr[ETH_ALEN];
228
229 /* Don't listen for Ethernet packets anymore */
230 dev_remove_pack(&fc->fcoe_packet_type);
231 dev_remove_pack(&fc->fip_packet_type);
232
233 /* Delete secondary MAC addresses */
234 rtnl_lock();
235 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
236 dev_unicast_delete(fc->real_dev, flogi_maddr);
237 if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
238 dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr);
239 if (fc->ctlr.spma)
240 dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr);
241 dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
242 rtnl_unlock();
243}
244
245/**
170 * fcoe_queue_timer() - fcoe queue timer 246 * fcoe_queue_timer() - fcoe queue timer
171 * @lp: the fc_lport pointer 247 * @lp: the fc_lport pointer
172 * 248 *
@@ -193,6 +269,7 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
193 u64 wwnn, wwpn; 269 u64 wwnn, wwpn;
194 struct fcoe_softc *fc; 270 struct fcoe_softc *fc;
195 u8 flogi_maddr[ETH_ALEN]; 271 u8 flogi_maddr[ETH_ALEN];
272 struct netdev_hw_addr *ha;
196 273
197 /* Setup lport private data to point to fcoe softc */ 274 /* Setup lport private data to point to fcoe softc */
198 fc = lport_priv(lp); 275 fc = lport_priv(lp);
@@ -250,9 +327,23 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
250 fc->fcoe_pending_queue_active = 0; 327 fc->fcoe_pending_queue_active = 0;
251 setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp); 328 setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp);
252 329
330 /* look for SAN MAC address, if multiple SAN MACs exist, only
331 * use the first one for SPMA */
332 rcu_read_lock();
333 for_each_dev_addr(netdev, ha) {
334 if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
335 (is_valid_ether_addr(fc->ctlr.ctl_src_addr))) {
336 memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN);
337 fc->ctlr.spma = 1;
338 break;
339 }
340 }
341 rcu_read_unlock();
342
253 /* setup Source Mac Address */ 343 /* setup Source Mac Address */
254 memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr, 344 if (!fc->ctlr.spma)
255 fc->real_dev->addr_len); 345 memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
346 fc->real_dev->addr_len);
256 347
257 wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0); 348 wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
258 fc_set_wwnn(lp, wwnn); 349 fc_set_wwnn(lp, wwnn);
@@ -267,7 +358,9 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
267 */ 358 */
268 rtnl_lock(); 359 rtnl_lock();
269 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); 360 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
270 dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN); 361 dev_unicast_add(fc->real_dev, flogi_maddr);
362 if (fc->ctlr.spma)
363 dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr);
271 dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); 364 dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
272 rtnl_unlock(); 365 rtnl_unlock();
273 366
@@ -280,6 +373,11 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
280 fc->fcoe_packet_type.dev = fc->real_dev; 373 fc->fcoe_packet_type.dev = fc->real_dev;
281 dev_add_pack(&fc->fcoe_packet_type); 374 dev_add_pack(&fc->fcoe_packet_type);
282 375
376 fc->fip_packet_type.func = fcoe_fip_recv;
377 fc->fip_packet_type.type = htons(ETH_P_FIP);
378 fc->fip_packet_type.dev = fc->real_dev;
379 dev_add_pack(&fc->fip_packet_type);
380
283 return 0; 381 return 0;
284} 382}
285 383
@@ -347,7 +445,6 @@ static int fcoe_if_destroy(struct net_device *netdev)
347{ 445{
348 struct fc_lport *lp = NULL; 446 struct fc_lport *lp = NULL;
349 struct fcoe_softc *fc; 447 struct fcoe_softc *fc;
350 u8 flogi_maddr[ETH_ALEN];
351 448
352 BUG_ON(!netdev); 449 BUG_ON(!netdev);
353 450
@@ -366,9 +463,10 @@ static int fcoe_if_destroy(struct net_device *netdev)
366 /* Remove the instance from fcoe's list */ 463 /* Remove the instance from fcoe's list */
367 fcoe_hostlist_remove(lp); 464 fcoe_hostlist_remove(lp);
368 465
369 /* Don't listen for Ethernet packets anymore */ 466 /* clean up netdev configurations */
370 dev_remove_pack(&fc->fcoe_packet_type); 467 fcoe_netdev_cleanup(fc);
371 dev_remove_pack(&fc->fip_packet_type); 468
469 /* tear-down the FCoE controller */
372 fcoe_ctlr_destroy(&fc->ctlr); 470 fcoe_ctlr_destroy(&fc->ctlr);
373 471
374 /* Cleanup the fc_lport */ 472 /* Cleanup the fc_lport */
@@ -383,16 +481,6 @@ static int fcoe_if_destroy(struct net_device *netdev)
383 if (lp->emp) 481 if (lp->emp)
384 fc_exch_mgr_free(lp->emp); 482 fc_exch_mgr_free(lp->emp);
385 483
386 /* Delete secondary MAC addresses */
387 rtnl_lock();
388 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
389 dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
390 if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
391 dev_unicast_delete(fc->real_dev,
392 fc->ctlr.data_src_addr, ETH_ALEN);
393 dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
394 rtnl_unlock();
395
396 /* Free the per-CPU receive threads */ 484 /* Free the per-CPU receive threads */
397 fcoe_percpu_clean(lp); 485 fcoe_percpu_clean(lp);
398 486
@@ -455,58 +543,6 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
455}; 543};
456 544
457/** 545/**
458 * fcoe_fip_recv - handle a received FIP frame.
459 * @skb: the receive skb
460 * @dev: associated &net_device
461 * @ptype: the &packet_type structure which was used to register this handler.
462 * @orig_dev: original receive &net_device, in case @dev is a bond.
463 *
464 * Returns: 0 for success
465 */
466static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
467 struct packet_type *ptype,
468 struct net_device *orig_dev)
469{
470 struct fcoe_softc *fc;
471
472 fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
473 fcoe_ctlr_recv(&fc->ctlr, skb);
474 return 0;
475}
476
477/**
478 * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
479 * @fip: FCoE controller.
480 * @skb: FIP Packet.
481 */
482static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
483{
484 skb->dev = fcoe_from_ctlr(fip)->real_dev;
485 dev_queue_xmit(skb);
486}
487
488/**
489 * fcoe_update_src_mac() - Update Ethernet MAC filters.
490 * @fip: FCoE controller.
491 * @old: Unicast MAC address to delete if the MAC is non-zero.
492 * @new: Unicast MAC address to add.
493 *
494 * Remove any previously-set unicast MAC filter.
495 * Add secondary FCoE MAC address filter for our OUI.
496 */
497static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
498{
499 struct fcoe_softc *fc;
500
501 fc = fcoe_from_ctlr(fip);
502 rtnl_lock();
503 if (!is_zero_ether_addr(old))
504 dev_unicast_delete(fc->real_dev, old, ETH_ALEN);
505 dev_unicast_add(fc->real_dev, new, ETH_ALEN);
506 rtnl_unlock();
507}
508
509/**
510 * fcoe_if_create() - this function creates the fcoe interface 546 * fcoe_if_create() - this function creates the fcoe interface
511 * @netdev: pointer the associated netdevice 547 * @netdev: pointer the associated netdevice
512 * 548 *
@@ -547,13 +583,6 @@ static int fcoe_if_create(struct net_device *netdev)
547 goto out_host_put; 583 goto out_host_put;
548 } 584 }
549 585
550 /* configure lport network properties */
551 rc = fcoe_netdev_config(lp, netdev);
552 if (rc) {
553 FC_DBG("Could not configure netdev for lport\n");
554 goto out_host_put;
555 }
556
557 /* 586 /*
558 * Initialize FIP. 587 * Initialize FIP.
559 */ 588 */
@@ -561,23 +590,25 @@ static int fcoe_if_create(struct net_device *netdev)
561 fc->ctlr.send = fcoe_fip_send; 590 fc->ctlr.send = fcoe_fip_send;
562 fc->ctlr.update_mac = fcoe_update_src_mac; 591 fc->ctlr.update_mac = fcoe_update_src_mac;
563 592
564 fc->fip_packet_type.func = fcoe_fip_recv; 593 /* configure lport network properties */
565 fc->fip_packet_type.type = htons(ETH_P_FIP); 594 rc = fcoe_netdev_config(lp, netdev);
566 fc->fip_packet_type.dev = fc->real_dev; 595 if (rc) {
567 dev_add_pack(&fc->fip_packet_type); 596 FC_DBG("Could not configure netdev for the interface\n");
597 goto out_netdev_cleanup;
598 }
568 599
569 /* configure lport scsi host properties */ 600 /* configure lport scsi host properties */
570 rc = fcoe_shost_config(lp, shost, &netdev->dev); 601 rc = fcoe_shost_config(lp, shost, &netdev->dev);
571 if (rc) { 602 if (rc) {
572 FC_DBG("Could not configure shost for lport\n"); 603 FC_DBG("Could not configure shost for lport\n");
573 goto out_host_put; 604 goto out_netdev_cleanup;
574 } 605 }
575 606
576 /* lport exch manager allocation */ 607 /* lport exch manager allocation */
577 rc = fcoe_em_config(lp); 608 rc = fcoe_em_config(lp);
578 if (rc) { 609 if (rc) {
579 FC_DBG("Could not configure em for lport\n"); 610 FC_DBG("Could not configure em for lport\n");
580 goto out_host_put; 611 goto out_netdev_cleanup;
581 } 612 }
582 613
583 /* Initialize the library */ 614 /* Initialize the library */
@@ -603,6 +634,8 @@ static int fcoe_if_create(struct net_device *netdev)
603 634
604out_lp_destroy: 635out_lp_destroy:
605 fc_exch_mgr_free(lp->emp); /* Free the EM */ 636 fc_exch_mgr_free(lp->emp); /* Free the EM */
637out_netdev_cleanup:
638 fcoe_netdev_cleanup(fc);
606out_host_put: 639out_host_put:
607 scsi_host_put(lp->host); 640 scsi_host_put(lp->host);
608 return rc; 641 return rc;