vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / dl2k.c
index 53f01d5..0c6c4ad 100644 (file)
@@ -72,16 +72,16 @@ static int tx_coalesce=16;  /* HW xmit count each TxDMAComplete */
 MODULE_AUTHOR ("Edward Peng");
 MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
 MODULE_LICENSE("GPL");
-MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s");
-MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i");
-MODULE_PARM (tx_flow, "i");
-MODULE_PARM (rx_flow, "i");
-MODULE_PARM (copy_thresh, "i");
-MODULE_PARM (rx_coalesce, "i");        /* Rx frame count each interrupt */
-MODULE_PARM (rx_timeout, "i"); /* Rx DMA wait time in 64ns increments */
-MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */
+module_param_array(mtu, int, NULL, 0);
+module_param_array(media, charp, NULL, 0);
+module_param_array(vlan, int, NULL, 0);
+module_param_array(jumbo, int, NULL, 0);
+module_param(tx_flow, int, 0);
+module_param(rx_flow, int, 0);
+module_param(copy_thresh, int, 0);
+module_param(rx_coalesce, int, 0);     /* Rx frame count each interrupt */
+module_param(rx_timeout, int, 0);      /* Rx DMA wait time in 64ns increments */
+module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
 
 
 /* Enable the default interrupts */
@@ -107,7 +107,6 @@ static int change_mtu (struct net_device *dev, int new_mtu);
 static void set_multicast (struct net_device *dev);
 static struct net_device_stats *get_stats (struct net_device *dev);
 static int clear_stats (struct net_device *dev);
-static int rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr);
 static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static int rio_close (struct net_device *dev);
 static int find_miiphy (struct net_device *dev);
@@ -122,6 +121,8 @@ static int mii_read (struct net_device *dev, int phy_addr, int reg_num);
 static int mii_write (struct net_device *dev, int phy_addr, int reg_num,
                      u16 data);
 
+static struct ethtool_ops ethtool_ops;
+
 static int __devinit
 rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -168,7 +169,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 #endif
        dev->base_addr = ioaddr;
        dev->irq = irq;
-       np = dev->priv;
+       np = netdev_priv(dev);
        np->chip_id = chip_idx;
        np->pdev = pdev;
        spin_lock_init (&np->tx_lock);
@@ -244,6 +245,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->tx_timeout = &rio_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
        dev->change_mtu = &change_mtu;
+       SET_ETHTOOL_OPS(dev, &ethtool_ops);
 #if 0
        dev->features = NETIF_F_IP_CSUM;
 #endif
@@ -335,7 +337,7 @@ find_miiphy (struct net_device *dev)
        int i, phy_found = 0;
        struct netdev_private *np;
        long ioaddr;
-       np = dev->priv;
+       np = netdev_priv(dev);
        ioaddr = dev->base_addr;
        np->phy_addr = 1;
 
@@ -362,7 +364,7 @@ parse_eeprom (struct net_device *dev)
        u8 *psib;
        u32 crc;
        PSROM_t psrom = (PSROM_t) sromdata;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
 
        int cid, next;
 
@@ -432,7 +434,7 @@ parse_eeprom (struct net_device *dev)
 static int
 rio_open (struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
        u16 macctrl;
@@ -516,7 +518,7 @@ static void
 rio_timer (unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        unsigned int entry;
        int next_tick = 1*HZ;
        unsigned long flags;
@@ -574,7 +576,7 @@ rio_tx_timeout (struct net_device *dev)
 static void
 alloc_list (struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        int i;
 
        np->cur_rx = np->cur_tx = 0;
@@ -631,7 +633,7 @@ alloc_list (struct net_device *dev)
 static int
 start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        struct netdev_desc *txdesc;
        unsigned entry;
        u32 ioaddr;
@@ -711,7 +713,7 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
        int handled = 0;
 
        ioaddr = dev->base_addr;
-       np = dev->priv;
+       np = netdev_priv(dev);
        while (1) {
                int_status = readw (ioaddr + IntStatus); 
                writew (int_status, ioaddr + IntStatus);
@@ -745,7 +747,7 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
 static void 
 rio_free_tx (struct net_device *dev, int irq) 
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        int entry = np->old_tx % TX_RING_SIZE;
        int tx_use = 0;
        unsigned long flag = 0;
@@ -798,7 +800,7 @@ tx_error (struct net_device *dev, int tx_status)
        int frame_id;
        int i;
 
-       np = dev->priv;
+       np = netdev_priv(dev);
 
        frame_id = (tx_status & 0xffff0000);
        printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
@@ -855,7 +857,7 @@ tx_error (struct net_device *dev, int tx_status)
 static int
 receive_packet (struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        int entry = np->cur_rx % RX_RING_SIZE;
        int cnt = 30;
 
@@ -965,7 +967,7 @@ static void
 rio_error (struct net_device *dev, int int_status)
 {
        long ioaddr = dev->base_addr;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        u16 macctrl;
 
        /* Link change event */
@@ -1016,7 +1018,7 @@ static struct net_device_stats *
 get_stats (struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
 #ifdef MEM_MAPPING
        int i;
 #endif
@@ -1132,7 +1134,7 @@ clear_stats (struct net_device *dev)
 int
 change_mtu (struct net_device *dev, int new_mtu)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        int max = (np->jumbo) ? MAX_JUMBO : 1536;
 
        if ((new_mtu < 68) || (new_mtu > max)) {
@@ -1150,7 +1152,7 @@ set_multicast (struct net_device *dev)
        long ioaddr = dev->base_addr;
        u32 hash_table[2];
        u16 rx_mode = 0;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        
        hash_table[0] = hash_table[1] = 0;
        /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
@@ -1194,137 +1196,118 @@ set_multicast (struct net_device *dev)
        writew (rx_mode, ioaddr + ReceiveMode);
 }
 
-static int
-rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
+static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       strcpy(info->driver, "DL2K");
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(np->pdev));
+}      
+
+static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct netdev_private *np = dev->priv;
-               u32 ethcmd;
+       struct netdev_private *np = netdev_priv(dev);
+       if (np->phy_media) {
+               /* fiber device */
+               cmd->supported = SUPPORTED_Autoneg | SUPPORTED_FIBRE;
+               cmd->advertising= ADVERTISED_Autoneg | ADVERTISED_FIBRE;
+               cmd->port = PORT_FIBRE;
+               cmd->transceiver = XCVR_INTERNAL;       
+       } else {
+               /* copper device */
+               cmd->supported = SUPPORTED_10baseT_Half | 
+                       SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
+                       | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |
+                       SUPPORTED_Autoneg | SUPPORTED_MII;
+               cmd->advertising = ADVERTISED_10baseT_Half |
+                       ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |
+                       ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|
+                       ADVERTISED_Autoneg | ADVERTISED_MII;
+               cmd->port = PORT_MII;
+               cmd->transceiver = XCVR_INTERNAL;
+       }
+       if ( np->link_status ) { 
+               cmd->speed = np->speed;
+               cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+       } else {
+               cmd->speed = -1;
+               cmd->duplex = -1;
+       }
+       if ( np->an_enable)
+               cmd->autoneg = AUTONEG_ENABLE;
+       else
+               cmd->autoneg = AUTONEG_DISABLE;
        
-       if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
-               return -EFAULT;
-       switch (ethcmd) {
-               case ETHTOOL_GDRVINFO: {
-                       struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-                       strcpy(info.driver, "DL2K");
-                       strcpy(info.version, DRV_VERSION);
-                       strcpy(info.bus_info, pci_name(np->pdev));
-                       memset(&info.fw_version, 0, sizeof(info.fw_version));
-                       if (copy_to_user(useraddr, &info, sizeof(info)))
-                               return -EFAULT;
+       cmd->phy_address = np->phy_addr;
+       return 0;                                  
+}
+
+static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       netif_carrier_off(dev);
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               if (np->an_enable)
                        return 0;
+               else {
+                       np->an_enable = 1;
+                       mii_set_media(dev);
+                       return 0;       
                }       
-       
-               case ETHTOOL_GSET: {
-                       struct ethtool_cmd cmd = { ETHTOOL_GSET };
-                       if (np->phy_media) {
-                               /* fiber device */
-                               cmd.supported = SUPPORTED_Autoneg | 
-                                                       SUPPORTED_FIBRE;
-                               cmd.advertising= ADVERTISED_Autoneg |
-                                                       ADVERTISED_FIBRE;
-                               cmd.port = PORT_FIBRE;
-                               cmd.transceiver = XCVR_INTERNAL;        
-                       } else {
-                               /* copper device */
-                               cmd.supported = SUPPORTED_10baseT_Half | 
-                                       SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
-                                       | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |
-                                       SUPPORTED_Autoneg | SUPPORTED_MII;
-                               cmd.advertising = ADVERTISED_10baseT_Half |
-                                       ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |
-                                       ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|
-                                       ADVERTISED_Autoneg | ADVERTISED_MII;
-                               cmd.port = PORT_MII;
-                               cmd.transceiver = XCVR_INTERNAL;
-                       }
-                       if ( np->link_status ) { 
-                               cmd.speed = np->speed;
-                               cmd.duplex = np->full_duplex ? 
-                                                   DUPLEX_FULL : DUPLEX_HALF;
-                       } else {
-                               cmd.speed = -1;
-                               cmd.duplex = -1;
-                       }
-                       if ( np->an_enable)
-                               cmd.autoneg = AUTONEG_ENABLE;
-                       else
-                               cmd.autoneg = AUTONEG_DISABLE;
-                       
-                       cmd.phy_address = np->phy_addr;
-
-                       if (copy_to_user(useraddr, &cmd,
-                                       sizeof(cmd)))
-                               return -EFAULT;
-                       return 0;                                  
-               }
-               case ETHTOOL_SSET: {
-                       struct ethtool_cmd cmd;
-                       if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
-                               return -EFAULT;
-                       netif_carrier_off(dev);
-                       if (cmd.autoneg == AUTONEG_ENABLE) {
-                               if (np->an_enable)
-                                       return 0;
-                               else {
-                                       np->an_enable = 1;
-                                       mii_set_media(dev);
-                                       return 0;       
-                               }       
-                       } else {
-                               np->an_enable = 0;
-                               if (np->speed == 1000){
-                                       cmd.speed = SPEED_100;                  
-                                       cmd.duplex = DUPLEX_FULL;
-                                       printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manul 100Mbps, Full duplex.\n");
-                                       }
-                               switch(cmd.speed + cmd.duplex){
-                               
-                               case SPEED_10 + DUPLEX_HALF:
-                                       np->speed = 10;
-                                       np->full_duplex = 0;
-                                       break;
-                               
-                               case SPEED_10 + DUPLEX_FULL:
-                                       np->speed = 10;
-                                       np->full_duplex = 1;
-                                       break;
-                               case SPEED_100 + DUPLEX_HALF:
-                                       np->speed = 100;
-                                       np->full_duplex = 0;
-                                       break;
-                               case SPEED_100 + DUPLEX_FULL:
-                                       np->speed = 100;
-                                       np->full_duplex = 1;
-                                       break;
-                               case SPEED_1000 + DUPLEX_HALF:/* not supported */
-                               case SPEED_1000 + DUPLEX_FULL:/* not supported */
-                               default:
-                                       return -EINVAL; 
-                               }
-                               mii_set_media(dev);
-                       }
-               return 0;                  
+       } else {
+               np->an_enable = 0;
+               if (np->speed == 1000) {
+                       cmd->speed = SPEED_100;                 
+                       cmd->duplex = DUPLEX_FULL;
+                       printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
                }
-#ifdef ETHTOOL_GLINK           
-               case ETHTOOL_GLINK:{
-               struct ethtool_value link = { ETHTOOL_GLINK };
-               link.data = np->link_status;
-               if (copy_to_user(useraddr, &link, sizeof(link)))
-                       return -EFAULT;
-               return 0;
-               }                          
-#endif
+               switch(cmd->speed + cmd->duplex) {
+               
+               case SPEED_10 + DUPLEX_HALF:
+                       np->speed = 10;
+                       np->full_duplex = 0;
+                       break;
+               
+               case SPEED_10 + DUPLEX_FULL:
+                       np->speed = 10;
+                       np->full_duplex = 1;
+                       break;
+               case SPEED_100 + DUPLEX_HALF:
+                       np->speed = 100;
+                       np->full_duplex = 0;
+                       break;
+               case SPEED_100 + DUPLEX_FULL:
+                       np->speed = 100;
+                       np->full_duplex = 1;
+                       break;
+               case SPEED_1000 + DUPLEX_HALF:/* not supported */
+               case SPEED_1000 + DUPLEX_FULL:/* not supported */
                default:
-               return -EOPNOTSUPP;
-       }       
+                       return -EINVAL; 
+               }
+               mii_set_media(dev);
+       }
+       return 0;
+}
+
+static u32 rio_get_link(struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       return np->link_status;
 }
 
+static struct ethtool_ops ethtool_ops = {
+       .get_drvinfo = rio_get_drvinfo,
+       .get_settings = rio_get_settings,
+       .set_settings = rio_set_settings,
+       .get_link = rio_get_link,
+};
 
 static int
 rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int phy_addr;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
        
        struct netdev_desc *desc;
@@ -1332,8 +1315,6 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 
        phy_addr = np->phy_addr;
        switch (cmd) {
-       case SIOCETHTOOL:
-               return rio_ethtool_ioctl(dev, rq->ifr_data);            
        case SIOCDEVPRIVATE:
                break;
        
@@ -1490,7 +1471,7 @@ mii_wait_link (struct net_device *dev, int wait)
        int phy_addr;
        struct netdev_private *np;
 
-       np = dev->priv;
+       np = netdev_priv(dev);
        phy_addr = np->phy_addr;
 
        do {
@@ -1512,7 +1493,7 @@ mii_get_media (struct net_device *dev)
        int phy_addr;
        struct netdev_private *np;
 
-       np = dev->priv;
+       np = netdev_priv(dev);
        phy_addr = np->phy_addr;
 
        bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
@@ -1594,7 +1575,7 @@ mii_set_media (struct net_device *dev)
        ANAR_t anar;
        int phy_addr;
        struct netdev_private *np;
-       np = dev->priv;
+       np = netdev_priv(dev);
        phy_addr = np->phy_addr;
 
        /* Does user set speed? */
@@ -1684,7 +1665,7 @@ mii_get_media_pcs (struct net_device *dev)
        int phy_addr;
        struct netdev_private *np;
 
-       np = dev->priv;
+       np = netdev_priv(dev);
        phy_addr = np->phy_addr;
 
        bmsr.image = mii_read (dev, phy_addr, PCS_BMSR);
@@ -1740,7 +1721,7 @@ mii_set_media_pcs (struct net_device *dev)
        ANAR_PCS_t anar;
        int phy_addr;
        struct netdev_private *np;
-       np = dev->priv;
+       np = netdev_priv(dev);
        phy_addr = np->phy_addr;
 
        /* Auto-Negotiation? */
@@ -1794,7 +1775,7 @@ static int
 rio_close (struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        struct sk_buff *skb;
        int i;
 
@@ -1840,7 +1821,7 @@ rio_remove1 (struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata (pdev);
 
        if (dev) {
-               struct netdev_private *np = dev->priv;
+               struct netdev_private *np = netdev_priv(dev);
 
                unregister_netdev (dev);
                pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring,