]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
[SCSI] fcoe: fix offload feature flag change from netdev
authorYi Zou <yi.zou@intel.com>
Tue, 20 Jul 2010 22:21:17 +0000 (15:21 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Wed, 28 Jul 2010 14:06:02 +0000 (09:06 -0500)
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>
drivers/scsi/fcoe/fcoe.c

index ab6ea60f2aee84cfe65ca73f12774fdfb0bb0915..cf9d718c731c374a031916089ca46c5e4bd36f02 100644 (file)
@@ -588,6 +588,50 @@ static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
        return -EINVAL;
 }
 
+/**
+ * fcoe_netdev_features_change - Updates the lport's offload flags based
+ * on the LLD netdev's FCoE feature flags
+ */
+static void fcoe_netdev_features_change(struct fc_lport *lport,
+                                       struct net_device *netdev)
+{
+       mutex_lock(&lport->lp_mutex);
+
+       if (netdev->features & NETIF_F_SG)
+               lport->sg_supp = 1;
+       else
+               lport->sg_supp = 0;
+
+       if (netdev->features & NETIF_F_FCOE_CRC) {
+               lport->crc_offload = 1;
+               FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
+       } else {
+               lport->crc_offload = 0;
+       }
+
+       if (netdev->features & NETIF_F_FSO) {
+               lport->seq_offload = 1;
+               lport->lso_max = netdev->gso_max_size;
+               FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
+                               lport->lso_max);
+       } else {
+               lport->seq_offload = 0;
+               lport->lso_max = 0;
+       }
+
+       if (netdev->fcoe_ddp_xid) {
+               lport->lro_enabled = 1;
+               lport->lro_xid = netdev->fcoe_ddp_xid;
+               FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
+                               lport->lro_xid);
+       } else {
+               lport->lro_enabled = 0;
+               lport->lro_xid = 0;
+       }
+
+       mutex_unlock(&lport->lp_mutex);
+}
+
 /**
  * fcoe_netdev_config() - Set up net devive for SW FCoE
  * @lport:  The local port that is associated with the net device
@@ -624,25 +668,8 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev)
                return -EINVAL;
 
        /* offload features support */
-       if (netdev->features & NETIF_F_SG)
-               lport->sg_supp = 1;
+       fcoe_netdev_features_change(lport, netdev);
 
-       if (netdev->features & NETIF_F_FCOE_CRC) {
-               lport->crc_offload = 1;
-               FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
-       }
-       if (netdev->features & NETIF_F_FSO) {
-               lport->seq_offload = 1;
-               lport->lso_max = netdev->gso_max_size;
-               FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
-                               lport->lso_max);
-       }
-       if (netdev->fcoe_ddp_xid) {
-               lport->lro_enabled = 1;
-               lport->lro_xid = netdev->fcoe_ddp_xid;
-               FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
-                               lport->lro_xid);
-       }
        skb_queue_head_init(&port->fcoe_pending_queue);
        port->fcoe_pending_queue_active = 0;
        setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport);
@@ -1861,6 +1888,9 @@ static int fcoe_device_notification(struct notifier_block *notifier,
                schedule_work(&port->destroy_work);
                goto out;
                break;
+       case NETDEV_FEAT_CHANGE:
+               fcoe_netdev_features_change(lport, netdev);
+               break;
        default:
                FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
                                "from netdev netlink\n", event);
@@ -2056,8 +2086,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
                rc = -ENODEV;
                goto out_putdev;
        }
-       list_del(&fcoe->list);
        fcoe_interface_cleanup(fcoe);
+       list_del(&fcoe->list);
        /* RTNL mutex is dropped by fcoe_if_destroy */
        fcoe_if_destroy(fcoe->ctlr.lp);