diff options
author | Yi Zou <yi.zou@intel.com> | 2010-07-20 18:21:17 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:06:02 -0400 |
commit | 54a5b21da9d4d3f58770da5d1c244db9724659ee (patch) | |
tree | 23167b4c07a6b3b1018976d45e808a624e0bce16 /drivers | |
parent | 922611569572d3c1aa0ed6491d21583fb3fcca22 (diff) |
[SCSI] fcoe: fix offload feature flag change from netdev
Currently, when FCoE netdev feature flags are toggled by the LLD, lport's
corresponding flags are not updated. This causes the fc_fcp to still try to
offload the I/O. This patch adds support of NETDEV_FEAT_CHANGE event in fcoe
netdev device notification callback so we can update the lport offload flags
appropriately.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index ab6ea60f2aee..cf9d718c731c 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -589,6 +589,50 @@ static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) | |||
589 | } | 589 | } |
590 | 590 | ||
591 | /** | 591 | /** |
592 | * fcoe_netdev_features_change - Updates the lport's offload flags based | ||
593 | * on the LLD netdev's FCoE feature flags | ||
594 | */ | ||
595 | static void fcoe_netdev_features_change(struct fc_lport *lport, | ||
596 | struct net_device *netdev) | ||
597 | { | ||
598 | mutex_lock(&lport->lp_mutex); | ||
599 | |||
600 | if (netdev->features & NETIF_F_SG) | ||
601 | lport->sg_supp = 1; | ||
602 | else | ||
603 | lport->sg_supp = 0; | ||
604 | |||
605 | if (netdev->features & NETIF_F_FCOE_CRC) { | ||
606 | lport->crc_offload = 1; | ||
607 | FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n"); | ||
608 | } else { | ||
609 | lport->crc_offload = 0; | ||
610 | } | ||
611 | |||
612 | if (netdev->features & NETIF_F_FSO) { | ||
613 | lport->seq_offload = 1; | ||
614 | lport->lso_max = netdev->gso_max_size; | ||
615 | FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n", | ||
616 | lport->lso_max); | ||
617 | } else { | ||
618 | lport->seq_offload = 0; | ||
619 | lport->lso_max = 0; | ||
620 | } | ||
621 | |||
622 | if (netdev->fcoe_ddp_xid) { | ||
623 | lport->lro_enabled = 1; | ||
624 | lport->lro_xid = netdev->fcoe_ddp_xid; | ||
625 | FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", | ||
626 | lport->lro_xid); | ||
627 | } else { | ||
628 | lport->lro_enabled = 0; | ||
629 | lport->lro_xid = 0; | ||
630 | } | ||
631 | |||
632 | mutex_unlock(&lport->lp_mutex); | ||
633 | } | ||
634 | |||
635 | /** | ||
592 | * fcoe_netdev_config() - Set up net devive for SW FCoE | 636 | * fcoe_netdev_config() - Set up net devive for SW FCoE |
593 | * @lport: The local port that is associated with the net device | 637 | * @lport: The local port that is associated with the net device |
594 | * @netdev: The associated net device | 638 | * @netdev: The associated net device |
@@ -624,25 +668,8 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) | |||
624 | return -EINVAL; | 668 | return -EINVAL; |
625 | 669 | ||
626 | /* offload features support */ | 670 | /* offload features support */ |
627 | if (netdev->features & NETIF_F_SG) | 671 | fcoe_netdev_features_change(lport, netdev); |
628 | lport->sg_supp = 1; | ||
629 | 672 | ||
630 | if (netdev->features & NETIF_F_FCOE_CRC) { | ||
631 | lport->crc_offload = 1; | ||
632 | FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n"); | ||
633 | } | ||
634 | if (netdev->features & NETIF_F_FSO) { | ||
635 | lport->seq_offload = 1; | ||
636 | lport->lso_max = netdev->gso_max_size; | ||
637 | FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n", | ||
638 | lport->lso_max); | ||
639 | } | ||
640 | if (netdev->fcoe_ddp_xid) { | ||
641 | lport->lro_enabled = 1; | ||
642 | lport->lro_xid = netdev->fcoe_ddp_xid; | ||
643 | FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", | ||
644 | lport->lro_xid); | ||
645 | } | ||
646 | skb_queue_head_init(&port->fcoe_pending_queue); | 673 | skb_queue_head_init(&port->fcoe_pending_queue); |
647 | port->fcoe_pending_queue_active = 0; | 674 | port->fcoe_pending_queue_active = 0; |
648 | setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); | 675 | setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); |
@@ -1861,6 +1888,9 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1861 | schedule_work(&port->destroy_work); | 1888 | schedule_work(&port->destroy_work); |
1862 | goto out; | 1889 | goto out; |
1863 | break; | 1890 | break; |
1891 | case NETDEV_FEAT_CHANGE: | ||
1892 | fcoe_netdev_features_change(lport, netdev); | ||
1893 | break; | ||
1864 | default: | 1894 | default: |
1865 | FCOE_NETDEV_DBG(netdev, "Unknown event %ld " | 1895 | FCOE_NETDEV_DBG(netdev, "Unknown event %ld " |
1866 | "from netdev netlink\n", event); | 1896 | "from netdev netlink\n", event); |
@@ -2056,8 +2086,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
2056 | rc = -ENODEV; | 2086 | rc = -ENODEV; |
2057 | goto out_putdev; | 2087 | goto out_putdev; |
2058 | } | 2088 | } |
2059 | list_del(&fcoe->list); | ||
2060 | fcoe_interface_cleanup(fcoe); | 2089 | fcoe_interface_cleanup(fcoe); |
2090 | list_del(&fcoe->list); | ||
2061 | /* RTNL mutex is dropped by fcoe_if_destroy */ | 2091 | /* RTNL mutex is dropped by fcoe_if_destroy */ |
2062 | fcoe_if_destroy(fcoe->ctlr.lp); | 2092 | fcoe_if_destroy(fcoe->ctlr.lp); |
2063 | 2093 | ||