Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09f5a214 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik
Browse files

[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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+48 −0
Original line number Diff line number Diff line
@@ -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,
};
+30 −36
Original line number Diff line number Diff line
@@ -2189,13 +2189,10 @@ rx_start:
			skb_put(pMsg, FrameLength);
		} /* frame > SK_COPY_TRESHOLD */

#ifdef USE_SK_RX_CHECKSUM
		if (pRxPort->RxCsum) {
			pMsg->csum = pRxd->TcpSums;
			pMsg->ip_summed = CHECKSUM_HW;
#else
		pMsg->ip_summed = CHECKSUM_NONE;
#endif

		}

		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
	if (pAC->ChipsetType) {
	/* Use only if yukon hardware */
		/* SK and ZEROCOPY - fly baby... */
		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
	}
	if (pAC->ChipsetType) {
#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");