diff options
author | Vasu Dev <vasu.dev@intel.com> | 2009-05-17 08:33:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-18 00:04:08 -0400 |
commit | ab6b85c1d7a1bf6c2b27fb542a7b2404e45b7e24 (patch) | |
tree | 4e88c6c0da92d5eee7d5f863b5439bea792e88ef /drivers/scsi | |
parent | aca6bee75fe53ae019b9cabff42095dfb6471fde (diff) |
fcoe: consolidates netdev related config and cleanup for spma mode
Currently fcoe_netdev_config adds netdev pkt handler for fcoe pkts,
fcoe_if_create adds netdev pkt handler for fip packets, a secondary
MAC address is added by fcoe_netdev_config and then later cleanup
for these netdev related config/adds is done only during
fcoe_if_destroy and no cleanup done on error during fcoe interface
creation after above netdev config calling in fcoe_if_create.
So this patch adds single func for above mentioned cleanup the
fcoe_netdev_cleanup and then calls this func on either fcoe interface
destroy or exiting from fcoe_if_create due to an error after fcoe/fip
related above netdev config is done.
Moved netdev pkt handler addition code blocks for fip pkts close to
similar code block for foce pkt in fcoe_netdev_config, so that added
fcoe_netdev_cleanup could be called on error from fcoe_netdev_config
to undo these both additions for fcoe/fip pkt handlers. This move
required reference to fcoe_fip_recv in fcoe_netdev_config, so moved
fip related functions fcoe_fip_recv, fcoe_fip_send and
fcoe_update_src_mac above fcoe_netdev_config.
This consolidation will enable spma mode support in next patch to
easily add or delete spma mode mac address beside fixing current
no cleanup issue during error.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 173 |
1 files changed, 94 insertions, 79 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 94e1e3189773..04f500571d49 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -136,6 +136,58 @@ static struct scsi_host_template fcoe_shost_template = { | |||
136 | }; | 136 | }; |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * fcoe_fip_recv - handle a received FIP frame. | ||
140 | * @skb: the receive skb | ||
141 | * @dev: associated &net_device | ||
142 | * @ptype: the &packet_type structure which was used to register this handler. | ||
143 | * @orig_dev: original receive &net_device, in case @dev is a bond. | ||
144 | * | ||
145 | * Returns: 0 for success | ||
146 | */ | ||
147 | static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, | ||
148 | struct packet_type *ptype, | ||
149 | struct net_device *orig_dev) | ||
150 | { | ||
151 | struct fcoe_softc *fc; | ||
152 | |||
153 | fc = container_of(ptype, struct fcoe_softc, fip_packet_type); | ||
154 | fcoe_ctlr_recv(&fc->ctlr, skb); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame. | ||
160 | * @fip: FCoE controller. | ||
161 | * @skb: FIP Packet. | ||
162 | */ | ||
163 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | ||
164 | { | ||
165 | skb->dev = fcoe_from_ctlr(fip)->real_dev; | ||
166 | dev_queue_xmit(skb); | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * fcoe_update_src_mac() - Update Ethernet MAC filters. | ||
171 | * @fip: FCoE controller. | ||
172 | * @old: Unicast MAC address to delete if the MAC is non-zero. | ||
173 | * @new: Unicast MAC address to add. | ||
174 | * | ||
175 | * Remove any previously-set unicast MAC filter. | ||
176 | * Add secondary FCoE MAC address filter for our OUI. | ||
177 | */ | ||
178 | static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) | ||
179 | { | ||
180 | struct fcoe_softc *fc; | ||
181 | |||
182 | fc = fcoe_from_ctlr(fip); | ||
183 | rtnl_lock(); | ||
184 | if (!is_zero_ether_addr(old)) | ||
185 | dev_unicast_delete(fc->real_dev, old, ETH_ALEN); | ||
186 | dev_unicast_add(fc->real_dev, new, ETH_ALEN); | ||
187 | rtnl_unlock(); | ||
188 | } | ||
189 | |||
190 | /** | ||
139 | * fcoe_lport_config() - sets up the fc_lport | 191 | * fcoe_lport_config() - sets up the fc_lport |
140 | * @lp: ptr to the fc_lport | 192 | * @lp: ptr to the fc_lport |
141 | * @shost: ptr to the parent scsi host | 193 | * @shost: ptr to the parent scsi host |
@@ -168,6 +220,29 @@ static int fcoe_lport_config(struct fc_lport *lp) | |||
168 | } | 220 | } |
169 | 221 | ||
170 | /** | 222 | /** |
223 | * fcoe_netdev_cleanup() - clean up netdev configurations | ||
224 | * @fc: ptr to the fcoe_softc | ||
225 | */ | ||
226 | void fcoe_netdev_cleanup(struct fcoe_softc *fc) | ||
227 | { | ||
228 | u8 flogi_maddr[ETH_ALEN]; | ||
229 | |||
230 | /* Don't listen for Ethernet packets anymore */ | ||
231 | dev_remove_pack(&fc->fcoe_packet_type); | ||
232 | dev_remove_pack(&fc->fip_packet_type); | ||
233 | |||
234 | /* Delete secondary MAC addresses */ | ||
235 | rtnl_lock(); | ||
236 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | ||
237 | dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN); | ||
238 | if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) | ||
239 | dev_unicast_delete(fc->real_dev, | ||
240 | fc->ctlr.data_src_addr, ETH_ALEN); | ||
241 | dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | ||
242 | rtnl_unlock(); | ||
243 | } | ||
244 | |||
245 | /** | ||
171 | * fcoe_netdev_config() - Set up netdev for SW FCoE | 246 | * fcoe_netdev_config() - Set up netdev for SW FCoE |
172 | * @lp : ptr to the fc_lport | 247 | * @lp : ptr to the fc_lport |
173 | * @netdev : ptr to the associated netdevice struct | 248 | * @netdev : ptr to the associated netdevice struct |
@@ -267,6 +342,11 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
267 | fc->fcoe_packet_type.dev = fc->real_dev; | 342 | fc->fcoe_packet_type.dev = fc->real_dev; |
268 | dev_add_pack(&fc->fcoe_packet_type); | 343 | dev_add_pack(&fc->fcoe_packet_type); |
269 | 344 | ||
345 | fc->fip_packet_type.func = fcoe_fip_recv; | ||
346 | fc->fip_packet_type.type = htons(ETH_P_FIP); | ||
347 | fc->fip_packet_type.dev = fc->real_dev; | ||
348 | dev_add_pack(&fc->fip_packet_type); | ||
349 | |||
270 | return 0; | 350 | return 0; |
271 | } | 351 | } |
272 | 352 | ||
@@ -334,7 +414,6 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
334 | { | 414 | { |
335 | struct fc_lport *lp = NULL; | 415 | struct fc_lport *lp = NULL; |
336 | struct fcoe_softc *fc; | 416 | struct fcoe_softc *fc; |
337 | u8 flogi_maddr[ETH_ALEN]; | ||
338 | 417 | ||
339 | BUG_ON(!netdev); | 418 | BUG_ON(!netdev); |
340 | 419 | ||
@@ -353,9 +432,10 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
353 | /* Remove the instance from fcoe's list */ | 432 | /* Remove the instance from fcoe's list */ |
354 | fcoe_hostlist_remove(lp); | 433 | fcoe_hostlist_remove(lp); |
355 | 434 | ||
356 | /* Don't listen for Ethernet packets anymore */ | 435 | /* clean up netdev configurations */ |
357 | dev_remove_pack(&fc->fcoe_packet_type); | 436 | fcoe_netdev_cleanup(fc); |
358 | dev_remove_pack(&fc->fip_packet_type); | 437 | |
438 | /* tear-down the FCoE controller */ | ||
359 | fcoe_ctlr_destroy(&fc->ctlr); | 439 | fcoe_ctlr_destroy(&fc->ctlr); |
360 | 440 | ||
361 | /* Cleanup the fc_lport */ | 441 | /* Cleanup the fc_lport */ |
@@ -370,16 +450,6 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
370 | if (lp->emp) | 450 | if (lp->emp) |
371 | fc_exch_mgr_free(lp->emp); | 451 | fc_exch_mgr_free(lp->emp); |
372 | 452 | ||
373 | /* Delete secondary MAC addresses */ | ||
374 | rtnl_lock(); | ||
375 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | ||
376 | dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN); | ||
377 | if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) | ||
378 | dev_unicast_delete(fc->real_dev, | ||
379 | fc->ctlr.data_src_addr, ETH_ALEN); | ||
380 | dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | ||
381 | rtnl_unlock(); | ||
382 | |||
383 | /* Free the per-CPU revieve threads */ | 453 | /* Free the per-CPU revieve threads */ |
384 | fcoe_percpu_clean(lp); | 454 | fcoe_percpu_clean(lp); |
385 | 455 | ||
@@ -439,58 +509,6 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = { | |||
439 | }; | 509 | }; |
440 | 510 | ||
441 | /** | 511 | /** |
442 | * fcoe_fip_recv - handle a received FIP frame. | ||
443 | * @skb: the receive skb | ||
444 | * @dev: associated &net_device | ||
445 | * @ptype: the &packet_type structure which was used to register this handler. | ||
446 | * @orig_dev: original receive &net_device, in case @dev is a bond. | ||
447 | * | ||
448 | * Returns: 0 for success | ||
449 | */ | ||
450 | static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, | ||
451 | struct packet_type *ptype, | ||
452 | struct net_device *orig_dev) | ||
453 | { | ||
454 | struct fcoe_softc *fc; | ||
455 | |||
456 | fc = container_of(ptype, struct fcoe_softc, fip_packet_type); | ||
457 | fcoe_ctlr_recv(&fc->ctlr, skb); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame. | ||
463 | * @fip: FCoE controller. | ||
464 | * @skb: FIP Packet. | ||
465 | */ | ||
466 | static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | ||
467 | { | ||
468 | skb->dev = fcoe_from_ctlr(fip)->real_dev; | ||
469 | dev_queue_xmit(skb); | ||
470 | } | ||
471 | |||
472 | /** | ||
473 | * fcoe_update_src_mac() - Update Ethernet MAC filters. | ||
474 | * @fip: FCoE controller. | ||
475 | * @old: Unicast MAC address to delete if the MAC is non-zero. | ||
476 | * @new: Unicast MAC address to add. | ||
477 | * | ||
478 | * Remove any previously-set unicast MAC filter. | ||
479 | * Add secondary FCoE MAC address filter for our OUI. | ||
480 | */ | ||
481 | static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) | ||
482 | { | ||
483 | struct fcoe_softc *fc; | ||
484 | |||
485 | fc = fcoe_from_ctlr(fip); | ||
486 | rtnl_lock(); | ||
487 | if (!is_zero_ether_addr(old)) | ||
488 | dev_unicast_delete(fc->real_dev, old, ETH_ALEN); | ||
489 | dev_unicast_add(fc->real_dev, new, ETH_ALEN); | ||
490 | rtnl_unlock(); | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | * fcoe_if_create() - this function creates the fcoe interface | 512 | * fcoe_if_create() - this function creates the fcoe interface |
495 | * @netdev: pointer the associated netdevice | 513 | * @netdev: pointer the associated netdevice |
496 | * | 514 | * |
@@ -531,13 +549,6 @@ static int fcoe_if_create(struct net_device *netdev) | |||
531 | goto out_host_put; | 549 | goto out_host_put; |
532 | } | 550 | } |
533 | 551 | ||
534 | /* configure lport network properties */ | ||
535 | rc = fcoe_netdev_config(lp, netdev); | ||
536 | if (rc) { | ||
537 | FC_DBG("Could not configure netdev for lport\n"); | ||
538 | goto out_host_put; | ||
539 | } | ||
540 | |||
541 | /* | 552 | /* |
542 | * Initialize FIP. | 553 | * Initialize FIP. |
543 | */ | 554 | */ |
@@ -545,23 +556,25 @@ static int fcoe_if_create(struct net_device *netdev) | |||
545 | fc->ctlr.send = fcoe_fip_send; | 556 | fc->ctlr.send = fcoe_fip_send; |
546 | fc->ctlr.update_mac = fcoe_update_src_mac; | 557 | fc->ctlr.update_mac = fcoe_update_src_mac; |
547 | 558 | ||
548 | fc->fip_packet_type.func = fcoe_fip_recv; | 559 | /* configure lport network properties */ |
549 | fc->fip_packet_type.type = htons(ETH_P_FIP); | 560 | rc = fcoe_netdev_config(lp, netdev); |
550 | fc->fip_packet_type.dev = fc->real_dev; | 561 | if (rc) { |
551 | dev_add_pack(&fc->fip_packet_type); | 562 | FC_DBG("Could not configure netdev for the interface\n"); |
563 | goto out_netdev_cleanup; | ||
564 | } | ||
552 | 565 | ||
553 | /* configure lport scsi host properties */ | 566 | /* configure lport scsi host properties */ |
554 | rc = fcoe_shost_config(lp, shost, &netdev->dev); | 567 | rc = fcoe_shost_config(lp, shost, &netdev->dev); |
555 | if (rc) { | 568 | if (rc) { |
556 | FC_DBG("Could not configure shost for lport\n"); | 569 | FC_DBG("Could not configure shost for lport\n"); |
557 | goto out_host_put; | 570 | goto out_netdev_cleanup; |
558 | } | 571 | } |
559 | 572 | ||
560 | /* lport exch manager allocation */ | 573 | /* lport exch manager allocation */ |
561 | rc = fcoe_em_config(lp); | 574 | rc = fcoe_em_config(lp); |
562 | if (rc) { | 575 | if (rc) { |
563 | FC_DBG("Could not configure em for lport\n"); | 576 | FC_DBG("Could not configure em for lport\n"); |
564 | goto out_host_put; | 577 | goto out_netdev_cleanup; |
565 | } | 578 | } |
566 | 579 | ||
567 | /* Initialize the library */ | 580 | /* Initialize the library */ |
@@ -587,6 +600,8 @@ static int fcoe_if_create(struct net_device *netdev) | |||
587 | 600 | ||
588 | out_lp_destroy: | 601 | out_lp_destroy: |
589 | fc_exch_mgr_free(lp->emp); /* Free the EM */ | 602 | fc_exch_mgr_free(lp->emp); /* Free the EM */ |
603 | out_netdev_cleanup: | ||
604 | fcoe_netdev_cleanup(fc); | ||
590 | out_host_put: | 605 | out_host_put: |
591 | scsi_host_put(lp->host); | 606 | scsi_host_put(lp->host); |
592 | return rc; | 607 | return rc; |