Commit 09f5a214 authored by shemminger@osdl.org's avatar shemminger@osdl.org Committed by Jeff Garzik

[PATCH] sk98lin: allow ethtool checksum on/off per port

Allow control of checksumming parameters via ethtool.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent e9022ee6
...@@ -297,6 +297,7 @@ struct s_RxPort { ...@@ -297,6 +297,7 @@ struct s_RxPort {
RXD *pRxdRingTail; /* Tail of Rx rings */ RXD *pRxdRingTail; /* Tail of Rx rings */
RXD *pRxdRingPrev; /* descriptor given to BMU previously */ RXD *pRxdRingPrev; /* descriptor given to BMU previously */
int RxdRingFree; /* # of free entrys */ int RxdRingFree; /* # of free entrys */
int RxCsum; /* use receive checksum hardware */
spinlock_t RxDesRingLock; /* serialize descriptor accesses */ spinlock_t RxDesRingLock; /* serialize descriptor accesses */
int RxFillLimit; /* limit for buffers in ring */ int RxFillLimit; /* limit for buffers in ring */
SK_IOC HwAddr; /* bmu registers address */ SK_IOC HwAddr; /* bmu registers address */
......
...@@ -539,6 +539,48 @@ static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *ep ...@@ -539,6 +539,48 @@ static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *ep
return ret ? -EIO : 0; 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 = { struct ethtool_ops SkGeEthtoolOps = {
.get_settings = getSettings, .get_settings = getSettings,
.set_settings = setSettings, .set_settings = setSettings,
...@@ -551,4 +593,10 @@ struct ethtool_ops SkGeEthtoolOps = { ...@@ -551,4 +593,10 @@ struct ethtool_ops SkGeEthtoolOps = {
.set_pauseparam = setPauseParams, .set_pauseparam = setPauseParams,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_perm_addr = ethtool_op_get_perm_addr, .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,
}; };
...@@ -2189,13 +2189,10 @@ SK_U64 PhysAddr; ...@@ -2189,13 +2189,10 @@ SK_U64 PhysAddr;
skb_put(pMsg, FrameLength); skb_put(pMsg, FrameLength);
} /* frame > SK_COPY_TRESHOLD */ } /* frame > SK_COPY_TRESHOLD */
#ifdef USE_SK_RX_CHECKSUM if (pRxPort->RxCsum) {
pMsg->csum = pRxd->TcpSums; pMsg->csum = pRxd->TcpSums;
pMsg->ip_summed = CHECKSUM_HW; pMsg->ip_summed = CHECKSUM_HW;
#else }
pMsg->ip_summed = CHECKSUM_NONE;
#endif
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
ForRlmt = SK_RLMT_RX_PROTOCOL; ForRlmt = SK_RLMT_RX_PROTOCOL;
...@@ -4149,6 +4146,7 @@ SK_BOOL DualNet; ...@@ -4149,6 +4146,7 @@ SK_BOOL DualNet;
Flags); Flags);
break; break;
case SK_DRV_NET_UP: /* SK_U32 PortIdx */ case SK_DRV_NET_UP: /* SK_U32 PortIdx */
{ struct net_device *dev = pAC->dev[Param.Para32[0]];
/* action list 5 */ /* action list 5 */
FromPort = Param.Para32[0]; FromPort = Param.Para32[0];
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
...@@ -4232,22 +4230,12 @@ SK_BOOL DualNet; ...@@ -4232,22 +4230,12 @@ SK_BOOL DualNet;
printk(" irq moderation: disabled\n"); printk(" irq moderation: disabled\n");
#ifdef SK_ZEROCOPY printk(" scatter-gather: %s\n",
if (pAC->ChipsetType) (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
#ifdef USE_SK_TX_CHECKSUM printk(" tx-checksum: %s\n",
printk(" scatter-gather: enabled\n"); (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
#else printk(" rx-checksum: %s\n",
printk(" tx-checksum: disabled\n"); pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
#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
} else { } else {
DoPrintInterfaceChange = SK_TRUE; DoPrintInterfaceChange = SK_TRUE;
...@@ -4262,9 +4250,9 @@ SK_BOOL DualNet; ...@@ -4262,9 +4250,9 @@ SK_BOOL DualNet;
} }
/* Inform the world that link protocol is up. */ /* Inform the world that link protocol is up. */
netif_carrier_on(pAC->dev[Param.Para32[0]]); netif_carrier_on(dev);
break; break;
}
case SK_DRV_NET_DOWN: /* SK_U32 Reason */ case SK_DRV_NET_DOWN: /* SK_U32 Reason */
/* action list 7 */ /* action list 7 */
SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, 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, ...@@ -4871,15 +4859,18 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY /* Use only if yukon hardware */
#ifdef USE_SK_TX_CHECKSUM
if (pAC->ChipsetType) { if (pAC->ChipsetType) {
/* Use only if yukon hardware */ #ifdef USE_SK_TX_CHECKSUM
/* SK and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_IP_CSUM;
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
}
#endif #endif
#ifdef SK_ZEROCOPY
dev->features |= NETIF_F_SG;
#endif
#ifdef USE_SK_RX_CHECKSUM
pAC->RxPort[0].RxCsum = 1;
#endif #endif
}
pAC->Index = boards_found++; pAC->Index = boards_found++;
...@@ -4944,14 +4935,17 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, ...@@ -4944,14 +4935,17 @@ static int __devinit skge_probe_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
#ifdef SK_ZEROCOPY
#ifdef USE_SK_TX_CHECKSUM
if (pAC->ChipsetType) { if (pAC->ChipsetType) {
/* SG and ZEROCOPY - fly baby... */ #ifdef USE_SK_TX_CHECKSUM
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; dev->features |= NETIF_F_IP_CSUM;
}
#endif #endif
#ifdef SK_ZEROCOPY
dev->features |= NETIF_F_SG;
#endif
#ifdef USE_SK_RX_CHECKSUM
pAC->RxPort[1].RxCsum = 1;
#endif #endif
}
if (register_netdev(dev)) { if (register_netdev(dev)) {
printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n"); printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment