X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fdl2k.c;h=038447fb5c5ee82ef17110189497e029c01d42fd;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=53f01d51c338da97ced39d43485add1410106cac;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 53f01d51c..038447fb5 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -50,9 +50,10 @@ */ #define DRV_NAME "D-Link DL2000-based linux driver" -#define DRV_VERSION "v1.17a" -#define DRV_RELDATE "2002/10/04" +#define DRV_VERSION "v1.17b" +#define DRV_RELDATE "2006/03/10" #include "dl2k.h" +#include static char version[] __devinitdata = KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n"; @@ -72,16 +73,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 */ @@ -90,8 +91,8 @@ MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */ #define EnableInt() \ writew(DEFAULT_INTR, ioaddr + IntEnable) -static int max_intrloop = 50; -static int multicast_filter_limit = 0x40; +static const int max_intrloop = 50; +static const int multicast_filter_limit = 0x40; static int rio_open (struct net_device *dev); static void rio_timer (unsigned long data); @@ -107,7 +108,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 +122,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 +170,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 +246,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, ðtool_ops); #if 0 dev->features = NETIF_F_IP_CSUM; #endif @@ -335,7 +338,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 +365,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 +435,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 +519,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; @@ -545,7 +548,7 @@ rio_timer (unsigned long data) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= @@ -574,7 +577,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; @@ -616,7 +619,7 @@ alloc_list (struct net_device *dev) /* Rubicon now supports 40 bits of addressing space. */ np->rx_ring[i].fraginfo = cpu_to_le64 ( pci_map_single ( - np->pdev, skb->tail, np->rx_buf_sz, + np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; } @@ -631,7 +634,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 +714,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 +748,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; @@ -763,7 +766,7 @@ rio_free_tx (struct net_device *dev, int irq) break; skb = np->tx_skbuff[entry]; pci_unmap_single (np->pdev, - np->tx_ring[entry].fraginfo, + np->tx_ring[entry].fraginfo & DMA_48BIT_MASK, skb->len, PCI_DMA_TODEVICE); if (irq) dev_kfree_skb_irq (skb); @@ -798,7 +801,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 +858,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; @@ -890,25 +893,28 @@ receive_packet (struct net_device *dev) /* Small skbuffs for short packets */ if (pkt_len > copy_thresh) { - pci_unmap_single (np->pdev, desc->fraginfo, + pci_unmap_single (np->pdev, + desc->fraginfo & DMA_48BIT_MASK, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb_put (skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) { pci_dma_sync_single_for_cpu(np->pdev, - desc->fraginfo, + desc->fraginfo & + DMA_48BIT_MASK, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* 16 byte align the IP header */ skb_reserve (skb, 2); eth_copy_and_sum (skb, - np->rx_skbuff[entry]->tail, + np->rx_skbuff[entry]->data, pkt_len, 0); skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, - desc->fraginfo, + desc->fraginfo & + DMA_48BIT_MASK, np->rx_buf_sz, PCI_DMA_FROMDEVICE); } @@ -948,7 +954,7 @@ receive_packet (struct net_device *dev) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= @@ -965,7 +971,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 +1022,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 +1138,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 +1156,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 +1200,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 (ðcmd, 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 +1319,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 +1475,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 +1497,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 +1579,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 +1669,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 +1725,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 +1779,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; @@ -1815,8 +1800,9 @@ rio_close (struct net_device *dev) np->rx_ring[i].fraginfo = 0; skb = np->rx_skbuff[i]; if (skb) { - pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo, - skb->len, PCI_DMA_FROMDEVICE); + pci_unmap_single(np->pdev, + np->rx_ring[i].fraginfo & DMA_48BIT_MASK, + skb->len, PCI_DMA_FROMDEVICE); dev_kfree_skb (skb); np->rx_skbuff[i] = NULL; } @@ -1824,8 +1810,9 @@ rio_close (struct net_device *dev) for (i = 0; i < TX_RING_SIZE; i++) { skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo, - skb->len, PCI_DMA_TODEVICE); + pci_unmap_single(np->pdev, + np->tx_ring[i].fraginfo & DMA_48BIT_MASK, + skb->len, PCI_DMA_TODEVICE); dev_kfree_skb (skb); np->tx_skbuff[i] = NULL; } @@ -1840,7 +1827,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,