]> err.no Git - linux-2.6/blobdiff - drivers/net/sis900.c
/spare/repo/libata-dev branch 'iomap-try3'
[linux-2.6] / drivers / net / sis900.c
index 3e9d9aab05887dc1a12e45fc27879fd0b3a985cd..23b713c700b3beb2e3db8aad2a1321254afae46e 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/processor.h>      /* Processor type for cache alignment. */
 #include <asm/io.h>
@@ -93,8 +94,6 @@ static int sis900_debug = -1; /* Use SIS900_DEF_MSG as value */
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
-/* SiS 900 is capable of 32 bits BM DMA */
-#define SIS900_DMA_MASK 0xffffffff
 
 enum {
        SIS_900 = 0,
@@ -162,6 +161,7 @@ struct sis900_private {
        struct mii_phy * mii;
        struct mii_phy * first_mii; /* record the first mii structure */
        unsigned int cur_phy;
+       struct mii_if_info mii_info;
 
        struct timer_list timer; /* Link status detection timer. */
        u8 autong_complete; /* 1: auto-negotiate complete  */
@@ -203,7 +203,7 @@ static int sis900_open(struct net_device *net_dev);
 static int sis900_mii_probe (struct net_device * net_dev);
 static void sis900_init_rxfilter (struct net_device * net_dev);
 static u16 read_eeprom(long ioaddr, int location);
-static u16 mdio_read(struct net_device *net_dev, int phy_id, int location);
+static int mdio_read(struct net_device *net_dev, int phy_id, int location);
 static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val);
 static void sis900_timer(unsigned long data);
 static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy);
@@ -413,7 +413,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
        ret = pci_enable_device(pci_dev);
        if(ret) return ret;
        
-       i = pci_set_dma_mask(pci_dev, SIS900_DMA_MASK);
+       i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
        if(i){
                printk(KERN_ERR "sis900.c: architecture does not support"
                        "32bit PCI busmaster DMA\n");
@@ -478,7 +478,13 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
                sis_priv->msg_enable = sis900_debug;
        else
                sis_priv->msg_enable = SIS900_DEF_MSG;
-               
+
+       sis_priv->mii_info.dev = net_dev;
+       sis_priv->mii_info.mdio_read = mdio_read;
+       sis_priv->mii_info.mdio_write = mdio_write;
+       sis_priv->mii_info.phy_id_mask = 0x1f;
+       sis_priv->mii_info.reg_num_mask = 0x1f;
+
        /* Get Mac address according to the chip revision */
        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev));
        if(netif_msg_probe(sis_priv))
@@ -725,6 +731,8 @@ static u16 sis900_default_phy(struct net_device * net_dev)
                       pci_name(sis_priv->pci_dev), sis_priv->cur_phy);
        }
        
+       sis_priv->mii_info.phy_id = sis_priv->cur_phy;
+
        status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
        status &= (~MII_CNTL_ISOLATE);
 
@@ -852,7 +860,7 @@ static void mdio_reset(long mdio_addr)
  *     Please see SiS7014 or ICS spec
  */
 
-static u16 mdio_read(struct net_device *net_dev, int phy_id, int location)
+static int mdio_read(struct net_device *net_dev, int phy_id, int location)
 {
        long mdio_addr = net_dev->base_addr + mear;
        int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
@@ -1146,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
                sis_priv->rx_skbuff[i] = skb;
                sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
                 sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
-                        skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                        skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
        }
        sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
 
@@ -1768,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev)
                        sis_priv->rx_skbuff[entry] = skb;
                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                        sis_priv->rx_ring[entry].bufptr = 
-                               pci_map_single(sis_priv->pci_dev, skb->tail
+                               pci_map_single(sis_priv->pci_dev, skb->data
                                        RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
                        sis_priv->dirty_rx++;
                }
@@ -1801,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev)
                        sis_priv->rx_skbuff[entry] = skb;
                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                        sis_priv->rx_ring[entry].bufptr =
-                               pci_map_single(sis_priv->pci_dev, skb->tail,
+                               pci_map_single(sis_priv->pci_dev, skb->data,
                                        RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
                }
        }
@@ -1966,10 +1974,47 @@ static void sis900_set_msglevel(struct net_device *net_dev, u32 value)
        sis_priv->msg_enable = value;
 }
 
+static u32 sis900_get_link(struct net_device *net_dev)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       return mii_link_ok(&sis_priv->mii_info);
+}
+
+static int sis900_get_settings(struct net_device *net_dev,
+                               struct ethtool_cmd *cmd)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       spin_lock_irq(&sis_priv->lock);
+       mii_ethtool_gset(&sis_priv->mii_info, cmd);
+       spin_unlock_irq(&sis_priv->lock);
+       return 0;
+}
+
+static int sis900_set_settings(struct net_device *net_dev,
+                               struct ethtool_cmd *cmd)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       int rt;
+       spin_lock_irq(&sis_priv->lock);
+       rt = mii_ethtool_sset(&sis_priv->mii_info, cmd);
+       spin_unlock_irq(&sis_priv->lock);
+       return rt;
+}
+
+static int sis900_nway_reset(struct net_device *net_dev)
+{
+       struct sis900_private *sis_priv = net_dev->priv;
+       return mii_nway_restart(&sis_priv->mii_info);
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
        .get_drvinfo    = sis900_get_drvinfo,
        .get_msglevel   = sis900_get_msglevel,
        .set_msglevel   = sis900_set_msglevel,
+       .get_link       = sis900_get_link,
+       .get_settings   = sis900_get_settings,
+       .set_settings   = sis900_set_settings,
+       .nway_reset     = sis900_nway_reset,
 };
 
 /**