aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2010-07-20 18:21:17 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:06:02 -0400
commit54a5b21da9d4d3f58770da5d1c244db9724659ee (patch)
tree23167b4c07a6b3b1018976d45e808a624e0bce16 /drivers
parent922611569572d3c1aa0ed6491d21583fb3fcca22 (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.c68
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 */
595static 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