Annotation of Gnu-Mach/linux/src/drivers/net/sis900.c, revision 1.1

1.1     ! root        1: /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
        !             2:    Copyright 1999 Silicon Integrated System Corporation
        !             3:    Revision:   1.06.11 Apr. 30 2002
        !             4: 
        !             5:    Modified from the driver which is originally written by Donald Becker.
        !             6: 
        !             7:    This software may be used and distributed according to the terms
        !             8:    of the GNU Public License (GPL), incorporated herein by reference.
        !             9:    Drivers based on this skeleton fall under the GPL and must retain
        !            10:    the authorship (implicit copyright) notice.
        !            11: 
        !            12:    References:
        !            13:    SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
        !            14:    preliminary Rev. 1.0 Jan. 14, 1998
        !            15:    SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
        !            16:    preliminary Rev. 1.0 Nov. 10, 1998
        !            17:    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
        !            18:    preliminary Rev. 1.0 Jan. 18, 1998
        !            19:    http://www.sis.com.tw/support/databook.htm
        !            20: 
        !            21:    Rev 1.06.11 Apr. 25 2002 Mufasa Yang ([email protected]) added SiS962 support
        !            22:    Rev 1.06.10 Dec. 18 2001 Hui-Fen Hsu workaround for EDB & RTL8201 PHY
        !            23:    Rev 1.06.09 Sep. 28 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
        !            24:    Rev 1.06.08 Mar.  2 2001 Hui-Fen Hsu ([email protected]) some bug fix & 635M/B support
        !            25:    Rev 1.06.07 Jan.  8 2001 Lei-Chun Chang added RTL8201 PHY support
        !            26:    Rev 1.06.06 Sep.  6 2000 Lei-Chun Chang added ICS1893 PHY support
        !            27:    Rev 1.06.05 Aug. 22 2000 Lei-Chun Chang ([email protected]) modified 630E equalier workaroung rule
        !            28:    Rev 1.06.03 Dec. 23 1999 Ollie Lho Third release
        !            29:    Rev 1.06.02 Nov. 23 1999 Ollie Lho bug in mac probing fixed
        !            30:    Rev 1.06.01 Nov. 16 1999 Ollie Lho CRC calculation provide by Joseph Zbiciak ([email protected])
        !            31:    Rev 1.06 Nov. 4 1999 Ollie Lho ([email protected]) Second release
        !            32:    Rev 1.05.05 Oct. 29 1999 Ollie Lho ([email protected]) Single buffer Tx/Rx
        !            33:    Chin-Shan Li ([email protected]) Added AMD Am79c901 HomePNA PHY support
        !            34:    Rev 1.05 Aug. 7 1999 Jim Huang ([email protected]) Initial release
        !            35: */
        !            36: 
        !            37: #include <linux/module.h>
        !            38: #include <linux/version.h>
        !            39: #include <linux/kernel.h>
        !            40: #include <linux/sched.h>
        !            41: #include <linux/string.h>
        !            42: #include <linux/timer.h>
        !            43: #include <linux/errno.h>
        !            44: #include <linux/ioport.h>
        !            45: #include <linux/malloc.h>
        !            46: #include <linux/interrupt.h>
        !            47: #include <linux/pci.h>
        !            48: #include <linux/netdevice.h>
        !            49: #include <linux/bios32.h>
        !            50: #include <linux/compatmac.h>
        !            51: 
        !            52: #include <linux/etherdevice.h>
        !            53: #include <linux/skbuff.h>
        !            54: #include <asm/processor.h>     /* Processor type for cache alignment. */
        !            55: #include <asm/bitops.h>
        !            56: #include <asm/io.h>
        !            57: #include <linux/delay.h>
        !            58: #include <asm/types.h>
        !            59: #include "sis900.h"
        !            60: 
        !            61: 
        !            62: #if LINUX_VERSION_CODE < 0x20159
        !            63: #define dev_free_skb(skb) dev_kfree_skb (skb, FREE_WRITE);
        !            64: #else  /* Grrr, incompatible changes should change the name. */
        !            65: #define dev_free_skb(skb) dev_kfree_skb(skb);
        !            66: #endif
        !            67: 
        !            68: static const char *version =
        !            69: "sis900.c: modified v1.06.11  4/30/2002";
        !            70: 
        !            71: static int max_interrupt_work = 20;
        !            72: static int multicast_filter_limit = 128;
        !            73: 
        !            74: #define sis900_debug debug
        !            75: static int sis900_debug = 0;
        !            76: 
        !            77: /* Time in jiffies before concluding the transmitter is hung. */
        !            78: #define TX_TIMEOUT  (4*HZ)
        !            79: 
        !            80: enum pci_flags_bit {
        !            81:   PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
        !            82:   PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
        !            83: };
        !            84: 
        !            85: struct mac_chip_info {
        !            86:   const char *name;
        !            87:   u16  vendor_id, device_id, flags;
        !            88:   int  io_size;
        !            89:   struct device *(*probe) (struct mac_chip_info *mac, long ioaddr, int irq,
        !            90:                           int pci_index,  unsigned char pci_device_fn, unsigned char pci_bus, struct device * net_dev);
        !            91: };
        !            92: static struct device * sis900_mac_probe (struct mac_chip_info * mac, long ioaddr, int irq,
        !            93:                                         int pci_index,  unsigned char pci_device_fn,
        !            94:                                         unsigned char pci_bus, struct device * net_dev);
        !            95: static struct mac_chip_info  mac_chip_table[] = {
        !            96:   { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900,
        !            97:     PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe},
        !            98:   { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016,
        !            99:     PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe},
        !           100:   {0,},                                               /* 0 terminatted list. */
        !           101: };
        !           102: 
        !           103: static void sis900_read_mode(struct device *net_dev, int *speed, int *duplex);
        !           104: 
        !           105: static struct mii_chip_info {
        !           106:   const char * name;
        !           107:   u16 phy_id0;
        !           108:   u16 phy_id1;
        !           109:   u8  phy_types;
        !           110: #define        HOME    0x0001
        !           111: #define LAN    0x0002
        !           112: #define MIX    0x0003
        !           113: } mii_chip_table[] = {
        !           114:   { "SiS 900 Internal MII PHY",                0x001d, 0x8000, LAN },
        !           115:   { "SiS 7014 Physical Layer Solution",        0x0016, 0xf830, LAN },
        !           116:   { "AMD 79C901 10BASE-T PHY",                 0x0000, 0x6B70, LAN },
        !           117:   { "AMD 79C901 HomePNA PHY",          0x0000, 0x6B90, HOME},
        !           118:   { "ICS LAN PHY",                     0x0015, 0xF440, LAN },
        !           119:   { "NS  83851 PHY",                   0x2000, 0x5C20, MIX },
        !           120:   { "Realtek RTL8201 PHY",             0x0000, 0x8200, LAN },
        !           121:   {0,},
        !           122: };
        !           123: 
        !           124: struct mii_phy {
        !           125:   struct mii_phy * next;
        !           126:   int phy_addr;
        !           127:   u16 phy_id0;
        !           128:   u16 phy_id1;
        !           129:   u16 status;
        !           130:   u8  phy_types;
        !           131: };
        !           132: 
        !           133: typedef struct _BufferDesc {
        !           134:   u32  link;
        !           135:   u32  cmdsts;
        !           136:   u32  bufptr;
        !           137: } BufferDesc;
        !           138: 
        !           139: struct sis900_private {
        !           140:   struct device *next_module;
        !           141:   struct enet_statistics stats;
        !           142: 
        !           143:   /*   struct pci_dev * pci_dev;*/
        !           144:   unsigned char pci_bus;
        !           145:   unsigned char pci_device_fn;
        !           146:   int pci_index;
        !           147: 
        !           148:   struct mac_chip_info * mac;
        !           149:   struct mii_phy * mii;
        !           150:   struct mii_phy * first_mii; /* record the first mii structure */
        !           151:   unsigned int cur_phy;
        !           152: 
        !           153:   struct timer_list timer; /* Link status detection timer. */
        !           154:   u8     autong_complete; /* 1: auto-negotiate complete  */
        !           155: 
        !           156:   unsigned int cur_rx, dirty_rx;       /* producer/comsumer pointers for Tx/Rx ring */
        !           157:   unsigned int cur_tx, dirty_tx;
        !           158: 
        !           159:   /* The saved address of a sent/receive-in-place packet buffer */
        !           160:   struct sk_buff *tx_skbuff[NUM_TX_DESC];
        !           161:   struct sk_buff *rx_skbuff[NUM_RX_DESC];
        !           162:   BufferDesc tx_ring[NUM_TX_DESC];
        !           163:   BufferDesc rx_ring[NUM_RX_DESC];
        !           164: 
        !           165:   unsigned int tx_full;                /* The Tx queue is full.    */
        !           166:   int LinkOn;
        !           167: };
        !           168: 
        !           169: #ifdef MODULE
        !           170: #if LINUX_VERSION_CODE > 0x20115
        !           171: MODULE_AUTHOR("Jim Huang <[email protected]>, Ollie Lho <[email protected]>");
        !           172: MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
        !           173: MODULE_PARM(multicast_filter_limit, "i");
        !           174: MODULE_PARM(max_interrupt_work, "i");
        !           175: MODULE_PARM(debug, "i");
        !           176: #endif
        !           177: #endif
        !           178: 
        !           179: static int sis900_open(struct device *net_dev);
        !           180: static int sis900_mii_probe (unsigned char pci_bus, unsigned char pci_device_fn, struct device * net_dev);
        !           181: static void sis900_init_rxfilter (struct device * net_dev);
        !           182: static u16 read_eeprom(long ioaddr, int location);
        !           183: static u16 mdio_read(struct device *net_dev, int phy_id, int location);
        !           184: static void mdio_write(struct device *net_dev, int phy_id, int location, int val);
        !           185: static void sis900_timer(unsigned long data);
        !           186: static void sis900_check_mode (struct device *net_dev, struct mii_phy *mii_phy);
        !           187: static void sis900_tx_timeout(struct device *net_dev);
        !           188: static void sis900_init_tx_ring(struct device *net_dev);
        !           189: static void sis900_init_rx_ring(struct device *net_dev);
        !           190: static int sis900_start_xmit(struct sk_buff *skb, struct device *net_dev);
        !           191: static int sis900_rx(struct device *net_dev);
        !           192: static void sis900_finish_xmit (struct device *net_dev);
        !           193: static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
        !           194: static int sis900_close(struct device *net_dev);
        !           195: static int mii_ioctl(struct device *net_dev, struct ifreq *rq, int cmd);
        !           196: static struct enet_statistics *sis900_get_stats(struct device *net_dev);
        !           197: static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision);
        !           198: static void set_rx_mode(struct device *net_dev);
        !           199: static void sis900_reset(struct device *net_dev);
        !           200: static void sis630_set_eq(struct device *net_dev, u8 revision);
        !           201: static u16 sis900_default_phy(struct device * net_dev);
        !           202: static void sis900_set_capability( struct device *net_dev ,struct mii_phy *phy);
        !           203: static u16 sis900_reset_phy(struct device *net_dev, int phy_addr);
        !           204: static void sis900_auto_negotiate(struct device *net_dev, int phy_addr);
        !           205: static void sis900_set_mode (long ioaddr, int speed, int duplex);
        !           206: 
        !           207: /* A list of all installed SiS900 devices, for removing the driver module. */
        !           208: static struct device *root_sis900_dev = NULL;
        !           209: 
        !           210: #ifdef HAVE_DEVLIST
        !           211: struct netdev_entry netcard_drv =
        !           212:   {"sis900", sis900_probe, SIS900_TOTAL_SIZE, NULL};
        !           213: #endif
        !           214: 
        !           215: /* walk through every ethernet PCI devices to see if some of them are matched with our card list*/
        !           216: int sis900_probe (struct device * net_dev)
        !           217: {
        !           218:   int found = 0;
        !           219:   int pci_index = 0;
        !           220:   unsigned char pci_bus, pci_device_fn;
        !           221:   long ioaddr;
        !           222:   int irq;
        !           223: 
        !           224:   if (!pcibios_present())
        !           225:     return -ENODEV;
        !           226: 
        !           227:   for (; pci_index < 0xff; pci_index++)
        !           228:     {
        !           229:       u16 vendor, device, pci_command;
        !           230:       struct mac_chip_info *mac;
        !           231: 
        !           232:       if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index,
        !           233:                              &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL)
        !           234:           break;
        !           235: 
        !           236:       pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor);
        !           237:       pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device);
        !           238: 
        !           239:       for (mac = mac_chip_table; mac->vendor_id; mac++)
        !           240:       {
        !           241:          if (vendor == mac->vendor_id && device == mac->device_id) break;
        !           242:        }
        !           243: 
        !           244:       /* pci_dev does not match any of our cards */
        !           245:       if (mac->vendor_id == 0)
        !           246:        continue;
        !           247: 
        !           248:       {
        !           249:        u32 pci_ioaddr;
        !           250:        u8 pci_irq_line;
        !           251: 
        !           252:        pcibios_read_config_byte(pci_bus, pci_device_fn,
        !           253:                                 PCI_INTERRUPT_LINE, &pci_irq_line);
        !           254:        pcibios_read_config_dword(pci_bus, pci_device_fn,
        !           255:                                  PCI_BASE_ADDRESS_0, &pci_ioaddr);
        !           256:        ioaddr = pci_ioaddr & ~3;
        !           257:        irq = pci_irq_line;
        !           258: 
        !           259:        if ((mac->flags & PCI_USES_IO) &&
        !           260:            check_region (pci_ioaddr, mac->io_size))
        !           261:          continue;
        !           262:        
        !           263:        pcibios_read_config_word(pci_bus, pci_device_fn,
        !           264:                                 PCI_COMMAND, &pci_command);
        !           265:        
        !           266:        {
        !           267:          u8 lat;
        !           268:        
        !           269:          pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &lat);
        !           270:          if (lat < 16) {
        !           271:            printk("PCI: Increasing latency timer of device %02x:%02x to 64\n",
        !           272:                   pci_bus, pci_device_fn);
        !           273:            pcibios_write_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, 64);
        !           274:          }
        !           275:        }
        !           276:        net_dev = mac->probe (mac, ioaddr, irq, pci_index, pci_device_fn, pci_bus, net_dev);
        !           277:        if (net_dev != NULL)
        !           278:          {
        !           279:            found++;
        !           280:          }
        !           281:        net_dev = NULL;
        !           282:       }
        !           283:     }
        !           284:   return found ? 0 : -ENODEV;
        !           285: 
        !           286: }
        !           287: 
        !           288: /* older SiS900 and friends, use EEPROM to store MAC address */
        !           289: static int
        !           290: sis900_get_mac_addr(long ioaddr, struct device *net_dev)
        !           291: {
        !           292:   u16 signature;
        !           293:   int i;
        !           294: 
        !           295:   /* check to see if we have sane EEPROM */
        !           296:   signature = (u16) read_eeprom(ioaddr, EEPROMSignature);
        !           297:   if (signature == 0xffff || signature == 0x0000) {
        !           298:        printk (KERN_INFO "%s: Error EERPOM read %x\n",
        !           299:                net_dev->name, signature);      
        !           300:        return 0;
        !           301:   }
        !           302: 
        !           303:   /* get MAC address from EEPROM */
        !           304:   for (i = 0; i < 3; i++)
        !           305:          ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
        !           306:   return 1;
        !           307: }
        !           308: 
        !           309: /* SiS630E model, use APC CMOS RAM to store MAC address */
        !           310: static int sis630e_get_mac_addr(long ioaddr, int pci_index, struct device *net_dev)
        !           311: {
        !           312:   u8 reg;
        !           313:   int i;
        !           314:   u8 pci_bus, pci_dfn;
        !           315:   int not_found;
        !           316: 
        !           317:   not_found = pcibios_find_device(0x1039, 0x0008,
        !           318:                                  pci_index,
        !           319:                                  &pci_bus,
        !           320:                                  &pci_dfn);
        !           321:   if (not_found) {
        !           322:     printk("%s: Can not find ISA bridge\n", net_dev->name);
        !           323:     return 0;
        !           324:   }
        !           325:   pcibios_read_config_byte(pci_bus, pci_dfn, 0x48, &reg);
        !           326:   pcibios_write_config_byte(pci_bus, pci_dfn, 0x48, reg | 0x40);
        !           327: 
        !           328:   for (i = 0; i < 6; i++) {
        !           329:     outb(0x09 + i, 0x70);
        !           330:     ((u8 *)(net_dev->dev_addr))[i] = inb(0x71);
        !           331:   }
        !           332:   pcibios_write_config_byte(pci_bus, pci_dfn, 0x48, reg & ~0x40);
        !           333: 
        !           334:   return 1;
        !           335: }
        !           336: 
        !           337: /* 635 model : set Mac reload bit and get mac address from rfdr */
        !           338: static int sis635_get_mac_addr(struct device *net_dev)
        !           339: {
        !           340:   long ioaddr = net_dev->base_addr;
        !           341:   u32 rfcrSave;
        !           342:   u32 i;
        !           343: 
        !           344:   rfcrSave = inl(rfcr + ioaddr);
        !           345: 
        !           346:   outl(rfcrSave | RELOAD, ioaddr + cr);
        !           347:   outl(0, ioaddr + cr);
        !           348: 
        !           349:   /* disable packet filtering before setting filter */
        !           350:   outl(rfcrSave & ~RFEN, rfcr + ioaddr);
        !           351: 
        !           352:   /* load MAC addr to filter data register */
        !           353:   for (i = 0 ; i < 3 ; i++) {
        !           354:     outl((i << RFADDR_shift), ioaddr + rfcr);
        !           355:     *( ((u16 *)net_dev->dev_addr) + i) = inw(ioaddr + rfdr);
        !           356:   }
        !           357: 
        !           358:   /* enable packet filitering */
        !           359:   outl(rfcrSave | RFEN, rfcr + ioaddr);
        !           360: 
        !           361:   return 1;
        !           362: }
        !           363: 
        !           364: 
        !           365: /**
        !           366:  *     sis962_get_mac_addr: - Get MAC address for SiS962 model
        !           367:  *     @pci_dev: the sis900 pci device
        !           368:  *     @net_dev: the net device to get address for
        !           369:  *
        !           370:  *     SiS962 model, use EEPROM to store MAC address. And EEPROM is shared by
        !           371:  *     LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
        !           372:  *     and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
        !           373:  *     by LAN, otherwise is not. After MAC address is read from EEPROM, send
        !           374:  *     EEDONE signal to refuse EEPROM access by LAN.
        !           375:  *     MAC address is read into @net_dev->dev_addr.
        !           376:  */
        !           377: 
        !           378: static int sis962_get_mac_addr(struct device *net_dev)
        !           379: {
        !           380:   long ioaddr = net_dev->base_addr;
        !           381:   long ee_addr = ioaddr + mear;
        !           382:   u32 waittime = 0;
        !           383:   int i;
        !           384:        
        !           385:   outl(EEREQ, ee_addr);
        !           386:   while(waittime < 2000) {
        !           387:        if(inl(ee_addr) & EEGNT) {
        !           388:                /* get MAC address from EEPROM */
        !           389:                 for (i = 0; i < 3; i++)
        !           390:                         ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
        !           391:                 outl(EEDONE, ee_addr);
        !           392:                 return 1;
        !           393:         } else {
        !           394:                udelay(1);      
        !           395:                waittime ++;
        !           396:        }
        !           397:   }
        !           398:   outl(EEDONE, ee_addr);
        !           399:   return 0;
        !           400: }
        !           401: 
        !           402: struct device *
        !           403: sis900_mac_probe (struct mac_chip_info *mac, long ioaddr, int irq, int pci_index,
        !           404:                  unsigned char pci_device_fn, unsigned char pci_bus, struct device * net_dev)
        !           405: {
        !           406:   struct sis900_private *sis_priv;
        !           407:   static int did_version = 0;
        !           408: 
        !           409:   u8 revision;
        !           410:   int i, ret = 0;
        !           411: 
        !           412:   if (did_version++ == 0)
        !           413:     printk(KERN_INFO "%s\n", version);
        !           414: 
        !           415:   if ((net_dev = init_etherdev(net_dev, 0)) == NULL)
        !           416:     return NULL;
        !           417: 
        !           418:   if ((net_dev->priv = kmalloc(sizeof(struct sis900_private), GFP_KERNEL)) == NULL) {
        !           419:     unregister_netdev(net_dev);
        !           420:     return NULL;
        !           421:   }
        !           422: 
        !           423:   sis_priv = net_dev->priv;
        !           424:   memset(sis_priv, 0, sizeof(struct sis900_private));
        !           425: 
        !           426:   /* We do a request_region() to register /proc/ioports info. */
        !           427:   request_region(ioaddr, mac->io_size, net_dev->name);
        !           428:   net_dev->base_addr = ioaddr;
        !           429:   net_dev->irq = irq;
        !           430: 
        !           431:   sis_priv->mac = mac;
        !           432:   sis_priv->pci_bus = pci_bus;
        !           433:   sis_priv->pci_device_fn = pci_device_fn;
        !           434:   sis_priv->pci_index = pci_index;
        !           435: 
        !           436:   pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION, &revision);
        !           437: 
        !           438:   if ( revision == SIS630E_900_REV )
        !           439:     ret = sis630e_get_mac_addr(ioaddr, pci_index, net_dev);
        !           440:   else if ((revision > 0x81) && (revision <= 0x90))
        !           441:     ret = sis635_get_mac_addr(net_dev);
        !           442:   else if (revision == SIS962_900_REV)
        !           443:     ret = sis962_get_mac_addr(net_dev);
        !           444:   else
        !           445:     ret = sis900_get_mac_addr(ioaddr, net_dev);
        !           446: 
        !           447:   if (ret == 0) {
        !           448:     unregister_netdev(net_dev);
        !           449:     return NULL;
        !           450:   }
        !           451: 
        !           452:   /* print some information about our NIC */
        !           453:   printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, mac->name,
        !           454:         ioaddr, irq);
        !           455:   for (i = 0; i < 5; i++)
        !           456:     printk("%2.2x:", (u8)net_dev->dev_addr[i]);
        !           457:   printk("%2.2x.\n", net_dev->dev_addr[i]);
        !           458: 
        !           459:   /* 630ET : set the mii access mode as software-mode */
        !           460:   if (revision == SIS630ET_900_REV)
        !           461:     outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
        !           462: 
        !           463:   /* probe for mii transceiver */
        !           464:   if (sis900_mii_probe(pci_bus, pci_device_fn, net_dev) == 0) {
        !           465:     unregister_netdev(net_dev);
        !           466:     kfree(sis_priv);
        !           467:     release_region(ioaddr, mac->io_size);
        !           468:     return NULL;
        !           469:   }
        !           470: 
        !           471:   sis_priv->next_module = root_sis900_dev;
        !           472:   root_sis900_dev = net_dev;
        !           473: 
        !           474:   /* The SiS900-specific entries in the device structure. */
        !           475:   net_dev->open = &sis900_open;
        !           476:   net_dev->hard_start_xmit = &sis900_start_xmit;
        !           477:   net_dev->stop = &sis900_close;
        !           478:   net_dev->get_stats = &sis900_get_stats;
        !           479:   net_dev->set_multicast_list = &set_rx_mode;
        !           480:   net_dev->do_ioctl = &mii_ioctl;
        !           481: 
        !           482:   return net_dev;
        !           483: }
        !           484: 
        !           485: /* sis900_mii_probe: - Probe MII PHY for sis900 */
        !           486: static int sis900_mii_probe (unsigned char pci_bus, unsigned char pci_device_fn, struct device * net_dev)
        !           487: {
        !           488:   struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
        !           489:   u16 poll_bit = MII_STAT_LINK, status = 0;
        !           490:   unsigned int timeout = jiffies + 5 * HZ;
        !           491:   int phy_addr;
        !           492:   u8 revision;
        !           493: 
        !           494:   sis_priv->mii = NULL;
        !           495: 
        !           496:   /* search for total of 32 possible mii phy addresses */
        !           497:   for (phy_addr = 0; phy_addr < 32; phy_addr++) {      
        !           498:     struct mii_phy * mii_phy = NULL;
        !           499:     u16 mii_status;
        !           500:     int i;
        !           501: 
        !           502:     for(i=0; i<2; i++)
        !           503:       mii_status = mdio_read(net_dev, phy_addr, MII_STATUS);
        !           504: 
        !           505:     if (mii_status == 0xffff || mii_status == 0x0000)
        !           506:       /* the mii is not accessable, try next one */
        !           507:       continue;
        !           508:                
        !           509:     if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) {
        !           510:       printk(KERN_INFO "Cannot allocate mem for struct mii_phy\n");
        !           511:       return 0;
        !           512:     }
        !           513:                
        !           514:     mii_phy->phy_id0 = mdio_read(net_dev, phy_addr, MII_PHY_ID0);
        !           515:     mii_phy->phy_id1 = mdio_read(net_dev, phy_addr, MII_PHY_ID1);              
        !           516:     mii_phy->phy_addr = phy_addr;
        !           517:     mii_phy->status = mii_status;
        !           518:     mii_phy->next = sis_priv->mii;
        !           519:     sis_priv->mii = mii_phy;
        !           520:     sis_priv->first_mii = mii_phy;
        !           521: 
        !           522:     for (i=0; mii_chip_table[i].phy_id1; i++)
        !           523:       if ( ( mii_phy->phy_id0 == mii_chip_table[i].phy_id0 ) &&
        !           524:           ( (mii_phy->phy_id1 & 0xFFF0) == mii_chip_table[i].phy_id1 )){
        !           525: 
        !           526:        mii_phy->phy_types = mii_chip_table[i].phy_types;
        !           527:        if(mii_chip_table[i].phy_types == MIX)
        !           528:          mii_phy->phy_types =
        !           529:            (mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX))?LAN:HOME;
        !           530:        printk(KERN_INFO "%s: %s transceiver found at address %d.\n",
        !           531:               net_dev->name, mii_chip_table[i].name, phy_addr);
        !           532:        break;
        !           533:       }
        !           534: 
        !           535:     if( !mii_chip_table[i].phy_id1 )
        !           536:       printk(KERN_INFO "%s: Unknown PHY transceiver found at address %d.\n",
        !           537:             net_dev->name, phy_addr);
        !           538:   }
        !           539:        
        !           540:   if (sis_priv->mii == NULL) {
        !           541:     printk(KERN_INFO "%s: No MII transceivers found!\n",
        !           542:           net_dev->name);
        !           543:     return 0;
        !           544:   }
        !           545: 
        !           546:   /* Slect Default PHY to put in sis_priv->mii & sis_priv->cur_phy */
        !           547:   sis_priv->mii = NULL;
        !           548:   sis900_default_phy( net_dev );
        !           549: 
        !           550:   /* Reset PHY if default PHY is internal sis900 */
        !           551:   if( (sis_priv->mii->phy_id0 == 0x001D) &&
        !           552:       ( (sis_priv->mii->phy_id1&0xFFF0) == 0x8000) )
        !           553:     status = sis900_reset_phy( net_dev,  sis_priv->cur_phy );
        !           554: 
        !           555:   /* workaround for ICS1893 PHY */
        !           556:   if ((sis_priv->mii->phy_id0 == 0x0015) &&
        !           557:       ((sis_priv->mii->phy_id1&0xFFF0) == 0xF440))
        !           558:     mdio_write(net_dev, sis_priv->cur_phy, 0x0018, 0xD200);
        !           559: 
        !           560:   if( status & MII_STAT_LINK ){
        !           561:     while (poll_bit)
        !           562:       {
        !           563:         poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit);
        !           564:         if (jiffies >= timeout)
        !           565:           {
        !           566:             printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name);
        !           567:             return -ETIME;
        !           568:           }
        !           569:        }
        !           570:   }
        !           571:        
        !           572:        pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION, &revision);
        !           573:        if (revision == SIS630E_900_REV) {
        !           574:                /* SiS 630E has some bugs on default value of PHY registers */
        !           575:                mdio_write(net_dev, sis_priv->cur_phy, MII_ANADV, 0x05e1);
        !           576:                mdio_write(net_dev, sis_priv->cur_phy, MII_CONFIG1, 0x22);
        !           577:                mdio_write(net_dev, sis_priv->cur_phy, MII_CONFIG2, 0xff00);
        !           578:                mdio_write(net_dev, sis_priv->cur_phy, MII_MASK, 0xffc0);
        !           579:                //mdio_write(net_dev, sis_priv->cur_phy, MII_CONTROL, 0x1000);  
        !           580:        }
        !           581: 
        !           582:        if (sis_priv->mii->status & MII_STAT_LINK)
        !           583:                sis_priv->LinkOn = TRUE;
        !           584:        else
        !           585:                sis_priv->LinkOn = FALSE;
        !           586: 
        !           587:        return 1;
        !           588: }
        !           589: 
        !           590: 
        !           591: /* sis900_default_phy : Select one default PHY for sis900 mac */
        !           592: static u16 sis900_default_phy(struct device * net_dev)
        !           593: {
        !           594:        struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
        !           595:        struct mii_phy *phy = NULL, *phy_home = NULL, *default_phy = NULL;
        !           596:        u16 status;
        !           597: 
        !           598:         for( phy=sis_priv->first_mii; phy; phy=phy->next ){
        !           599:                status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
        !           600:                status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
        !           601: 
        !           602:                /* Link ON & Not select deafalut PHY */
        !           603:                 if ( (status & MII_STAT_LINK) && !(default_phy) )
        !           604:                        default_phy = phy;
        !           605:                 else{
        !           606:                        status = mdio_read(net_dev, phy->phy_addr, MII_CONTROL);
        !           607:                        mdio_write(net_dev, phy->phy_addr, MII_CONTROL,
        !           608:                                status | MII_CNTL_AUTO | MII_CNTL_ISOLATE);
        !           609:                        if( phy->phy_types == HOME )
        !           610:                                phy_home = phy;
        !           611:                 }
        !           612:        }
        !           613: 
        !           614:        if( (!default_phy) && phy_home )
        !           615:                default_phy = phy_home;
        !           616:        else if(!default_phy)
        !           617:                default_phy = sis_priv->first_mii;
        !           618: 
        !           619:        if( sis_priv->mii != default_phy ){
        !           620:                sis_priv->mii = default_phy;
        !           621:                sis_priv->cur_phy = default_phy->phy_addr;
        !           622:                printk(KERN_INFO "%s: Using transceiver found at address %d as default\n", net_dev->name,sis_priv->cur_phy);
        !           623:        }
        !           624:        
        !           625:        status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
        !           626:        status &= (~MII_CNTL_ISOLATE);
        !           627: 
        !           628:        mdio_write(net_dev, sis_priv->cur_phy, MII_CONTROL, status);    
        !           629:        status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
        !           630:        status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
        !           631: 
        !           632:        return status;  
        !           633: }
        !           634: 
        !           635: 
        !           636: /* sis900_set_capability : set the media capability of network adapter */
        !           637: static void sis900_set_capability( struct device *net_dev , struct mii_phy *phy )
        !           638: {
        !           639:        u16 cap;
        !           640:        u16 status;
        !           641:        
        !           642:        status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
        !           643:        status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
        !           644:        
        !           645:        cap = MII_NWAY_CSMA_CD |
        !           646:                ((phy->status & MII_STAT_CAN_TX_FDX)? MII_NWAY_TX_FDX:0) |
        !           647:                ((phy->status & MII_STAT_CAN_TX)    ? MII_NWAY_TX:0) |
        !           648:                ((phy->status & MII_STAT_CAN_T_FDX) ? MII_NWAY_T_FDX:0)|
        !           649:                ((phy->status & MII_STAT_CAN_T)     ? MII_NWAY_T:0);
        !           650: 
        !           651:        mdio_write( net_dev, phy->phy_addr, MII_ANADV, cap );
        !           652: }
        !           653: 
        !           654: 
        !           655: /* Delay between EEPROM clock transitions. */
        !           656: #define eeprom_delay() inl(ee_addr)
        !           657: 
        !           658: /* Read Serial EEPROM through EEPROM Access Register, Note that location is
        !           659:    in word (16 bits) unit */
        !           660: static u16 read_eeprom(long ioaddr, int location)
        !           661: {
        !           662:        int i;
        !           663:        u16 retval = 0;
        !           664:        long ee_addr = ioaddr + mear;
        !           665:        u32 read_cmd = location | EEread;
        !           666: 
        !           667:        outl(0, ee_addr);
        !           668:        eeprom_delay();
        !           669:        outl(EECS, ee_addr);
        !           670:        eeprom_delay();
        !           671: 
        !           672:        /* Shift the read command (9) bits out. */
        !           673:        for (i = 8; i >= 0; i--) {
        !           674:                u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
        !           675:                outl(dataval, ee_addr);
        !           676:                eeprom_delay();
        !           677:                outl(dataval | EECLK, ee_addr);
        !           678:                eeprom_delay();
        !           679:        }
        !           680:        outb(EECS, ee_addr);
        !           681:        eeprom_delay();
        !           682: 
        !           683:        /* read the 16-bits data in */
        !           684:        for (i = 16; i > 0; i--) {
        !           685:                outl(EECS, ee_addr);
        !           686:                eeprom_delay();
        !           687:                outl(EECS | EECLK, ee_addr);
        !           688:                eeprom_delay();
        !           689:                retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
        !           690:                eeprom_delay();
        !           691:        }
        !           692: 
        !           693:        /* Terminate the EEPROM access. */
        !           694:        outl(0, ee_addr);
        !           695:        eeprom_delay();
        !           696: //     outl(EECLK, ee_addr);
        !           697: 
        !           698:        return (retval);
        !           699: }
        !           700: 
        !           701: /* Read and write the MII management registers using software-generated
        !           702:    serial MDIO protocol. Note that the command bits and data bits are
        !           703:    send out seperately */
        !           704: #define mdio_delay()   inl(mdio_addr)
        !           705: 
        !           706: static void mdio_idle(long mdio_addr)
        !           707: {
        !           708:        outl(MDIO | MDDIR, mdio_addr);
        !           709:        mdio_delay();
        !           710:        outl(MDIO | MDDIR | MDC, mdio_addr);
        !           711: }
        !           712: 
        !           713: /* Syncronize the MII management interface by shifting 32 one bits out. */
        !           714: static void mdio_reset(long mdio_addr)
        !           715: {
        !           716:        int i;
        !           717: 
        !           718:        for (i = 31; i >= 0; i--) {
        !           719:                outl(MDDIR | MDIO, mdio_addr);
        !           720:                mdio_delay();
        !           721:                outl(MDDIR | MDIO | MDC, mdio_addr);
        !           722:                mdio_delay();
        !           723:        }
        !           724:        return;
        !           725: }
        !           726: 
        !           727: static u16 mdio_read(struct device *net_dev, int phy_id, int location)
        !           728: {
        !           729:        long mdio_addr = net_dev->base_addr + mear;
        !           730:        int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
        !           731:        u16 retval = 0;
        !           732:        int i;
        !           733: 
        !           734:        mdio_reset(mdio_addr);
        !           735:        mdio_idle(mdio_addr);
        !           736: 
        !           737:        for (i = 15; i >= 0; i--) {
        !           738:                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
        !           739:                outl(dataval, mdio_addr);
        !           740:                mdio_delay();
        !           741:                outl(dataval | MDC, mdio_addr);
        !           742:                mdio_delay();
        !           743:        }
        !           744: 
        !           745:        /* Read the 16 data bits. */
        !           746:        for (i = 16; i > 0; i--) {
        !           747:                outl(0, mdio_addr);
        !           748:                mdio_delay();
        !           749:                retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
        !           750:                outl(MDC, mdio_addr);
        !           751:                mdio_delay();
        !           752:        }
        !           753:        outl(0x00, mdio_addr);
        !           754: 
        !           755:        return retval;
        !           756: }
        !           757: 
        !           758: static void mdio_write(struct device *net_dev, int phy_id, int location, int value)
        !           759: {
        !           760:        long mdio_addr = net_dev->base_addr + mear;
        !           761:        int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
        !           762:        int i;
        !           763: 
        !           764:        mdio_reset(mdio_addr);
        !           765:        mdio_idle(mdio_addr);
        !           766: 
        !           767:        /* Shift the command bits out. */
        !           768:        for (i = 15; i >= 0; i--) {
        !           769:                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
        !           770:                outb(dataval, mdio_addr);
        !           771:                mdio_delay();
        !           772:                outb(dataval | MDC, mdio_addr);
        !           773:                mdio_delay();
        !           774:        }
        !           775:        mdio_delay();
        !           776: 
        !           777:        /* Shift the value bits out. */
        !           778:        for (i = 15; i >= 0; i--) {
        !           779:                int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
        !           780:                outl(dataval, mdio_addr);
        !           781:                mdio_delay();
        !           782:                outl(dataval | MDC, mdio_addr);
        !           783:                mdio_delay();
        !           784:        }
        !           785:        mdio_delay();
        !           786: 
        !           787:        /* Clear out extra bits. */
        !           788:        for (i = 2; i > 0; i--) {
        !           789:                outb(0, mdio_addr);
        !           790:                mdio_delay();
        !           791:                outb(MDC, mdio_addr);
        !           792:                mdio_delay();
        !           793:        }
        !           794:        outl(0x00, mdio_addr);
        !           795: 
        !           796:        return;
        !           797: }
        !           798: 
        !           799: static u16 sis900_reset_phy(struct device *net_dev, int phy_addr)
        !           800: {
        !           801:        int i = 0;
        !           802:        u16 status;
        !           803: 
        !           804:        while (i++ < 2)
        !           805:                status = mdio_read(net_dev, phy_addr, MII_STATUS);
        !           806: 
        !           807:        mdio_write( net_dev, phy_addr, MII_CONTROL, MII_CNTL_RESET );
        !           808:        
        !           809:        return status;
        !           810: }
        !           811: 
        !           812: static int
        !           813: sis900_open(struct device *net_dev)
        !           814: {
        !           815:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !           816:        long ioaddr = net_dev->base_addr;
        !           817:        u8 revision;
        !           818: 
        !           819:        /* Soft reset the chip. */
        !           820:        sis900_reset(net_dev);
        !           821:        
        !           822:        /* Equalizer workaroung Rule */
        !           823:        pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION, &revision);
        !           824:        sis630_set_eq(net_dev, revision);
        !           825:        
        !           826:        if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) {
        !           827:                return -EAGAIN;
        !           828:        }
        !           829: 
        !           830:        MOD_INC_USE_COUNT;
        !           831: 
        !           832:        sis900_init_rxfilter(net_dev);
        !           833: 
        !           834:        sis900_init_tx_ring(net_dev);
        !           835:        sis900_init_rx_ring(net_dev);
        !           836: 
        !           837:        set_rx_mode(net_dev);
        !           838: 
        !           839:        net_dev->tbusy = 0;
        !           840:        net_dev->interrupt = 0;
        !           841:        net_dev->start = 1;
        !           842: 
        !           843:        /* Workaround for EDB */
        !           844:        sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
        !           845: 
        !           846:        /* Enable all known interrupts by setting the interrupt mask. */
        !           847:        outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
        !           848:        outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
        !           849:        outl(IE, ioaddr + ier);
        !           850: 
        !           851:        sis900_check_mode(net_dev, sis_priv->mii);
        !           852: 
        !           853:        /* Set the timer to switch to check for link beat and perhaps switch
        !           854:           to an alternate media type. */
        !           855:        init_timer(&sis_priv->timer);
        !           856:        sis_priv->timer.expires = jiffies + HZ;
        !           857:        sis_priv->timer.data = (unsigned long)net_dev;
        !           858:        sis_priv->timer.function = &sis900_timer;
        !           859:        add_timer(&sis_priv->timer);
        !           860: 
        !           861:        return 0;
        !           862: }
        !           863: 
        !           864: /* set receive filter address to our MAC address */
        !           865: static void
        !           866: sis900_init_rxfilter (struct device * net_dev)
        !           867: {
        !           868:        long ioaddr = net_dev->base_addr;
        !           869:        u32 rfcrSave;
        !           870:        u32 i;
        !           871: 
        !           872:        rfcrSave = inl(rfcr + ioaddr);
        !           873: 
        !           874:        /* disable packet filtering before setting filter */
        !           875:        outl(rfcrSave & ~RFEN, rfcr + ioaddr);
        !           876: 
        !           877:        /* load MAC addr to filter data register */
        !           878:        for (i = 0 ; i < 3 ; i++) {
        !           879:                u32 w;
        !           880: 
        !           881:                w = (u32) *((u16 *)(net_dev->dev_addr)+i);
        !           882:                outl((i << RFADDR_shift), ioaddr + rfcr);
        !           883:                outl(w, ioaddr + rfdr);
        !           884: 
        !           885:                if (sis900_debug > 2) {
        !           886:                        printk(KERN_INFO "%s: Receive Filter Addrss[%d]=%x\n",
        !           887:                               net_dev->name, i, inl(ioaddr + rfdr));
        !           888:                }
        !           889:        }
        !           890: 
        !           891:        /* enable packet filitering */
        !           892:        outl(rfcrSave | RFEN, rfcr + ioaddr);
        !           893: }
        !           894: 
        !           895: /* Initialize the Tx ring. */
        !           896: static void
        !           897: sis900_init_tx_ring(struct device *net_dev)
        !           898: {
        !           899:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !           900:        long ioaddr = net_dev->base_addr;
        !           901:        int i;
        !           902: 
        !           903:        sis_priv->tx_full = 0;
        !           904:        sis_priv->dirty_tx = sis_priv->cur_tx = 0;
        !           905: 
        !           906:        for (i = 0; i < NUM_TX_DESC; i++) {
        !           907:                sis_priv->tx_skbuff[i] = NULL;
        !           908: 
        !           909:                sis_priv->tx_ring[i].link = (u32) virt_to_bus(&sis_priv->tx_ring[i+1]);
        !           910:                sis_priv->tx_ring[i].cmdsts = 0;
        !           911:                sis_priv->tx_ring[i].bufptr = 0;
        !           912:        }
        !           913:        sis_priv->tx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->tx_ring[0]);
        !           914: 
        !           915:        /* load Transmit Descriptor Register */
        !           916:        outl(virt_to_bus(&sis_priv->tx_ring[0]), ioaddr + txdp);
        !           917:        if (sis900_debug > 2)
        !           918:                printk(KERN_INFO "%s: TX descriptor register loaded with: %8.8x\n",
        !           919:                       net_dev->name, inl(ioaddr + txdp));
        !           920: }
        !           921: 
        !           922: /* Initialize the Rx descriptor ring, pre-allocate recevie buffers */
        !           923: static void
        !           924: sis900_init_rx_ring(struct device *net_dev)
        !           925: {
        !           926:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !           927:        long ioaddr = net_dev->base_addr;
        !           928:        int i;
        !           929: 
        !           930:        sis_priv->cur_rx = 0;
        !           931:        sis_priv->dirty_rx = 0;
        !           932: 
        !           933:        /* init RX descriptor */
        !           934:        for (i = 0; i < NUM_RX_DESC; i++) {
        !           935:                sis_priv->rx_skbuff[i] = NULL;
        !           936: 
        !           937:                sis_priv->rx_ring[i].link = (u32) virt_to_bus(&sis_priv->rx_ring[i+1]);
        !           938:                sis_priv->rx_ring[i].cmdsts = 0;
        !           939:                sis_priv->rx_ring[i].bufptr = 0;
        !           940:        }
        !           941:        sis_priv->rx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->rx_ring[0]);
        !           942: 
        !           943:        /* allocate sock buffers */
        !           944:        for (i = 0; i < NUM_RX_DESC; i++) {
        !           945:                struct sk_buff *skb;
        !           946: 
        !           947:                if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
        !           948:                        /* not enough memory for skbuff, this makes a "hole"
        !           949:                           on the buffer ring, it is not clear how the
        !           950:                           hardware will react to this kind of degenerated
        !           951:                           buffer */
        !           952:                        break;
        !           953:                }
        !           954:                skb->dev = net_dev;
        !           955:                sis_priv->rx_skbuff[i] = skb;
        !           956:                sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
        !           957:                sis_priv->rx_ring[i].bufptr = virt_to_bus(skb->tail);
        !           958:        }
        !           959:        sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
        !           960: 
        !           961:        /* load Receive Descriptor Register */
        !           962:        outl(virt_to_bus(&sis_priv->rx_ring[0]), ioaddr + rxdp);
        !           963:        if (sis900_debug > 2)
        !           964:                printk(KERN_INFO "%s: RX descriptor register loaded with: %8.8x\n",
        !           965:                       net_dev->name, inl(ioaddr + rxdp));
        !           966: }
        !           967: 
        !           968: /**
        !           969:  *     sis630_set_eq: - set phy equalizer value for 630 LAN
        !           970:  *     @net_dev: the net device to set equalizer value
        !           971:  *     @revision: 630 LAN revision number
        !           972:  *
        !           973:  *     630E equalizer workaround rule(Cyrus Huang 08/15)
        !           974:  *     PHY register 14h(Test)
        !           975:  *     Bit 14: 0 -- Automatically dectect (default)
        !           976:  *             1 -- Manually set Equalizer filter
        !           977:  *     Bit 13: 0 -- (Default)
        !           978:  *             1 -- Speed up convergence of equalizer setting
        !           979:  *     Bit 9 : 0 -- (Default)
        !           980:  *             1 -- Disable Baseline Wander
        !           981:  *     Bit 3~7   -- Equalizer filter setting
        !           982:  *     Link ON: Set Bit 9, 13 to 1, Bit 14 to 0
        !           983:  *     Then calculate equalizer value
        !           984:  *     Then set equalizer value, and set Bit 14 to 1, Bit 9 to 0
        !           985:  *     Link Off:Set Bit 13 to 1, Bit 14 to 0
        !           986:  *     Calculate Equalizer value:
        !           987:  *     When Link is ON and Bit 14 is 0, SIS900PHY will auto-dectect proper equalizer value.
        !           988:  *     When the equalizer is stable, this value is not a fixed value. It will be within
        !           989:  *     a small range(eg. 7~9). Then we get a minimum and a maximum value(eg. min=7, max=9)
        !           990:  *     0 <= max <= 4  --> set equalizer to max
        !           991:  *     5 <= max <= 14 --> set equalizer to max+1 or set equalizer to max+2 if max == min
        !           992:  *     max >= 15      --> set equalizer to max+5 or set equalizer to max+6 if max == min
        !           993:  */
        !           994: 
        !           995: static void sis630_set_eq(struct device *net_dev, u8 revision)
        !           996: {
        !           997:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !           998:        u16 reg14h, eq_value, max_value=0, min_value=0;
        !           999:        u8 host_bridge_rev;
        !          1000:        int i, maxcount=10;
        !          1001:        int not_found;
        !          1002:        u8 pci_bus, pci_device_fn;
        !          1003: 
        !          1004:        if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
        !          1005:               revision == SIS630A_900_REV || revision ==  SIS630ET_900_REV) )
        !          1006:                return;
        !          1007:        not_found = pcibios_find_device(SIS630_VENDOR_ID, SIS630_DEVICE_ID,
        !          1008:                                        sis_priv->pci_index,
        !          1009:                                        &pci_bus,
        !          1010:                                        &pci_device_fn);
        !          1011:        if (not_found)
        !          1012:            pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CLASS_REVISION, &host_bridge_rev);
        !          1013: 
        !          1014:        if (sis_priv->LinkOn) {
        !          1015:                reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
        !          1016:                mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
        !          1017:                for (i=0; i < maxcount; i++) {
        !          1018:                        eq_value=(0x00F8 & mdio_read(net_dev, sis_priv->cur_phy, MII_RESV)) >> 3;
        !          1019:                        if (i == 0)
        !          1020:                                max_value=min_value=eq_value;
        !          1021:                        max_value=(eq_value > max_value) ? eq_value : max_value;
        !          1022:                        min_value=(eq_value < min_value) ? eq_value : min_value;
        !          1023:                }
        !          1024:                /* 630E rule to determine the equalizer value */
        !          1025:                if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
        !          1026:                    revision == SIS630ET_900_REV) {
        !          1027:                        if (max_value < 5)
        !          1028:                                eq_value=max_value;
        !          1029:                        else if (max_value >= 5 && max_value < 15)
        !          1030:                                eq_value=(max_value == min_value) ? max_value+2 : max_value+1;
        !          1031:                        else if (max_value >= 15)
        !          1032:                                eq_value=(max_value == min_value) ? max_value+6 : max_value+5;
        !          1033:                }
        !          1034:                /* 630B0&B1 rule to determine the equalizer value */
        !          1035:                if (revision == SIS630A_900_REV &&
        !          1036:                    (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1)) {
        !          1037:                        if (max_value == 0)
        !          1038:                                eq_value=3;
        !          1039:                        else
        !          1040:                                eq_value=(max_value+min_value+1)/2;
        !          1041:                }
        !          1042:                /* write equalizer value and setting */
        !          1043:                reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
        !          1044:                reg14h=(reg14h & 0xFF07) | ((eq_value << 3) & 0x00F8);
        !          1045:                reg14h=(reg14h | 0x6000) & 0xFDFF;
        !          1046:                mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, reg14h);
        !          1047:        }
        !          1048:        else {
        !          1049:                reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
        !          1050:                if (revision == SIS630A_900_REV &&
        !          1051:                    (host_bridge_rev == SIS630B0 || host_bridge_rev == SIS630B1))
        !          1052:                        mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF);
        !          1053:                else
        !          1054:                        mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF);
        !          1055:        }
        !          1056:        return;
        !          1057: }
        !          1058: 
        !          1059: 
        !          1060: /* on each timer ticks we check two things, Link Status (ON/OFF) and
        !          1061:    Link Mode (10/100/Full/Half)
        !          1062: */
        !          1063: static void sis900_timer(unsigned long data)
        !          1064: {
        !          1065:        struct device *net_dev = (struct device *)data;
        !          1066:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1067:        struct mii_phy *mii_phy = sis_priv->mii;
        !          1068:        static int next_tick = 5*HZ;
        !          1069:        u16 status;
        !          1070:        u8 revision;
        !          1071: 
        !          1072:        if(!sis_priv->autong_complete){
        !          1073:                int speed, duplex = 0;
        !          1074: 
        !          1075:                sis900_read_mode(net_dev, &speed, &duplex);
        !          1076:                if(duplex){
        !          1077:                        sis900_set_mode(net_dev->base_addr, speed, duplex);
        !          1078:                        pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION, &revision);
        !          1079:                        sis630_set_eq(net_dev, revision);
        !          1080:                }
        !          1081:                
        !          1082:                sis_priv->timer.expires = jiffies + HZ;
        !          1083:                add_timer(&sis_priv->timer);
        !          1084:                return;
        !          1085:        }
        !          1086: 
        !          1087:        status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
        !          1088:        status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
        !          1089: 
        !          1090:        /* Link OFF -> ON */
        !          1091:        if ( !sis_priv->LinkOn ) {
        !          1092: LookForLink:
        !          1093:                /* Search for new PHY */
        !          1094:                status = sis900_default_phy( net_dev );
        !          1095:                mii_phy = sis_priv->mii;
        !          1096: 
        !          1097:                if( status & MII_STAT_LINK ){
        !          1098:                        sis900_check_mode(net_dev, mii_phy);
        !          1099:                        sis_priv->LinkOn = TRUE;
        !          1100:                }
        !          1101:        }
        !          1102:        /* Link ON -> OFF */
        !          1103:        else{
        !          1104:                 if( !(status & MII_STAT_LINK) ){
        !          1105:                        sis_priv->LinkOn = FALSE;
        !          1106:                        printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
        !          1107: 
        !          1108:                        /* Change mode issue */
        !          1109:                        if( (mii_phy->phy_id0 == 0x001D) &&
        !          1110:                          ( (mii_phy->phy_id1 & 0xFFF0) == 0x8000 ))
        !          1111:                                        sis900_reset_phy( net_dev,  sis_priv->cur_phy );
        !          1112: 
        !          1113:                        pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION, &revision);
        !          1114:                        sis630_set_eq(net_dev, revision);
        !          1115: 
        !          1116:                        goto LookForLink;
        !          1117:                 }
        !          1118:        }
        !          1119: 
        !          1120:        sis_priv->timer.expires = jiffies + next_tick;
        !          1121:        add_timer(&sis_priv->timer);
        !          1122: }
        !          1123: 
        !          1124: static void sis900_check_mode (struct device *net_dev, struct mii_phy *mii_phy)
        !          1125: {
        !          1126:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1127:        long ioaddr = net_dev->base_addr;
        !          1128:        int speed, duplex;
        !          1129: 
        !          1130:        if( mii_phy->phy_types == LAN  ){
        !          1131:                outl( ~EXD & inl( ioaddr + cfg ), ioaddr + cfg);
        !          1132:                sis900_set_capability(net_dev , mii_phy);
        !          1133:                sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
        !          1134:        }else{
        !          1135:                outl(EXD | inl( ioaddr + cfg ), ioaddr + cfg);
        !          1136:                speed = HW_SPEED_HOME;
        !          1137:                duplex = FDX_CAPABLE_HALF_SELECTED;
        !          1138:                sis900_set_mode(net_dev->base_addr, speed, duplex);
        !          1139:                sis_priv->autong_complete = 1;
        !          1140:        }
        !          1141: }
        !          1142: 
        !          1143: static void sis900_set_mode (long ioaddr, int speed, int duplex)
        !          1144: {
        !          1145:        u32 tx_flags = 0, rx_flags = 0;
        !          1146: 
        !          1147:        if( inl(ioaddr + cfg) & EDB_MASTER_EN ){
        !          1148:                tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
        !          1149:                rx_flags = DMA_BURST_64 << RxMXDMA_shift;
        !          1150:        }
        !          1151:        else{
        !          1152:                tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
        !          1153:                rx_flags = DMA_BURST_512 << RxMXDMA_shift;
        !          1154:        }
        !          1155: 
        !          1156:        if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS ) {
        !          1157:                rx_flags |= (RxDRNT_10 << RxDRNT_shift);
        !          1158:                tx_flags |= (TxDRNT_10 << TxDRNT_shift);
        !          1159:        }
        !          1160:        else {
        !          1161:                rx_flags |= (RxDRNT_100 << RxDRNT_shift);
        !          1162:                tx_flags |= (TxDRNT_100 << TxDRNT_shift);
        !          1163:        }
        !          1164: 
        !          1165:        if (duplex == FDX_CAPABLE_FULL_SELECTED) {
        !          1166:                tx_flags |= (TxCSI | TxHBI);
        !          1167:                rx_flags |= RxATX;
        !          1168:        }
        !          1169: 
        !          1170:        outl (tx_flags, ioaddr + txcfg);
        !          1171:        outl (rx_flags, ioaddr + rxcfg);
        !          1172: }
        !          1173: 
        !          1174: 
        !          1175: static void sis900_auto_negotiate(struct device *net_dev, int phy_addr)
        !          1176: {
        !          1177:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1178:        int i = 0;
        !          1179:        u32 status;
        !          1180:        
        !          1181:        while (i++ < 2)
        !          1182:                status = mdio_read(net_dev, phy_addr, MII_STATUS);
        !          1183: 
        !          1184:        if (!(status & MII_STAT_LINK)){
        !          1185:                printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
        !          1186:                sis_priv->autong_complete = 1;
        !          1187:                sis_priv->LinkOn = FALSE;
        !          1188:                return;
        !          1189:        }
        !          1190: 
        !          1191:        /* (Re)start AutoNegotiate */
        !          1192:        mdio_write(net_dev, phy_addr, MII_CONTROL,
        !          1193:                        MII_CNTL_AUTO | MII_CNTL_RST_AUTO);
        !          1194:        sis_priv->autong_complete = 0;
        !          1195: }
        !          1196: 
        !          1197: 
        !          1198: static void sis900_read_mode(struct device *net_dev, int *speed, int *duplex)
        !          1199: {
        !          1200:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1201:        struct mii_phy *phy = sis_priv->mii;
        !          1202:        int phy_addr = sis_priv->cur_phy;
        !          1203:        u32 status;
        !          1204:        u16 autoadv, autorec;
        !          1205:        int i = 0;
        !          1206: 
        !          1207:        while (i++ < 2)
        !          1208:                status = mdio_read(net_dev, phy_addr, MII_STATUS);
        !          1209: 
        !          1210:        if (!(status & MII_STAT_LINK))  return;
        !          1211:        
        !          1212:        /* AutoNegotiate completed */
        !          1213:        autoadv = mdio_read(net_dev, phy_addr, MII_ANADV);
        !          1214:        autorec = mdio_read(net_dev, phy_addr, MII_ANLPAR);
        !          1215:        status = autoadv & autorec;
        !          1216: 
        !          1217:        *speed = HW_SPEED_10_MBPS;
        !          1218:        *duplex = FDX_CAPABLE_HALF_SELECTED;
        !          1219: 
        !          1220:        if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
        !          1221:                *speed = HW_SPEED_100_MBPS;
        !          1222:        if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
        !          1223:                *duplex = FDX_CAPABLE_FULL_SELECTED;
        !          1224: 
        !          1225:        sis_priv->autong_complete = 1;
        !          1226: 
        !          1227:        /* Workaround for Realtek RTL8201 PHY issue */
        !          1228:        if((phy->phy_id0 == 0x0000) && ((phy->phy_id1 & 0xFFF0) == 0x8200)){
        !          1229:                if(mdio_read(net_dev, phy_addr, MII_CONTROL) & MII_CNTL_FDX)
        !          1230:                        *duplex = FDX_CAPABLE_FULL_SELECTED;
        !          1231:                if(mdio_read(net_dev, phy_addr, 0x0019) & 0x01)
        !          1232:                        *speed = HW_SPEED_100_MBPS;
        !          1233:        }
        !          1234:                        
        !          1235:        printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
        !          1236:               net_dev->name,
        !          1237:               *speed == HW_SPEED_100_MBPS ?
        !          1238:               "100mbps" : "10mbps",
        !          1239:               *duplex == FDX_CAPABLE_FULL_SELECTED ?
        !          1240:               "full" : "half");
        !          1241: }
        !          1242: 
        !          1243: 
        !          1244: static void sis900_tx_timeout(struct device *net_dev)
        !          1245: {
        !          1246:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1247:        long ioaddr = net_dev->base_addr;
        !          1248:        int i;
        !          1249: 
        !          1250:        printk(KERN_INFO "%s: Transmit timeout, status %8.8x %8.8x \n",
        !          1251:               net_dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
        !          1252: 
        !          1253:        /* Disable interrupts by clearing the interrupt mask. */
        !          1254:        outl(0x0000, ioaddr + imr);
        !          1255: 
        !          1256:        /* discard unsent packets, should this code section be protected by
        !          1257:           cli(), sti() ?? */
        !          1258:        sis_priv->dirty_tx = sis_priv->cur_tx = 0;
        !          1259:        for (i = 0; i < NUM_TX_DESC; i++) {
        !          1260:                if (sis_priv->tx_skbuff[i] != NULL) {
        !          1261:                        dev_free_skb(sis_priv->tx_skbuff[i]);
        !          1262:                        sis_priv->tx_skbuff[i] = 0;
        !          1263:                        sis_priv->tx_ring[i].cmdsts = 0;
        !          1264:                        sis_priv->tx_ring[i].bufptr = 0;
        !          1265:                        sis_priv->stats.tx_dropped++;
        !          1266:                }
        !          1267:        }
        !          1268:        net_dev->trans_start = jiffies;
        !          1269:        net_dev->tbusy = sis_priv->tx_full = 0;
        !          1270: 
        !          1271:        /* FIXME: Should we restart the transmission thread here  ?? */
        !          1272:        outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
        !          1273: 
        !          1274:        /* Enable all known interrupts by setting the interrupt mask. */
        !          1275:        outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
        !          1276:        return;
        !          1277: }
        !          1278: 
        !          1279: static int
        !          1280: sis900_start_xmit(struct sk_buff *skb, struct device *net_dev)
        !          1281: {
        !          1282:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1283:        long ioaddr = net_dev->base_addr;
        !          1284:        unsigned int  entry;
        !          1285: 
        !          1286:        /* test tbusy to see if we have timeout situation then set it */
        !          1287:        if (test_and_set_bit(0, (void*)&net_dev->tbusy) != 0) {
        !          1288:                if (jiffies - net_dev->trans_start > TX_TIMEOUT)
        !          1289:                        sis900_tx_timeout(net_dev);
        !          1290:                return 1;
        !          1291:        }
        !          1292: 
        !          1293:        /* Calculate the next Tx descriptor entry. */
        !          1294:        entry = sis_priv->cur_tx % NUM_TX_DESC;
        !          1295:        sis_priv->tx_skbuff[entry] = skb;
        !          1296: 
        !          1297:        /* set the transmit buffer descriptor and enable Transmit State Machine */
        !          1298:        sis_priv->tx_ring[entry].bufptr = virt_to_bus(skb->data);
        !          1299:        sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
        !          1300:        outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
        !          1301: 
        !          1302:        if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
        !          1303:                /* Typical path, clear tbusy to indicate more
        !          1304:                   transmission is possible */
        !          1305:                clear_bit(0, (void*)&net_dev->tbusy);
        !          1306:        } else {
        !          1307:                /* no more transmit descriptor avaiable, tbusy remain set */
        !          1308:                sis_priv->tx_full = 1;
        !          1309:        }
        !          1310: 
        !          1311:        net_dev->trans_start = jiffies;
        !          1312:        
        !          1313:        {
        !          1314:          int i;
        !          1315:          for (i = 0; i < 100000; i++); /* GRUIIIIIK */
        !          1316:        }
        !          1317:        
        !          1318:        if (sis900_debug > 3)
        !          1319:                printk(KERN_INFO "%s: Queued Tx packet at %p size %d "
        !          1320:                       "to slot %d.\n",
        !          1321:                       net_dev->name, skb->data, (int)skb->len, entry);
        !          1322: 
        !          1323:        return 0;
        !          1324: }
        !          1325: 
        !          1326: /* The interrupt handler does all of the Rx thread work and cleans up
        !          1327:    after the Tx thread. */
        !          1328: static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        !          1329: {
        !          1330:        struct device *net_dev = (struct device *)dev_instance;
        !          1331:        int boguscnt = max_interrupt_work;
        !          1332:        long ioaddr = net_dev->base_addr;
        !          1333:        u32 status;
        !          1334: 
        !          1335: #if defined(__i386__)
        !          1336:        /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
        !          1337:        if (test_and_set_bit(0, (void*)&net_dev->interrupt)) {
        !          1338:                printk(KERN_INFO "%s: SMP simultaneous entry of "
        !          1339:                       "an interrupt handler.\n", net_dev->name);
        !          1340:                net_dev->interrupt = 0;         /* Avoid halting machine. */
        !          1341:                return;
        !          1342:        }
        !          1343: #else
        !          1344:        if (net_dev->interrupt) {
        !          1345:                printk(KERN_INFO "%s: Re-entering the interrupt handler.\n",
        !          1346:                       net_dev->name);
        !          1347:                return;
        !          1348:        }
        !          1349:        net_dev->interrupt = 1;
        !          1350: #endif
        !          1351: 
        !          1352:        do {
        !          1353:                status = inl(ioaddr + isr);
        !          1354: 
        !          1355:                if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
        !          1356:                        /* nothing intresting happened */
        !          1357:                        break;
        !          1358: 
        !          1359:                /* why dow't we break after Tx/Rx case ?? keyword: full-duplex */
        !          1360:                if (status & (RxORN | RxERR | RxOK))
        !          1361:                        /* Rx interrupt */
        !          1362:                        sis900_rx(net_dev);
        !          1363: 
        !          1364:                if (status & (TxURN | TxERR | TxIDLE))
        !          1365:                        /* Tx interrupt */
        !          1366:                        sis900_finish_xmit(net_dev);
        !          1367: 
        !          1368:                /* something strange happened !!! */
        !          1369:                if (status & HIBERR) {
        !          1370:                        printk(KERN_INFO "%s: Abnormal interrupt,"
        !          1371:                               "status %#8.8x.\n", net_dev->name, status);
        !          1372:                        break;
        !          1373:                }
        !          1374:                if (--boguscnt < 0) {
        !          1375:                        printk(KERN_INFO "%s: Too much work at interrupt, "
        !          1376:                               "interrupt status = %#8.8x.\n",
        !          1377:                               net_dev->name, status);
        !          1378:                        break;
        !          1379:                }
        !          1380:        } while (1);
        !          1381: 
        !          1382:        if (sis900_debug > 4)
        !          1383:                printk(KERN_INFO "%s: exiting interrupt, "
        !          1384:                       "interrupt status = 0x%#8.8x.\n",
        !          1385:                       net_dev->name, inl(ioaddr + isr));
        !          1386:        
        !          1387: #if defined(__i386__)
        !          1388:        clear_bit(0, (void*)&net_dev->interrupt);
        !          1389: #else
        !          1390:        net_dev->interrupt = 0;
        !          1391: #endif
        !          1392:        return;
        !          1393: }
        !          1394: 
        !          1395: /* Process receive interrupt events, put buffer to higher layer and refill buffer pool
        !          1396:    Note: This fucntion is called by interrupt handler, don't do "too much" work here */
        !          1397: static int sis900_rx(struct device *net_dev)
        !          1398: {
        !          1399:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1400:        long ioaddr = net_dev->base_addr;
        !          1401:        unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
        !          1402:        u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
        !          1403: 
        !          1404:        if (sis900_debug > 4)
        !          1405:                printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
        !          1406:                       "status:0x%8.8x\n",
        !          1407:                       sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
        !          1408: 
        !          1409:        while (rx_status & OWN) {
        !          1410:                unsigned int rx_size;
        !          1411: 
        !          1412:                rx_size = (rx_status & DSIZE) - CRC_SIZE;
        !          1413: 
        !          1414:                if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
        !          1415:                        /* corrupted packet received */
        !          1416:                        if (sis900_debug > 4)
        !          1417:                                printk(KERN_INFO "%s: Corrupted packet "
        !          1418:                                       "received, buffer status = 0x%8.8x.\n",
        !          1419:                                       net_dev->name, rx_status);
        !          1420:                        sis_priv->stats.rx_errors++;
        !          1421:                        if (rx_status & OVERRUN)
        !          1422:                                sis_priv->stats.rx_over_errors++;
        !          1423:                        if (rx_status & (TOOLONG|RUNT))
        !          1424:                                sis_priv->stats.rx_length_errors++;
        !          1425:                        if (rx_status & (RXISERR | FAERR))
        !          1426:                                sis_priv->stats.rx_frame_errors++;
        !          1427:                        if (rx_status & CRCERR)
        !          1428:                                sis_priv->stats.rx_crc_errors++;
        !          1429:                        /* reset buffer descriptor state */
        !          1430:                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
        !          1431:                } else {
        !          1432:                        struct sk_buff * skb;
        !          1433: 
        !          1434:                        /* This situation should never happen, but due to
        !          1435:                           some unknow bugs, it is possible that
        !          1436:                           we are working on NULL sk_buff :-( */
        !          1437:                        if (sis_priv->rx_skbuff[entry] == NULL) {
        !          1438:                                printk(KERN_INFO "%s: NULL pointer "
        !          1439:                                       "encountered in Rx ring, skipping\n",
        !          1440:                                       net_dev->name);
        !          1441:                                break;
        !          1442:                        }
        !          1443: 
        !          1444:                        /* gvie the socket buffer to upper layers */
        !          1445:                        skb = sis_priv->rx_skbuff[entry];
        !          1446:                        skb_put(skb, rx_size);
        !          1447:                        skb->protocol = eth_type_trans(skb, net_dev);
        !          1448:                        netif_rx(skb);
        !          1449: 
        !          1450:                        /* some network statistics */
        !          1451:                        if ((rx_status & BCAST) == MCAST)
        !          1452:                                sis_priv->stats.multicast++;
        !          1453:                        net_dev->last_rx = jiffies;
        !          1454:                        /*                      sis_priv->stats.rx_bytes += rx_size;*/
        !          1455:                        sis_priv->stats.rx_packets++;
        !          1456: 
        !          1457:                        /* refill the Rx buffer, what if there is not enought memory for
        !          1458:                           new socket buffer ?? */
        !          1459:                        if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
        !          1460:                                /* not enough memory for skbuff, this makes a "hole"
        !          1461:                                   on the buffer ring, it is not clear how the
        !          1462:                                   hardware will react to this kind of degenerated
        !          1463:                                   buffer */
        !          1464:                                printk(KERN_INFO "%s: Memory squeeze,"
        !          1465:                                       "deferring packet.\n",
        !          1466:                                       net_dev->name);
        !          1467:                                sis_priv->rx_skbuff[entry] = NULL;
        !          1468:                                /* reset buffer descriptor state */
        !          1469:                                sis_priv->rx_ring[entry].cmdsts = 0;
        !          1470:                                sis_priv->rx_ring[entry].bufptr = 0;
        !          1471:                                sis_priv->stats.rx_dropped++;
        !          1472:                                break;
        !          1473:                        }
        !          1474:                        skb->dev = net_dev;
        !          1475:                        sis_priv->rx_skbuff[entry] = skb;
        !          1476:                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
        !          1477:                        sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail);
        !          1478:                        sis_priv->dirty_rx++;
        !          1479:                }
        !          1480:                sis_priv->cur_rx++;
        !          1481:                entry = sis_priv->cur_rx % NUM_RX_DESC;
        !          1482:                rx_status = sis_priv->rx_ring[entry].cmdsts;
        !          1483:        } // while
        !          1484: 
        !          1485:        /* refill the Rx buffer, what if the rate of refilling is slower than
        !          1486:           consuming ?? */
        !          1487:        for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
        !          1488:                struct sk_buff *skb;
        !          1489: 
        !          1490:                entry = sis_priv->dirty_rx % NUM_RX_DESC;
        !          1491: 
        !          1492:                if (sis_priv->rx_skbuff[entry] == NULL) {
        !          1493:                        if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
        !          1494:                                /* not enough memory for skbuff, this makes a "hole"
        !          1495:                                   on the buffer ring, it is not clear how the
        !          1496:                                   hardware will react to this kind of degenerated
        !          1497:                                   buffer */
        !          1498:                                printk(KERN_INFO "%s: Memory squeeze,"
        !          1499:                                       "deferring packet.\n",
        !          1500:                                       net_dev->name);
        !          1501:                                sis_priv->stats.rx_dropped++;
        !          1502:                                break;
        !          1503:                        }
        !          1504:                        skb->dev = net_dev;
        !          1505:                        sis_priv->rx_skbuff[entry] = skb;
        !          1506:                        sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
        !          1507:                        sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail);
        !          1508:                }
        !          1509:        }
        !          1510: 
        !          1511:        /* re-enable the potentially idle receive state matchine */
        !          1512:        outl(RxENA | inl(ioaddr + cr), ioaddr + cr );
        !          1513: 
        !          1514:        return 0;
        !          1515: }
        !          1516: 
        !          1517: /* finish up transmission of packets, check for error condition and free skbuff etc.
        !          1518:    Note: This fucntion is called by interrupt handler, don't do "too much" work here */
        !          1519: static void sis900_finish_xmit (struct device *net_dev)
        !          1520: {
        !          1521:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1522: 
        !          1523:        for (; sis_priv->dirty_tx < sis_priv->cur_tx; sis_priv->dirty_tx++) {
        !          1524:                unsigned int entry;
        !          1525:                u32 tx_status;
        !          1526: 
        !          1527:                entry = sis_priv->dirty_tx % NUM_TX_DESC;
        !          1528:                tx_status = sis_priv->tx_ring[entry].cmdsts;
        !          1529: 
        !          1530:                if (tx_status & OWN) {
        !          1531:                        /* The packet is not transmitted yet (owned by hardware) !
        !          1532:                           Note: the interrupt is generated only when Tx Machine
        !          1533:                           is idle, so this is an almost impossible case */
        !          1534:                        break;
        !          1535:                }
        !          1536: 
        !          1537:                if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
        !          1538:                        /* packet unsuccessfully transmitted */
        !          1539:                        if (sis900_debug > 4)
        !          1540:                                printk(KERN_INFO "%s: Transmit "
        !          1541:                                       "error, Tx status %8.8x.\n",
        !          1542:                                       net_dev->name, tx_status);
        !          1543:                        sis_priv->stats.tx_errors++;
        !          1544:                        if (tx_status & UNDERRUN)
        !          1545:                                sis_priv->stats.tx_fifo_errors++;
        !          1546:                        if (tx_status & ABORT)
        !          1547:                                sis_priv->stats.tx_aborted_errors++;
        !          1548:                        if (tx_status & NOCARRIER)
        !          1549:                                sis_priv->stats.tx_carrier_errors++;
        !          1550:                        if (tx_status & OWCOLL)
        !          1551:                                sis_priv->stats.tx_window_errors++;
        !          1552:                } else {
        !          1553:                        /* packet successfully transmitted */
        !          1554:                        sis_priv->stats.collisions += (tx_status & COLCNT) >> 16;
        !          1555:                        /*                      sis_priv->stats.tx_bytes += tx_status & DSIZE;*/
        !          1556:                        sis_priv->stats.tx_packets++;
        !          1557:                }
        !          1558:                /* Free the original skb. */
        !          1559:                dev_free_skb(sis_priv->tx_skbuff[entry]);
        !          1560:                sis_priv->tx_skbuff[entry] = NULL;
        !          1561:                sis_priv->tx_ring[entry].bufptr = 0;
        !          1562:                sis_priv->tx_ring[entry].cmdsts = 0;
        !          1563:        }
        !          1564: 
        !          1565:        if (sis_priv->tx_full && net_dev->tbusy &&
        !          1566:            sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC - 4) {
        !          1567:                /* The ring is no longer full, clear tbusy, tx_full and
        !          1568:                   schedule more transmission by marking NET_BH */
        !          1569:                sis_priv->tx_full = 0;
        !          1570:                clear_bit(0, (void *)&net_dev->tbusy);
        !          1571:                mark_bh(NET_BH);
        !          1572:        }
        !          1573: }
        !          1574: 
        !          1575: static int
        !          1576: sis900_close(struct device *net_dev)
        !          1577: {
        !          1578:        long ioaddr = net_dev->base_addr;
        !          1579:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1580:        int i;
        !          1581: 
        !          1582:        net_dev->start = 0;
        !          1583:        net_dev->tbusy = 1;
        !          1584: 
        !          1585:        /* Disable interrupts by clearing the interrupt mask. */
        !          1586:        outl(0x0000, ioaddr + imr);
        !          1587:        outl(0x0000, ioaddr + ier);
        !          1588: 
        !          1589:        /* Stop the chip's Tx and Rx Status Machine */
        !          1590:        outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
        !          1591: 
        !          1592:        del_timer(&sis_priv->timer);
        !          1593: 
        !          1594:        free_irq(net_dev->irq, net_dev);
        !          1595: 
        !          1596:        /* Free Tx and RX skbuff */
        !          1597:        for (i = 0; i < NUM_RX_DESC; i++) {
        !          1598:                if (sis_priv->rx_skbuff[i] != NULL)
        !          1599:                        dev_free_skb(sis_priv->rx_skbuff[i]);
        !          1600:                sis_priv->rx_skbuff[i] = 0;
        !          1601:        }
        !          1602:        for (i = 0; i < NUM_TX_DESC; i++) {
        !          1603:                if (sis_priv->tx_skbuff[i] != NULL)
        !          1604:                        dev_free_skb(sis_priv->tx_skbuff[i]);
        !          1605:                sis_priv->tx_skbuff[i] = 0;
        !          1606:        }
        !          1607: 
        !          1608:        /* Green! Put the chip in low-power mode. */
        !          1609: 
        !          1610:        MOD_DEC_USE_COUNT;
        !          1611: 
        !          1612:        return 0;
        !          1613: }
        !          1614: 
        !          1615: static int mii_ioctl(struct device *net_dev, struct ifreq *rq, int cmd)
        !          1616: {
        !          1617:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1618:        u16 *data = (u16 *)&rq->ifr_data;
        !          1619: 
        !          1620:        switch(cmd) {
        !          1621:        case SIOCDEVPRIVATE:                    /* Get the address of the PHY in use. */
        !          1622:                data[0] = sis_priv->mii->phy_addr;
        !          1623:                /* Fall Through */
        !          1624:        case SIOCDEVPRIVATE+1:                  /* Read the specified MII register. */
        !          1625:                data[3] = mdio_read(net_dev, data[0] & 0x1f, data[1] & 0x1f);
        !          1626:                return 0;
        !          1627:        case SIOCDEVPRIVATE+2:                  /* Write the specified MII register */
        !          1628:                if (!suser())
        !          1629:                        return -EPERM;
        !          1630:                mdio_write(net_dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
        !          1631:                return 0;
        !          1632:        default:
        !          1633:                return -EOPNOTSUPP;
        !          1634:        }
        !          1635: }
        !          1636: 
        !          1637: static struct enet_statistics *
        !          1638: sis900_get_stats(struct device *net_dev)
        !          1639: {
        !          1640:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1641: 
        !          1642:        return &sis_priv->stats;
        !          1643: }
        !          1644: 
        !          1645: 
        !          1646: /* SiS 900 uses the most sigificant 7 bits to index a 128 bits multicast
        !          1647:  * hash table, which makes this function a little bit different from other drivers
        !          1648:  * SiS 900 B0 & 635 M/B uses the most significat 8 bits to index 256 bits
        !          1649:  * multicast hash table.
        !          1650:  */
        !          1651: static u16 sis900_compute_hashtable_index(u8 *addr, u8 revision)
        !          1652: {
        !          1653: 
        !          1654: /* what is the correct value of the POLYNOMIAL ??
        !          1655:    Donald Becker use 0x04C11DB7U
        !          1656:    Joseph Zbiciak [email protected] gives me the
        !          1657:    correct answer, thank you Joe !! */
        !          1658: #define POLYNOMIAL 0x04C11DB7L
        !          1659:        u32 crc = 0xffffffff, msb;
        !          1660:        int  i, j;
        !          1661:        u32 byte;
        !          1662: 
        !          1663:        for (i = 0; i < 6; i++) {
        !          1664:                byte = *addr++;
        !          1665:                for (j = 0; j < 8; j++) {
        !          1666:                        msb = crc >> 31;
        !          1667:                        crc <<= 1;
        !          1668:                        if (msb ^ (byte & 1)) {
        !          1669:                                crc ^= POLYNOMIAL;
        !          1670:                        }
        !          1671:                        byte >>= 1;
        !          1672:                }
        !          1673:        }
        !          1674: 
        !          1675:        /* leave 8 or 7 most siginifant bits */
        !          1676:        if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
        !          1677:                return ((int)(crc >> 24));
        !          1678:        else
        !          1679:                return ((int)(crc >> 25));
        !          1680: }
        !          1681: 
        !          1682: static void set_rx_mode(struct device *net_dev)
        !          1683: {
        !          1684:        long ioaddr = net_dev->base_addr;
        !          1685:        struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
        !          1686:        u16 mc_filter[16] = {0};        /* 256/128 bits multicast hash table */
        !          1687:        int i, table_entries;
        !          1688:        u32 rx_mode;
        !          1689:        u8 revision;
        !          1690: 
        !          1691:        /* 635 Hash Table entires = 256(2^16) */
        !          1692:        pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION, &revision);
        !          1693:        if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
        !          1694:                table_entries = 16;
        !          1695:        else
        !          1696:                table_entries = 8;
        !          1697: 
        !          1698:        if (net_dev->flags & IFF_PROMISC) {
        !          1699:                /* Accept any kinds of packets */
        !          1700:                rx_mode = RFPromiscuous;
        !          1701:                for (i = 0; i < table_entries; i++)
        !          1702:                        mc_filter[i] = 0xffff;
        !          1703:        } else if ((net_dev->mc_count > multicast_filter_limit) ||
        !          1704:                   (net_dev->flags & IFF_ALLMULTI)) {
        !          1705:                /* too many multicast addresses or accept all multicast packets */
        !          1706:                rx_mode = RFAAB | RFAAM;
        !          1707:                for (i = 0; i < table_entries; i++)
        !          1708:                        mc_filter[i] = 0xffff;
        !          1709:        } else {
        !          1710:                /* Accept Broadcast packets, destination addresses match our MAC address,
        !          1711:                   use Receive Filter to reject unwanted MCAST packets */
        !          1712:                struct dev_mc_list *mclist;
        !          1713:                rx_mode = RFAAB;
        !          1714:                for (i = 0, mclist = net_dev->mc_list; mclist && i < net_dev->mc_count;
        !          1715:                     i++, mclist = mclist->next)
        !          1716:                        set_bit(sis900_compute_hashtable_index(mclist->dmi_addr, revision),
        !          1717:                                mc_filter);
        !          1718:        }
        !          1719: 
        !          1720:        /* update Multicast Hash Table in Receive Filter */
        !          1721:        for (i = 0; i < table_entries; i++) {
        !          1722:                /* why plus 0x04 ??, That makes the correct value for hash table. */
        !          1723:                outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
        !          1724:                outl(mc_filter[i], ioaddr + rfdr);
        !          1725:        }
        !          1726: 
        !          1727:        outl(RFEN | rx_mode, ioaddr + rfcr);
        !          1728: 
        !          1729:        /* sis900 is capatable of looping back packet at MAC level for debugging purpose */
        !          1730:        if (net_dev->flags & IFF_LOOPBACK) {
        !          1731:                u32 cr_saved;
        !          1732:                /* We must disable Tx/Rx before setting loopback mode */
        !          1733:                cr_saved = inl(ioaddr + cr);
        !          1734:                outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);
        !          1735:                /* enable loopback */
        !          1736:                outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);
        !          1737:                outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);
        !          1738:                /* restore cr */
        !          1739:                outl(cr_saved, ioaddr + cr);
        !          1740:        }               
        !          1741: 
        !          1742:        return;
        !          1743: }
        !          1744: 
        !          1745: static void sis900_reset(struct device *net_dev)
        !          1746: {
        !          1747:        long ioaddr = net_dev->base_addr;
        !          1748:        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
        !          1749:        int i = 0;
        !          1750:        u8 revision;
        !          1751:        u32 status = TxRCMP | RxRCMP;
        !          1752: 
        !          1753:        outl(0, ioaddr + ier);
        !          1754:        outl(0, ioaddr + imr);
        !          1755:        outl(0, ioaddr + rfcr);
        !          1756: 
        !          1757:        outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
        !          1758:        
        !          1759:        /* Check that the chip has finished the reset. */
        !          1760:        while (status && (i++ < 1000)) {
        !          1761:                status ^= (inl(isr + ioaddr) & status);
        !          1762:        }
        !          1763: 
        !          1764:        pcibios_read_config_byte(sis_priv->pci_bus, sis_priv->pci_device_fn, PCI_CLASS_REVISION, &revision);
        !          1765:        if( (revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV) )
        !          1766:                outl(PESEL | RND_CNT, ioaddr + cfg);
        !          1767:        else
        !          1768:                outl(PESEL, ioaddr + cfg);
        !          1769: }
        !          1770: 
        !          1771: #ifdef MODULE
        !          1772: int init_module(void)
        !          1773: {
        !          1774:        return sis900_probe(NULL);
        !          1775: }
        !          1776: 
        !          1777: void
        !          1778: cleanup_module(void)
        !          1779: {
        !          1780:        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
        !          1781:        while (root_sis900_dev) {
        !          1782:                struct sis900_private *sis_priv =
        !          1783:                        (struct sis900_private *)root_sis900_dev->priv;
        !          1784:                struct device *next_dev = sis_priv->next_module;
        !          1785:                struct mii_phy *phy = NULL;
        !          1786: 
        !          1787:                while(sis_priv->first_mii){
        !          1788:                        phy = sis_priv->first_mii;
        !          1789:                        sis_priv->first_mii = phy->next;
        !          1790:                        kfree(phy);
        !          1791:                }
        !          1792: 
        !          1793:                unregister_netdev(root_sis900_dev);
        !          1794:                release_region(root_sis900_dev->base_addr,
        !          1795:                               sis_priv->mac->io_size);
        !          1796:                kfree(sis_priv);
        !          1797:                kfree(root_sis900_dev);
        !          1798: 
        !          1799:                root_sis900_dev = next_dev;
        !          1800:        }
        !          1801: }
        !          1802: 
        !          1803: #endif /* MODULE */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.