iPXE
sis190.c
Go to the documentation of this file.
00001 /*
00002    sis190.c: Silicon Integrated Systems SiS190 ethernet driver
00003 
00004    Copyright (c) 2003 K.M. Liu <kmliu@sis.com>
00005    Copyright (c) 2003, 2004 Jeff Garzik <jgarzik@pobox.com>
00006    Copyright (c) 2003, 2004, 2005 Francois Romieu <romieu@fr.zoreil.com>
00007 
00008    Modified for iPXE 2009 by Thomas Miletich <thomas.miletich@gmail.com>
00009 
00010    Based on r8169.c, tg3.c, 8139cp.c, skge.c, epic100.c and SiS 190/191
00011    genuine driver.
00012 
00013    This software may be used and distributed according to the terms of
00014    the GNU General Public License (GPL), incorporated herein by reference.
00015    Drivers based on or derived from this code fall under the GPL and must
00016    retain the authorship, copyright and license notice.  This file is not
00017    a complete program and may only be used when the entire operating
00018    system is licensed under the GPL.
00019 
00020    See the file COPYING in this distribution for more information.
00021 
00022  */
00023 
00024 FILE_LICENCE ( GPL_ANY );
00025 
00026 #include "sis190.h"
00027 
00028 static struct pci_device_id sis190_pci_tbl[] = {
00029         PCI_ROM (0x1039, 0x0190, "sis190", "sis190", 0),
00030         PCI_ROM (0x1039, 0x0191, "sis191", "sis191", 0),
00031 };
00032 
00033 /******************************************************************************
00034  *************** HACK to keep ISA bridge in the PCI device list ***************
00035  ******************************************************************************/
00036 
00037 /* Some sis190 variants store the MAC address in the BIOS CMOS. To read it, we
00038  * have to use a PCI to ISA bridge. To access the bridge we need a few things
00039  * from it's struct pci_device. We fake the successful probe of a driver to
00040  * keep the bridge's struct pci_device in the list of pci_devices.
00041  * See details in sis190_get_mac_addr_from_apc().
00042  */
00043 
00044 static struct pci_device_id sis190_isa_bridge_tbl[] = {
00045         PCI_ID (0x1039, 0x0965, "", "", 0),
00046         PCI_ID (0x1039, 0x0966, "", "", 0),
00047         PCI_ID (0x1039, 0x0968, "", "", 0),
00048 };
00049 
00050 static int sis190_isa_bridge_probe(struct pci_device *pdev __unused)
00051 {
00052         return 0;
00053 }
00054 
00055 static void sis190_isa_bridge_remove(struct pci_device *pdev __unused)
00056 {
00057         return;
00058 }
00059 
00060 struct pci_driver sis190_isa_bridge_driver __pci_driver = {
00061         .ids            = sis190_isa_bridge_tbl,
00062         .id_count       = (sizeof(sis190_isa_bridge_tbl) /
00063                            sizeof(sis190_isa_bridge_tbl[0])),
00064         .probe          = sis190_isa_bridge_probe,
00065         .remove         = sis190_isa_bridge_remove,
00066 };
00067 
00068 /******************************************************************************
00069  *********************************** </HACK> **********************************
00070  ******************************************************************************/
00071 
00072 static const u32 sis190_intr_mask =
00073         RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
00074 
00075 static void __mdio_cmd(void *ioaddr, u32 ctl)
00076 {
00077         unsigned int i;
00078 
00079         SIS_W32(GMIIControl, ctl);
00080 
00081         mdelay(1);
00082 
00083         for (i = 0; i < 100; i++) {
00084                 if (!(SIS_R32(GMIIControl) & EhnMIInotDone))
00085                         break;
00086                 mdelay(1);
00087         }
00088 
00089         if (i > 99)
00090                 DBG("sis190: PHY command timed out !\n");
00091 }
00092 
00093 static void mdio_write(void *ioaddr, int phy_id, int reg, int val)
00094 {
00095         __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite |
00096                 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) |
00097                 (((u32) val) << EhnMIIdataShift));
00098 }
00099 
00100 static int mdio_read(void *ioaddr, int phy_id, int reg)
00101 {
00102         __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread |
00103                 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift));
00104 
00105         return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift);
00106 }
00107 
00108 static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val)
00109 {
00110         struct sis190_private *tp = netdev_priv(dev);
00111 
00112         mdio_write(tp->mmio_addr, phy_id, reg, val);
00113 }
00114 
00115 static int __mdio_read(struct net_device *dev, int phy_id, int reg)
00116 {
00117         struct sis190_private *tp = netdev_priv(dev);
00118 
00119         return mdio_read(tp->mmio_addr, phy_id, reg);
00120 }
00121 
00122 static u16 mdio_read_latched(void *ioaddr, int phy_id, int reg)
00123 {
00124         mdio_read(ioaddr, phy_id, reg);
00125         return mdio_read(ioaddr, phy_id, reg);
00126 }
00127 
00128 static u16 sis190_read_eeprom(void *ioaddr, u32 reg)
00129 {
00130         u16 data = 0xffff;
00131         unsigned int i;
00132 
00133         if (!(SIS_R32(ROMControl) & 0x0002))
00134                 return 0;
00135 
00136         SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
00137 
00138         for (i = 0; i < 200; i++) {
00139                 if (!(SIS_R32(ROMInterface) & EEREQ)) {
00140                         data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
00141                         break;
00142                 }
00143                 mdelay(1);
00144         }
00145 
00146         return data;
00147 }
00148 
00149 static void sis190_irq_mask_and_ack(void *ioaddr)
00150 {
00151         SIS_W32(IntrMask, 0x00);
00152         SIS_W32(IntrStatus, 0xffffffff);
00153         SIS_PCI_COMMIT();
00154 }
00155 
00156 static void sis190_asic_down(void *ioaddr)
00157 {
00158         /* Stop the chip's Tx and Rx DMA processes. */
00159 
00160         SIS_W32(TxControl, 0x1a00);
00161         SIS_W32(RxControl, 0x1a00);
00162 
00163         sis190_irq_mask_and_ack(ioaddr);
00164 }
00165 
00166 static inline void sis190_mark_as_last_descriptor(struct RxDesc *desc)
00167 {
00168         desc->size |= cpu_to_le32(RingEnd);
00169 }
00170 
00171 static inline void sis190_give_to_asic(struct RxDesc *desc)
00172 {
00173         u32 eor = le32_to_cpu(desc->size) & RingEnd;
00174 
00175         desc->PSize = 0x0;
00176         desc->size = cpu_to_le32((RX_BUF_SIZE & RX_BUF_MASK) | eor);
00177         wmb();
00178         desc->status = cpu_to_le32(OWNbit | INTbit);
00179 }
00180 
00181 static inline void sis190_map_to_asic(struct RxDesc *desc, u32 mapping)
00182 {
00183         desc->addr = cpu_to_le32(mapping);
00184         sis190_give_to_asic(desc);
00185 }
00186 
00187 static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
00188 {
00189         desc->PSize = 0x0;
00190         desc->addr = cpu_to_le32(0xdeadbeef);
00191         desc->size &= cpu_to_le32(RingEnd);
00192         wmb();
00193         desc->status = 0x0;
00194 }
00195 
00196 static struct io_buffer *sis190_alloc_rx_iob(struct RxDesc *desc)
00197 {
00198         struct io_buffer *iob;
00199 
00200         iob = alloc_iob(RX_BUF_SIZE);
00201         if (iob) {
00202                 u32 mapping;
00203 
00204                 mapping = virt_to_bus(iob->data);
00205                 sis190_map_to_asic(desc, mapping);
00206         } else {
00207                 DBG("sis190: alloc_iob failed\n");
00208                 sis190_make_unusable_by_asic(desc);
00209         }
00210 
00211         return iob;
00212 }
00213 
00214 static u32 sis190_rx_fill(struct sis190_private *tp, u32 start, u32 end)
00215 {
00216         u32 cur;
00217 
00218         for (cur = start; cur < end; cur++) {
00219                 unsigned int i = cur % NUM_RX_DESC;
00220 
00221                 if (tp->Rx_iobuf[i])
00222                         continue;
00223 
00224                 tp->Rx_iobuf[i] = sis190_alloc_rx_iob(tp->RxDescRing + i);
00225 
00226                 if (!tp->Rx_iobuf[i])
00227                         break;
00228         }
00229         return cur - start;
00230 }
00231 
00232 static inline int sis190_rx_pkt_err(u32 status)
00233 {
00234 #define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
00235 
00236         if ((status & CRCOK) && !(status & ErrMask))
00237                 return 0;
00238 
00239         return -1;
00240 }
00241 
00242 static int sis190_process_rx(struct sis190_private *tp)
00243 {
00244         u32 rx_left, cur_rx = tp->cur_rx;
00245         u32 delta, count;
00246 
00247         rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
00248 
00249         for (; rx_left > 0; rx_left--, cur_rx++) {
00250                 unsigned int entry = cur_rx % NUM_RX_DESC;
00251                 struct RxDesc *desc = tp->RxDescRing + entry;
00252                 u32 status;
00253 
00254                 if (le32_to_cpu(desc->status) & OWNbit)
00255                         break;
00256 
00257                 status = le32_to_cpu(desc->PSize);
00258 
00259                 if (sis190_rx_pkt_err(status) < 0) {
00260                         sis190_give_to_asic(desc);
00261                 } else {
00262                         struct io_buffer *iob = tp->Rx_iobuf[entry];
00263                         unsigned int pkt_size = (status & RxSizeMask) - 4;
00264 
00265                         if (pkt_size > RX_BUF_SIZE) {
00266                                 DBG("sis190: (frag) status = %08x.\n", status);
00267                                 sis190_give_to_asic(desc);
00268                                 continue;
00269                         }
00270 
00271                         sis190_make_unusable_by_asic(desc);
00272 
00273                         iob_put(iob, pkt_size);
00274 
00275                         DBG2("sis190: received packet. len: %d\n", pkt_size);
00276                         netdev_rx(tp->dev, iob);
00277                         DBGIO_HD(iob->data, 60);
00278                         tp->Rx_iobuf[entry] = NULL;
00279                 }
00280         }
00281         count = cur_rx - tp->cur_rx;
00282         tp->cur_rx = cur_rx;
00283 
00284         delta = sis190_rx_fill(tp, tp->dirty_rx, tp->cur_rx);
00285         if (!delta && count)
00286                 DBG("sis190: no Rx buffer allocated.\n");
00287         tp->dirty_rx += delta;
00288 
00289         if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx))
00290                 DBG("sis190: Rx buffers exhausted.\n");
00291 
00292         return count;
00293 }
00294 
00295 static inline int sis190_tx_pkt_err(u32 status)
00296 {
00297 #define TxErrMask (WND | TABRT | FIFO | LINK)
00298 
00299         if (!(status & TxErrMask))
00300                 return 0;
00301 
00302         return -1;
00303 }
00304 
00305 static void sis190_process_tx(struct sis190_private *tp)
00306 {
00307         u32 pending, dirty_tx = tp->dirty_tx;
00308 
00309         pending = tp->cur_tx - dirty_tx;
00310 
00311         for (; pending; pending--, dirty_tx++) {
00312                 unsigned int entry = dirty_tx % NUM_TX_DESC;
00313                 struct TxDesc *txd = tp->TxDescRing + entry;
00314                 u32 status = le32_to_cpu(txd->status);
00315                 struct io_buffer *iob;
00316 
00317                 if (status & OWNbit)
00318                         break;
00319 
00320                 iob = tp->Tx_iobuf[entry];
00321 
00322                 if (!iob)
00323                         break;
00324 
00325                 if (sis190_tx_pkt_err(status) == 0) {
00326                         DBG2("sis190: Transmitted packet: %#08x\n", status);
00327                         netdev_tx_complete(tp->dev, iob);
00328                 } else {
00329                         DBG("sis190: Transmit error: %#08x\n", status);
00330                         netdev_tx_complete_err(tp->dev, iob, -EINVAL);
00331                 }
00332 
00333                 tp->Tx_iobuf[entry] = NULL;
00334         }
00335 
00336         if (tp->dirty_tx != dirty_tx)
00337                 tp->dirty_tx = dirty_tx;
00338 }
00339 
00340 /*
00341  * The interrupt handler does all of the Rx thread work and cleans up after
00342  * the Tx thread.
00343  */
00344 static void sis190_poll(struct net_device *dev)
00345 {
00346         struct sis190_private *tp = netdev_priv(dev);
00347         void  *ioaddr = tp->mmio_addr;
00348         u32 status;
00349 
00350         status = SIS_R32(IntrStatus);
00351 
00352         if ((status == 0xffffffff) || !status)
00353                 return;
00354 
00355         SIS_W32(IntrStatus, status);
00356 
00357         /* sis190_phy_task() needs to be called in event of a LinkChange and
00358          * after auto-negotiation is finished. Finishing auto-neg won't generate
00359          * any indication, hence we call it every time if the link is bad. */
00360         if ((status & LinkChange) || !netdev_link_ok(dev))
00361                 sis190_phy_task(tp);
00362 
00363         if (status & RxQInt)
00364                 sis190_process_rx(tp);
00365 
00366         if (status & TxQ0Int)
00367                 sis190_process_tx(tp);
00368 }
00369 
00370 static inline void sis190_init_ring_indexes(struct sis190_private *tp)
00371 {
00372         tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
00373 }
00374 
00375 static int sis190_init_ring(struct net_device *dev)
00376 {
00377         struct sis190_private *tp = netdev_priv(dev);
00378 
00379         sis190_init_ring_indexes(tp);
00380 
00381         memset(tp->Tx_iobuf, 0, NUM_TX_DESC * sizeof(struct io_buffer *));
00382         memset(tp->Rx_iobuf, 0, NUM_RX_DESC * sizeof(struct io_buffer *));
00383 
00384         if (sis190_rx_fill(tp, 0, NUM_RX_DESC) != NUM_RX_DESC)
00385                 goto err;
00386 
00387         sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
00388 
00389         return 0;
00390 
00391 err:
00392         sis190_free(dev);
00393         return -ENOMEM;
00394 }
00395 
00396 static void sis190_set_rx_mode(struct net_device *dev)
00397 {
00398         struct sis190_private *tp = netdev_priv(dev);
00399         void *ioaddr = tp->mmio_addr;
00400         u32 mc_filter[2];       /* Multicast hash filter */
00401         u16 rx_mode;
00402 
00403         rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
00404         mc_filter[1] = mc_filter[0] = 0xffffffff;
00405 
00406         SIS_W16(RxMacControl, rx_mode | 0x2);
00407         SIS_W32(RxHashTable, mc_filter[0]);
00408         SIS_W32(RxHashTable + 4, mc_filter[1]);
00409 
00410 }
00411 
00412 static void sis190_soft_reset(void  *ioaddr)
00413 {
00414         SIS_W32(IntrControl, 0x8000);
00415         SIS_PCI_COMMIT();
00416         SIS_W32(IntrControl, 0x0);
00417         sis190_asic_down(ioaddr);
00418 }
00419 
00420 static void sis190_hw_start(struct net_device *dev)
00421 {
00422         struct sis190_private *tp = netdev_priv(dev);
00423         void *ioaddr = tp->mmio_addr;
00424 
00425         sis190_soft_reset(ioaddr);
00426 
00427         SIS_W32(TxDescStartAddr, tp->tx_dma);
00428         SIS_W32(RxDescStartAddr, tp->rx_dma);
00429 
00430         SIS_W32(IntrStatus, 0xffffffff);
00431         SIS_W32(IntrMask, 0x0);
00432         SIS_W32(GMIIControl, 0x0);
00433         SIS_W32(TxMacControl, 0x60);
00434         SIS_W16(RxMacControl, 0x02);
00435         SIS_W32(RxHashTable, 0x0);
00436         SIS_W32(0x6c, 0x0);
00437         SIS_W32(RxWolCtrl, 0x0);
00438         SIS_W32(RxWolData, 0x0);
00439 
00440         SIS_PCI_COMMIT();
00441 
00442         sis190_set_rx_mode(dev);
00443 
00444         SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
00445         SIS_W32(RxControl, 0x1a1d);
00446 }
00447 
00448 static void sis190_phy_task(struct sis190_private *tp)
00449 {
00450         struct net_device *dev = tp->dev;
00451         void *ioaddr = tp->mmio_addr;
00452         int phy_id = tp->mii_if.phy_id;
00453         int cnt = 0;
00454         u16 val;
00455 
00456         val = mdio_read(ioaddr, phy_id, MII_BMCR);
00457 
00458         /* 100ms timeout is completely arbitrary. I have no datasheet to
00459          * check whether that's a sensible value or not.
00460          */
00461         while ((val & BMCR_RESET) && (cnt < 100)) {
00462                 val = mdio_read(ioaddr, phy_id, MII_BMCR);
00463                 mdelay(1);
00464                 cnt++;
00465         }
00466 
00467         if (cnt > 99) {
00468                 DBG("sis190: BMCR_RESET timeout\n");
00469                 return;
00470         }
00471 
00472         if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
00473                      BMSR_ANEGCOMPLETE)) {
00474                 DBG("sis190: auto-negotiating...\n");
00475                 netdev_link_down(dev);
00476         } else {
00477                 /* Rejoice ! */
00478                 struct {
00479                         int val;
00480                         u32 ctl;
00481                         const char *msg;
00482                 } reg31[] = {
00483                         { LPA_1000FULL, 0x07000c00 | 0x00001000,
00484                                 "1000 Mbps Full Duplex" },
00485                         { LPA_1000HALF, 0x07000c00,
00486                                 "1000 Mbps Half Duplex" },
00487                         { LPA_100FULL, 0x04000800 | 0x00001000,
00488                                 "100 Mbps Full Duplex" },
00489                         { LPA_100HALF, 0x04000800,
00490                                 "100 Mbps Half Duplex" },
00491                         { LPA_10FULL, 0x04000400 | 0x00001000,
00492                                 "10 Mbps Full Duplex" },
00493                         { LPA_10HALF, 0x04000400,
00494                                 "10 Mbps Half Duplex" },
00495                         { 0, 0x04000400, "unknown" }
00496                 }, *p = NULL;
00497                 u16 adv, autoexp, gigadv, gigrec;
00498 
00499                 val = mdio_read(ioaddr, phy_id, 0x1f);
00500 
00501                 val = mdio_read(ioaddr, phy_id, MII_LPA);
00502                 adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
00503 
00504                 autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
00505 
00506                 if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
00507                         /* check for gigabit speed */
00508                         gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
00509                         gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
00510                         val = (gigadv & (gigrec >> 2));
00511                         if (val & ADVERTISE_1000FULL)
00512                                 p = reg31;
00513                         else if (val & ADVERTISE_1000HALF)
00514                                 p = reg31 + 1;
00515                 }
00516 
00517                 if (!p) {
00518                         val &= adv;
00519 
00520                         for (p = reg31; p->val; p++) {
00521                                 if ((val & p->val) == p->val)
00522                                         break;
00523                         }
00524                 }
00525 
00526                 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
00527 
00528                 if ((tp->features & F_HAS_RGMII) &&
00529                     (tp->features & F_PHY_BCM5461)) {
00530                         // Set Tx Delay in RGMII mode.
00531                         mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
00532                         udelay(200);
00533                         mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
00534                         p->ctl |= 0x03000000;
00535                 }
00536 
00537                 SIS_W32(StationControl, p->ctl);
00538 
00539                 if (tp->features & F_HAS_RGMII) {
00540                         SIS_W32(RGDelay, 0x0441);
00541                         SIS_W32(RGDelay, 0x0440);
00542                 }
00543 
00544                 DBG("sis190: link on %s mode.\n", p->msg);
00545                 netdev_link_up(dev);
00546         }
00547 }
00548 
00549 static int sis190_open(struct net_device *dev)
00550 {
00551         struct sis190_private *tp = netdev_priv(dev);
00552         int rc;
00553 
00554         /* Allocate TX ring */
00555         tp->TxDescRing = malloc_dma(TX_RING_BYTES, RING_ALIGNMENT);
00556         if (!tp->TxDescRing) {
00557                 DBG("sis190: TX ring allocation failed\n");
00558                 rc = -ENOMEM;
00559                 goto out;
00560         }
00561         tp->tx_dma = cpu_to_le32(virt_to_bus(tp->TxDescRing));
00562 
00563         /* Allocate RX ring */
00564         tp->RxDescRing = malloc_dma(RX_RING_BYTES, RING_ALIGNMENT);
00565         if (!tp->RxDescRing) {
00566                 DBG("sis190: RX ring allocation failed\n");
00567                 rc = -ENOMEM;
00568                 goto error;
00569         }
00570         tp->rx_dma = cpu_to_le32(virt_to_bus(tp->RxDescRing));
00571 
00572         rc = sis190_init_ring(dev);
00573         if (rc < 0)
00574                 goto error;
00575 
00576         /* init rx filter, also program MAC address to card */
00577         sis190_init_rxfilter(dev);
00578 
00579         sis190_hw_start(dev);
00580 out:
00581         return rc;
00582 
00583 error:
00584         sis190_free(dev);
00585         goto out;
00586 }
00587 
00588 static void sis190_down(struct net_device *dev)
00589 {
00590         struct sis190_private *tp = netdev_priv(dev);
00591         void  *ioaddr = tp->mmio_addr;
00592 
00593         do {
00594                 sis190_asic_down(ioaddr);
00595         } while (SIS_R32(IntrMask));
00596 }
00597 
00598 static void sis190_free(struct net_device *dev)
00599 {
00600         struct sis190_private *tp = netdev_priv(dev);
00601         int i;
00602 
00603         free_dma(tp->TxDescRing, TX_RING_BYTES);
00604         free_dma(tp->RxDescRing, RX_RING_BYTES);
00605 
00606         tp->TxDescRing = NULL;
00607         tp->RxDescRing = NULL;
00608 
00609         tp->tx_dma = 0;
00610         tp->rx_dma = 0;
00611 
00612         tp->cur_tx = tp->dirty_tx = 0;
00613         tp->cur_rx = tp->dirty_rx = 0;
00614 
00615         for (i = 0; i < NUM_RX_DESC; i++) {
00616                 free_iob(tp->Rx_iobuf[i]);
00617                 tp->Rx_iobuf[i] = NULL;
00618         }
00619 
00620         /* tx io_buffers aren't owned by the driver, so don't free them */
00621         for(i = 0; i < NUM_TX_DESC; i++)
00622                 tp->Tx_iobuf[i] = NULL;
00623 }
00624 
00625 static void sis190_close(struct net_device *dev)
00626 {
00627         sis190_down(dev);
00628         sis190_free(dev);
00629 }
00630 
00631 static int sis190_transmit(struct net_device *dev, struct io_buffer *iob)
00632 {
00633         struct sis190_private *tp = netdev_priv(dev);
00634         void  *ioaddr = tp->mmio_addr;
00635         u32 len, entry;
00636         struct TxDesc *desc;
00637 
00638         len = iob_len(iob);
00639         if (len < ETH_ZLEN) {
00640                 iob_pad(iob, ETH_ZLEN);
00641                 len = ETH_ZLEN;
00642         }
00643 
00644         entry = tp->cur_tx % NUM_TX_DESC;
00645         desc = tp->TxDescRing + entry;
00646 
00647         if (le32_to_cpu(desc->status) & OWNbit) {
00648                 DBG("sis190: Tx Ring full\n");
00649                 return -EINVAL;
00650         }
00651 
00652         tp->Tx_iobuf[entry] = iob;
00653 
00654         desc->PSize = cpu_to_le32(len);
00655         desc->addr = cpu_to_le32(virt_to_bus(iob->data));
00656 
00657         desc->size = cpu_to_le32(len);
00658         if (entry == (NUM_TX_DESC - 1))
00659                 desc->size |= cpu_to_le32(RingEnd);
00660 
00661         wmb();
00662 
00663         desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
00664 
00665         tp->cur_tx++;
00666 
00667         SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
00668 
00669         return 0;
00670 }
00671 
00672 static void sis190_free_phy(struct list_head *first_phy)
00673 {
00674         struct sis190_phy *cur, *next;
00675 
00676         list_for_each_entry_safe(cur, next, first_phy, list) {
00677                 free(cur);
00678         }
00679 }
00680 
00681 /**
00682  *      sis190_default_phy - Select default PHY for sis190 mac.
00683  *      @dev: the net device to probe for
00684  *
00685  *      Select first detected PHY with link as default.
00686  *      If no one is link on, select PHY whose types is HOME as default.
00687  *      If HOME doesn't exist, select LAN.
00688  */
00689 static u16 sis190_default_phy(struct sis190_private *tp)
00690 {
00691         struct sis190_phy *phy, *phy_home, *phy_default, *phy_lan;
00692         struct mii_if_info *mii_if = &tp->mii_if;
00693         void  *ioaddr = tp->mmio_addr;
00694         u16 status;
00695 
00696         phy_home = phy_default = phy_lan = NULL;
00697 
00698         list_for_each_entry(phy, &tp->first_phy, list) {
00699                 status = mdio_read_latched(ioaddr, phy->phy_id, MII_BMSR);
00700 
00701                 // Link ON & Not select default PHY & not ghost PHY.
00702                 if ((status & BMSR_LSTATUS) &&
00703                     !phy_default &&
00704                     (phy->type != UNKNOWN)) {
00705                         phy_default = phy;
00706                 } else {
00707                         status = mdio_read(ioaddr, phy->phy_id, MII_BMCR);
00708                         mdio_write(ioaddr, phy->phy_id, MII_BMCR,
00709                                    status | BMCR_ANENABLE | BMCR_ISOLATE);
00710                         if (phy->type == HOME)
00711                                 phy_home = phy;
00712                         else if (phy->type == LAN)
00713                                 phy_lan = phy;
00714                 }
00715         }
00716 
00717         if (!phy_default) {
00718                 if (phy_home)
00719                         phy_default = phy_home;
00720                 else if (phy_lan)
00721                         phy_default = phy_lan;
00722                 else
00723                         phy_default = list_entry(&tp->first_phy,
00724                                                  struct sis190_phy, list);
00725         }
00726 
00727         if (mii_if->phy_id != phy_default->phy_id) {
00728                 mii_if->phy_id = phy_default->phy_id;
00729                 DBG("sis190: Using transceiver at address %d as default.\n",
00730                      mii_if->phy_id);
00731         }
00732 
00733         status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR);
00734         status &= (~BMCR_ISOLATE);
00735 
00736         mdio_write(ioaddr, mii_if->phy_id, MII_BMCR, status);
00737         status = mdio_read_latched(ioaddr, mii_if->phy_id, MII_BMSR);
00738 
00739         return status;
00740 }
00741 
00742 static void sis190_init_phy(struct sis190_private *tp,
00743                             struct sis190_phy *phy, unsigned int phy_id,
00744                             u16 mii_status)
00745 {
00746         void *ioaddr = tp->mmio_addr;
00747         struct mii_chip_info *p;
00748 
00749         INIT_LIST_HEAD(&phy->list);
00750         phy->status = mii_status;
00751         phy->phy_id = phy_id;
00752 
00753         phy->id[0] = mdio_read(ioaddr, phy_id, MII_PHYSID1);
00754         phy->id[1] = mdio_read(ioaddr, phy_id, MII_PHYSID2);
00755 
00756         for (p = mii_chip_table; p->type; p++) {
00757                 if ((p->id[0] == phy->id[0]) &&
00758                     (p->id[1] == (phy->id[1] & 0xfff0))) {
00759                         break;
00760                 }
00761         }
00762 
00763         if (p->id[1]) {
00764                 phy->type = (p->type == MIX) ?
00765                         ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
00766                                 LAN : HOME) : p->type;
00767                 tp->features |= p->feature;
00768 
00769                 DBG("sis190: %s transceiver at address %d.\n", p->name, phy_id);
00770         } else {
00771                 phy->type = UNKNOWN;
00772 
00773                 DBG("sis190: unknown PHY 0x%x:0x%x transceiver at address %d\n",
00774                     phy->id[0], (phy->id[1] & 0xfff0), phy_id);
00775         }
00776 }
00777 
00778 static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
00779 {
00780         if (tp->features & F_PHY_88E1111) {
00781                 void *ioaddr = tp->mmio_addr;
00782                 int phy_id = tp->mii_if.phy_id;
00783                 u16 reg[2][2] = {
00784                         { 0x808b, 0x0ce1 },
00785                         { 0x808f, 0x0c60 }
00786                 }, *p;
00787 
00788                 p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
00789 
00790                 mdio_write(ioaddr, phy_id, 0x1b, p[0]);
00791                 udelay(200);
00792                 mdio_write(ioaddr, phy_id, 0x14, p[1]);
00793                 udelay(200);
00794         }
00795 }
00796 
00797 /**
00798  *      sis190_mii_probe - Probe MII PHY for sis190
00799  *      @dev: the net device to probe for
00800  *
00801  *      Search for total of 32 possible mii phy addresses.
00802  *      Identify and set current phy if found one,
00803  *      return error if it failed to found.
00804  */
00805 static int sis190_mii_probe(struct net_device *dev)
00806 {
00807         struct sis190_private *tp = netdev_priv(dev);
00808         struct mii_if_info *mii_if = &tp->mii_if;
00809         void *ioaddr = tp->mmio_addr;
00810         int phy_id;
00811         int rc = 0;
00812 
00813         INIT_LIST_HEAD(&tp->first_phy);
00814 
00815         for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
00816                 struct sis190_phy *phy;
00817                 u16 status;
00818 
00819                 status = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
00820 
00821                 // Try next mii if the current one is not accessible.
00822                 if (status == 0xffff || status == 0x0000)
00823                         continue;
00824 
00825                 phy = zalloc(sizeof(*phy));
00826                 if (!phy) {
00827                         sis190_free_phy(&tp->first_phy);
00828                         rc = -ENOMEM;
00829                         goto out;
00830                 }
00831 
00832                 DBG("sis190: found PHY\n");
00833 
00834                 sis190_init_phy(tp, phy, phy_id, status);
00835 
00836                 list_add(&tp->first_phy, &phy->list);
00837         }
00838 
00839         if (list_empty(&tp->first_phy)) {
00840                 DBG("sis190: No MII transceivers found!\n");
00841                 rc = -EIO;
00842                 goto out;
00843         }
00844 
00845         /* Select default PHY for mac */
00846         sis190_default_phy(tp);
00847 
00848         sis190_mii_probe_88e1111_fixup(tp);
00849 
00850         mii_if->dev = dev;
00851         mii_if->mdio_read = __mdio_read;
00852         mii_if->mdio_write = __mdio_write;
00853         mii_if->phy_id_mask = PHY_ID_ANY;
00854         mii_if->reg_num_mask = MII_REG_ANY;
00855 out:
00856         return rc;
00857 }
00858 
00859 static void sis190_mii_remove(struct net_device *dev)
00860 {
00861         struct sis190_private *tp = netdev_priv(dev);
00862 
00863         sis190_free_phy(&tp->first_phy);
00864 }
00865 
00866 static int sis190_init_board(struct pci_device *pdev, struct net_device **netdev)
00867 {
00868         struct sis190_private *tp;
00869         struct net_device *dev;
00870         void *ioaddr;
00871         int rc;
00872 
00873         dev = alloc_etherdev(sizeof(*tp));
00874         if (!dev) {
00875                 DBG("sis190: unable to alloc new etherdev\n");
00876                 rc = -ENOMEM;
00877                 goto err;
00878         }
00879 
00880         dev->dev = &pdev->dev;
00881 
00882         tp = netdev_priv(dev);
00883         memset(tp, 0, sizeof(*tp));
00884 
00885         tp->dev = dev;
00886 
00887         adjust_pci_device(pdev);
00888 
00889         ioaddr = ioremap(pdev->membase, SIS190_REGS_SIZE);
00890         if (!ioaddr) {
00891                 DBG("sis190: cannot remap MMIO, aborting\n");
00892                 rc = -EIO;
00893                 goto err;
00894         }
00895 
00896         tp->pci_device = pdev;
00897         tp->mmio_addr = ioaddr;
00898 
00899         sis190_irq_mask_and_ack(ioaddr);
00900 
00901         sis190_soft_reset(ioaddr);
00902 
00903         *netdev = dev;
00904 
00905         return 0;
00906 
00907 err:
00908         return rc;
00909 }
00910 
00911 static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
00912 {
00913         tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
00914 }
00915 
00916 static int sis190_get_mac_addr_from_eeprom(struct pci_device *pdev __unused,
00917                                                      struct net_device *dev)
00918 {
00919         struct sis190_private *tp = netdev_priv(dev);
00920         void *ioaddr = tp->mmio_addr;
00921         u16 sig;
00922         int i;
00923 
00924         DBG("sis190: Read MAC address from EEPROM\n");
00925 
00926         /* Check to see if there is a sane EEPROM */
00927         sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
00928 
00929         if ((sig == 0xffff) || (sig == 0x0000)) {
00930                 DBG("sis190: Error EEPROM read.\n");
00931                 return -EIO;
00932         }
00933 
00934         /* Get MAC address from EEPROM */
00935         for (i = 0; i < ETH_ALEN / 2; i++) {
00936                 u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
00937 
00938                 ((u16 *)dev->hw_addr)[i] = cpu_to_le16(w);
00939         }
00940 
00941         sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
00942 
00943         return 0;
00944 }
00945 
00946 /**
00947  *      sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model
00948  *      @pdev: PCI device
00949  *      @dev:  network device to get address for
00950  *
00951  *      SiS96x model, use APC CMOS RAM to store MAC address.
00952  *      APC CMOS RAM is accessed through ISA bridge.
00953  *      MAC address is read into @net_dev->dev_addr.
00954  */
00955 static int sis190_get_mac_addr_from_apc(struct pci_device *pdev,
00956                                         struct net_device *dev)
00957 {
00958         struct sis190_private *tp = netdev_priv(dev);
00959         struct pci_device *isa_bridge = NULL;
00960         struct device *d;
00961         u8 reg, tmp8;
00962         unsigned int i;
00963 
00964         DBG("sis190: Read MAC address from APC.\n");
00965 
00966         list_for_each_entry(d, &(pdev->dev.siblings), siblings) {
00967                 unsigned int i;
00968                 for(i = 0; i < sis190_isa_bridge_driver.id_count; i++) {
00969                         isa_bridge = container_of(d, struct pci_device, dev);
00970                         if(isa_bridge->vendor ==
00971                              sis190_isa_bridge_driver.ids[i].vendor
00972                              && isa_bridge->device ==
00973                              sis190_isa_bridge_driver.ids[i].device) {
00974                                 DBG("sis190: ISA bridge found\n");
00975                                 break;
00976                         } else {
00977                                 isa_bridge = NULL;
00978                         }
00979                 }
00980                 if(isa_bridge)
00981                         break;
00982         }
00983 
00984         if (!isa_bridge) {
00985                 DBG("sis190: Can not find ISA bridge.\n");
00986                 return -EIO;
00987         }
00988 
00989         /* Enable port 78h & 79h to access APC Registers. */
00990         pci_read_config_byte(isa_bridge, 0x48, &tmp8);
00991         reg = (tmp8 & ~0x02);
00992         pci_write_config_byte(isa_bridge, 0x48, reg);
00993         udelay(50);
00994         pci_read_config_byte(isa_bridge, 0x48, &reg);
00995 
00996         for (i = 0; i < ETH_ALEN; i++) {
00997                 outb(0x9 + i, 0x78);
00998                 dev->hw_addr[i] = inb(0x79);
00999         }
01000 
01001         outb(0x12, 0x78);
01002         reg = inb(0x79);
01003 
01004         sis190_set_rgmii(tp, reg);
01005 
01006         /* Restore the value to ISA Bridge */
01007         pci_write_config_byte(isa_bridge, 0x48, tmp8);
01008 
01009         return 0;
01010 }
01011 
01012 /**
01013  *      sis190_init_rxfilter - Initialize the Rx filter
01014  *      @dev: network device to initialize
01015  *
01016  *      Set receive filter address to our MAC address
01017  *      and enable packet filtering.
01018  */
01019 static inline void sis190_init_rxfilter(struct net_device *dev)
01020 {
01021         struct sis190_private *tp = netdev_priv(dev);
01022         void *ioaddr = tp->mmio_addr;
01023         u16 ctl;
01024         int i;
01025 
01026         ctl = SIS_R16(RxMacControl);
01027         /*
01028          * Disable packet filtering before setting filter.
01029          * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
01030          * only and followed by RxMacAddr (6 bytes). Strange. -- FR
01031          */
01032         SIS_W16(RxMacControl, ctl & ~0x0f00);
01033 
01034         for (i = 0; i < ETH_ALEN; i++)
01035                 SIS_W8(RxMacAddr + i, dev->ll_addr[i]);
01036 
01037         SIS_W16(RxMacControl, ctl);
01038         SIS_PCI_COMMIT();
01039 }
01040 
01041 static int sis190_get_mac_addr(struct pci_device *pdev,
01042                                          struct net_device *dev)
01043 {
01044         int rc;
01045 
01046         rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
01047         if (rc < 0) {
01048                 u8 reg;
01049 
01050                 pci_read_config_byte(pdev, 0x73, &reg);
01051 
01052                 if (reg & 0x00000001)
01053                         rc = sis190_get_mac_addr_from_apc(pdev, dev);
01054         }
01055         return rc;
01056 }
01057 
01058 static void sis190_set_speed_auto(struct net_device *dev)
01059 {
01060         struct sis190_private *tp = netdev_priv(dev);
01061         void *ioaddr = tp->mmio_addr;
01062         int phy_id = tp->mii_if.phy_id;
01063         int val;
01064 
01065         DBG("sis190: Enabling Auto-negotiation.\n");
01066 
01067         val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
01068 
01069         // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
01070         // unchanged.
01071         mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
01072                    ADVERTISE_100FULL | ADVERTISE_10FULL |
01073                    ADVERTISE_100HALF | ADVERTISE_10HALF);
01074 
01075         // Enable 1000 Full Mode.
01076         mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
01077 
01078         // Enable auto-negotiation and restart auto-negotiation.
01079         mdio_write(ioaddr, phy_id, MII_BMCR,
01080                    BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
01081 }
01082 
01083 static void sis190_irq(struct net_device *dev, int enable)
01084 {
01085         struct sis190_private *tp = netdev_priv(dev);
01086         void *ioaddr = tp->mmio_addr;
01087 
01088         SIS_W32(IntrStatus, 0xffffffff);
01089 
01090         if (enable == 0)
01091                 SIS_W32(IntrMask, 0x00);
01092         else
01093                 SIS_W32(IntrMask, sis190_intr_mask);
01094 
01095         SIS_PCI_COMMIT();
01096 }
01097 
01098 static struct net_device_operations sis190_netdev_ops = {
01099         .open = sis190_open,
01100         .close = sis190_close,
01101         .poll = sis190_poll,
01102         .transmit = sis190_transmit,
01103         .irq = sis190_irq,
01104 };
01105 
01106 static int sis190_probe(struct pci_device *pdev)
01107 {
01108         struct sis190_private *tp;
01109         struct net_device *dev;
01110         int rc;
01111 
01112         rc = sis190_init_board(pdev, &dev);
01113         if (rc < 0)
01114                 goto out;
01115         netdev_init(dev, &sis190_netdev_ops);
01116 
01117         pci_set_drvdata(pdev, dev);
01118 
01119         tp = netdev_priv(dev);
01120 
01121         rc = sis190_get_mac_addr(pdev, dev);
01122         if (rc < 0)
01123                 goto err;
01124 
01125         rc = sis190_mii_probe(dev);
01126         if (rc < 0)
01127                 goto err;
01128 
01129         rc = register_netdev(dev);
01130         if (rc < 0)
01131                 goto err;
01132 
01133         sis190_set_speed_auto(dev);
01134         sis190_phy_task(tp);
01135 
01136 out:
01137         return rc;
01138 
01139 err:
01140         sis190_mii_remove(dev);
01141         iounmap(tp->mmio_addr);
01142         goto out;
01143 }
01144 
01145 static void sis190_remove(struct pci_device *pdev)
01146 {
01147         struct net_device *dev = pci_get_drvdata(pdev);
01148         struct sis190_private *tp = dev->priv;
01149         void *ioaddr = tp->mmio_addr;
01150 
01151         sis190_mii_remove(dev);
01152 
01153         /* shutdown chip, disable interrupts, etc */
01154         sis190_soft_reset(ioaddr);
01155 
01156         iounmap(tp->mmio_addr);
01157 
01158         unregister_netdev(dev);
01159         netdev_nullify(dev);
01160         netdev_put(dev);
01161 }
01162 
01163 struct pci_driver sis190_pci_driver __pci_driver = {
01164         .ids            = sis190_pci_tbl,
01165         .id_count       = (sizeof(sis190_pci_tbl) / sizeof(sis190_pci_tbl[0])),
01166         .probe          = sis190_probe,
01167         .remove         = sis190_remove,
01168 };