]> err.no Git - linux-2.6/commitdiff
[PATCH] sk98lin: allow ethtool checksum on/off per port
authorshemminger@osdl.org <shemminger@osdl.org>
Thu, 24 Nov 2005 06:00:52 +0000 (22:00 -0800)
committerJeff Garzik <jgarzik@pobox.com>
Thu, 1 Dec 2005 07:22:52 +0000 (02:22 -0500)
Allow control of checksumming parameters via ethtool.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
drivers/net/sk98lin/h/skdrv2nd.h
drivers/net/sk98lin/skethtool.c
drivers/net/sk98lin/skge.c

index 9bdfde80c30bb28678e688546c8938b6a00748c0..0ebafc8857053f70e773dedf13e26f60ed78e5ea 100644 (file)
@@ -297,6 +297,7 @@ struct s_RxPort {
        RXD             *pRxdRingTail;  /* Tail of Rx rings */
        RXD             *pRxdRingPrev;  /* descriptor given to BMU previously */
        int             RxdRingFree;    /* # of free entrys */
+       int             RxCsum;         /* use receive checksum hardware */
        spinlock_t      RxDesRingLock;  /* serialize descriptor accesses */
        int             RxFillLimit;    /* limit for buffers in ring */
        SK_IOC          HwAddr;         /* bmu registers address */
index b71769ae4603ac3a0f89c07aefd626f63795438e..4265ed91a9c4800eee83f7ed2f53ae2a63f1459f 100644 (file)
@@ -539,6 +539,48 @@ static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *ep
         return ret ? -EIO : 0;
 }
 
+/* Only Yukon supports checksum offload. */
+static int setScatterGather(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+       return ethtool_op_set_sg(dev, data);
+}
+
+static int setTxCsum(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+
+       return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 getRxCsum(struct net_device *dev)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       return pAC->RxPort[pNet->PortNr].RxCsum;
+}
+
+static int setRxCsum(struct net_device *dev, u32 data)
+{
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+
+       if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+               return -EOPNOTSUPP;
+
+       pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
+       return 0;
+}
+
 struct ethtool_ops SkGeEthtoolOps = {
        .get_settings           = getSettings,
        .set_settings           = setSettings,
@@ -551,4 +593,10 @@ struct ethtool_ops SkGeEthtoolOps = {
        .set_pauseparam         = setPauseParams,
        .get_link               = ethtool_op_get_link,
        .get_perm_addr          = ethtool_op_get_perm_addr,
+       .get_sg                 = ethtool_op_get_sg,
+       .set_sg                 = setScatterGather,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
+       .set_tx_csum            = setTxCsum,
+       .get_rx_csum            = getRxCsum,
+       .set_rx_csum            = setRxCsum,
 };
index 107c5d97546ccbdb6680c81a95ec39784ba9e69f..02143fa3ee5bbafc2976a806ee4af454385bd762 100644 (file)
@@ -2189,13 +2189,10 @@ rx_start:
                        skb_put(pMsg, FrameLength);
                } /* frame > SK_COPY_TRESHOLD */
 
-#ifdef USE_SK_RX_CHECKSUM
-               pMsg->csum = pRxd->TcpSums;
-               pMsg->ip_summed = CHECKSUM_HW;
-#else
-               pMsg->ip_summed = CHECKSUM_NONE;
-#endif
-
+               if (pRxPort->RxCsum) {
+                       pMsg->csum = pRxd->TcpSums;
+                       pMsg->ip_summed = CHECKSUM_HW;
+               }
 
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
                ForRlmt = SK_RLMT_RX_PROTOCOL;
@@ -4149,6 +4146,7 @@ SK_BOOL           DualNet;
                        Flags);
                break;
        case SK_DRV_NET_UP:      /* SK_U32 PortIdx */
+       {       struct net_device *dev = pAC->dev[Param.Para32[0]];
                /* action list 5 */
                FromPort = Param.Para32[0];
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4232,22 +4230,12 @@ SK_BOOL         DualNet;
                        printk("    irq moderation:  disabled\n");
 
 
-#ifdef SK_ZEROCOPY
-               if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
-                       printk("    scatter-gather:  enabled\n");
-#else
-                       printk("    tx-checksum:     disabled\n");
-#endif
-               else
-                       printk("    scatter-gather:  disabled\n");
-#else
-                       printk("    scatter-gather:  disabled\n");
-#endif
-
-#ifndef USE_SK_RX_CHECKSUM
-                       printk("    rx-checksum:     disabled\n");
-#endif
+               printk("    scatter-gather:  %s\n",
+                      (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
+               printk("    tx-checksum:     %s\n",
+                      (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
+               printk("    rx-checksum:     %s\n",
+                      pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
 
                } else {
                         DoPrintInterfaceChange = SK_TRUE;
@@ -4262,9 +4250,9 @@ SK_BOOL           DualNet;
                }
 
                /* Inform the world that link protocol is up. */
-               netif_carrier_on(pAC->dev[Param.Para32[0]]);
-
+               netif_carrier_on(dev);
                break;
+       }
        case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
                /* action list 7 */
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4871,15 +4859,18 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
        SET_NETDEV_DEV(dev, &pdev->dev);
        SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
+       /* Use only if yukon hardware */
        if (pAC->ChipsetType) {
-               /* Use only if yukon hardware */
-               /* SK and ZEROCOPY - fly baby... */
-               dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-       }
+#ifdef USE_SK_TX_CHECKSUM
+               dev->features |= NETIF_F_IP_CSUM;
 #endif
+#ifdef SK_ZEROCOPY
+               dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+               pAC->RxPort[0].RxCsum = 1;
 #endif
+       }
 
        pAC->Index = boards_found++;
 
@@ -4944,14 +4935,17 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
                SET_NETDEV_DEV(dev, &pdev->dev);
                SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
                if (pAC->ChipsetType) {
-                       /* SG and ZEROCOPY - fly baby... */
-                       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-               }
+#ifdef USE_SK_TX_CHECKSUM
+                       dev->features |= NETIF_F_IP_CSUM;
 #endif
+#ifdef SK_ZEROCOPY
+                       dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+                       pAC->RxPort[1].RxCsum = 1;
 #endif
+               }
 
                if (register_netdev(dev)) {
                        printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");