[PATCH] sk98lin: MII ioctl support
authorStephen Hemminger <shemminger@osdl.org>
Thu, 5 Oct 2006 17:21:26 +0000 (10:21 -0700)
committerJeff Garzik <jeff@garzik.org>
Sat, 2 Dec 2006 05:11:56 +0000 (00:11 -0500)
Add MII ioctl support to the deprecated sk98lin driver.
This allows comparison with skge driver's PHY settings.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/sk98lin/skge.c

index d4913c3de2a18fe59066537de9c60245621ad5f3..a5d41ebc9fb4b4b1d5398a9d8a8773eb39e212df 100644 (file)
 #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"
@@ -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;
        }