aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/fcoe/fcoe.c173
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 */
147static 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 */
163static 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 */
178static 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 */
226void 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 */
450static 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 */
466static 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 */
481static 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
588out_lp_destroy: 601out_lp_destroy:
589 fc_exch_mgr_free(lp->emp); /* Free the EM */ 602 fc_exch_mgr_free(lp->emp); /* Free the EM */
603out_netdev_cleanup:
604 fcoe_netdev_cleanup(fc);
590out_host_put: 605out_host_put:
591 scsi_host_put(lp->host); 606 scsi_host_put(lp->host);
592 return rc; 607 return rc;