Merge branch 'e1000-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / drivers / net / sk98lin / skge.c
index eb3b351..e0a9300 100644 (file)
 #include       <linux/init.h>
 #include       <linux/dma-mapping.h>
 #include       <linux/ip.h>
+#include       <linux/mii.h>
+#include       <linux/mm.h>
 
 #include       "h/skdrv1st.h"
 #include       "h/skdrv2nd.h"
@@ -196,8 +198,8 @@ static SK_BOOL      BoardAllocMem(SK_AC *pAC);
 static void    BoardFreeMem(SK_AC *pAC);
 static void    BoardInitMem(SK_AC *pAC);
 static void    SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
-static SkIsrRetVar     SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
-static SkIsrRetVar     SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+static SkIsrRetVar     SkGeIsr(int irq, void *dev_id);
+static SkIsrRetVar     SkGeIsrOnePort(int irq, void *dev_id);
 static int     SkGeOpen(struct SK_NET_DEVICE *dev);
 static int     SkGeClose(struct SK_NET_DEVICE *dev);
 static int     SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
@@ -248,7 +250,7 @@ static void DumpLong(char*, int);
 
 /* global variables *********************************************************/
 static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
-extern  struct ethtool_ops SkGeEthtoolOps;
+extern const struct ethtool_ops SkGeEthtoolOps;
 
 /* local variables **********************************************************/
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
@@ -880,7 +882,7 @@ int PortIndex)      /* index of the port for which to re-init */
  * Returns: N/A
  *
  */
-static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
+static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
 {
 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
 DEV_NET                *pNet;
@@ -1029,7 +1031,7 @@ SK_U32            IntSrc;         /* interrupts source register contents */
  * Returns: N/A
  *
  */
-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
+static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
 {
 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
 DEV_NET                *pNet;
@@ -1140,7 +1142,7 @@ SK_U32            IntSrc;         /* interrupts source register contents */
 static void SkGePollController(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       SkGeIsr(dev->irq, dev, NULL);
+       SkGeIsr(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1560,10 +1562,10 @@ struct sk_buff  *pMessage)      /* pointer to send-message              */
        pTxd->pMBuf     = pMessage;
 
        if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
-               u16 hdrlen = pMessage->h.raw - pMessage->data;
-               u16 offset = hdrlen + pMessage->csum;
+               u16 hdrlen = skb_transport_offset(pMessage);
+               u16 offset = hdrlen + pMessage->csum_offset;
 
-               if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
+               if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
                        (pAC->GIni.GIChipRev == 0) &&
                        (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
                        pTxd->TBControl = BMU_TCP_CHECK;
@@ -1679,8 +1681,8 @@ struct sk_buff    *pMessage)      /* pointer to send-message              */
        ** Does the HW need to evaluate checksum for TCP or UDP packets? 
        */
        if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
-               u16 hdrlen = pMessage->h.raw - pMessage->data;
-               u16 offset = hdrlen + pMessage->csum;
+               u16 hdrlen = skb_transport_offset(pMessage);
+               u16 offset = hdrlen + pMessage->csum_offset;
 
                Control = BMU_STFWD;
 
@@ -1689,7 +1691,7 @@ struct sk_buff    *pMessage)      /* pointer to send-message              */
                ** opcode for udp is not working in the hardware yet 
                ** (Revision 2.0)
                */
-               if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
+               if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
                        (pAC->GIni.GIChipRev == 0) &&
                        (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
                        Control |= BMU_TCP_CHECK;
@@ -2125,7 +2127,7 @@ rx_start:
                                                    (dma_addr_t) PhysAddr,
                                                    FrameLength,
                                                    PCI_DMA_FROMDEVICE);
-                       memcpy(pNewMsg->data, pMsg, FrameLength);
+                       skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength);
 
                        pci_dma_sync_single_for_device(pAC->PciDev,
                                                       (dma_addr_t) PhysAddr,
@@ -2191,7 +2193,6 @@ rx_start:
                                SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
                                        FrameLength, pRxPort->PortIndex);
 
-                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
                                pMsg->protocol = eth_type_trans(pMsg,
                                        pAC->dev[pRxPort->PortIndex]);
                                netif_rx(pMsg);
@@ -2244,7 +2245,6 @@ rx_start:
                                (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
                                (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
                                SK_RLMT_RX_PROTOCOL) {
-                               pMsg->dev = pAC->dev[pRxPort->PortIndex];
                                pMsg->protocol = eth_type_trans(pMsg,
                                        pAC->dev[pRxPort->PortIndex]);
                                netif_rx(pMsg);
@@ -2843,6 +2843,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 +2926,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;
        }
@@ -5133,7 +5186,10 @@ static struct pci_driver skge_driver = {
 
 static int __init skge_init(void)
 {
-       return pci_module_init(&skge_driver);
+       printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
+              " and is scheduled for removal\n");
+
+       return pci_register_driver(&skge_driver);
 }
 
 static void __exit skge_exit(void)