aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fnic/fnic_main.c
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-11-03 14:49:22 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:19 -0500
commit78112e5558064cb4d2e355aed87b2036fcdfe3dd (patch)
treedf34a54d3dcfb503621e3cdd64b22dc173a6722e /drivers/scsi/fnic/fnic_main.c
parent386309ce927a308d7742a6fb24a536d3383fbd49 (diff)
[SCSI] fnic: Add FIP support to the fnic driver
Use libfcoe as a common FIP implementation with fcoe. FIP or non-FIP mode is fully automatic if the firmware supports and enables it. Even if FIP is not supported, this uses libfcoe for the non-FIP handling of FLOGI and its response. Use the new lport_set_port_id() notification to capture successful FLOGI responses and port_id resets. While transitioning between Ethernet and FC mode, all rx and tx FC frames are queued. In Ethernet mode, all frames are passed to the exchange manager to capture FLOGI responses. Change to set data_src_addr to the ctl_src_addr whenever it would have previously been zero because we're not logged in. This seems safer so we'll never send a frame with a 0 source MAC. This also eliminates a special case for sending FLOGI frames. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fnic/fnic_main.c')
-rw-r--r--drivers/scsi/fnic/fnic_main.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 018cc427504a..0333c7f52e66 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -25,6 +25,8 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/workqueue.h> 27#include <linux/workqueue.h>
28#include <linux/if_ether.h>
29#include <scsi/fc/fc_fip.h>
28#include <scsi/scsi_host.h> 30#include <scsi/scsi_host.h>
29#include <scsi/scsi_transport.h> 31#include <scsi/scsi_transport.h>
30#include <scsi/scsi_transport_fc.h> 32#include <scsi/scsi_transport_fc.h>
@@ -68,6 +70,7 @@ MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels");
68 70
69static struct libfc_function_template fnic_transport_template = { 71static struct libfc_function_template fnic_transport_template = {
70 .frame_send = fnic_send, 72 .frame_send = fnic_send,
73 .lport_set_port_id = fnic_set_port_id,
71 .fcp_abort_io = fnic_empty_scsi_cleanup, 74 .fcp_abort_io = fnic_empty_scsi_cleanup,
72 .fcp_cleanup = fnic_empty_scsi_cleanup, 75 .fcp_cleanup = fnic_empty_scsi_cleanup,
73 .exch_mgr_reset = fnic_exch_mgr_reset 76 .exch_mgr_reset = fnic_exch_mgr_reset
@@ -324,9 +327,6 @@ static int fnic_cleanup(struct fnic *fnic)
324{ 327{
325 unsigned int i; 328 unsigned int i;
326 int err; 329 int err;
327 unsigned long flags;
328 struct fc_frame *flogi = NULL;
329 struct fc_frame *flogi_resp = NULL;
330 330
331 vnic_dev_disable(fnic->vdev); 331 vnic_dev_disable(fnic->vdev);
332 for (i = 0; i < fnic->intr_count; i++) 332 for (i = 0; i < fnic->intr_count; i++)
@@ -367,24 +367,6 @@ static int fnic_cleanup(struct fnic *fnic)
367 for (i = 0; i < fnic->intr_count; i++) 367 for (i = 0; i < fnic->intr_count; i++)
368 vnic_intr_clean(&fnic->intr[i]); 368 vnic_intr_clean(&fnic->intr[i]);
369 369
370 /*
371 * Remove cached flogi and flogi resp frames if any
372 * These frames are not in any queue, and therefore queue
373 * cleanup does not clean them. So clean them explicitly
374 */
375 spin_lock_irqsave(&fnic->fnic_lock, flags);
376 flogi = fnic->flogi;
377 fnic->flogi = NULL;
378 flogi_resp = fnic->flogi_resp;
379 fnic->flogi_resp = NULL;
380 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
381
382 if (flogi)
383 dev_kfree_skb(fp_skb(flogi));
384
385 if (flogi_resp)
386 dev_kfree_skb(fp_skb(flogi_resp));
387
388 mempool_destroy(fnic->io_req_pool); 370 mempool_destroy(fnic->io_req_pool);
389 for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) 371 for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
390 mempool_destroy(fnic->io_sgl_pool[i]); 372 mempool_destroy(fnic->io_sgl_pool[i]);
@@ -409,6 +391,17 @@ static void *fnic_alloc_slab_dma(gfp_t gfp_mask, void *pool_data)
409 return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA); 391 return kmem_cache_alloc(mem, gfp_mask | GFP_ATOMIC | GFP_DMA);
410} 392}
411 393
394/**
395 * fnic_get_mac() - get assigned data MAC address for FIP code.
396 * @lport: local port.
397 */
398static u8 *fnic_get_mac(struct fc_lport *lport)
399{
400 struct fnic *fnic = lport_priv(lport);
401
402 return fnic->data_src_addr;
403}
404
412static int __devinit fnic_probe(struct pci_dev *pdev, 405static int __devinit fnic_probe(struct pci_dev *pdev,
413 const struct pci_device_id *ent) 406 const struct pci_device_id *ent)
414{ 407{
@@ -433,6 +426,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
433 host = lp->host; 426 host = lp->host;
434 fnic = lport_priv(lp); 427 fnic = lport_priv(lp);
435 fnic->lport = lp; 428 fnic->lport = lp;
429 fnic->ctlr.lp = lp;
436 430
437 snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME, 431 snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
438 host->host_no); 432 host->host_no);
@@ -541,12 +535,14 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
541 goto err_out_dev_close; 535 goto err_out_dev_close;
542 } 536 }
543 537
544 err = vnic_dev_mac_addr(fnic->vdev, fnic->mac_addr); 538 err = vnic_dev_mac_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
545 if (err) { 539 if (err) {
546 shost_printk(KERN_ERR, fnic->lport->host, 540 shost_printk(KERN_ERR, fnic->lport->host,
547 "vNIC get MAC addr failed \n"); 541 "vNIC get MAC addr failed \n");
548 goto err_out_dev_close; 542 goto err_out_dev_close;
549 } 543 }
544 /* set data_src for point-to-point mode and to keep it non-zero */
545 memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
550 546
551 /* Get vNIC configuration */ 547 /* Get vNIC configuration */
552 err = fnic_get_vnic_config(fnic); 548 err = fnic_get_vnic_config(fnic);
@@ -615,9 +611,21 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
615 fnic->vlan_hw_insert = 1; 611 fnic->vlan_hw_insert = 1;
616 fnic->vlan_id = 0; 612 fnic->vlan_id = 0;
617 613
618 fnic->flogi_oxid = FC_XID_UNKNOWN; 614 /* Initialize the FIP fcoe_ctrl struct */
619 fnic->flogi = NULL; 615 fnic->ctlr.send = fnic_eth_send;
620 fnic->flogi_resp = NULL; 616 fnic->ctlr.update_mac = fnic_update_mac;
617 fnic->ctlr.get_src_addr = fnic_get_mac;
618 fcoe_ctlr_init(&fnic->ctlr);
619 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
620 shost_printk(KERN_INFO, fnic->lport->host,
621 "firmware supports FIP\n");
622 vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
623 vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
624 } else {
625 shost_printk(KERN_INFO, fnic->lport->host,
626 "firmware uses non-FIP mode\n");
627 fnic->ctlr.mode = FIP_ST_NON_FIP;
628 }
621 fnic->state = FNIC_IN_FC_MODE; 629 fnic->state = FNIC_IN_FC_MODE;
622 630
623 /* Enable hardware stripping of vlan header on ingress */ 631 /* Enable hardware stripping of vlan header on ingress */
@@ -708,6 +716,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
708 INIT_WORK(&fnic->link_work, fnic_handle_link); 716 INIT_WORK(&fnic->link_work, fnic_handle_link);
709 INIT_WORK(&fnic->frame_work, fnic_handle_frame); 717 INIT_WORK(&fnic->frame_work, fnic_handle_frame);
710 skb_queue_head_init(&fnic->frame_queue); 718 skb_queue_head_init(&fnic->frame_queue);
719 skb_queue_head_init(&fnic->tx_queue);
711 720
712 /* Enable all queues */ 721 /* Enable all queues */
713 for (i = 0; i < fnic->raw_wq_count; i++) 722 for (i = 0; i < fnic->raw_wq_count; i++)
@@ -738,8 +747,8 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
738err_out_free_exch_mgr: 747err_out_free_exch_mgr:
739 fc_exch_mgr_free(lp); 748 fc_exch_mgr_free(lp);
740err_out_remove_scsi_host: 749err_out_remove_scsi_host:
741 fc_remove_host(fnic->lport->host); 750 fc_remove_host(lp->host);
742 scsi_remove_host(fnic->lport->host); 751 scsi_remove_host(lp->host);
743err_out_free_rq_buf: 752err_out_free_rq_buf:
744 for (i = 0; i < fnic->rq_count; i++) 753 for (i = 0; i < fnic->rq_count; i++)
745 vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); 754 vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
@@ -773,6 +782,7 @@ err_out:
773static void __devexit fnic_remove(struct pci_dev *pdev) 782static void __devexit fnic_remove(struct pci_dev *pdev)
774{ 783{
775 struct fnic *fnic = pci_get_drvdata(pdev); 784 struct fnic *fnic = pci_get_drvdata(pdev);
785 struct fc_lport *lp = fnic->lport;
776 unsigned long flags; 786 unsigned long flags;
777 787
778 /* 788 /*
@@ -794,6 +804,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
794 */ 804 */
795 flush_workqueue(fnic_event_queue); 805 flush_workqueue(fnic_event_queue);
796 skb_queue_purge(&fnic->frame_queue); 806 skb_queue_purge(&fnic->frame_queue);
807 skb_queue_purge(&fnic->tx_queue);
797 808
798 /* 809 /*
799 * Log off the fabric. This stops all remote ports, dns port, 810 * Log off the fabric. This stops all remote ports, dns port,
@@ -806,7 +817,8 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
806 fnic->in_remove = 1; 817 fnic->in_remove = 1;
807 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 818 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
808 819
809 fc_lport_destroy(fnic->lport); 820 fcoe_ctlr_destroy(&fnic->ctlr);
821 fc_lport_destroy(lp);
810 822
811 /* 823 /*
812 * This stops the fnic device, masks all interrupts. Completed 824 * This stops the fnic device, masks all interrupts. Completed
@@ -816,6 +828,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
816 fnic_cleanup(fnic); 828 fnic_cleanup(fnic);
817 829
818 BUG_ON(!skb_queue_empty(&fnic->frame_queue)); 830 BUG_ON(!skb_queue_empty(&fnic->frame_queue));
831 BUG_ON(!skb_queue_empty(&fnic->tx_queue));
819 832
820 spin_lock_irqsave(&fnic_list_lock, flags); 833 spin_lock_irqsave(&fnic_list_lock, flags);
821 list_del(&fnic->list); 834 list_del(&fnic->list);
@@ -834,7 +847,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
834 pci_release_regions(pdev); 847 pci_release_regions(pdev);
835 pci_disable_device(pdev); 848 pci_disable_device(pdev);
836 pci_set_drvdata(pdev, NULL); 849 pci_set_drvdata(pdev, NULL);
837 scsi_host_put(fnic->lport->host); 850 scsi_host_put(lp->host);
838} 851}
839 852
840static struct pci_driver fnic_driver = { 853static struct pci_driver fnic_driver = {