[SCSI] fcoe: Use per-CPU kernel function for dev_stats instead of an array
[pandora-kernel.git] / drivers / scsi / fcoe / fcoe_sw.c
index da210eb..a675390 100644 (file)
@@ -113,8 +113,6 @@ static struct scsi_host_template fcoe_sw_shost_template = {
  */
 static int fcoe_sw_lport_config(struct fc_lport *lp)
 {
-       int i = 0;
-
        lp->link_up = 0;
        lp->qfull = 0;
        lp->max_retry_count = 3;
@@ -123,16 +121,18 @@ static int fcoe_sw_lport_config(struct fc_lport *lp)
        lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
                              FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
 
-       /*
-        * allocate per cpu stats block
-        */
-       for_each_online_cpu(i)
-               lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
-                                          GFP_KERNEL);
+       fc_lport_init_stats(lp);
 
        /* lport fc_lport related configuration */
        fc_lport_config(lp);
 
+       /* offload related configuration */
+       lp->crc_offload = 0;
+       lp->seq_offload = 0;
+       lp->lro_enabled = 0;
+       lp->lro_xid = 0;
+       lp->lso_max = 0;
+
        return 0;
 }
 
@@ -186,7 +186,27 @@ static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
        if (fc->real_dev->features & NETIF_F_SG)
                lp->sg_supp = 1;
 
-
+#ifdef NETIF_F_FCOE_CRC
+       if (netdev->features & NETIF_F_FCOE_CRC) {
+               lp->crc_offload = 1;
+               printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
+                      netdev->name);
+       }
+#endif
+#ifdef NETIF_F_FSO
+       if (netdev->features & NETIF_F_FSO) {
+               lp->seq_offload = 1;
+               lp->lso_max = netdev->gso_max_size;
+               printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
+                      netdev->name, lp->lso_max);
+       }
+#endif
+       if (netdev->fcoe_ddp_xid) {
+               lp->lro_enabled = 1;
+               lp->lro_xid = netdev->fcoe_ddp_xid;
+               printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
+                      netdev->name, lp->lro_xid);
+       }
        skb_queue_head_init(&fc->fcoe_pending_queue);
        fc->fcoe_pending_queue_active = 0;
 
@@ -284,7 +304,6 @@ static inline int fcoe_sw_em_config(struct fc_lport *lp)
  */
 static int fcoe_sw_destroy(struct net_device *netdev)
 {
-       int cpu;
        struct fc_lport *lp = NULL;
        struct fcoe_softc *fc;
        u8 flogi_maddr[ETH_ALEN];
@@ -336,8 +355,7 @@ static int fcoe_sw_destroy(struct net_device *netdev)
        fcoe_clean_pending_queue(lp);
 
        /* Free memory used by statistical counters */
-       for_each_online_cpu(cpu)
-               kfree(lp->dev_stats[cpu]);
+       fc_lport_free_stats(lp);
 
        /* Release the net_device and Scsi_Host */
        dev_put(fc->real_dev);
@@ -346,8 +364,46 @@ static int fcoe_sw_destroy(struct net_device *netdev)
        return 0;
 }
 
+/*
+ * fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device
+ * @lp:        the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ * @sgl: the scatterlist describing this transfer
+ * @sgc: number of sg items
+ *
+ * Returns : 0 no ddp
+ */
+static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid,
+                            struct scatterlist *sgl, unsigned int sgc)
+{
+       struct net_device *n = fcoe_netdev(lp);
+
+       if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
+               return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+
+       return 0;
+}
+
+/*
+ * fcoe_sw_ddp_done - calls LLD's ddp_done through net_device
+ * @lp:        the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ *
+ * Returns : the length of data that have been completed by ddp
+ */
+static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid)
+{
+       struct net_device *n = fcoe_netdev(lp);
+
+       if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
+               return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
+       return 0;
+}
+
 static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
        .frame_send = fcoe_xmit,
+       .ddp_setup = fcoe_sw_ddp_setup,
+       .ddp_done = fcoe_sw_ddp_done,
 };
 
 /**