13401299aSJeff Kirsher /* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */ 23401299aSJeff Kirsher /* 33401299aSJeff Kirsher Copyright (c) 2001, 2002 by D-Link Corporation 43401299aSJeff Kirsher Written by Edward Peng.<edward_peng@dlink.com.tw> 53401299aSJeff Kirsher Created 03-May-2001, base on Linux' sundance.c. 63401299aSJeff Kirsher 73401299aSJeff Kirsher This program is free software; you can redistribute it and/or modify 83401299aSJeff Kirsher it under the terms of the GNU General Public License as published by 93401299aSJeff Kirsher the Free Software Foundation; either version 2 of the License, or 103401299aSJeff Kirsher (at your option) any later version. 113401299aSJeff Kirsher */ 123401299aSJeff Kirsher 133401299aSJeff Kirsher #define DRV_NAME "DL2000/TC902x-based linux driver" 143401299aSJeff Kirsher #define DRV_VERSION "v1.19" 153401299aSJeff Kirsher #define DRV_RELDATE "2007/08/12" 163401299aSJeff Kirsher #include "dl2k.h" 173401299aSJeff Kirsher #include <linux/dma-mapping.h> 183401299aSJeff Kirsher 193401299aSJeff Kirsher static char version[] __devinitdata = 203401299aSJeff Kirsher KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n"; 213401299aSJeff Kirsher #define MAX_UNITS 8 223401299aSJeff Kirsher static int mtu[MAX_UNITS]; 233401299aSJeff Kirsher static int vlan[MAX_UNITS]; 243401299aSJeff Kirsher static int jumbo[MAX_UNITS]; 253401299aSJeff Kirsher static char *media[MAX_UNITS]; 263401299aSJeff Kirsher static int tx_flow=-1; 273401299aSJeff Kirsher static int rx_flow=-1; 283401299aSJeff Kirsher static int copy_thresh; 293401299aSJeff Kirsher static int rx_coalesce=10; /* Rx frame count each interrupt */ 303401299aSJeff Kirsher static int rx_timeout=200; /* Rx DMA wait time in 640ns increments */ 313401299aSJeff Kirsher static int tx_coalesce=16; /* HW xmit count each TxDMAComplete */ 323401299aSJeff Kirsher 333401299aSJeff Kirsher 343401299aSJeff Kirsher MODULE_AUTHOR ("Edward Peng"); 353401299aSJeff Kirsher MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter"); 363401299aSJeff Kirsher MODULE_LICENSE("GPL"); 373401299aSJeff Kirsher module_param_array(mtu, int, NULL, 0); 383401299aSJeff Kirsher module_param_array(media, charp, NULL, 0); 393401299aSJeff Kirsher module_param_array(vlan, int, NULL, 0); 403401299aSJeff Kirsher module_param_array(jumbo, int, NULL, 0); 413401299aSJeff Kirsher module_param(tx_flow, int, 0); 423401299aSJeff Kirsher module_param(rx_flow, int, 0); 433401299aSJeff Kirsher module_param(copy_thresh, int, 0); 443401299aSJeff Kirsher module_param(rx_coalesce, int, 0); /* Rx frame count each interrupt */ 453401299aSJeff Kirsher module_param(rx_timeout, int, 0); /* Rx DMA wait time in 64ns increments */ 463401299aSJeff Kirsher module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */ 473401299aSJeff Kirsher 483401299aSJeff Kirsher 493401299aSJeff Kirsher /* Enable the default interrupts */ 503401299aSJeff Kirsher #define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \ 513401299aSJeff Kirsher UpdateStats | LinkEvent) 523401299aSJeff Kirsher #define EnableInt() \ 533401299aSJeff Kirsher writew(DEFAULT_INTR, ioaddr + IntEnable) 543401299aSJeff Kirsher 553401299aSJeff Kirsher static const int max_intrloop = 50; 563401299aSJeff Kirsher static const int multicast_filter_limit = 0x40; 573401299aSJeff Kirsher 583401299aSJeff Kirsher static int rio_open (struct net_device *dev); 593401299aSJeff Kirsher static void rio_timer (unsigned long data); 603401299aSJeff Kirsher static void rio_tx_timeout (struct net_device *dev); 613401299aSJeff Kirsher static void alloc_list (struct net_device *dev); 623401299aSJeff Kirsher static netdev_tx_t start_xmit (struct sk_buff *skb, struct net_device *dev); 633401299aSJeff Kirsher static irqreturn_t rio_interrupt (int irq, void *dev_instance); 643401299aSJeff Kirsher static void rio_free_tx (struct net_device *dev, int irq); 653401299aSJeff Kirsher static void tx_error (struct net_device *dev, int tx_status); 663401299aSJeff Kirsher static int receive_packet (struct net_device *dev); 673401299aSJeff Kirsher static void rio_error (struct net_device *dev, int int_status); 683401299aSJeff Kirsher static int change_mtu (struct net_device *dev, int new_mtu); 693401299aSJeff Kirsher static void set_multicast (struct net_device *dev); 703401299aSJeff Kirsher static struct net_device_stats *get_stats (struct net_device *dev); 713401299aSJeff Kirsher static int clear_stats (struct net_device *dev); 723401299aSJeff Kirsher static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); 733401299aSJeff Kirsher static int rio_close (struct net_device *dev); 743401299aSJeff Kirsher static int find_miiphy (struct net_device *dev); 753401299aSJeff Kirsher static int parse_eeprom (struct net_device *dev); 763401299aSJeff Kirsher static int read_eeprom (long ioaddr, int eep_addr); 773401299aSJeff Kirsher static int mii_wait_link (struct net_device *dev, int wait); 783401299aSJeff Kirsher static int mii_set_media (struct net_device *dev); 793401299aSJeff Kirsher static int mii_get_media (struct net_device *dev); 803401299aSJeff Kirsher static int mii_set_media_pcs (struct net_device *dev); 813401299aSJeff Kirsher static int mii_get_media_pcs (struct net_device *dev); 823401299aSJeff Kirsher static int mii_read (struct net_device *dev, int phy_addr, int reg_num); 833401299aSJeff Kirsher static int mii_write (struct net_device *dev, int phy_addr, int reg_num, 843401299aSJeff Kirsher u16 data); 853401299aSJeff Kirsher 863401299aSJeff Kirsher static const struct ethtool_ops ethtool_ops; 873401299aSJeff Kirsher 883401299aSJeff Kirsher static const struct net_device_ops netdev_ops = { 893401299aSJeff Kirsher .ndo_open = rio_open, 903401299aSJeff Kirsher .ndo_start_xmit = start_xmit, 913401299aSJeff Kirsher .ndo_stop = rio_close, 923401299aSJeff Kirsher .ndo_get_stats = get_stats, 933401299aSJeff Kirsher .ndo_validate_addr = eth_validate_addr, 943401299aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 95afc4b13dSJiri Pirko .ndo_set_rx_mode = set_multicast, 963401299aSJeff Kirsher .ndo_do_ioctl = rio_ioctl, 973401299aSJeff Kirsher .ndo_tx_timeout = rio_tx_timeout, 983401299aSJeff Kirsher .ndo_change_mtu = change_mtu, 993401299aSJeff Kirsher }; 1003401299aSJeff Kirsher 1013401299aSJeff Kirsher static int __devinit 1023401299aSJeff Kirsher rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) 1033401299aSJeff Kirsher { 1043401299aSJeff Kirsher struct net_device *dev; 1053401299aSJeff Kirsher struct netdev_private *np; 1063401299aSJeff Kirsher static int card_idx; 1073401299aSJeff Kirsher int chip_idx = ent->driver_data; 1083401299aSJeff Kirsher int err, irq; 1093401299aSJeff Kirsher long ioaddr; 1103401299aSJeff Kirsher static int version_printed; 1113401299aSJeff Kirsher void *ring_space; 1123401299aSJeff Kirsher dma_addr_t ring_dma; 1133401299aSJeff Kirsher 1143401299aSJeff Kirsher if (!version_printed++) 1153401299aSJeff Kirsher printk ("%s", version); 1163401299aSJeff Kirsher 1173401299aSJeff Kirsher err = pci_enable_device (pdev); 1183401299aSJeff Kirsher if (err) 1193401299aSJeff Kirsher return err; 1203401299aSJeff Kirsher 1213401299aSJeff Kirsher irq = pdev->irq; 1223401299aSJeff Kirsher err = pci_request_regions (pdev, "dl2k"); 1233401299aSJeff Kirsher if (err) 1243401299aSJeff Kirsher goto err_out_disable; 1253401299aSJeff Kirsher 1263401299aSJeff Kirsher pci_set_master (pdev); 1273401299aSJeff Kirsher dev = alloc_etherdev (sizeof (*np)); 1283401299aSJeff Kirsher if (!dev) { 1293401299aSJeff Kirsher err = -ENOMEM; 1303401299aSJeff Kirsher goto err_out_res; 1313401299aSJeff Kirsher } 1323401299aSJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev); 1333401299aSJeff Kirsher 1343401299aSJeff Kirsher #ifdef MEM_MAPPING 1353401299aSJeff Kirsher ioaddr = pci_resource_start (pdev, 1); 1363401299aSJeff Kirsher ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE); 1373401299aSJeff Kirsher if (!ioaddr) { 1383401299aSJeff Kirsher err = -ENOMEM; 1393401299aSJeff Kirsher goto err_out_dev; 1403401299aSJeff Kirsher } 1413401299aSJeff Kirsher #else 1423401299aSJeff Kirsher ioaddr = pci_resource_start (pdev, 0); 1433401299aSJeff Kirsher #endif 1443401299aSJeff Kirsher dev->base_addr = ioaddr; 1453401299aSJeff Kirsher dev->irq = irq; 1463401299aSJeff Kirsher np = netdev_priv(dev); 1473401299aSJeff Kirsher np->chip_id = chip_idx; 1483401299aSJeff Kirsher np->pdev = pdev; 1493401299aSJeff Kirsher spin_lock_init (&np->tx_lock); 1503401299aSJeff Kirsher spin_lock_init (&np->rx_lock); 1513401299aSJeff Kirsher 1523401299aSJeff Kirsher /* Parse manual configuration */ 1533401299aSJeff Kirsher np->an_enable = 1; 1543401299aSJeff Kirsher np->tx_coalesce = 1; 1553401299aSJeff Kirsher if (card_idx < MAX_UNITS) { 1563401299aSJeff Kirsher if (media[card_idx] != NULL) { 1573401299aSJeff Kirsher np->an_enable = 0; 1583401299aSJeff Kirsher if (strcmp (media[card_idx], "auto") == 0 || 1593401299aSJeff Kirsher strcmp (media[card_idx], "autosense") == 0 || 1603401299aSJeff Kirsher strcmp (media[card_idx], "0") == 0 ) { 1613401299aSJeff Kirsher np->an_enable = 2; 1623401299aSJeff Kirsher } else if (strcmp (media[card_idx], "100mbps_fd") == 0 || 1633401299aSJeff Kirsher strcmp (media[card_idx], "4") == 0) { 1643401299aSJeff Kirsher np->speed = 100; 1653401299aSJeff Kirsher np->full_duplex = 1; 1663401299aSJeff Kirsher } else if (strcmp (media[card_idx], "100mbps_hd") == 0 || 1673401299aSJeff Kirsher strcmp (media[card_idx], "3") == 0) { 1683401299aSJeff Kirsher np->speed = 100; 1693401299aSJeff Kirsher np->full_duplex = 0; 1703401299aSJeff Kirsher } else if (strcmp (media[card_idx], "10mbps_fd") == 0 || 1713401299aSJeff Kirsher strcmp (media[card_idx], "2") == 0) { 1723401299aSJeff Kirsher np->speed = 10; 1733401299aSJeff Kirsher np->full_duplex = 1; 1743401299aSJeff Kirsher } else if (strcmp (media[card_idx], "10mbps_hd") == 0 || 1753401299aSJeff Kirsher strcmp (media[card_idx], "1") == 0) { 1763401299aSJeff Kirsher np->speed = 10; 1773401299aSJeff Kirsher np->full_duplex = 0; 1783401299aSJeff Kirsher } else if (strcmp (media[card_idx], "1000mbps_fd") == 0 || 1793401299aSJeff Kirsher strcmp (media[card_idx], "6") == 0) { 1803401299aSJeff Kirsher np->speed=1000; 1813401299aSJeff Kirsher np->full_duplex=1; 1823401299aSJeff Kirsher } else if (strcmp (media[card_idx], "1000mbps_hd") == 0 || 1833401299aSJeff Kirsher strcmp (media[card_idx], "5") == 0) { 1843401299aSJeff Kirsher np->speed = 1000; 1853401299aSJeff Kirsher np->full_duplex = 0; 1863401299aSJeff Kirsher } else { 1873401299aSJeff Kirsher np->an_enable = 1; 1883401299aSJeff Kirsher } 1893401299aSJeff Kirsher } 1903401299aSJeff Kirsher if (jumbo[card_idx] != 0) { 1913401299aSJeff Kirsher np->jumbo = 1; 1923401299aSJeff Kirsher dev->mtu = MAX_JUMBO; 1933401299aSJeff Kirsher } else { 1943401299aSJeff Kirsher np->jumbo = 0; 1953401299aSJeff Kirsher if (mtu[card_idx] > 0 && mtu[card_idx] < PACKET_SIZE) 1963401299aSJeff Kirsher dev->mtu = mtu[card_idx]; 1973401299aSJeff Kirsher } 1983401299aSJeff Kirsher np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ? 1993401299aSJeff Kirsher vlan[card_idx] : 0; 2003401299aSJeff Kirsher if (rx_coalesce > 0 && rx_timeout > 0) { 2013401299aSJeff Kirsher np->rx_coalesce = rx_coalesce; 2023401299aSJeff Kirsher np->rx_timeout = rx_timeout; 2033401299aSJeff Kirsher np->coalesce = 1; 2043401299aSJeff Kirsher } 2053401299aSJeff Kirsher np->tx_flow = (tx_flow == 0) ? 0 : 1; 2063401299aSJeff Kirsher np->rx_flow = (rx_flow == 0) ? 0 : 1; 2073401299aSJeff Kirsher 2083401299aSJeff Kirsher if (tx_coalesce < 1) 2093401299aSJeff Kirsher tx_coalesce = 1; 2103401299aSJeff Kirsher else if (tx_coalesce > TX_RING_SIZE-1) 2113401299aSJeff Kirsher tx_coalesce = TX_RING_SIZE - 1; 2123401299aSJeff Kirsher } 2133401299aSJeff Kirsher dev->netdev_ops = &netdev_ops; 2143401299aSJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT; 2153401299aSJeff Kirsher SET_ETHTOOL_OPS(dev, ðtool_ops); 2163401299aSJeff Kirsher #if 0 2173401299aSJeff Kirsher dev->features = NETIF_F_IP_CSUM; 2183401299aSJeff Kirsher #endif 2193401299aSJeff Kirsher pci_set_drvdata (pdev, dev); 2203401299aSJeff Kirsher 2213401299aSJeff Kirsher ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma); 2223401299aSJeff Kirsher if (!ring_space) 2233401299aSJeff Kirsher goto err_out_iounmap; 2243401299aSJeff Kirsher np->tx_ring = ring_space; 2253401299aSJeff Kirsher np->tx_ring_dma = ring_dma; 2263401299aSJeff Kirsher 2273401299aSJeff Kirsher ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma); 2283401299aSJeff Kirsher if (!ring_space) 2293401299aSJeff Kirsher goto err_out_unmap_tx; 2303401299aSJeff Kirsher np->rx_ring = ring_space; 2313401299aSJeff Kirsher np->rx_ring_dma = ring_dma; 2323401299aSJeff Kirsher 2333401299aSJeff Kirsher /* Parse eeprom data */ 2343401299aSJeff Kirsher parse_eeprom (dev); 2353401299aSJeff Kirsher 2363401299aSJeff Kirsher /* Find PHY address */ 2373401299aSJeff Kirsher err = find_miiphy (dev); 2383401299aSJeff Kirsher if (err) 2393401299aSJeff Kirsher goto err_out_unmap_rx; 2403401299aSJeff Kirsher 2413401299aSJeff Kirsher /* Fiber device? */ 2423401299aSJeff Kirsher np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0; 2433401299aSJeff Kirsher np->link_status = 0; 2443401299aSJeff Kirsher /* Set media and reset PHY */ 2453401299aSJeff Kirsher if (np->phy_media) { 2463401299aSJeff Kirsher /* default Auto-Negotiation for fiber deivices */ 2473401299aSJeff Kirsher if (np->an_enable == 2) { 2483401299aSJeff Kirsher np->an_enable = 1; 2493401299aSJeff Kirsher } 2503401299aSJeff Kirsher mii_set_media_pcs (dev); 2513401299aSJeff Kirsher } else { 2523401299aSJeff Kirsher /* Auto-Negotiation is mandatory for 1000BASE-T, 2533401299aSJeff Kirsher IEEE 802.3ab Annex 28D page 14 */ 2543401299aSJeff Kirsher if (np->speed == 1000) 2553401299aSJeff Kirsher np->an_enable = 1; 2563401299aSJeff Kirsher mii_set_media (dev); 2573401299aSJeff Kirsher } 2583401299aSJeff Kirsher 2593401299aSJeff Kirsher err = register_netdev (dev); 2603401299aSJeff Kirsher if (err) 2613401299aSJeff Kirsher goto err_out_unmap_rx; 2623401299aSJeff Kirsher 2633401299aSJeff Kirsher card_idx++; 2643401299aSJeff Kirsher 2653401299aSJeff Kirsher printk (KERN_INFO "%s: %s, %pM, IRQ %d\n", 2663401299aSJeff Kirsher dev->name, np->name, dev->dev_addr, irq); 2673401299aSJeff Kirsher if (tx_coalesce > 1) 2683401299aSJeff Kirsher printk(KERN_INFO "tx_coalesce:\t%d packets\n", 2693401299aSJeff Kirsher tx_coalesce); 2703401299aSJeff Kirsher if (np->coalesce) 2713401299aSJeff Kirsher printk(KERN_INFO 2723401299aSJeff Kirsher "rx_coalesce:\t%d packets\n" 2733401299aSJeff Kirsher "rx_timeout: \t%d ns\n", 2743401299aSJeff Kirsher np->rx_coalesce, np->rx_timeout*640); 2753401299aSJeff Kirsher if (np->vlan) 2763401299aSJeff Kirsher printk(KERN_INFO "vlan(id):\t%d\n", np->vlan); 2773401299aSJeff Kirsher return 0; 2783401299aSJeff Kirsher 2793401299aSJeff Kirsher err_out_unmap_rx: 2803401299aSJeff Kirsher pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma); 2813401299aSJeff Kirsher err_out_unmap_tx: 2823401299aSJeff Kirsher pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma); 2833401299aSJeff Kirsher err_out_iounmap: 2843401299aSJeff Kirsher #ifdef MEM_MAPPING 2853401299aSJeff Kirsher iounmap ((void *) ioaddr); 2863401299aSJeff Kirsher 2873401299aSJeff Kirsher err_out_dev: 2883401299aSJeff Kirsher #endif 2893401299aSJeff Kirsher free_netdev (dev); 2903401299aSJeff Kirsher 2913401299aSJeff Kirsher err_out_res: 2923401299aSJeff Kirsher pci_release_regions (pdev); 2933401299aSJeff Kirsher 2943401299aSJeff Kirsher err_out_disable: 2953401299aSJeff Kirsher pci_disable_device (pdev); 2963401299aSJeff Kirsher return err; 2973401299aSJeff Kirsher } 2983401299aSJeff Kirsher 2993401299aSJeff Kirsher static int 3003401299aSJeff Kirsher find_miiphy (struct net_device *dev) 3013401299aSJeff Kirsher { 3023401299aSJeff Kirsher int i, phy_found = 0; 3033401299aSJeff Kirsher struct netdev_private *np; 3043401299aSJeff Kirsher long ioaddr; 3053401299aSJeff Kirsher np = netdev_priv(dev); 3063401299aSJeff Kirsher ioaddr = dev->base_addr; 3073401299aSJeff Kirsher np->phy_addr = 1; 3083401299aSJeff Kirsher 3093401299aSJeff Kirsher for (i = 31; i >= 0; i--) { 3103401299aSJeff Kirsher int mii_status = mii_read (dev, i, 1); 3113401299aSJeff Kirsher if (mii_status != 0xffff && mii_status != 0x0000) { 3123401299aSJeff Kirsher np->phy_addr = i; 3133401299aSJeff Kirsher phy_found++; 3143401299aSJeff Kirsher } 3153401299aSJeff Kirsher } 3163401299aSJeff Kirsher if (!phy_found) { 3173401299aSJeff Kirsher printk (KERN_ERR "%s: No MII PHY found!\n", dev->name); 3183401299aSJeff Kirsher return -ENODEV; 3193401299aSJeff Kirsher } 3203401299aSJeff Kirsher return 0; 3213401299aSJeff Kirsher } 3223401299aSJeff Kirsher 3233401299aSJeff Kirsher static int 3243401299aSJeff Kirsher parse_eeprom (struct net_device *dev) 3253401299aSJeff Kirsher { 3263401299aSJeff Kirsher int i, j; 3273401299aSJeff Kirsher long ioaddr = dev->base_addr; 3283401299aSJeff Kirsher u8 sromdata[256]; 3293401299aSJeff Kirsher u8 *psib; 3303401299aSJeff Kirsher u32 crc; 3313401299aSJeff Kirsher PSROM_t psrom = (PSROM_t) sromdata; 3323401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 3333401299aSJeff Kirsher 3343401299aSJeff Kirsher int cid, next; 3353401299aSJeff Kirsher 3363401299aSJeff Kirsher #ifdef MEM_MAPPING 3373401299aSJeff Kirsher ioaddr = pci_resource_start (np->pdev, 0); 3383401299aSJeff Kirsher #endif 3393401299aSJeff Kirsher /* Read eeprom */ 3403401299aSJeff Kirsher for (i = 0; i < 128; i++) { 3413401299aSJeff Kirsher ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom (ioaddr, i)); 3423401299aSJeff Kirsher } 3433401299aSJeff Kirsher #ifdef MEM_MAPPING 3443401299aSJeff Kirsher ioaddr = dev->base_addr; 3453401299aSJeff Kirsher #endif 3463401299aSJeff Kirsher if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */ 3473401299aSJeff Kirsher /* Check CRC */ 3483401299aSJeff Kirsher crc = ~ether_crc_le (256 - 4, sromdata); 3493401299aSJeff Kirsher if (psrom->crc != cpu_to_le32(crc)) { 3503401299aSJeff Kirsher printk (KERN_ERR "%s: EEPROM data CRC error.\n", 3513401299aSJeff Kirsher dev->name); 3523401299aSJeff Kirsher return -1; 3533401299aSJeff Kirsher } 3543401299aSJeff Kirsher } 3553401299aSJeff Kirsher 3563401299aSJeff Kirsher /* Set MAC address */ 3573401299aSJeff Kirsher for (i = 0; i < 6; i++) 3583401299aSJeff Kirsher dev->dev_addr[i] = psrom->mac_addr[i]; 3593401299aSJeff Kirsher 3603401299aSJeff Kirsher if (np->pdev->vendor != PCI_VENDOR_ID_DLINK) { 3613401299aSJeff Kirsher return 0; 3623401299aSJeff Kirsher } 3633401299aSJeff Kirsher 3643401299aSJeff Kirsher /* Parse Software Information Block */ 3653401299aSJeff Kirsher i = 0x30; 3663401299aSJeff Kirsher psib = (u8 *) sromdata; 3673401299aSJeff Kirsher do { 3683401299aSJeff Kirsher cid = psib[i++]; 3693401299aSJeff Kirsher next = psib[i++]; 3703401299aSJeff Kirsher if ((cid == 0 && next == 0) || (cid == 0xff && next == 0xff)) { 3713401299aSJeff Kirsher printk (KERN_ERR "Cell data error\n"); 3723401299aSJeff Kirsher return -1; 3733401299aSJeff Kirsher } 3743401299aSJeff Kirsher switch (cid) { 3753401299aSJeff Kirsher case 0: /* Format version */ 3763401299aSJeff Kirsher break; 3773401299aSJeff Kirsher case 1: /* End of cell */ 3783401299aSJeff Kirsher return 0; 3793401299aSJeff Kirsher case 2: /* Duplex Polarity */ 3803401299aSJeff Kirsher np->duplex_polarity = psib[i]; 3813401299aSJeff Kirsher writeb (readb (ioaddr + PhyCtrl) | psib[i], 3823401299aSJeff Kirsher ioaddr + PhyCtrl); 3833401299aSJeff Kirsher break; 3843401299aSJeff Kirsher case 3: /* Wake Polarity */ 3853401299aSJeff Kirsher np->wake_polarity = psib[i]; 3863401299aSJeff Kirsher break; 3873401299aSJeff Kirsher case 9: /* Adapter description */ 3883401299aSJeff Kirsher j = (next - i > 255) ? 255 : next - i; 3893401299aSJeff Kirsher memcpy (np->name, &(psib[i]), j); 3903401299aSJeff Kirsher break; 3913401299aSJeff Kirsher case 4: 3923401299aSJeff Kirsher case 5: 3933401299aSJeff Kirsher case 6: 3943401299aSJeff Kirsher case 7: 3953401299aSJeff Kirsher case 8: /* Reversed */ 3963401299aSJeff Kirsher break; 3973401299aSJeff Kirsher default: /* Unknown cell */ 3983401299aSJeff Kirsher return -1; 3993401299aSJeff Kirsher } 4003401299aSJeff Kirsher i = next; 4013401299aSJeff Kirsher } while (1); 4023401299aSJeff Kirsher 4033401299aSJeff Kirsher return 0; 4043401299aSJeff Kirsher } 4053401299aSJeff Kirsher 4063401299aSJeff Kirsher static int 4073401299aSJeff Kirsher rio_open (struct net_device *dev) 4083401299aSJeff Kirsher { 4093401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 4103401299aSJeff Kirsher long ioaddr = dev->base_addr; 4113401299aSJeff Kirsher int i; 4123401299aSJeff Kirsher u16 macctrl; 4133401299aSJeff Kirsher 4143401299aSJeff Kirsher i = request_irq (dev->irq, rio_interrupt, IRQF_SHARED, dev->name, dev); 4153401299aSJeff Kirsher if (i) 4163401299aSJeff Kirsher return i; 4173401299aSJeff Kirsher 4183401299aSJeff Kirsher /* Reset all logic functions */ 4193401299aSJeff Kirsher writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset, 4203401299aSJeff Kirsher ioaddr + ASICCtrl + 2); 4213401299aSJeff Kirsher mdelay(10); 4223401299aSJeff Kirsher 4233401299aSJeff Kirsher /* DebugCtrl bit 4, 5, 9 must set */ 4243401299aSJeff Kirsher writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl); 4253401299aSJeff Kirsher 4263401299aSJeff Kirsher /* Jumbo frame */ 4273401299aSJeff Kirsher if (np->jumbo != 0) 4283401299aSJeff Kirsher writew (MAX_JUMBO+14, ioaddr + MaxFrameSize); 4293401299aSJeff Kirsher 4303401299aSJeff Kirsher alloc_list (dev); 4313401299aSJeff Kirsher 4323401299aSJeff Kirsher /* Get station address */ 4333401299aSJeff Kirsher for (i = 0; i < 6; i++) 4343401299aSJeff Kirsher writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i); 4353401299aSJeff Kirsher 4363401299aSJeff Kirsher set_multicast (dev); 4373401299aSJeff Kirsher if (np->coalesce) { 4383401299aSJeff Kirsher writel (np->rx_coalesce | np->rx_timeout << 16, 4393401299aSJeff Kirsher ioaddr + RxDMAIntCtrl); 4403401299aSJeff Kirsher } 4413401299aSJeff Kirsher /* Set RIO to poll every N*320nsec. */ 4423401299aSJeff Kirsher writeb (0x20, ioaddr + RxDMAPollPeriod); 4433401299aSJeff Kirsher writeb (0xff, ioaddr + TxDMAPollPeriod); 4443401299aSJeff Kirsher writeb (0x30, ioaddr + RxDMABurstThresh); 4453401299aSJeff Kirsher writeb (0x30, ioaddr + RxDMAUrgentThresh); 4463401299aSJeff Kirsher writel (0x0007ffff, ioaddr + RmonStatMask); 4473401299aSJeff Kirsher /* clear statistics */ 4483401299aSJeff Kirsher clear_stats (dev); 4493401299aSJeff Kirsher 4503401299aSJeff Kirsher /* VLAN supported */ 4513401299aSJeff Kirsher if (np->vlan) { 4523401299aSJeff Kirsher /* priority field in RxDMAIntCtrl */ 4533401299aSJeff Kirsher writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10, 4543401299aSJeff Kirsher ioaddr + RxDMAIntCtrl); 4553401299aSJeff Kirsher /* VLANId */ 4563401299aSJeff Kirsher writew (np->vlan, ioaddr + VLANId); 4573401299aSJeff Kirsher /* Length/Type should be 0x8100 */ 4583401299aSJeff Kirsher writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag); 4593401299aSJeff Kirsher /* Enable AutoVLANuntagging, but disable AutoVLANtagging. 4603401299aSJeff Kirsher VLAN information tagged by TFC' VID, CFI fields. */ 4613401299aSJeff Kirsher writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging, 4623401299aSJeff Kirsher ioaddr + MACCtrl); 4633401299aSJeff Kirsher } 4643401299aSJeff Kirsher 4653401299aSJeff Kirsher init_timer (&np->timer); 4663401299aSJeff Kirsher np->timer.expires = jiffies + 1*HZ; 4673401299aSJeff Kirsher np->timer.data = (unsigned long) dev; 4683401299aSJeff Kirsher np->timer.function = rio_timer; 4693401299aSJeff Kirsher add_timer (&np->timer); 4703401299aSJeff Kirsher 4713401299aSJeff Kirsher /* Start Tx/Rx */ 4723401299aSJeff Kirsher writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 4733401299aSJeff Kirsher ioaddr + MACCtrl); 4743401299aSJeff Kirsher 4753401299aSJeff Kirsher macctrl = 0; 4763401299aSJeff Kirsher macctrl |= (np->vlan) ? AutoVLANuntagging : 0; 4773401299aSJeff Kirsher macctrl |= (np->full_duplex) ? DuplexSelect : 0; 4783401299aSJeff Kirsher macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0; 4793401299aSJeff Kirsher macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0; 4803401299aSJeff Kirsher writew(macctrl, ioaddr + MACCtrl); 4813401299aSJeff Kirsher 4823401299aSJeff Kirsher netif_start_queue (dev); 4833401299aSJeff Kirsher 4843401299aSJeff Kirsher /* Enable default interrupts */ 4853401299aSJeff Kirsher EnableInt (); 4863401299aSJeff Kirsher return 0; 4873401299aSJeff Kirsher } 4883401299aSJeff Kirsher 4893401299aSJeff Kirsher static void 4903401299aSJeff Kirsher rio_timer (unsigned long data) 4913401299aSJeff Kirsher { 4923401299aSJeff Kirsher struct net_device *dev = (struct net_device *)data; 4933401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 4943401299aSJeff Kirsher unsigned int entry; 4953401299aSJeff Kirsher int next_tick = 1*HZ; 4963401299aSJeff Kirsher unsigned long flags; 4973401299aSJeff Kirsher 4983401299aSJeff Kirsher spin_lock_irqsave(&np->rx_lock, flags); 4993401299aSJeff Kirsher /* Recover rx ring exhausted error */ 5003401299aSJeff Kirsher if (np->cur_rx - np->old_rx >= RX_RING_SIZE) { 5013401299aSJeff Kirsher printk(KERN_INFO "Try to recover rx ring exhausted...\n"); 5023401299aSJeff Kirsher /* Re-allocate skbuffs to fill the descriptor ring */ 5033401299aSJeff Kirsher for (; np->cur_rx - np->old_rx > 0; np->old_rx++) { 5043401299aSJeff Kirsher struct sk_buff *skb; 5053401299aSJeff Kirsher entry = np->old_rx % RX_RING_SIZE; 5063401299aSJeff Kirsher /* Dropped packets don't need to re-allocate */ 5073401299aSJeff Kirsher if (np->rx_skbuff[entry] == NULL) { 5083401299aSJeff Kirsher skb = netdev_alloc_skb_ip_align(dev, 5093401299aSJeff Kirsher np->rx_buf_sz); 5103401299aSJeff Kirsher if (skb == NULL) { 5113401299aSJeff Kirsher np->rx_ring[entry].fraginfo = 0; 5123401299aSJeff Kirsher printk (KERN_INFO 5133401299aSJeff Kirsher "%s: Still unable to re-allocate Rx skbuff.#%d\n", 5143401299aSJeff Kirsher dev->name, entry); 5153401299aSJeff Kirsher break; 5163401299aSJeff Kirsher } 5173401299aSJeff Kirsher np->rx_skbuff[entry] = skb; 5183401299aSJeff Kirsher np->rx_ring[entry].fraginfo = 5193401299aSJeff Kirsher cpu_to_le64 (pci_map_single 5203401299aSJeff Kirsher (np->pdev, skb->data, np->rx_buf_sz, 5213401299aSJeff Kirsher PCI_DMA_FROMDEVICE)); 5223401299aSJeff Kirsher } 5233401299aSJeff Kirsher np->rx_ring[entry].fraginfo |= 5243401299aSJeff Kirsher cpu_to_le64((u64)np->rx_buf_sz << 48); 5253401299aSJeff Kirsher np->rx_ring[entry].status = 0; 5263401299aSJeff Kirsher } /* end for */ 5273401299aSJeff Kirsher } /* end if */ 5283401299aSJeff Kirsher spin_unlock_irqrestore (&np->rx_lock, flags); 5293401299aSJeff Kirsher np->timer.expires = jiffies + next_tick; 5303401299aSJeff Kirsher add_timer(&np->timer); 5313401299aSJeff Kirsher } 5323401299aSJeff Kirsher 5333401299aSJeff Kirsher static void 5343401299aSJeff Kirsher rio_tx_timeout (struct net_device *dev) 5353401299aSJeff Kirsher { 5363401299aSJeff Kirsher long ioaddr = dev->base_addr; 5373401299aSJeff Kirsher 5383401299aSJeff Kirsher printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n", 5393401299aSJeff Kirsher dev->name, readl (ioaddr + TxStatus)); 5403401299aSJeff Kirsher rio_free_tx(dev, 0); 5413401299aSJeff Kirsher dev->if_port = 0; 5423401299aSJeff Kirsher dev->trans_start = jiffies; /* prevent tx timeout */ 5433401299aSJeff Kirsher } 5443401299aSJeff Kirsher 5453401299aSJeff Kirsher /* allocate and initialize Tx and Rx descriptors */ 5463401299aSJeff Kirsher static void 5473401299aSJeff Kirsher alloc_list (struct net_device *dev) 5483401299aSJeff Kirsher { 5493401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 5503401299aSJeff Kirsher int i; 5513401299aSJeff Kirsher 5523401299aSJeff Kirsher np->cur_rx = np->cur_tx = 0; 5533401299aSJeff Kirsher np->old_rx = np->old_tx = 0; 5543401299aSJeff Kirsher np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32); 5553401299aSJeff Kirsher 5563401299aSJeff Kirsher /* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */ 5573401299aSJeff Kirsher for (i = 0; i < TX_RING_SIZE; i++) { 5583401299aSJeff Kirsher np->tx_skbuff[i] = NULL; 5593401299aSJeff Kirsher np->tx_ring[i].status = cpu_to_le64 (TFDDone); 5603401299aSJeff Kirsher np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma + 5613401299aSJeff Kirsher ((i+1)%TX_RING_SIZE) * 5623401299aSJeff Kirsher sizeof (struct netdev_desc)); 5633401299aSJeff Kirsher } 5643401299aSJeff Kirsher 5653401299aSJeff Kirsher /* Initialize Rx descriptors */ 5663401299aSJeff Kirsher for (i = 0; i < RX_RING_SIZE; i++) { 5673401299aSJeff Kirsher np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma + 5683401299aSJeff Kirsher ((i + 1) % RX_RING_SIZE) * 5693401299aSJeff Kirsher sizeof (struct netdev_desc)); 5703401299aSJeff Kirsher np->rx_ring[i].status = 0; 5713401299aSJeff Kirsher np->rx_ring[i].fraginfo = 0; 5723401299aSJeff Kirsher np->rx_skbuff[i] = NULL; 5733401299aSJeff Kirsher } 5743401299aSJeff Kirsher 5753401299aSJeff Kirsher /* Allocate the rx buffers */ 5763401299aSJeff Kirsher for (i = 0; i < RX_RING_SIZE; i++) { 5773401299aSJeff Kirsher /* Allocated fixed size of skbuff */ 5783401299aSJeff Kirsher struct sk_buff *skb; 5793401299aSJeff Kirsher 5803401299aSJeff Kirsher skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz); 5813401299aSJeff Kirsher np->rx_skbuff[i] = skb; 5823401299aSJeff Kirsher if (skb == NULL) { 5833401299aSJeff Kirsher printk (KERN_ERR 5843401299aSJeff Kirsher "%s: alloc_list: allocate Rx buffer error! ", 5853401299aSJeff Kirsher dev->name); 5863401299aSJeff Kirsher break; 5873401299aSJeff Kirsher } 5883401299aSJeff Kirsher /* Rubicon now supports 40 bits of addressing space. */ 5893401299aSJeff Kirsher np->rx_ring[i].fraginfo = 5903401299aSJeff Kirsher cpu_to_le64 ( pci_map_single ( 5913401299aSJeff Kirsher np->pdev, skb->data, np->rx_buf_sz, 5923401299aSJeff Kirsher PCI_DMA_FROMDEVICE)); 5933401299aSJeff Kirsher np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48); 5943401299aSJeff Kirsher } 5953401299aSJeff Kirsher 5963401299aSJeff Kirsher /* Set RFDListPtr */ 5973401299aSJeff Kirsher writel (np->rx_ring_dma, dev->base_addr + RFDListPtr0); 5983401299aSJeff Kirsher writel (0, dev->base_addr + RFDListPtr1); 5993401299aSJeff Kirsher } 6003401299aSJeff Kirsher 6013401299aSJeff Kirsher static netdev_tx_t 6023401299aSJeff Kirsher start_xmit (struct sk_buff *skb, struct net_device *dev) 6033401299aSJeff Kirsher { 6043401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 6053401299aSJeff Kirsher struct netdev_desc *txdesc; 6063401299aSJeff Kirsher unsigned entry; 6073401299aSJeff Kirsher u32 ioaddr; 6083401299aSJeff Kirsher u64 tfc_vlan_tag = 0; 6093401299aSJeff Kirsher 6103401299aSJeff Kirsher if (np->link_status == 0) { /* Link Down */ 6113401299aSJeff Kirsher dev_kfree_skb(skb); 6123401299aSJeff Kirsher return NETDEV_TX_OK; 6133401299aSJeff Kirsher } 6143401299aSJeff Kirsher ioaddr = dev->base_addr; 6153401299aSJeff Kirsher entry = np->cur_tx % TX_RING_SIZE; 6163401299aSJeff Kirsher np->tx_skbuff[entry] = skb; 6173401299aSJeff Kirsher txdesc = &np->tx_ring[entry]; 6183401299aSJeff Kirsher 6193401299aSJeff Kirsher #if 0 6203401299aSJeff Kirsher if (skb->ip_summed == CHECKSUM_PARTIAL) { 6213401299aSJeff Kirsher txdesc->status |= 6223401299aSJeff Kirsher cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable | 6233401299aSJeff Kirsher IPChecksumEnable); 6243401299aSJeff Kirsher } 6253401299aSJeff Kirsher #endif 6263401299aSJeff Kirsher if (np->vlan) { 6273401299aSJeff Kirsher tfc_vlan_tag = VLANTagInsert | 6283401299aSJeff Kirsher ((u64)np->vlan << 32) | 6293401299aSJeff Kirsher ((u64)skb->priority << 45); 6303401299aSJeff Kirsher } 6313401299aSJeff Kirsher txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data, 6323401299aSJeff Kirsher skb->len, 6333401299aSJeff Kirsher PCI_DMA_TODEVICE)); 6343401299aSJeff Kirsher txdesc->fraginfo |= cpu_to_le64((u64)skb->len << 48); 6353401299aSJeff Kirsher 6363401299aSJeff Kirsher /* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode 6373401299aSJeff Kirsher * Work around: Always use 1 descriptor in 10Mbps mode */ 6383401299aSJeff Kirsher if (entry % np->tx_coalesce == 0 || np->speed == 10) 6393401299aSJeff Kirsher txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag | 6403401299aSJeff Kirsher WordAlignDisable | 6413401299aSJeff Kirsher TxDMAIndicate | 6423401299aSJeff Kirsher (1 << FragCountShift)); 6433401299aSJeff Kirsher else 6443401299aSJeff Kirsher txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag | 6453401299aSJeff Kirsher WordAlignDisable | 6463401299aSJeff Kirsher (1 << FragCountShift)); 6473401299aSJeff Kirsher 6483401299aSJeff Kirsher /* TxDMAPollNow */ 6493401299aSJeff Kirsher writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl); 6503401299aSJeff Kirsher /* Schedule ISR */ 6513401299aSJeff Kirsher writel(10000, ioaddr + CountDown); 6523401299aSJeff Kirsher np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE; 6533401299aSJeff Kirsher if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE 6543401299aSJeff Kirsher < TX_QUEUE_LEN - 1 && np->speed != 10) { 6553401299aSJeff Kirsher /* do nothing */ 6563401299aSJeff Kirsher } else if (!netif_queue_stopped(dev)) { 6573401299aSJeff Kirsher netif_stop_queue (dev); 6583401299aSJeff Kirsher } 6593401299aSJeff Kirsher 6603401299aSJeff Kirsher /* The first TFDListPtr */ 6613401299aSJeff Kirsher if (readl (dev->base_addr + TFDListPtr0) == 0) { 6623401299aSJeff Kirsher writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc), 6633401299aSJeff Kirsher dev->base_addr + TFDListPtr0); 6643401299aSJeff Kirsher writel (0, dev->base_addr + TFDListPtr1); 6653401299aSJeff Kirsher } 6663401299aSJeff Kirsher 6673401299aSJeff Kirsher return NETDEV_TX_OK; 6683401299aSJeff Kirsher } 6693401299aSJeff Kirsher 6703401299aSJeff Kirsher static irqreturn_t 6713401299aSJeff Kirsher rio_interrupt (int irq, void *dev_instance) 6723401299aSJeff Kirsher { 6733401299aSJeff Kirsher struct net_device *dev = dev_instance; 6743401299aSJeff Kirsher struct netdev_private *np; 6753401299aSJeff Kirsher unsigned int_status; 6763401299aSJeff Kirsher long ioaddr; 6773401299aSJeff Kirsher int cnt = max_intrloop; 6783401299aSJeff Kirsher int handled = 0; 6793401299aSJeff Kirsher 6803401299aSJeff Kirsher ioaddr = dev->base_addr; 6813401299aSJeff Kirsher np = netdev_priv(dev); 6823401299aSJeff Kirsher while (1) { 6833401299aSJeff Kirsher int_status = readw (ioaddr + IntStatus); 6843401299aSJeff Kirsher writew (int_status, ioaddr + IntStatus); 6853401299aSJeff Kirsher int_status &= DEFAULT_INTR; 6863401299aSJeff Kirsher if (int_status == 0 || --cnt < 0) 6873401299aSJeff Kirsher break; 6883401299aSJeff Kirsher handled = 1; 6893401299aSJeff Kirsher /* Processing received packets */ 6903401299aSJeff Kirsher if (int_status & RxDMAComplete) 6913401299aSJeff Kirsher receive_packet (dev); 6923401299aSJeff Kirsher /* TxDMAComplete interrupt */ 6933401299aSJeff Kirsher if ((int_status & (TxDMAComplete|IntRequested))) { 6943401299aSJeff Kirsher int tx_status; 6953401299aSJeff Kirsher tx_status = readl (ioaddr + TxStatus); 6963401299aSJeff Kirsher if (tx_status & 0x01) 6973401299aSJeff Kirsher tx_error (dev, tx_status); 6983401299aSJeff Kirsher /* Free used tx skbuffs */ 6993401299aSJeff Kirsher rio_free_tx (dev, 1); 7003401299aSJeff Kirsher } 7013401299aSJeff Kirsher 7023401299aSJeff Kirsher /* Handle uncommon events */ 7033401299aSJeff Kirsher if (int_status & 7043401299aSJeff Kirsher (HostError | LinkEvent | UpdateStats)) 7053401299aSJeff Kirsher rio_error (dev, int_status); 7063401299aSJeff Kirsher } 7073401299aSJeff Kirsher if (np->cur_tx != np->old_tx) 7083401299aSJeff Kirsher writel (100, ioaddr + CountDown); 7093401299aSJeff Kirsher return IRQ_RETVAL(handled); 7103401299aSJeff Kirsher } 7113401299aSJeff Kirsher 7123401299aSJeff Kirsher static inline dma_addr_t desc_to_dma(struct netdev_desc *desc) 7133401299aSJeff Kirsher { 7143401299aSJeff Kirsher return le64_to_cpu(desc->fraginfo) & DMA_BIT_MASK(48); 7153401299aSJeff Kirsher } 7163401299aSJeff Kirsher 7173401299aSJeff Kirsher static void 7183401299aSJeff Kirsher rio_free_tx (struct net_device *dev, int irq) 7193401299aSJeff Kirsher { 7203401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 7213401299aSJeff Kirsher int entry = np->old_tx % TX_RING_SIZE; 7223401299aSJeff Kirsher int tx_use = 0; 7233401299aSJeff Kirsher unsigned long flag = 0; 7243401299aSJeff Kirsher 7253401299aSJeff Kirsher if (irq) 7263401299aSJeff Kirsher spin_lock(&np->tx_lock); 7273401299aSJeff Kirsher else 7283401299aSJeff Kirsher spin_lock_irqsave(&np->tx_lock, flag); 7293401299aSJeff Kirsher 7303401299aSJeff Kirsher /* Free used tx skbuffs */ 7313401299aSJeff Kirsher while (entry != np->cur_tx) { 7323401299aSJeff Kirsher struct sk_buff *skb; 7333401299aSJeff Kirsher 7343401299aSJeff Kirsher if (!(np->tx_ring[entry].status & cpu_to_le64(TFDDone))) 7353401299aSJeff Kirsher break; 7363401299aSJeff Kirsher skb = np->tx_skbuff[entry]; 7373401299aSJeff Kirsher pci_unmap_single (np->pdev, 7383401299aSJeff Kirsher desc_to_dma(&np->tx_ring[entry]), 7393401299aSJeff Kirsher skb->len, PCI_DMA_TODEVICE); 7403401299aSJeff Kirsher if (irq) 7413401299aSJeff Kirsher dev_kfree_skb_irq (skb); 7423401299aSJeff Kirsher else 7433401299aSJeff Kirsher dev_kfree_skb (skb); 7443401299aSJeff Kirsher 7453401299aSJeff Kirsher np->tx_skbuff[entry] = NULL; 7463401299aSJeff Kirsher entry = (entry + 1) % TX_RING_SIZE; 7473401299aSJeff Kirsher tx_use++; 7483401299aSJeff Kirsher } 7493401299aSJeff Kirsher if (irq) 7503401299aSJeff Kirsher spin_unlock(&np->tx_lock); 7513401299aSJeff Kirsher else 7523401299aSJeff Kirsher spin_unlock_irqrestore(&np->tx_lock, flag); 7533401299aSJeff Kirsher np->old_tx = entry; 7543401299aSJeff Kirsher 7553401299aSJeff Kirsher /* If the ring is no longer full, clear tx_full and 7563401299aSJeff Kirsher call netif_wake_queue() */ 7573401299aSJeff Kirsher 7583401299aSJeff Kirsher if (netif_queue_stopped(dev) && 7593401299aSJeff Kirsher ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE 7603401299aSJeff Kirsher < TX_QUEUE_LEN - 1 || np->speed == 10)) { 7613401299aSJeff Kirsher netif_wake_queue (dev); 7623401299aSJeff Kirsher } 7633401299aSJeff Kirsher } 7643401299aSJeff Kirsher 7653401299aSJeff Kirsher static void 7663401299aSJeff Kirsher tx_error (struct net_device *dev, int tx_status) 7673401299aSJeff Kirsher { 7683401299aSJeff Kirsher struct netdev_private *np; 7693401299aSJeff Kirsher long ioaddr = dev->base_addr; 7703401299aSJeff Kirsher int frame_id; 7713401299aSJeff Kirsher int i; 7723401299aSJeff Kirsher 7733401299aSJeff Kirsher np = netdev_priv(dev); 7743401299aSJeff Kirsher 7753401299aSJeff Kirsher frame_id = (tx_status & 0xffff0000); 7763401299aSJeff Kirsher printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n", 7773401299aSJeff Kirsher dev->name, tx_status, frame_id); 7783401299aSJeff Kirsher np->stats.tx_errors++; 7793401299aSJeff Kirsher /* Ttransmit Underrun */ 7803401299aSJeff Kirsher if (tx_status & 0x10) { 7813401299aSJeff Kirsher np->stats.tx_fifo_errors++; 7823401299aSJeff Kirsher writew (readw (ioaddr + TxStartThresh) + 0x10, 7833401299aSJeff Kirsher ioaddr + TxStartThresh); 7843401299aSJeff Kirsher /* Transmit Underrun need to set TxReset, DMARest, FIFOReset */ 7853401299aSJeff Kirsher writew (TxReset | DMAReset | FIFOReset | NetworkReset, 7863401299aSJeff Kirsher ioaddr + ASICCtrl + 2); 7873401299aSJeff Kirsher /* Wait for ResetBusy bit clear */ 7883401299aSJeff Kirsher for (i = 50; i > 0; i--) { 7893401299aSJeff Kirsher if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0) 7903401299aSJeff Kirsher break; 7913401299aSJeff Kirsher mdelay (1); 7923401299aSJeff Kirsher } 7933401299aSJeff Kirsher rio_free_tx (dev, 1); 7943401299aSJeff Kirsher /* Reset TFDListPtr */ 7953401299aSJeff Kirsher writel (np->tx_ring_dma + 7963401299aSJeff Kirsher np->old_tx * sizeof (struct netdev_desc), 7973401299aSJeff Kirsher dev->base_addr + TFDListPtr0); 7983401299aSJeff Kirsher writel (0, dev->base_addr + TFDListPtr1); 7993401299aSJeff Kirsher 8003401299aSJeff Kirsher /* Let TxStartThresh stay default value */ 8013401299aSJeff Kirsher } 8023401299aSJeff Kirsher /* Late Collision */ 8033401299aSJeff Kirsher if (tx_status & 0x04) { 8043401299aSJeff Kirsher np->stats.tx_fifo_errors++; 8053401299aSJeff Kirsher /* TxReset and clear FIFO */ 8063401299aSJeff Kirsher writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2); 8073401299aSJeff Kirsher /* Wait reset done */ 8083401299aSJeff Kirsher for (i = 50; i > 0; i--) { 8093401299aSJeff Kirsher if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0) 8103401299aSJeff Kirsher break; 8113401299aSJeff Kirsher mdelay (1); 8123401299aSJeff Kirsher } 8133401299aSJeff Kirsher /* Let TxStartThresh stay default value */ 8143401299aSJeff Kirsher } 8153401299aSJeff Kirsher /* Maximum Collisions */ 8163401299aSJeff Kirsher #ifdef ETHER_STATS 8173401299aSJeff Kirsher if (tx_status & 0x08) 8183401299aSJeff Kirsher np->stats.collisions16++; 8193401299aSJeff Kirsher #else 8203401299aSJeff Kirsher if (tx_status & 0x08) 8213401299aSJeff Kirsher np->stats.collisions++; 8223401299aSJeff Kirsher #endif 8233401299aSJeff Kirsher /* Restart the Tx */ 8243401299aSJeff Kirsher writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl); 8253401299aSJeff Kirsher } 8263401299aSJeff Kirsher 8273401299aSJeff Kirsher static int 8283401299aSJeff Kirsher receive_packet (struct net_device *dev) 8293401299aSJeff Kirsher { 8303401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 8313401299aSJeff Kirsher int entry = np->cur_rx % RX_RING_SIZE; 8323401299aSJeff Kirsher int cnt = 30; 8333401299aSJeff Kirsher 8343401299aSJeff Kirsher /* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */ 8353401299aSJeff Kirsher while (1) { 8363401299aSJeff Kirsher struct netdev_desc *desc = &np->rx_ring[entry]; 8373401299aSJeff Kirsher int pkt_len; 8383401299aSJeff Kirsher u64 frame_status; 8393401299aSJeff Kirsher 8403401299aSJeff Kirsher if (!(desc->status & cpu_to_le64(RFDDone)) || 8413401299aSJeff Kirsher !(desc->status & cpu_to_le64(FrameStart)) || 8423401299aSJeff Kirsher !(desc->status & cpu_to_le64(FrameEnd))) 8433401299aSJeff Kirsher break; 8443401299aSJeff Kirsher 8453401299aSJeff Kirsher /* Chip omits the CRC. */ 8463401299aSJeff Kirsher frame_status = le64_to_cpu(desc->status); 8473401299aSJeff Kirsher pkt_len = frame_status & 0xffff; 8483401299aSJeff Kirsher if (--cnt < 0) 8493401299aSJeff Kirsher break; 8503401299aSJeff Kirsher /* Update rx error statistics, drop packet. */ 8513401299aSJeff Kirsher if (frame_status & RFS_Errors) { 8523401299aSJeff Kirsher np->stats.rx_errors++; 8533401299aSJeff Kirsher if (frame_status & (RxRuntFrame | RxLengthError)) 8543401299aSJeff Kirsher np->stats.rx_length_errors++; 8553401299aSJeff Kirsher if (frame_status & RxFCSError) 8563401299aSJeff Kirsher np->stats.rx_crc_errors++; 8573401299aSJeff Kirsher if (frame_status & RxAlignmentError && np->speed != 1000) 8583401299aSJeff Kirsher np->stats.rx_frame_errors++; 8593401299aSJeff Kirsher if (frame_status & RxFIFOOverrun) 8603401299aSJeff Kirsher np->stats.rx_fifo_errors++; 8613401299aSJeff Kirsher } else { 8623401299aSJeff Kirsher struct sk_buff *skb; 8633401299aSJeff Kirsher 8643401299aSJeff Kirsher /* Small skbuffs for short packets */ 8653401299aSJeff Kirsher if (pkt_len > copy_thresh) { 8663401299aSJeff Kirsher pci_unmap_single (np->pdev, 8673401299aSJeff Kirsher desc_to_dma(desc), 8683401299aSJeff Kirsher np->rx_buf_sz, 8693401299aSJeff Kirsher PCI_DMA_FROMDEVICE); 8703401299aSJeff Kirsher skb_put (skb = np->rx_skbuff[entry], pkt_len); 8713401299aSJeff Kirsher np->rx_skbuff[entry] = NULL; 8723401299aSJeff Kirsher } else if ((skb = netdev_alloc_skb_ip_align(dev, pkt_len))) { 8733401299aSJeff Kirsher pci_dma_sync_single_for_cpu(np->pdev, 8743401299aSJeff Kirsher desc_to_dma(desc), 8753401299aSJeff Kirsher np->rx_buf_sz, 8763401299aSJeff Kirsher PCI_DMA_FROMDEVICE); 8773401299aSJeff Kirsher skb_copy_to_linear_data (skb, 8783401299aSJeff Kirsher np->rx_skbuff[entry]->data, 8793401299aSJeff Kirsher pkt_len); 8803401299aSJeff Kirsher skb_put (skb, pkt_len); 8813401299aSJeff Kirsher pci_dma_sync_single_for_device(np->pdev, 8823401299aSJeff Kirsher desc_to_dma(desc), 8833401299aSJeff Kirsher np->rx_buf_sz, 8843401299aSJeff Kirsher PCI_DMA_FROMDEVICE); 8853401299aSJeff Kirsher } 8863401299aSJeff Kirsher skb->protocol = eth_type_trans (skb, dev); 8873401299aSJeff Kirsher #if 0 8883401299aSJeff Kirsher /* Checksum done by hw, but csum value unavailable. */ 8893401299aSJeff Kirsher if (np->pdev->pci_rev_id >= 0x0c && 8903401299aSJeff Kirsher !(frame_status & (TCPError | UDPError | IPError))) { 8913401299aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 8923401299aSJeff Kirsher } 8933401299aSJeff Kirsher #endif 8943401299aSJeff Kirsher netif_rx (skb); 8953401299aSJeff Kirsher } 8963401299aSJeff Kirsher entry = (entry + 1) % RX_RING_SIZE; 8973401299aSJeff Kirsher } 8983401299aSJeff Kirsher spin_lock(&np->rx_lock); 8993401299aSJeff Kirsher np->cur_rx = entry; 9003401299aSJeff Kirsher /* Re-allocate skbuffs to fill the descriptor ring */ 9013401299aSJeff Kirsher entry = np->old_rx; 9023401299aSJeff Kirsher while (entry != np->cur_rx) { 9033401299aSJeff Kirsher struct sk_buff *skb; 9043401299aSJeff Kirsher /* Dropped packets don't need to re-allocate */ 9053401299aSJeff Kirsher if (np->rx_skbuff[entry] == NULL) { 9063401299aSJeff Kirsher skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz); 9073401299aSJeff Kirsher if (skb == NULL) { 9083401299aSJeff Kirsher np->rx_ring[entry].fraginfo = 0; 9093401299aSJeff Kirsher printk (KERN_INFO 9103401299aSJeff Kirsher "%s: receive_packet: " 9113401299aSJeff Kirsher "Unable to re-allocate Rx skbuff.#%d\n", 9123401299aSJeff Kirsher dev->name, entry); 9133401299aSJeff Kirsher break; 9143401299aSJeff Kirsher } 9153401299aSJeff Kirsher np->rx_skbuff[entry] = skb; 9163401299aSJeff Kirsher np->rx_ring[entry].fraginfo = 9173401299aSJeff Kirsher cpu_to_le64 (pci_map_single 9183401299aSJeff Kirsher (np->pdev, skb->data, np->rx_buf_sz, 9193401299aSJeff Kirsher PCI_DMA_FROMDEVICE)); 9203401299aSJeff Kirsher } 9213401299aSJeff Kirsher np->rx_ring[entry].fraginfo |= 9223401299aSJeff Kirsher cpu_to_le64((u64)np->rx_buf_sz << 48); 9233401299aSJeff Kirsher np->rx_ring[entry].status = 0; 9243401299aSJeff Kirsher entry = (entry + 1) % RX_RING_SIZE; 9253401299aSJeff Kirsher } 9263401299aSJeff Kirsher np->old_rx = entry; 9273401299aSJeff Kirsher spin_unlock(&np->rx_lock); 9283401299aSJeff Kirsher return 0; 9293401299aSJeff Kirsher } 9303401299aSJeff Kirsher 9313401299aSJeff Kirsher static void 9323401299aSJeff Kirsher rio_error (struct net_device *dev, int int_status) 9333401299aSJeff Kirsher { 9343401299aSJeff Kirsher long ioaddr = dev->base_addr; 9353401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 9363401299aSJeff Kirsher u16 macctrl; 9373401299aSJeff Kirsher 9383401299aSJeff Kirsher /* Link change event */ 9393401299aSJeff Kirsher if (int_status & LinkEvent) { 9403401299aSJeff Kirsher if (mii_wait_link (dev, 10) == 0) { 9413401299aSJeff Kirsher printk (KERN_INFO "%s: Link up\n", dev->name); 9423401299aSJeff Kirsher if (np->phy_media) 9433401299aSJeff Kirsher mii_get_media_pcs (dev); 9443401299aSJeff Kirsher else 9453401299aSJeff Kirsher mii_get_media (dev); 9463401299aSJeff Kirsher if (np->speed == 1000) 9473401299aSJeff Kirsher np->tx_coalesce = tx_coalesce; 9483401299aSJeff Kirsher else 9493401299aSJeff Kirsher np->tx_coalesce = 1; 9503401299aSJeff Kirsher macctrl = 0; 9513401299aSJeff Kirsher macctrl |= (np->vlan) ? AutoVLANuntagging : 0; 9523401299aSJeff Kirsher macctrl |= (np->full_duplex) ? DuplexSelect : 0; 9533401299aSJeff Kirsher macctrl |= (np->tx_flow) ? 9543401299aSJeff Kirsher TxFlowControlEnable : 0; 9553401299aSJeff Kirsher macctrl |= (np->rx_flow) ? 9563401299aSJeff Kirsher RxFlowControlEnable : 0; 9573401299aSJeff Kirsher writew(macctrl, ioaddr + MACCtrl); 9583401299aSJeff Kirsher np->link_status = 1; 9593401299aSJeff Kirsher netif_carrier_on(dev); 9603401299aSJeff Kirsher } else { 9613401299aSJeff Kirsher printk (KERN_INFO "%s: Link off\n", dev->name); 9623401299aSJeff Kirsher np->link_status = 0; 9633401299aSJeff Kirsher netif_carrier_off(dev); 9643401299aSJeff Kirsher } 9653401299aSJeff Kirsher } 9663401299aSJeff Kirsher 9673401299aSJeff Kirsher /* UpdateStats statistics registers */ 9683401299aSJeff Kirsher if (int_status & UpdateStats) { 9693401299aSJeff Kirsher get_stats (dev); 9703401299aSJeff Kirsher } 9713401299aSJeff Kirsher 9723401299aSJeff Kirsher /* PCI Error, a catastronphic error related to the bus interface 9733401299aSJeff Kirsher occurs, set GlobalReset and HostReset to reset. */ 9743401299aSJeff Kirsher if (int_status & HostError) { 9753401299aSJeff Kirsher printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n", 9763401299aSJeff Kirsher dev->name, int_status); 9773401299aSJeff Kirsher writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2); 9783401299aSJeff Kirsher mdelay (500); 9793401299aSJeff Kirsher } 9803401299aSJeff Kirsher } 9813401299aSJeff Kirsher 9823401299aSJeff Kirsher static struct net_device_stats * 9833401299aSJeff Kirsher get_stats (struct net_device *dev) 9843401299aSJeff Kirsher { 9853401299aSJeff Kirsher long ioaddr = dev->base_addr; 9863401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 9873401299aSJeff Kirsher #ifdef MEM_MAPPING 9883401299aSJeff Kirsher int i; 9893401299aSJeff Kirsher #endif 9903401299aSJeff Kirsher unsigned int stat_reg; 9913401299aSJeff Kirsher 9923401299aSJeff Kirsher /* All statistics registers need to be acknowledged, 9933401299aSJeff Kirsher else statistic overflow could cause problems */ 9943401299aSJeff Kirsher 9953401299aSJeff Kirsher np->stats.rx_packets += readl (ioaddr + FramesRcvOk); 9963401299aSJeff Kirsher np->stats.tx_packets += readl (ioaddr + FramesXmtOk); 9973401299aSJeff Kirsher np->stats.rx_bytes += readl (ioaddr + OctetRcvOk); 9983401299aSJeff Kirsher np->stats.tx_bytes += readl (ioaddr + OctetXmtOk); 9993401299aSJeff Kirsher 10003401299aSJeff Kirsher np->stats.multicast = readl (ioaddr + McstFramesRcvdOk); 10013401299aSJeff Kirsher np->stats.collisions += readl (ioaddr + SingleColFrames) 10023401299aSJeff Kirsher + readl (ioaddr + MultiColFrames); 10033401299aSJeff Kirsher 10043401299aSJeff Kirsher /* detailed tx errors */ 10053401299aSJeff Kirsher stat_reg = readw (ioaddr + FramesAbortXSColls); 10063401299aSJeff Kirsher np->stats.tx_aborted_errors += stat_reg; 10073401299aSJeff Kirsher np->stats.tx_errors += stat_reg; 10083401299aSJeff Kirsher 10093401299aSJeff Kirsher stat_reg = readw (ioaddr + CarrierSenseErrors); 10103401299aSJeff Kirsher np->stats.tx_carrier_errors += stat_reg; 10113401299aSJeff Kirsher np->stats.tx_errors += stat_reg; 10123401299aSJeff Kirsher 10133401299aSJeff Kirsher /* Clear all other statistic register. */ 10143401299aSJeff Kirsher readl (ioaddr + McstOctetXmtOk); 10153401299aSJeff Kirsher readw (ioaddr + BcstFramesXmtdOk); 10163401299aSJeff Kirsher readl (ioaddr + McstFramesXmtdOk); 10173401299aSJeff Kirsher readw (ioaddr + BcstFramesRcvdOk); 10183401299aSJeff Kirsher readw (ioaddr + MacControlFramesRcvd); 10193401299aSJeff Kirsher readw (ioaddr + FrameTooLongErrors); 10203401299aSJeff Kirsher readw (ioaddr + InRangeLengthErrors); 10213401299aSJeff Kirsher readw (ioaddr + FramesCheckSeqErrors); 10223401299aSJeff Kirsher readw (ioaddr + FramesLostRxErrors); 10233401299aSJeff Kirsher readl (ioaddr + McstOctetXmtOk); 10243401299aSJeff Kirsher readl (ioaddr + BcstOctetXmtOk); 10253401299aSJeff Kirsher readl (ioaddr + McstFramesXmtdOk); 10263401299aSJeff Kirsher readl (ioaddr + FramesWDeferredXmt); 10273401299aSJeff Kirsher readl (ioaddr + LateCollisions); 10283401299aSJeff Kirsher readw (ioaddr + BcstFramesXmtdOk); 10293401299aSJeff Kirsher readw (ioaddr + MacControlFramesXmtd); 10303401299aSJeff Kirsher readw (ioaddr + FramesWEXDeferal); 10313401299aSJeff Kirsher 10323401299aSJeff Kirsher #ifdef MEM_MAPPING 10333401299aSJeff Kirsher for (i = 0x100; i <= 0x150; i += 4) 10343401299aSJeff Kirsher readl (ioaddr + i); 10353401299aSJeff Kirsher #endif 10363401299aSJeff Kirsher readw (ioaddr + TxJumboFrames); 10373401299aSJeff Kirsher readw (ioaddr + RxJumboFrames); 10383401299aSJeff Kirsher readw (ioaddr + TCPCheckSumErrors); 10393401299aSJeff Kirsher readw (ioaddr + UDPCheckSumErrors); 10403401299aSJeff Kirsher readw (ioaddr + IPCheckSumErrors); 10413401299aSJeff Kirsher return &np->stats; 10423401299aSJeff Kirsher } 10433401299aSJeff Kirsher 10443401299aSJeff Kirsher static int 10453401299aSJeff Kirsher clear_stats (struct net_device *dev) 10463401299aSJeff Kirsher { 10473401299aSJeff Kirsher long ioaddr = dev->base_addr; 10483401299aSJeff Kirsher #ifdef MEM_MAPPING 10493401299aSJeff Kirsher int i; 10503401299aSJeff Kirsher #endif 10513401299aSJeff Kirsher 10523401299aSJeff Kirsher /* All statistics registers need to be acknowledged, 10533401299aSJeff Kirsher else statistic overflow could cause problems */ 10543401299aSJeff Kirsher readl (ioaddr + FramesRcvOk); 10553401299aSJeff Kirsher readl (ioaddr + FramesXmtOk); 10563401299aSJeff Kirsher readl (ioaddr + OctetRcvOk); 10573401299aSJeff Kirsher readl (ioaddr + OctetXmtOk); 10583401299aSJeff Kirsher 10593401299aSJeff Kirsher readl (ioaddr + McstFramesRcvdOk); 10603401299aSJeff Kirsher readl (ioaddr + SingleColFrames); 10613401299aSJeff Kirsher readl (ioaddr + MultiColFrames); 10623401299aSJeff Kirsher readl (ioaddr + LateCollisions); 10633401299aSJeff Kirsher /* detailed rx errors */ 10643401299aSJeff Kirsher readw (ioaddr + FrameTooLongErrors); 10653401299aSJeff Kirsher readw (ioaddr + InRangeLengthErrors); 10663401299aSJeff Kirsher readw (ioaddr + FramesCheckSeqErrors); 10673401299aSJeff Kirsher readw (ioaddr + FramesLostRxErrors); 10683401299aSJeff Kirsher 10693401299aSJeff Kirsher /* detailed tx errors */ 10703401299aSJeff Kirsher readw (ioaddr + FramesAbortXSColls); 10713401299aSJeff Kirsher readw (ioaddr + CarrierSenseErrors); 10723401299aSJeff Kirsher 10733401299aSJeff Kirsher /* Clear all other statistic register. */ 10743401299aSJeff Kirsher readl (ioaddr + McstOctetXmtOk); 10753401299aSJeff Kirsher readw (ioaddr + BcstFramesXmtdOk); 10763401299aSJeff Kirsher readl (ioaddr + McstFramesXmtdOk); 10773401299aSJeff Kirsher readw (ioaddr + BcstFramesRcvdOk); 10783401299aSJeff Kirsher readw (ioaddr + MacControlFramesRcvd); 10793401299aSJeff Kirsher readl (ioaddr + McstOctetXmtOk); 10803401299aSJeff Kirsher readl (ioaddr + BcstOctetXmtOk); 10813401299aSJeff Kirsher readl (ioaddr + McstFramesXmtdOk); 10823401299aSJeff Kirsher readl (ioaddr + FramesWDeferredXmt); 10833401299aSJeff Kirsher readw (ioaddr + BcstFramesXmtdOk); 10843401299aSJeff Kirsher readw (ioaddr + MacControlFramesXmtd); 10853401299aSJeff Kirsher readw (ioaddr + FramesWEXDeferal); 10863401299aSJeff Kirsher #ifdef MEM_MAPPING 10873401299aSJeff Kirsher for (i = 0x100; i <= 0x150; i += 4) 10883401299aSJeff Kirsher readl (ioaddr + i); 10893401299aSJeff Kirsher #endif 10903401299aSJeff Kirsher readw (ioaddr + TxJumboFrames); 10913401299aSJeff Kirsher readw (ioaddr + RxJumboFrames); 10923401299aSJeff Kirsher readw (ioaddr + TCPCheckSumErrors); 10933401299aSJeff Kirsher readw (ioaddr + UDPCheckSumErrors); 10943401299aSJeff Kirsher readw (ioaddr + IPCheckSumErrors); 10953401299aSJeff Kirsher return 0; 10963401299aSJeff Kirsher } 10973401299aSJeff Kirsher 10983401299aSJeff Kirsher 10993401299aSJeff Kirsher static int 11003401299aSJeff Kirsher change_mtu (struct net_device *dev, int new_mtu) 11013401299aSJeff Kirsher { 11023401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 11033401299aSJeff Kirsher int max = (np->jumbo) ? MAX_JUMBO : 1536; 11043401299aSJeff Kirsher 11053401299aSJeff Kirsher if ((new_mtu < 68) || (new_mtu > max)) { 11063401299aSJeff Kirsher return -EINVAL; 11073401299aSJeff Kirsher } 11083401299aSJeff Kirsher 11093401299aSJeff Kirsher dev->mtu = new_mtu; 11103401299aSJeff Kirsher 11113401299aSJeff Kirsher return 0; 11123401299aSJeff Kirsher } 11133401299aSJeff Kirsher 11143401299aSJeff Kirsher static void 11153401299aSJeff Kirsher set_multicast (struct net_device *dev) 11163401299aSJeff Kirsher { 11173401299aSJeff Kirsher long ioaddr = dev->base_addr; 11183401299aSJeff Kirsher u32 hash_table[2]; 11193401299aSJeff Kirsher u16 rx_mode = 0; 11203401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 11213401299aSJeff Kirsher 11223401299aSJeff Kirsher hash_table[0] = hash_table[1] = 0; 11233401299aSJeff Kirsher /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */ 11243401299aSJeff Kirsher hash_table[1] |= 0x02000000; 11253401299aSJeff Kirsher if (dev->flags & IFF_PROMISC) { 11263401299aSJeff Kirsher /* Receive all frames promiscuously. */ 11273401299aSJeff Kirsher rx_mode = ReceiveAllFrames; 11283401299aSJeff Kirsher } else if ((dev->flags & IFF_ALLMULTI) || 11293401299aSJeff Kirsher (netdev_mc_count(dev) > multicast_filter_limit)) { 11303401299aSJeff Kirsher /* Receive broadcast and multicast frames */ 11313401299aSJeff Kirsher rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast; 11323401299aSJeff Kirsher } else if (!netdev_mc_empty(dev)) { 11333401299aSJeff Kirsher struct netdev_hw_addr *ha; 11343401299aSJeff Kirsher /* Receive broadcast frames and multicast frames filtering 11353401299aSJeff Kirsher by Hashtable */ 11363401299aSJeff Kirsher rx_mode = 11373401299aSJeff Kirsher ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast; 11383401299aSJeff Kirsher netdev_for_each_mc_addr(ha, dev) { 11393401299aSJeff Kirsher int bit, index = 0; 11403401299aSJeff Kirsher int crc = ether_crc_le(ETH_ALEN, ha->addr); 11413401299aSJeff Kirsher /* The inverted high significant 6 bits of CRC are 11423401299aSJeff Kirsher used as an index to hashtable */ 11433401299aSJeff Kirsher for (bit = 0; bit < 6; bit++) 11443401299aSJeff Kirsher if (crc & (1 << (31 - bit))) 11453401299aSJeff Kirsher index |= (1 << bit); 11463401299aSJeff Kirsher hash_table[index / 32] |= (1 << (index % 32)); 11473401299aSJeff Kirsher } 11483401299aSJeff Kirsher } else { 11493401299aSJeff Kirsher rx_mode = ReceiveBroadcast | ReceiveUnicast; 11503401299aSJeff Kirsher } 11513401299aSJeff Kirsher if (np->vlan) { 11523401299aSJeff Kirsher /* ReceiveVLANMatch field in ReceiveMode */ 11533401299aSJeff Kirsher rx_mode |= ReceiveVLANMatch; 11543401299aSJeff Kirsher } 11553401299aSJeff Kirsher 11563401299aSJeff Kirsher writel (hash_table[0], ioaddr + HashTable0); 11573401299aSJeff Kirsher writel (hash_table[1], ioaddr + HashTable1); 11583401299aSJeff Kirsher writew (rx_mode, ioaddr + ReceiveMode); 11593401299aSJeff Kirsher } 11603401299aSJeff Kirsher 11613401299aSJeff Kirsher static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 11623401299aSJeff Kirsher { 11633401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 11643401299aSJeff Kirsher strcpy(info->driver, "dl2k"); 11653401299aSJeff Kirsher strcpy(info->version, DRV_VERSION); 11663401299aSJeff Kirsher strcpy(info->bus_info, pci_name(np->pdev)); 11673401299aSJeff Kirsher } 11683401299aSJeff Kirsher 11693401299aSJeff Kirsher static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 11703401299aSJeff Kirsher { 11713401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 11723401299aSJeff Kirsher if (np->phy_media) { 11733401299aSJeff Kirsher /* fiber device */ 11743401299aSJeff Kirsher cmd->supported = SUPPORTED_Autoneg | SUPPORTED_FIBRE; 11753401299aSJeff Kirsher cmd->advertising= ADVERTISED_Autoneg | ADVERTISED_FIBRE; 11763401299aSJeff Kirsher cmd->port = PORT_FIBRE; 11773401299aSJeff Kirsher cmd->transceiver = XCVR_INTERNAL; 11783401299aSJeff Kirsher } else { 11793401299aSJeff Kirsher /* copper device */ 11803401299aSJeff Kirsher cmd->supported = SUPPORTED_10baseT_Half | 11813401299aSJeff Kirsher SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half 11823401299aSJeff Kirsher | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | 11833401299aSJeff Kirsher SUPPORTED_Autoneg | SUPPORTED_MII; 11843401299aSJeff Kirsher cmd->advertising = ADVERTISED_10baseT_Half | 11853401299aSJeff Kirsher ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half | 11863401299aSJeff Kirsher ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full| 11873401299aSJeff Kirsher ADVERTISED_Autoneg | ADVERTISED_MII; 11883401299aSJeff Kirsher cmd->port = PORT_MII; 11893401299aSJeff Kirsher cmd->transceiver = XCVR_INTERNAL; 11903401299aSJeff Kirsher } 11913401299aSJeff Kirsher if ( np->link_status ) { 11923401299aSJeff Kirsher ethtool_cmd_speed_set(cmd, np->speed); 11933401299aSJeff Kirsher cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 11943401299aSJeff Kirsher } else { 11953401299aSJeff Kirsher ethtool_cmd_speed_set(cmd, -1); 11963401299aSJeff Kirsher cmd->duplex = -1; 11973401299aSJeff Kirsher } 11983401299aSJeff Kirsher if ( np->an_enable) 11993401299aSJeff Kirsher cmd->autoneg = AUTONEG_ENABLE; 12003401299aSJeff Kirsher else 12013401299aSJeff Kirsher cmd->autoneg = AUTONEG_DISABLE; 12023401299aSJeff Kirsher 12033401299aSJeff Kirsher cmd->phy_address = np->phy_addr; 12043401299aSJeff Kirsher return 0; 12053401299aSJeff Kirsher } 12063401299aSJeff Kirsher 12073401299aSJeff Kirsher static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 12083401299aSJeff Kirsher { 12093401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 12103401299aSJeff Kirsher netif_carrier_off(dev); 12113401299aSJeff Kirsher if (cmd->autoneg == AUTONEG_ENABLE) { 12123401299aSJeff Kirsher if (np->an_enable) 12133401299aSJeff Kirsher return 0; 12143401299aSJeff Kirsher else { 12153401299aSJeff Kirsher np->an_enable = 1; 12163401299aSJeff Kirsher mii_set_media(dev); 12173401299aSJeff Kirsher return 0; 12183401299aSJeff Kirsher } 12193401299aSJeff Kirsher } else { 12203401299aSJeff Kirsher np->an_enable = 0; 12213401299aSJeff Kirsher if (np->speed == 1000) { 12223401299aSJeff Kirsher ethtool_cmd_speed_set(cmd, SPEED_100); 12233401299aSJeff Kirsher cmd->duplex = DUPLEX_FULL; 12243401299aSJeff Kirsher printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n"); 12253401299aSJeff Kirsher } 12263401299aSJeff Kirsher switch (ethtool_cmd_speed(cmd)) { 12273401299aSJeff Kirsher case SPEED_10: 12283401299aSJeff Kirsher np->speed = 10; 12293401299aSJeff Kirsher np->full_duplex = (cmd->duplex == DUPLEX_FULL); 12303401299aSJeff Kirsher break; 12313401299aSJeff Kirsher case SPEED_100: 12323401299aSJeff Kirsher np->speed = 100; 12333401299aSJeff Kirsher np->full_duplex = (cmd->duplex == DUPLEX_FULL); 12343401299aSJeff Kirsher break; 12353401299aSJeff Kirsher case SPEED_1000: /* not supported */ 12363401299aSJeff Kirsher default: 12373401299aSJeff Kirsher return -EINVAL; 12383401299aSJeff Kirsher } 12393401299aSJeff Kirsher mii_set_media(dev); 12403401299aSJeff Kirsher } 12413401299aSJeff Kirsher return 0; 12423401299aSJeff Kirsher } 12433401299aSJeff Kirsher 12443401299aSJeff Kirsher static u32 rio_get_link(struct net_device *dev) 12453401299aSJeff Kirsher { 12463401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 12473401299aSJeff Kirsher return np->link_status; 12483401299aSJeff Kirsher } 12493401299aSJeff Kirsher 12503401299aSJeff Kirsher static const struct ethtool_ops ethtool_ops = { 12513401299aSJeff Kirsher .get_drvinfo = rio_get_drvinfo, 12523401299aSJeff Kirsher .get_settings = rio_get_settings, 12533401299aSJeff Kirsher .set_settings = rio_set_settings, 12543401299aSJeff Kirsher .get_link = rio_get_link, 12553401299aSJeff Kirsher }; 12563401299aSJeff Kirsher 12573401299aSJeff Kirsher static int 12583401299aSJeff Kirsher rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) 12593401299aSJeff Kirsher { 12603401299aSJeff Kirsher int phy_addr; 12613401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 12621bb57e94SJeff Mahoney struct mii_ioctl_data *miidata = if_mii(rq); 12633401299aSJeff Kirsher 12643401299aSJeff Kirsher phy_addr = np->phy_addr; 12653401299aSJeff Kirsher switch (cmd) { 12661bb57e94SJeff Mahoney case SIOCGMIIPHY: 12671bb57e94SJeff Mahoney miidata->phy_id = phy_addr; 12683401299aSJeff Kirsher break; 12691bb57e94SJeff Mahoney case SIOCGMIIREG: 12701bb57e94SJeff Mahoney miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num); 12713401299aSJeff Kirsher break; 12721bb57e94SJeff Mahoney case SIOCSMIIREG: 12731bb57e94SJeff Mahoney if (!capable(CAP_NET_ADMIN)) 12741bb57e94SJeff Mahoney return -EPERM; 12751bb57e94SJeff Mahoney mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in); 12763401299aSJeff Kirsher break; 12773401299aSJeff Kirsher default: 12783401299aSJeff Kirsher return -EOPNOTSUPP; 12793401299aSJeff Kirsher } 12803401299aSJeff Kirsher return 0; 12813401299aSJeff Kirsher } 12823401299aSJeff Kirsher 12833401299aSJeff Kirsher #define EEP_READ 0x0200 12843401299aSJeff Kirsher #define EEP_BUSY 0x8000 12853401299aSJeff Kirsher /* Read the EEPROM word */ 12863401299aSJeff Kirsher /* We use I/O instruction to read/write eeprom to avoid fail on some machines */ 12873401299aSJeff Kirsher static int 12883401299aSJeff Kirsher read_eeprom (long ioaddr, int eep_addr) 12893401299aSJeff Kirsher { 12903401299aSJeff Kirsher int i = 1000; 12913401299aSJeff Kirsher outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl); 12923401299aSJeff Kirsher while (i-- > 0) { 12933401299aSJeff Kirsher if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) { 12943401299aSJeff Kirsher return inw (ioaddr + EepromData); 12953401299aSJeff Kirsher } 12963401299aSJeff Kirsher } 12973401299aSJeff Kirsher return 0; 12983401299aSJeff Kirsher } 12993401299aSJeff Kirsher 13003401299aSJeff Kirsher enum phy_ctrl_bits { 13013401299aSJeff Kirsher MII_READ = 0x00, MII_CLK = 0x01, MII_DATA1 = 0x02, MII_WRITE = 0x04, 13023401299aSJeff Kirsher MII_DUPLEX = 0x08, 13033401299aSJeff Kirsher }; 13043401299aSJeff Kirsher 13053401299aSJeff Kirsher #define mii_delay() readb(ioaddr) 13063401299aSJeff Kirsher static void 13073401299aSJeff Kirsher mii_sendbit (struct net_device *dev, u32 data) 13083401299aSJeff Kirsher { 13093401299aSJeff Kirsher long ioaddr = dev->base_addr + PhyCtrl; 13103401299aSJeff Kirsher data = (data) ? MII_DATA1 : 0; 13113401299aSJeff Kirsher data |= MII_WRITE; 13123401299aSJeff Kirsher data |= (readb (ioaddr) & 0xf8) | MII_WRITE; 13133401299aSJeff Kirsher writeb (data, ioaddr); 13143401299aSJeff Kirsher mii_delay (); 13153401299aSJeff Kirsher writeb (data | MII_CLK, ioaddr); 13163401299aSJeff Kirsher mii_delay (); 13173401299aSJeff Kirsher } 13183401299aSJeff Kirsher 13193401299aSJeff Kirsher static int 13203401299aSJeff Kirsher mii_getbit (struct net_device *dev) 13213401299aSJeff Kirsher { 13223401299aSJeff Kirsher long ioaddr = dev->base_addr + PhyCtrl; 13233401299aSJeff Kirsher u8 data; 13243401299aSJeff Kirsher 13253401299aSJeff Kirsher data = (readb (ioaddr) & 0xf8) | MII_READ; 13263401299aSJeff Kirsher writeb (data, ioaddr); 13273401299aSJeff Kirsher mii_delay (); 13283401299aSJeff Kirsher writeb (data | MII_CLK, ioaddr); 13293401299aSJeff Kirsher mii_delay (); 13303401299aSJeff Kirsher return ((readb (ioaddr) >> 1) & 1); 13313401299aSJeff Kirsher } 13323401299aSJeff Kirsher 13333401299aSJeff Kirsher static void 13343401299aSJeff Kirsher mii_send_bits (struct net_device *dev, u32 data, int len) 13353401299aSJeff Kirsher { 13363401299aSJeff Kirsher int i; 13373401299aSJeff Kirsher for (i = len - 1; i >= 0; i--) { 13383401299aSJeff Kirsher mii_sendbit (dev, data & (1 << i)); 13393401299aSJeff Kirsher } 13403401299aSJeff Kirsher } 13413401299aSJeff Kirsher 13423401299aSJeff Kirsher static int 13433401299aSJeff Kirsher mii_read (struct net_device *dev, int phy_addr, int reg_num) 13443401299aSJeff Kirsher { 13453401299aSJeff Kirsher u32 cmd; 13463401299aSJeff Kirsher int i; 13473401299aSJeff Kirsher u32 retval = 0; 13483401299aSJeff Kirsher 13493401299aSJeff Kirsher /* Preamble */ 13503401299aSJeff Kirsher mii_send_bits (dev, 0xffffffff, 32); 13513401299aSJeff Kirsher /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */ 13523401299aSJeff Kirsher /* ST,OP = 0110'b for read operation */ 13533401299aSJeff Kirsher cmd = (0x06 << 10 | phy_addr << 5 | reg_num); 13543401299aSJeff Kirsher mii_send_bits (dev, cmd, 14); 13553401299aSJeff Kirsher /* Turnaround */ 13563401299aSJeff Kirsher if (mii_getbit (dev)) 13573401299aSJeff Kirsher goto err_out; 13583401299aSJeff Kirsher /* Read data */ 13593401299aSJeff Kirsher for (i = 0; i < 16; i++) { 13603401299aSJeff Kirsher retval |= mii_getbit (dev); 13613401299aSJeff Kirsher retval <<= 1; 13623401299aSJeff Kirsher } 13633401299aSJeff Kirsher /* End cycle */ 13643401299aSJeff Kirsher mii_getbit (dev); 13653401299aSJeff Kirsher return (retval >> 1) & 0xffff; 13663401299aSJeff Kirsher 13673401299aSJeff Kirsher err_out: 13683401299aSJeff Kirsher return 0; 13693401299aSJeff Kirsher } 13703401299aSJeff Kirsher static int 13713401299aSJeff Kirsher mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data) 13723401299aSJeff Kirsher { 13733401299aSJeff Kirsher u32 cmd; 13743401299aSJeff Kirsher 13753401299aSJeff Kirsher /* Preamble */ 13763401299aSJeff Kirsher mii_send_bits (dev, 0xffffffff, 32); 13773401299aSJeff Kirsher /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */ 13783401299aSJeff Kirsher /* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */ 13793401299aSJeff Kirsher cmd = (0x5002 << 16) | (phy_addr << 23) | (reg_num << 18) | data; 13803401299aSJeff Kirsher mii_send_bits (dev, cmd, 32); 13813401299aSJeff Kirsher /* End cycle */ 13823401299aSJeff Kirsher mii_getbit (dev); 13833401299aSJeff Kirsher return 0; 13843401299aSJeff Kirsher } 13853401299aSJeff Kirsher static int 13863401299aSJeff Kirsher mii_wait_link (struct net_device *dev, int wait) 13873401299aSJeff Kirsher { 13883401299aSJeff Kirsher __u16 bmsr; 13893401299aSJeff Kirsher int phy_addr; 13903401299aSJeff Kirsher struct netdev_private *np; 13913401299aSJeff Kirsher 13923401299aSJeff Kirsher np = netdev_priv(dev); 13933401299aSJeff Kirsher phy_addr = np->phy_addr; 13943401299aSJeff Kirsher 13953401299aSJeff Kirsher do { 13963401299aSJeff Kirsher bmsr = mii_read (dev, phy_addr, MII_BMSR); 139778f6a6bdSFrancois Romieu if (bmsr & BMSR_LSTATUS) 13983401299aSJeff Kirsher return 0; 13993401299aSJeff Kirsher mdelay (1); 14003401299aSJeff Kirsher } while (--wait > 0); 14013401299aSJeff Kirsher return -1; 14023401299aSJeff Kirsher } 14033401299aSJeff Kirsher static int 14043401299aSJeff Kirsher mii_get_media (struct net_device *dev) 14053401299aSJeff Kirsher { 14063401299aSJeff Kirsher __u16 negotiate; 14073401299aSJeff Kirsher __u16 bmsr; 14083401299aSJeff Kirsher __u16 mscr; 14093401299aSJeff Kirsher __u16 mssr; 14103401299aSJeff Kirsher int phy_addr; 14113401299aSJeff Kirsher struct netdev_private *np; 14123401299aSJeff Kirsher 14133401299aSJeff Kirsher np = netdev_priv(dev); 14143401299aSJeff Kirsher phy_addr = np->phy_addr; 14153401299aSJeff Kirsher 14163401299aSJeff Kirsher bmsr = mii_read (dev, phy_addr, MII_BMSR); 14173401299aSJeff Kirsher if (np->an_enable) { 141878f6a6bdSFrancois Romieu if (!(bmsr & BMSR_ANEGCOMPLETE)) { 14193401299aSJeff Kirsher /* Auto-Negotiation not completed */ 14203401299aSJeff Kirsher return -1; 14213401299aSJeff Kirsher } 142278f6a6bdSFrancois Romieu negotiate = mii_read (dev, phy_addr, MII_ADVERTISE) & 142378f6a6bdSFrancois Romieu mii_read (dev, phy_addr, MII_LPA); 142478f6a6bdSFrancois Romieu mscr = mii_read (dev, phy_addr, MII_CTRL1000); 142578f6a6bdSFrancois Romieu mssr = mii_read (dev, phy_addr, MII_STAT1000); 142678f6a6bdSFrancois Romieu if (mscr & ADVERTISE_1000FULL && mssr & LPA_1000FULL) { 14273401299aSJeff Kirsher np->speed = 1000; 14283401299aSJeff Kirsher np->full_duplex = 1; 14293401299aSJeff Kirsher printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); 143078f6a6bdSFrancois Romieu } else if (mscr & ADVERTISE_1000HALF && mssr & LPA_1000HALF) { 14313401299aSJeff Kirsher np->speed = 1000; 14323401299aSJeff Kirsher np->full_duplex = 0; 14333401299aSJeff Kirsher printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n"); 143478f6a6bdSFrancois Romieu } else if (negotiate & ADVERTISE_100FULL) { 14353401299aSJeff Kirsher np->speed = 100; 14363401299aSJeff Kirsher np->full_duplex = 1; 14373401299aSJeff Kirsher printk (KERN_INFO "Auto 100 Mbps, Full duplex\n"); 143878f6a6bdSFrancois Romieu } else if (negotiate & ADVERTISE_100HALF) { 14393401299aSJeff Kirsher np->speed = 100; 14403401299aSJeff Kirsher np->full_duplex = 0; 14413401299aSJeff Kirsher printk (KERN_INFO "Auto 100 Mbps, Half duplex\n"); 144278f6a6bdSFrancois Romieu } else if (negotiate & ADVERTISE_10FULL) { 14433401299aSJeff Kirsher np->speed = 10; 14443401299aSJeff Kirsher np->full_duplex = 1; 14453401299aSJeff Kirsher printk (KERN_INFO "Auto 10 Mbps, Full duplex\n"); 144678f6a6bdSFrancois Romieu } else if (negotiate & ADVERTISE_10HALF) { 14473401299aSJeff Kirsher np->speed = 10; 14483401299aSJeff Kirsher np->full_duplex = 0; 14493401299aSJeff Kirsher printk (KERN_INFO "Auto 10 Mbps, Half duplex\n"); 14503401299aSJeff Kirsher } 145178f6a6bdSFrancois Romieu if (negotiate & ADVERTISE_PAUSE_CAP) { 14523401299aSJeff Kirsher np->tx_flow &= 1; 14533401299aSJeff Kirsher np->rx_flow &= 1; 145478f6a6bdSFrancois Romieu } else if (negotiate & ADVERTISE_PAUSE_ASYM) { 14553401299aSJeff Kirsher np->tx_flow = 0; 14563401299aSJeff Kirsher np->rx_flow &= 1; 14573401299aSJeff Kirsher } 14583401299aSJeff Kirsher /* else tx_flow, rx_flow = user select */ 14593401299aSJeff Kirsher } else { 14603401299aSJeff Kirsher __u16 bmcr = mii_read (dev, phy_addr, MII_BMCR); 146178f6a6bdSFrancois Romieu switch (bmcr & (BMCR_SPEED100 | BMCR_SPEED1000)) { 146278f6a6bdSFrancois Romieu case BMCR_SPEED1000: 14633401299aSJeff Kirsher printk (KERN_INFO "Operating at 1000 Mbps, "); 14643401299aSJeff Kirsher break; 146578f6a6bdSFrancois Romieu case BMCR_SPEED100: 14663401299aSJeff Kirsher printk (KERN_INFO "Operating at 100 Mbps, "); 14673401299aSJeff Kirsher break; 14683401299aSJeff Kirsher case 0: 14693401299aSJeff Kirsher printk (KERN_INFO "Operating at 10 Mbps, "); 14703401299aSJeff Kirsher } 147178f6a6bdSFrancois Romieu if (bmcr & BMCR_FULLDPLX) { 14723401299aSJeff Kirsher printk (KERN_CONT "Full duplex\n"); 14733401299aSJeff Kirsher } else { 14743401299aSJeff Kirsher printk (KERN_CONT "Half duplex\n"); 14753401299aSJeff Kirsher } 14763401299aSJeff Kirsher } 14773401299aSJeff Kirsher if (np->tx_flow) 14783401299aSJeff Kirsher printk(KERN_INFO "Enable Tx Flow Control\n"); 14793401299aSJeff Kirsher else 14803401299aSJeff Kirsher printk(KERN_INFO "Disable Tx Flow Control\n"); 14813401299aSJeff Kirsher if (np->rx_flow) 14823401299aSJeff Kirsher printk(KERN_INFO "Enable Rx Flow Control\n"); 14833401299aSJeff Kirsher else 14843401299aSJeff Kirsher printk(KERN_INFO "Disable Rx Flow Control\n"); 14853401299aSJeff Kirsher 14863401299aSJeff Kirsher return 0; 14873401299aSJeff Kirsher } 14883401299aSJeff Kirsher 14893401299aSJeff Kirsher static int 14903401299aSJeff Kirsher mii_set_media (struct net_device *dev) 14913401299aSJeff Kirsher { 14923401299aSJeff Kirsher __u16 pscr; 14933401299aSJeff Kirsher __u16 bmcr; 14943401299aSJeff Kirsher __u16 bmsr; 14953401299aSJeff Kirsher __u16 anar; 14963401299aSJeff Kirsher int phy_addr; 14973401299aSJeff Kirsher struct netdev_private *np; 14983401299aSJeff Kirsher np = netdev_priv(dev); 14993401299aSJeff Kirsher phy_addr = np->phy_addr; 15003401299aSJeff Kirsher 15013401299aSJeff Kirsher /* Does user set speed? */ 15023401299aSJeff Kirsher if (np->an_enable) { 15033401299aSJeff Kirsher /* Advertise capabilities */ 15043401299aSJeff Kirsher bmsr = mii_read (dev, phy_addr, MII_BMSR); 150578f6a6bdSFrancois Romieu anar = mii_read (dev, phy_addr, MII_ADVERTISE) & 150678f6a6bdSFrancois Romieu ~(ADVERTISE_100FULL | ADVERTISE_10FULL | 150778f6a6bdSFrancois Romieu ADVERTISE_100HALF | ADVERTISE_10HALF | 150878f6a6bdSFrancois Romieu ADVERTISE_100BASE4); 150978f6a6bdSFrancois Romieu if (bmsr & BMSR_100FULL) 151078f6a6bdSFrancois Romieu anar |= ADVERTISE_100FULL; 151178f6a6bdSFrancois Romieu if (bmsr & BMSR_100HALF) 151278f6a6bdSFrancois Romieu anar |= ADVERTISE_100HALF; 151378f6a6bdSFrancois Romieu if (bmsr & BMSR_100BASE4) 151478f6a6bdSFrancois Romieu anar |= ADVERTISE_100BASE4; 151578f6a6bdSFrancois Romieu if (bmsr & BMSR_10FULL) 151678f6a6bdSFrancois Romieu anar |= ADVERTISE_10FULL; 151778f6a6bdSFrancois Romieu if (bmsr & BMSR_10HALF) 151878f6a6bdSFrancois Romieu anar |= ADVERTISE_10HALF; 151978f6a6bdSFrancois Romieu anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; 152078f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_ADVERTISE, anar); 15213401299aSJeff Kirsher 15223401299aSJeff Kirsher /* Enable Auto crossover */ 15233401299aSJeff Kirsher pscr = mii_read (dev, phy_addr, MII_PHY_SCR); 15243401299aSJeff Kirsher pscr |= 3 << 5; /* 11'b */ 15253401299aSJeff Kirsher mii_write (dev, phy_addr, MII_PHY_SCR, pscr); 15263401299aSJeff Kirsher 15273401299aSJeff Kirsher /* Soft reset PHY */ 152878f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_BMCR, BMCR_RESET); 152978f6a6bdSFrancois Romieu bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET; 15303401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 15313401299aSJeff Kirsher mdelay(1); 15323401299aSJeff Kirsher } else { 15333401299aSJeff Kirsher /* Force speed setting */ 15343401299aSJeff Kirsher /* 1) Disable Auto crossover */ 15353401299aSJeff Kirsher pscr = mii_read (dev, phy_addr, MII_PHY_SCR); 15363401299aSJeff Kirsher pscr &= ~(3 << 5); 15373401299aSJeff Kirsher mii_write (dev, phy_addr, MII_PHY_SCR, pscr); 15383401299aSJeff Kirsher 15393401299aSJeff Kirsher /* 2) PHY Reset */ 15403401299aSJeff Kirsher bmcr = mii_read (dev, phy_addr, MII_BMCR); 154178f6a6bdSFrancois Romieu bmcr |= BMCR_RESET; 15423401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 15433401299aSJeff Kirsher 15443401299aSJeff Kirsher /* 3) Power Down */ 15453401299aSJeff Kirsher bmcr = 0x1940; /* must be 0x1940 */ 15463401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 15473401299aSJeff Kirsher mdelay (100); /* wait a certain time */ 15483401299aSJeff Kirsher 15493401299aSJeff Kirsher /* 4) Advertise nothing */ 155078f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_ADVERTISE, 0); 15513401299aSJeff Kirsher 15523401299aSJeff Kirsher /* 5) Set media and Power Up */ 155378f6a6bdSFrancois Romieu bmcr = BMCR_PDOWN; 15543401299aSJeff Kirsher if (np->speed == 100) { 155578f6a6bdSFrancois Romieu bmcr |= BMCR_SPEED100; 15563401299aSJeff Kirsher printk (KERN_INFO "Manual 100 Mbps, "); 15573401299aSJeff Kirsher } else if (np->speed == 10) { 15583401299aSJeff Kirsher printk (KERN_INFO "Manual 10 Mbps, "); 15593401299aSJeff Kirsher } 15603401299aSJeff Kirsher if (np->full_duplex) { 156178f6a6bdSFrancois Romieu bmcr |= BMCR_FULLDPLX; 15623401299aSJeff Kirsher printk (KERN_CONT "Full duplex\n"); 15633401299aSJeff Kirsher } else { 15643401299aSJeff Kirsher printk (KERN_CONT "Half duplex\n"); 15653401299aSJeff Kirsher } 15663401299aSJeff Kirsher #if 0 15673401299aSJeff Kirsher /* Set 1000BaseT Master/Slave setting */ 156878f6a6bdSFrancois Romieu mscr = mii_read (dev, phy_addr, MII_CTRL1000); 15693401299aSJeff Kirsher mscr |= MII_MSCR_CFG_ENABLE; 15703401299aSJeff Kirsher mscr &= ~MII_MSCR_CFG_VALUE = 0; 15713401299aSJeff Kirsher #endif 15723401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 15733401299aSJeff Kirsher mdelay(10); 15743401299aSJeff Kirsher } 15753401299aSJeff Kirsher return 0; 15763401299aSJeff Kirsher } 15773401299aSJeff Kirsher 15783401299aSJeff Kirsher static int 15793401299aSJeff Kirsher mii_get_media_pcs (struct net_device *dev) 15803401299aSJeff Kirsher { 15813401299aSJeff Kirsher __u16 negotiate; 15823401299aSJeff Kirsher __u16 bmsr; 15833401299aSJeff Kirsher int phy_addr; 15843401299aSJeff Kirsher struct netdev_private *np; 15853401299aSJeff Kirsher 15863401299aSJeff Kirsher np = netdev_priv(dev); 15873401299aSJeff Kirsher phy_addr = np->phy_addr; 15883401299aSJeff Kirsher 15893401299aSJeff Kirsher bmsr = mii_read (dev, phy_addr, PCS_BMSR); 15903401299aSJeff Kirsher if (np->an_enable) { 159178f6a6bdSFrancois Romieu if (!(bmsr & BMSR_ANEGCOMPLETE)) { 15923401299aSJeff Kirsher /* Auto-Negotiation not completed */ 15933401299aSJeff Kirsher return -1; 15943401299aSJeff Kirsher } 15953401299aSJeff Kirsher negotiate = mii_read (dev, phy_addr, PCS_ANAR) & 15963401299aSJeff Kirsher mii_read (dev, phy_addr, PCS_ANLPAR); 15973401299aSJeff Kirsher np->speed = 1000; 15983401299aSJeff Kirsher if (negotiate & PCS_ANAR_FULL_DUPLEX) { 15993401299aSJeff Kirsher printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); 16003401299aSJeff Kirsher np->full_duplex = 1; 16013401299aSJeff Kirsher } else { 16023401299aSJeff Kirsher printk (KERN_INFO "Auto 1000 Mbps, half duplex\n"); 16033401299aSJeff Kirsher np->full_duplex = 0; 16043401299aSJeff Kirsher } 16053401299aSJeff Kirsher if (negotiate & PCS_ANAR_PAUSE) { 16063401299aSJeff Kirsher np->tx_flow &= 1; 16073401299aSJeff Kirsher np->rx_flow &= 1; 16083401299aSJeff Kirsher } else if (negotiate & PCS_ANAR_ASYMMETRIC) { 16093401299aSJeff Kirsher np->tx_flow = 0; 16103401299aSJeff Kirsher np->rx_flow &= 1; 16113401299aSJeff Kirsher } 16123401299aSJeff Kirsher /* else tx_flow, rx_flow = user select */ 16133401299aSJeff Kirsher } else { 16143401299aSJeff Kirsher __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); 16153401299aSJeff Kirsher printk (KERN_INFO "Operating at 1000 Mbps, "); 161678f6a6bdSFrancois Romieu if (bmcr & BMCR_FULLDPLX) { 16173401299aSJeff Kirsher printk (KERN_CONT "Full duplex\n"); 16183401299aSJeff Kirsher } else { 16193401299aSJeff Kirsher printk (KERN_CONT "Half duplex\n"); 16203401299aSJeff Kirsher } 16213401299aSJeff Kirsher } 16223401299aSJeff Kirsher if (np->tx_flow) 16233401299aSJeff Kirsher printk(KERN_INFO "Enable Tx Flow Control\n"); 16243401299aSJeff Kirsher else 16253401299aSJeff Kirsher printk(KERN_INFO "Disable Tx Flow Control\n"); 16263401299aSJeff Kirsher if (np->rx_flow) 16273401299aSJeff Kirsher printk(KERN_INFO "Enable Rx Flow Control\n"); 16283401299aSJeff Kirsher else 16293401299aSJeff Kirsher printk(KERN_INFO "Disable Rx Flow Control\n"); 16303401299aSJeff Kirsher 16313401299aSJeff Kirsher return 0; 16323401299aSJeff Kirsher } 16333401299aSJeff Kirsher 16343401299aSJeff Kirsher static int 16353401299aSJeff Kirsher mii_set_media_pcs (struct net_device *dev) 16363401299aSJeff Kirsher { 16373401299aSJeff Kirsher __u16 bmcr; 16383401299aSJeff Kirsher __u16 esr; 16393401299aSJeff Kirsher __u16 anar; 16403401299aSJeff Kirsher int phy_addr; 16413401299aSJeff Kirsher struct netdev_private *np; 16423401299aSJeff Kirsher np = netdev_priv(dev); 16433401299aSJeff Kirsher phy_addr = np->phy_addr; 16443401299aSJeff Kirsher 16453401299aSJeff Kirsher /* Auto-Negotiation? */ 16463401299aSJeff Kirsher if (np->an_enable) { 16473401299aSJeff Kirsher /* Advertise capabilities */ 16483401299aSJeff Kirsher esr = mii_read (dev, phy_addr, PCS_ESR); 164978f6a6bdSFrancois Romieu anar = mii_read (dev, phy_addr, MII_ADVERTISE) & 16503401299aSJeff Kirsher ~PCS_ANAR_HALF_DUPLEX & 16513401299aSJeff Kirsher ~PCS_ANAR_FULL_DUPLEX; 16523401299aSJeff Kirsher if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD)) 16533401299aSJeff Kirsher anar |= PCS_ANAR_HALF_DUPLEX; 16543401299aSJeff Kirsher if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD)) 16553401299aSJeff Kirsher anar |= PCS_ANAR_FULL_DUPLEX; 16563401299aSJeff Kirsher anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC; 165778f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_ADVERTISE, anar); 16583401299aSJeff Kirsher 16593401299aSJeff Kirsher /* Soft reset PHY */ 166078f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_BMCR, BMCR_RESET); 166178f6a6bdSFrancois Romieu bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET; 16623401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 16633401299aSJeff Kirsher mdelay(1); 16643401299aSJeff Kirsher } else { 16653401299aSJeff Kirsher /* Force speed setting */ 16663401299aSJeff Kirsher /* PHY Reset */ 166778f6a6bdSFrancois Romieu bmcr = BMCR_RESET; 16683401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 16693401299aSJeff Kirsher mdelay(10); 16703401299aSJeff Kirsher if (np->full_duplex) { 167178f6a6bdSFrancois Romieu bmcr = BMCR_FULLDPLX; 16723401299aSJeff Kirsher printk (KERN_INFO "Manual full duplex\n"); 16733401299aSJeff Kirsher } else { 16743401299aSJeff Kirsher bmcr = 0; 16753401299aSJeff Kirsher printk (KERN_INFO "Manual half duplex\n"); 16763401299aSJeff Kirsher } 16773401299aSJeff Kirsher mii_write (dev, phy_addr, MII_BMCR, bmcr); 16783401299aSJeff Kirsher mdelay(10); 16793401299aSJeff Kirsher 16803401299aSJeff Kirsher /* Advertise nothing */ 168178f6a6bdSFrancois Romieu mii_write (dev, phy_addr, MII_ADVERTISE, 0); 16823401299aSJeff Kirsher } 16833401299aSJeff Kirsher return 0; 16843401299aSJeff Kirsher } 16853401299aSJeff Kirsher 16863401299aSJeff Kirsher 16873401299aSJeff Kirsher static int 16883401299aSJeff Kirsher rio_close (struct net_device *dev) 16893401299aSJeff Kirsher { 16903401299aSJeff Kirsher long ioaddr = dev->base_addr; 16913401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 16923401299aSJeff Kirsher struct sk_buff *skb; 16933401299aSJeff Kirsher int i; 16943401299aSJeff Kirsher 16953401299aSJeff Kirsher netif_stop_queue (dev); 16963401299aSJeff Kirsher 16973401299aSJeff Kirsher /* Disable interrupts */ 16983401299aSJeff Kirsher writew (0, ioaddr + IntEnable); 16993401299aSJeff Kirsher 17003401299aSJeff Kirsher /* Stop Tx and Rx logics */ 17013401299aSJeff Kirsher writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl); 17023401299aSJeff Kirsher 17033401299aSJeff Kirsher free_irq (dev->irq, dev); 17043401299aSJeff Kirsher del_timer_sync (&np->timer); 17053401299aSJeff Kirsher 17063401299aSJeff Kirsher /* Free all the skbuffs in the queue. */ 17073401299aSJeff Kirsher for (i = 0; i < RX_RING_SIZE; i++) { 17083401299aSJeff Kirsher skb = np->rx_skbuff[i]; 17093401299aSJeff Kirsher if (skb) { 17103401299aSJeff Kirsher pci_unmap_single(np->pdev, 17113401299aSJeff Kirsher desc_to_dma(&np->rx_ring[i]), 17123401299aSJeff Kirsher skb->len, PCI_DMA_FROMDEVICE); 17133401299aSJeff Kirsher dev_kfree_skb (skb); 17143401299aSJeff Kirsher np->rx_skbuff[i] = NULL; 17153401299aSJeff Kirsher } 17163401299aSJeff Kirsher np->rx_ring[i].status = 0; 17173401299aSJeff Kirsher np->rx_ring[i].fraginfo = 0; 17183401299aSJeff Kirsher } 17193401299aSJeff Kirsher for (i = 0; i < TX_RING_SIZE; i++) { 17203401299aSJeff Kirsher skb = np->tx_skbuff[i]; 17213401299aSJeff Kirsher if (skb) { 17223401299aSJeff Kirsher pci_unmap_single(np->pdev, 17233401299aSJeff Kirsher desc_to_dma(&np->tx_ring[i]), 17243401299aSJeff Kirsher skb->len, PCI_DMA_TODEVICE); 17253401299aSJeff Kirsher dev_kfree_skb (skb); 17263401299aSJeff Kirsher np->tx_skbuff[i] = NULL; 17273401299aSJeff Kirsher } 17283401299aSJeff Kirsher } 17293401299aSJeff Kirsher 17303401299aSJeff Kirsher return 0; 17313401299aSJeff Kirsher } 17323401299aSJeff Kirsher 17333401299aSJeff Kirsher static void __devexit 17343401299aSJeff Kirsher rio_remove1 (struct pci_dev *pdev) 17353401299aSJeff Kirsher { 17363401299aSJeff Kirsher struct net_device *dev = pci_get_drvdata (pdev); 17373401299aSJeff Kirsher 17383401299aSJeff Kirsher if (dev) { 17393401299aSJeff Kirsher struct netdev_private *np = netdev_priv(dev); 17403401299aSJeff Kirsher 17413401299aSJeff Kirsher unregister_netdev (dev); 17423401299aSJeff Kirsher pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, 17433401299aSJeff Kirsher np->rx_ring_dma); 17443401299aSJeff Kirsher pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, 17453401299aSJeff Kirsher np->tx_ring_dma); 17463401299aSJeff Kirsher #ifdef MEM_MAPPING 17473401299aSJeff Kirsher iounmap ((char *) (dev->base_addr)); 17483401299aSJeff Kirsher #endif 17493401299aSJeff Kirsher free_netdev (dev); 17503401299aSJeff Kirsher pci_release_regions (pdev); 17513401299aSJeff Kirsher pci_disable_device (pdev); 17523401299aSJeff Kirsher } 17533401299aSJeff Kirsher pci_set_drvdata (pdev, NULL); 17543401299aSJeff Kirsher } 17553401299aSJeff Kirsher 17563401299aSJeff Kirsher static struct pci_driver rio_driver = { 17573401299aSJeff Kirsher .name = "dl2k", 17583401299aSJeff Kirsher .id_table = rio_pci_tbl, 17593401299aSJeff Kirsher .probe = rio_probe1, 17603401299aSJeff Kirsher .remove = __devexit_p(rio_remove1), 17613401299aSJeff Kirsher }; 17623401299aSJeff Kirsher 17633401299aSJeff Kirsher static int __init 17643401299aSJeff Kirsher rio_init (void) 17653401299aSJeff Kirsher { 17663401299aSJeff Kirsher return pci_register_driver(&rio_driver); 17673401299aSJeff Kirsher } 17683401299aSJeff Kirsher 17693401299aSJeff Kirsher static void __exit 17703401299aSJeff Kirsher rio_exit (void) 17713401299aSJeff Kirsher { 17723401299aSJeff Kirsher pci_unregister_driver (&rio_driver); 17733401299aSJeff Kirsher } 17743401299aSJeff Kirsher 17753401299aSJeff Kirsher module_init (rio_init); 17763401299aSJeff Kirsher module_exit (rio_exit); 17773401299aSJeff Kirsher 17783401299aSJeff Kirsher /* 17793401299aSJeff Kirsher 17803401299aSJeff Kirsher Compile command: 17813401299aSJeff Kirsher 17823401299aSJeff Kirsher gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c 17833401299aSJeff Kirsher 17843401299aSJeff Kirsher Read Documentation/networking/dl2k.txt for details. 17853401299aSJeff Kirsher 17863401299aSJeff Kirsher */ 17873401299aSJeff Kirsher 1788