summary refs log tree commit diff
path: root/drivers/net/sk98lin
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sk98lin')
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h2
-rw-r--r--drivers/net/sk98lin/skdim.c4
-rw-r--r--drivers/net/sk98lin/skethtool.c26
-rw-r--r--drivers/net/sk98lin/skge.c58
4 files changed, 85 insertions, 5 deletions
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
index 778d9e618ebd..3fa67171e832 100644
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -160,7 +160,7 @@ struct s_IOCTL {
 
 /*
 ** Interim definition of SK_DRV_TIMER placed in this file until 
-** common modules have boon finallized
+** common modules have been finalized
 */
 #define SK_DRV_TIMER			11 
 #define	SK_DRV_MODERATION_TIMER		1
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
index 07c1b4c8699d..37ce03fb8de3 100644
--- a/drivers/net/sk98lin/skdim.c
+++ b/drivers/net/sk98lin/skdim.c
@@ -252,7 +252,7 @@ SkDimEnableModerationIfNeeded(SK_AC *pAC) {
 
 /*******************************************************************************
 ** Function     : SkDimDisplayModerationSettings
-** Description  : Displays the current settings regaring interrupt moderation
+** Description  : Displays the current settings regarding interrupt moderation
 ** Programmer   : Ralph Roesler
 ** Last Modified: 22-mar-03
 ** Returns      : void (!)
@@ -510,7 +510,7 @@ EnableIntMod(SK_AC *pAC) {
 
 /*******************************************************************************
 ** Function     : DisableIntMod()
-** Description  : Disbles the interrupt moderation independent of what inter-
+** Description  : Disables the interrupt moderation independent of what inter-
 **                rupts are running or not
 ** Programmer   : Ralph Roesler
 ** Last Modified: 23-mar-03
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
index e5cb5b548b88..36460694eb82 100644
--- a/drivers/net/sk98lin/skethtool.c
+++ b/drivers/net/sk98lin/skethtool.c
@@ -581,6 +581,30 @@ static int setRxCsum(struct net_device *dev, u32 data)
 	return 0;
 }
 
+static int getRegsLen(struct net_device *dev)
+{
+	return 0x4000;
+}
+
+/*
+ * Returns copy of whole control register region
+ * Note: skip RAM address register because accessing it will
+ * 	 cause bus hangs!
+ */
+static void getRegs(struct net_device *dev, struct ethtool_regs *regs,
+			  void *p)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	const void __iomem *io = pNet->pAC->IoBase;
+
+	regs->version = 1;
+	memset(p, 0, regs->len);
+	memcpy_fromio(p, io, B3_RAM_ADDR);
+
+	memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
+		      regs->len - B3_RI_WTO_R1);
+}
+
 const struct ethtool_ops SkGeEthtoolOps = {
 	.get_settings		= getSettings,
 	.set_settings		= setSettings,
@@ -599,4 +623,6 @@ const struct ethtool_ops SkGeEthtoolOps = {
 	.set_tx_csum		= setTxCsum,
 	.get_rx_csum		= getRxCsum,
 	.set_rx_csum		= setRxCsum,
+	.get_regs		= getRegs,
+	.get_regs_len		= getRegsLen,
 };
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index d4913c3de2a1..12cbfd190dd7 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -113,6 +113,7 @@
 #include	<linux/init.h>
 #include	<linux/dma-mapping.h>
 #include	<linux/ip.h>
+#include	<linux/mii.h>
 
 #include	"h/skdrv1st.h"
 #include	"h/skdrv2nd.h"
@@ -1561,7 +1562,7 @@ struct sk_buff	*pMessage)	/* pointer to send-message              */
 
 	if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
 		u16 hdrlen = pMessage->h.raw - pMessage->data;
-		u16 offset = hdrlen + pMessage->csum;
+		u16 offset = hdrlen + pMessage->csum_offset;
 
 		if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
 			(pAC->GIni.GIChipRev == 0) &&
@@ -1680,7 +1681,7 @@ struct sk_buff	*pMessage)	/* pointer to send-message              */
 	*/
 	if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
 		u16 hdrlen = pMessage->h.raw - pMessage->data;
-		u16 offset = hdrlen + pMessage->csum;
+		u16 offset = hdrlen + pMessage->csum_offset;
 
 		Control = BMU_STFWD;
 
@@ -2843,6 +2844,56 @@ unsigned long	Flags;			/* for spin lock */
 	return(&pAC->stats);
 } /* SkGeStats */
 
+/*
+ * Basic MII register access
+ */
+static int SkGeMiiIoctl(struct net_device *dev,
+			struct mii_ioctl_data *data, int cmd)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	SK_IOC IoC = pAC->IoBase;
+	int Port = pNet->PortNr;
+	SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
+	unsigned long Flags;
+	int err = 0;
+	int reg = data->reg_num & 0x1f;
+	SK_U16 val = data->val_in;
+
+	if (!netif_running(dev))
+		return -ENODEV;	/* Phy still in reset */
+
+	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+	switch(cmd) {
+	case SIOCGMIIPHY:
+		data->phy_id = pPrt->PhyAddr;
+
+		/* fallthru */
+	case SIOCGMIIREG:
+		if (pAC->GIni.GIGenesis)
+			SkXmPhyRead(pAC, IoC, Port, reg, &val);
+		else
+			SkGmPhyRead(pAC, IoC, Port, reg, &val);
+
+		data->val_out = val;
+		break;
+
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			err = -EPERM;
+
+		else if (pAC->GIni.GIGenesis)
+			SkXmPhyWrite(pAC, IoC, Port, reg, val);
+		else
+			SkGmPhyWrite(pAC, IoC, Port, reg, val);
+		break;
+	default:
+		err = -EOPNOTSUPP;
+	}
+        spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+	return err;
+}
+
 
 /*****************************************************************************
  *
@@ -2876,6 +2927,9 @@ int		HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
 	pNet = netdev_priv(dev);
 	pAC = pNet->pAC;
 	
+	if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG)
+	    return SkGeMiiIoctl(dev, if_mii(rq), cmd);
+
 	if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
 		return -EFAULT;
 	}