sis190.c File Reference

#include "sis190.h"

Go to the source code of this file.

Defines

#define ErrMask   (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
#define TxErrMask   (WND | TABRT | FIFO | LINK)

Functions

 FILE_LICENCE (GPL_ANY)
static int sis190_isa_bridge_probe (struct pci_device *pdev __unused, const struct pci_device_id *ent __unused)
static void sis190_isa_bridge_remove (struct pci_device *pdev __unused)
static void __mdio_cmd (void *ioaddr, u32 ctl)
static void mdio_write (void *ioaddr, int phy_id, int reg, int val)
static int mdio_read (void *ioaddr, int phy_id, int reg)
static void __mdio_write (struct net_device *dev, int phy_id, int reg, int val)
static int __mdio_read (struct net_device *dev, int phy_id, int reg)
static u16 mdio_read_latched (void *ioaddr, int phy_id, int reg)
static u16 sis190_read_eeprom (void *ioaddr, u32 reg)
static void sis190_irq_mask_and_ack (void *ioaddr)
static void sis190_asic_down (void *ioaddr)
static void sis190_mark_as_last_descriptor (struct RxDesc *desc)
static void sis190_give_to_asic (struct RxDesc *desc)
static void sis190_map_to_asic (struct RxDesc *desc, u32 mapping)
static void sis190_make_unusable_by_asic (struct RxDesc *desc)
static struct io_buffersis190_alloc_rx_iob (struct RxDesc *desc)
static u32 sis190_rx_fill (struct sis190_private *tp, u32 start, u32 end)
static int sis190_rx_pkt_err (u32 status)
static int sis190_process_rx (struct sis190_private *tp)
static int sis190_tx_pkt_err (u32 status)
static void sis190_process_tx (struct sis190_private *tp)
static void sis190_poll (struct net_device *dev)
static void sis190_init_ring_indexes (struct sis190_private *tp)
static int sis190_init_ring (struct net_device *dev)
static void sis190_set_rx_mode (struct net_device *dev)
static void sis190_soft_reset (void *ioaddr)
static void sis190_hw_start (struct net_device *dev)
static void sis190_phy_task (struct sis190_private *tp)
static int sis190_open (struct net_device *dev)
static void sis190_down (struct net_device *dev)
static void sis190_free (struct net_device *dev)
static void sis190_close (struct net_device *dev)
static int sis190_transmit (struct net_device *dev, struct io_buffer *iob)
static void sis190_free_phy (struct list_head *first_phy)
static u16 sis190_default_phy (struct sis190_private *tp)
 sis190_default_phy - Select default PHY for sis190 mac.
static void sis190_init_phy (struct sis190_private *tp, struct sis190_phy *phy, unsigned int phy_id, u16 mii_status)
static void sis190_mii_probe_88e1111_fixup (struct sis190_private *tp)
static int sis190_mii_probe (struct net_device *dev)
 sis190_mii_probe - Probe MII PHY for sis190 : the net device to probe for
static void sis190_mii_remove (struct net_device *dev)
static int sis190_init_board (struct pci_device *pdev, struct net_device **netdev)
static void sis190_set_rgmii (struct sis190_private *tp, u8 reg)
static int sis190_get_mac_addr_from_eeprom (struct pci_device *pdev __unused, struct net_device *dev)
static int sis190_get_mac_addr_from_apc (struct pci_device *pdev, struct net_device *dev)
 sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model : PCI device : network device to get address for
static void sis190_init_rxfilter (struct net_device *dev)
 sis190_init_rxfilter - Initialize the Rx filter : network device to initialize
static int sis190_get_mac_addr (struct pci_device *pdev, struct net_device *dev)
static void sis190_set_speed_auto (struct net_device *dev)
static void sis190_irq (struct net_device *dev, int enable)
static int sis190_probe (struct pci_device *pdev, const struct pci_device_id *ent __unused)
static void sis190_remove (struct pci_device *pdev)

Variables

static struct pci_device_id sis190_pci_tbl []
static struct pci_device_id sis190_isa_bridge_tbl []
struct pci_driver
sis190_isa_bridge_driver 
__pci_driver
static const u32 sis190_intr_mask
static const int multicast_filter_limit = 32
static struct net_device_operations sis190_netdev_ops


Define Documentation

#define ErrMask   (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)

Referenced by sis190_rx_pkt_err().

#define TxErrMask   (WND | TABRT | FIFO | LINK)

Referenced by sis190_tx_pkt_err().


Function Documentation

FILE_LICENCE ( GPL_ANY   ) 

static int sis190_isa_bridge_probe ( struct pci_device *pdev  __unused,
const struct pci_device_id *ent  __unused 
) [static]

Definition at line 50 of file sis190.c.

00052 {
00053         return 0;
00054 }

static void sis190_isa_bridge_remove ( struct pci_device *pdev  __unused  )  [static]

Definition at line 56 of file sis190.c.

00057 {
00058         return;
00059 }

static void __mdio_cmd ( void *  ioaddr,
u32  ctl 
) [static]

Definition at line 82 of file sis190.c.

References DBG, EhnMIInotDone, GMIIControl, mdelay(), SIS_R32, and SIS_W32.

Referenced by mdio_read(), and mdio_write().

00083 {
00084         unsigned int i;
00085 
00086         SIS_W32(GMIIControl, ctl);
00087 
00088         mdelay(1);
00089 
00090         for (i = 0; i < 100; i++) {
00091                 if (!(SIS_R32(GMIIControl) & EhnMIInotDone))
00092                         break;
00093                 mdelay(1);
00094         }
00095 
00096         if (i > 99)
00097                 DBG("sis190: PHY command timed out !\n");
00098 }

static void mdio_write ( void *  ioaddr,
int  phy_id,
int  reg,
int  val 
) [static]

Definition at line 100 of file sis190.c.

References __mdio_cmd(), EhnMIIdataShift, EhnMIIpmdShift, EhnMIIregShift, EhnMIIreq, EhnMIIwrite, and u32.

00101 {
00102         __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite |
00103                 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) |
00104                 (((u32) val) << EhnMIIdataShift));
00105 }

static int mdio_read ( void *  ioaddr,
int  phy_id,
int  reg 
) [static]

Definition at line 107 of file sis190.c.

References __mdio_cmd(), EhnMIIdataShift, EhnMIIpmdShift, EhnMIIread, EhnMIIregShift, EhnMIIreq, GMIIControl, SIS_R32, u16, and u32.

00108 {
00109         __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread |
00110                 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift));
00111 
00112         return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift);
00113 }

static void __mdio_write ( struct net_device dev,
int  phy_id,
int  reg,
int  val 
) [static]

Definition at line 115 of file sis190.c.

References mdio_write(), sis190_private::mmio_addr, netdev_priv(), and tp.

Referenced by sis190_mii_probe().

00116 {
00117         struct sis190_private *tp = netdev_priv(dev);
00118 
00119         mdio_write(tp->mmio_addr, phy_id, reg, val);
00120 }

static int __mdio_read ( struct net_device dev,
int  phy_id,
int  reg 
) [static]

Definition at line 122 of file sis190.c.

References mdio_read(), sis190_private::mmio_addr, netdev_priv(), and tp.

Referenced by sis190_mii_probe().

00123 {
00124         struct sis190_private *tp = netdev_priv(dev);
00125 
00126         return mdio_read(tp->mmio_addr, phy_id, reg);
00127 }

static u16 mdio_read_latched ( void *  ioaddr,
int  phy_id,
int  reg 
) [static]

Definition at line 129 of file sis190.c.

References mdio_read().

Referenced by sis190_default_phy(), sis190_mii_probe(), and sis190_phy_task().

00130 {
00131         mdio_read(ioaddr, phy_id, reg);
00132         return mdio_read(ioaddr, phy_id, reg);
00133 }

static u16 sis190_read_eeprom ( void *  ioaddr,
u32  reg 
) [static]

Definition at line 135 of file sis190.c.

References EEREQ, EEROP, mdelay(), ROMControl, ROMInterface, SIS_R32, SIS_W32, and u16.

Referenced by sis190_get_mac_addr_from_eeprom().

00136 {
00137         u16 data = 0xffff;
00138         unsigned int i;
00139 
00140         if (!(SIS_R32(ROMControl) & 0x0002))
00141                 return 0;
00142 
00143         SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
00144 
00145         for (i = 0; i < 200; i++) {
00146                 if (!(SIS_R32(ROMInterface) & EEREQ)) {
00147                         data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
00148                         break;
00149                 }
00150                 mdelay(1);
00151         }
00152 
00153         return data;
00154 }

static void sis190_irq_mask_and_ack ( void *  ioaddr  )  [static]

Definition at line 156 of file sis190.c.

References IntrMask, IntrStatus, SIS_PCI_COMMIT, and SIS_W32.

Referenced by sis190_asic_down(), and sis190_init_board().

00157 {
00158         SIS_W32(IntrMask, 0x00);
00159         SIS_W32(IntrStatus, 0xffffffff);
00160         SIS_PCI_COMMIT();
00161 }

static void sis190_asic_down ( void *  ioaddr  )  [static]

Definition at line 163 of file sis190.c.

References RxControl, sis190_irq_mask_and_ack(), SIS_W32, and TxControl.

Referenced by sis190_down(), and sis190_soft_reset().

00164 {
00165         /* Stop the chip's Tx and Rx DMA processes. */
00166 
00167         SIS_W32(TxControl, 0x1a00);
00168         SIS_W32(RxControl, 0x1a00);
00169 
00170         sis190_irq_mask_and_ack(ioaddr);
00171 }

static void sis190_mark_as_last_descriptor ( struct RxDesc desc  )  [inline, static]

Definition at line 173 of file sis190.c.

References cpu_to_le32, RingEnd, and RxDesc::size.

Referenced by sis190_init_ring().

00174 {
00175         desc->size |= cpu_to_le32(RingEnd);
00176 }

static void sis190_give_to_asic ( struct RxDesc desc  )  [inline, static]

Definition at line 178 of file sis190.c.

References cpu_to_le32, INTbit, le32_to_cpu, OWNbit, RxDesc::PSize, RingEnd, RX_BUF_MASK, RX_BUF_SIZE, RxDesc::size, RxDesc::status, u32, and wmb.

Referenced by sis190_map_to_asic(), and sis190_process_rx().

00179 {
00180         u32 eor = le32_to_cpu(desc->size) & RingEnd;
00181 
00182         desc->PSize = 0x0;
00183         desc->size = cpu_to_le32((RX_BUF_SIZE & RX_BUF_MASK) | eor);
00184         wmb();
00185         desc->status = cpu_to_le32(OWNbit | INTbit);
00186 }

static void sis190_map_to_asic ( struct RxDesc desc,
u32  mapping 
) [inline, static]

Definition at line 188 of file sis190.c.

References RxDesc::addr, cpu_to_le32, and sis190_give_to_asic().

Referenced by sis190_alloc_rx_iob().

00189 {
00190         desc->addr = cpu_to_le32(mapping);
00191         sis190_give_to_asic(desc);
00192 }

static void sis190_make_unusable_by_asic ( struct RxDesc desc  )  [inline, static]

Definition at line 194 of file sis190.c.

References RxDesc::addr, cpu_to_le32, RxDesc::PSize, RingEnd, RxDesc::size, RxDesc::status, and wmb.

Referenced by sis190_alloc_rx_iob(), and sis190_process_rx().

00195 {
00196         desc->PSize = 0x0;
00197         desc->addr = cpu_to_le32(0xdeadbeef);
00198         desc->size &= cpu_to_le32(RingEnd);
00199         wmb();
00200         desc->status = 0x0;
00201 }

static struct io_buffer* sis190_alloc_rx_iob ( struct RxDesc desc  )  [static, read]

Definition at line 203 of file sis190.c.

References alloc_iob(), io_buffer::data, DBG, RX_BUF_SIZE, sis190_make_unusable_by_asic(), sis190_map_to_asic(), u32, and virt_to_bus().

Referenced by sis190_rx_fill().

00204 {
00205         struct io_buffer *iob;
00206 
00207         iob = alloc_iob(RX_BUF_SIZE);
00208         if (iob) {
00209                 u32 mapping;
00210 
00211                 mapping = virt_to_bus(iob->data);
00212                 sis190_map_to_asic(desc, mapping);
00213         } else {
00214                 DBG("sis190: alloc_iob failed\n");
00215                 sis190_make_unusable_by_asic(desc);
00216         }
00217 
00218         return iob;
00219 }

static u32 sis190_rx_fill ( struct sis190_private tp,
u32  start,
u32  end 
) [static]

Definition at line 221 of file sis190.c.

References NUM_RX_DESC, sis190_private::Rx_iobuf, sis190_private::RxDescRing, sis190_alloc_rx_iob(), and u32.

Referenced by sis190_init_ring(), and sis190_process_rx().

00222 {
00223         u32 cur;
00224 
00225         for (cur = start; cur < end; cur++) {
00226                 unsigned int i = cur % NUM_RX_DESC;
00227 
00228                 if (tp->Rx_iobuf[i])
00229                         continue;
00230 
00231                 tp->Rx_iobuf[i] = sis190_alloc_rx_iob(tp->RxDescRing + i);
00232 
00233                 if (!tp->Rx_iobuf[i])
00234                         break;
00235         }
00236         return cur - start;
00237 }

static int sis190_rx_pkt_err ( u32  status  )  [inline, static]

Definition at line 239 of file sis190.c.

References CRCOK, and ErrMask.

Referenced by sis190_process_rx().

00240 {
00241 #define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
00242 
00243         if ((status & CRCOK) && !(status & ErrMask))
00244                 return 0;
00245 
00246         return -1;
00247 }

static int sis190_process_rx ( struct sis190_private tp  )  [static]

Definition at line 249 of file sis190.c.

References sis190_private::cur_rx, cur_rx, io_buffer::data, DBG, DBG2, DBGIO_HD, sis190_private::dev, sis190_private::dirty_rx, entry, iob_put, le32_to_cpu, netdev_rx(), NULL, NUM_RX_DESC, OWNbit, RxDesc::PSize, RX_BUF_SIZE, sis190_private::Rx_iobuf, sis190_private::RxDescRing, RxSizeMask, sis190_give_to_asic(), sis190_make_unusable_by_asic(), sis190_rx_fill(), sis190_rx_pkt_err(), RxDesc::status, and u32.

Referenced by sis190_poll().

00250 {
00251         u32 rx_left, cur_rx = tp->cur_rx;
00252         u32 delta, count;
00253 
00254         rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
00255 
00256         for (; rx_left > 0; rx_left--, cur_rx++) {
00257                 unsigned int entry = cur_rx % NUM_RX_DESC;
00258                 struct RxDesc *desc = tp->RxDescRing + entry;
00259                 u32 status;
00260 
00261                 if (le32_to_cpu(desc->status) & OWNbit)
00262                         break;
00263 
00264                 status = le32_to_cpu(desc->PSize);
00265 
00266                 if (sis190_rx_pkt_err(status) < 0) {
00267                         sis190_give_to_asic(desc);
00268                 } else {
00269                         struct io_buffer *iob = tp->Rx_iobuf[entry];
00270                         unsigned int pkt_size = (status & RxSizeMask) - 4;
00271 
00272                         if (pkt_size > RX_BUF_SIZE) {
00273                                 DBG("sis190: (frag) status = %08x.\n", status);
00274                                 sis190_give_to_asic(desc);
00275                                 continue;
00276                         }
00277 
00278                         sis190_make_unusable_by_asic(desc);
00279 
00280                         iob_put(iob, pkt_size);
00281 
00282                         DBG2("sis190: received packet. len: %d\n", pkt_size);
00283                         netdev_rx(tp->dev, iob);
00284                         DBGIO_HD(iob->data, 60);
00285                         tp->Rx_iobuf[entry] = NULL;
00286                 }
00287         }
00288         count = cur_rx - tp->cur_rx;
00289         tp->cur_rx = cur_rx;
00290 
00291         delta = sis190_rx_fill(tp, tp->dirty_rx, tp->cur_rx);
00292         if (!delta && count)
00293                 DBG("sis190: no Rx buffer allocated.\n");
00294         tp->dirty_rx += delta;
00295 
00296         if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx))
00297                 DBG("sis190: Rx buffers exhausted.\n");
00298 
00299         return count;
00300 }

static int sis190_tx_pkt_err ( u32  status  )  [inline, static]

Definition at line 302 of file sis190.c.

References TxErrMask.

Referenced by sis190_process_tx().

00303 {
00304 #define TxErrMask (WND | TABRT | FIFO | LINK)
00305 
00306         if (!(status & TxErrMask))
00307                 return 0;
00308 
00309         return -1;
00310 }

static void sis190_process_tx ( struct sis190_private tp  )  [static]

Definition at line 312 of file sis190.c.

References sis190_private::cur_tx, DBG, DBG2, sis190_private::dev, sis190_private::dirty_tx, EINVAL, entry, le32_to_cpu, netdev_tx_complete(), netdev_tx_complete_err(), NULL, NUM_TX_DESC, OWNbit, sis190_tx_pkt_err(), TxDesc::status, sis190_private::Tx_iobuf, txd, sis190_private::TxDescRing, and u32.

Referenced by sis190_poll().

00313 {
00314         u32 pending, dirty_tx = tp->dirty_tx;
00315 
00316         pending = tp->cur_tx - dirty_tx;
00317 
00318         for (; pending; pending--, dirty_tx++) {
00319                 unsigned int entry = dirty_tx % NUM_TX_DESC;
00320                 struct TxDesc *txd = tp->TxDescRing + entry;
00321                 u32 status = le32_to_cpu(txd->status);
00322                 struct io_buffer *iob;
00323 
00324                 if (status & OWNbit)
00325                         break;
00326 
00327                 iob = tp->Tx_iobuf[entry];
00328 
00329                 if (!iob)
00330                         break;
00331 
00332                 if (sis190_tx_pkt_err(status) == 0) {
00333                         DBG2("sis190: Transmitted packet: %#08x\n", status);
00334                         netdev_tx_complete(tp->dev, iob);
00335                 } else {
00336                         DBG("sis190: Transmit error: %#08x\n", status);
00337                         netdev_tx_complete_err(tp->dev, iob, -EINVAL);
00338                 }
00339 
00340                 tp->Tx_iobuf[entry] = NULL;
00341         }
00342 
00343         if (tp->dirty_tx != dirty_tx)
00344                 tp->dirty_tx = dirty_tx;
00345 }

static void sis190_poll ( struct net_device dev  )  [static]

Definition at line 351 of file sis190.c.

References IntrStatus, ioaddr, LinkChange, sis190_private::mmio_addr, netdev_link_ok(), netdev_priv(), RxQInt, sis190_phy_task(), sis190_process_rx(), sis190_process_tx(), SIS_R32, SIS_W32, tp, TxQ0Int, and u32.

00352 {
00353         struct sis190_private *tp = netdev_priv(dev);
00354         void  *ioaddr = tp->mmio_addr;
00355         u32 status;
00356 
00357         status = SIS_R32(IntrStatus);
00358 
00359         if ((status == 0xffffffff) || !status)
00360                 return;
00361 
00362         SIS_W32(IntrStatus, status);
00363 
00364         /* sis190_phy_task() needs to be called in event of a LinkChange and
00365          * after auto-negotiation is finished. Finishing auto-neg won't generate
00366          * any indication, hence we call it every time if the link is bad. */
00367         if ((status & LinkChange) || !netdev_link_ok(dev))
00368                 sis190_phy_task(tp);
00369 
00370         if (status & RxQInt)
00371                 sis190_process_rx(tp);
00372 
00373         if (status & TxQ0Int)
00374                 sis190_process_tx(tp);
00375 }

static void sis190_init_ring_indexes ( struct sis190_private tp  )  [inline, static]

Definition at line 377 of file sis190.c.

References sis190_private::cur_rx, sis190_private::cur_tx, sis190_private::dirty_rx, and sis190_private::dirty_tx.

Referenced by sis190_init_ring().

00378 {
00379         tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
00380 }

static int sis190_init_ring ( struct net_device dev  )  [static]

Definition at line 382 of file sis190.c.

References ENOMEM, memset(), netdev_priv(), NUM_RX_DESC, NUM_TX_DESC, sis190_private::Rx_iobuf, sis190_private::RxDescRing, sis190_free(), sis190_init_ring_indexes(), sis190_mark_as_last_descriptor(), sis190_rx_fill(), tp, and sis190_private::Tx_iobuf.

Referenced by sis190_open().

00383 {
00384         struct sis190_private *tp = netdev_priv(dev);
00385 
00386         sis190_init_ring_indexes(tp);
00387 
00388         memset(tp->Tx_iobuf, 0, NUM_TX_DESC * sizeof(struct io_buffer *));
00389         memset(tp->Rx_iobuf, 0, NUM_RX_DESC * sizeof(struct io_buffer *));
00390 
00391         if (sis190_rx_fill(tp, 0, NUM_RX_DESC) != NUM_RX_DESC)
00392                 goto err;
00393 
00394         sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
00395 
00396         return 0;
00397 
00398 err:
00399         sis190_free(dev);
00400         return -ENOMEM;
00401 }

static void sis190_set_rx_mode ( struct net_device dev  )  [static]

Definition at line 403 of file sis190.c.

References AcceptBroadcast, AcceptMulticast, AcceptMyPhys, ioaddr, sis190_private::mmio_addr, netdev_priv(), RxHashTable, RxMacControl, SIS_W16, SIS_W32, tp, u16, and u32.

Referenced by sis190_hw_start().

00404 {
00405         struct sis190_private *tp = netdev_priv(dev);
00406         void *ioaddr = tp->mmio_addr;
00407         u32 mc_filter[2];       /* Multicast hash filter */
00408         u16 rx_mode;
00409 
00410         rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
00411         mc_filter[1] = mc_filter[0] = 0xffffffff;
00412 
00413         SIS_W16(RxMacControl, rx_mode | 0x2);
00414         SIS_W32(RxHashTable, mc_filter[0]);
00415         SIS_W32(RxHashTable + 4, mc_filter[1]);
00416 
00417 }

static void sis190_soft_reset ( void *  ioaddr  )  [static]

Definition at line 419 of file sis190.c.

References IntrControl, sis190_asic_down(), SIS_PCI_COMMIT, and SIS_W32.

Referenced by sis190_hw_start(), sis190_init_board(), and sis190_remove().

00420 {
00421         SIS_W32(IntrControl, 0x8000);
00422         SIS_PCI_COMMIT();
00423         SIS_W32(IntrControl, 0x0);
00424         sis190_asic_down(ioaddr);
00425 }

static void sis190_hw_start ( struct net_device dev  )  [static]

Definition at line 427 of file sis190.c.

References CmdTxEnb, GMIIControl, IntrMask, IntrStatus, ioaddr, sis190_private::mmio_addr, netdev_priv(), sis190_private::rx_dma, RxControl, RxDescStartAddr, RxHashTable, RxMacControl, RxWolCtrl, RxWolData, sis190_set_rx_mode(), sis190_soft_reset(), SIS_PCI_COMMIT, SIS_W16, SIS_W32, tp, sis190_private::tx_dma, TxControl, TxDescStartAddr, and TxMacControl.

Referenced by sis190_open().

00428 {
00429         struct sis190_private *tp = netdev_priv(dev);
00430         void *ioaddr = tp->mmio_addr;
00431 
00432         sis190_soft_reset(ioaddr);
00433 
00434         SIS_W32(TxDescStartAddr, tp->tx_dma);
00435         SIS_W32(RxDescStartAddr, tp->rx_dma);
00436 
00437         SIS_W32(IntrStatus, 0xffffffff);
00438         SIS_W32(IntrMask, 0x0);
00439         SIS_W32(GMIIControl, 0x0);
00440         SIS_W32(TxMacControl, 0x60);
00441         SIS_W16(RxMacControl, 0x02);
00442         SIS_W32(RxHashTable, 0x0);
00443         SIS_W32(0x6c, 0x0);
00444         SIS_W32(RxWolCtrl, 0x0);
00445         SIS_W32(RxWolData, 0x0);
00446 
00447         SIS_PCI_COMMIT();
00448 
00449         sis190_set_rx_mode(dev);
00450 
00451         SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
00452         SIS_W32(RxControl, 0x1a1d);
00453 }

static void sis190_phy_task ( struct sis190_private tp  )  [static]

Definition at line 455 of file sis190.c.

References ADVERTISE_1000FULL, ADVERTISE_1000HALF, BMCR_RESET, BMSR_ANEGCOMPLETE, DBG, sis190_private::dev, net_device::dev, EXPANSION_NWAY, F_HAS_RGMII, F_PHY_BCM5461, sis190_private::features, ioaddr, LPA_1000FULL, LPA_1000HALF, LPA_100FULL, LPA_100HALF, LPA_10FULL, LPA_10HALF, LPA_NPAGE, mdelay(), mdio_read(), mdio_read_latched(), mdio_write(), MII_ADVERTISE, MII_BMCR, MII_BMSR, MII_CTRL1000, MII_EXPANSION, sis190_private::mii_if, MII_LPA, MII_STAT1000, sis190_private::mmio_addr, msg(), netdev_link_down(), netdev_link_up(), NULL, mii_if_info::phy_id, RGDelay, SIS_R32, SIS_W32, StationControl, u16, u32, and udelay().

Referenced by sis190_poll(), and sis190_probe().

00456 {
00457         struct net_device *dev = tp->dev;
00458         void *ioaddr = tp->mmio_addr;
00459         int phy_id = tp->mii_if.phy_id;
00460         int cnt = 0;
00461         u16 val;
00462 
00463         val = mdio_read(ioaddr, phy_id, MII_BMCR);
00464 
00465         /* 100ms timeout is completely arbitrary. I have no datasheet to
00466          * check whether that's a sensible value or not.
00467          */
00468         while ((val & BMCR_RESET) && (cnt < 100)) {
00469                 val = mdio_read(ioaddr, phy_id, MII_BMCR);
00470                 mdelay(1);
00471                 cnt++;
00472         }
00473 
00474         if (cnt > 99) {
00475                 DBG("sis190: BMCR_RESET timeout\n");
00476                 return;
00477         }
00478 
00479         if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
00480                      BMSR_ANEGCOMPLETE)) {
00481                 DBG("sis190: auto-negotiating...\n");
00482                 netdev_link_down(dev);
00483         } else {
00484                 /* Rejoice ! */
00485                 struct {
00486                         int val;
00487                         u32 ctl;
00488                         const char *msg;
00489                 } reg31[] = {
00490                         { LPA_1000FULL, 0x07000c00 | 0x00001000,
00491                                 "1000 Mbps Full Duplex" },
00492                         { LPA_1000HALF, 0x07000c00,
00493                                 "1000 Mbps Half Duplex" },
00494                         { LPA_100FULL, 0x04000800 | 0x00001000,
00495                                 "100 Mbps Full Duplex" },
00496                         { LPA_100HALF, 0x04000800,
00497                                 "100 Mbps Half Duplex" },
00498                         { LPA_10FULL, 0x04000400 | 0x00001000,
00499                                 "10 Mbps Full Duplex" },
00500                         { LPA_10HALF, 0x04000400,
00501                                 "10 Mbps Half Duplex" },
00502                         { 0, 0x04000400, "unknown" }
00503                 }, *p = NULL;
00504                 u16 adv, autoexp, gigadv, gigrec;
00505 
00506                 val = mdio_read(ioaddr, phy_id, 0x1f);
00507 
00508                 val = mdio_read(ioaddr, phy_id, MII_LPA);
00509                 adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
00510 
00511                 autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
00512 
00513                 if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
00514                         /* check for gigabit speed */
00515                         gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
00516                         gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
00517                         val = (gigadv & (gigrec >> 2));
00518                         if (val & ADVERTISE_1000FULL)
00519                                 p = reg31;
00520                         else if (val & ADVERTISE_1000HALF)
00521                                 p = reg31 + 1;
00522                 }
00523 
00524                 if (!p) {
00525                         val &= adv;
00526 
00527                         for (p = reg31; p->val; p++) {
00528                                 if ((val & p->val) == p->val)
00529                                         break;
00530                         }
00531                 }
00532 
00533                 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
00534 
00535                 if ((tp->features & F_HAS_RGMII) &&
00536                     (tp->features & F_PHY_BCM5461)) {
00537                         // Set Tx Delay in RGMII mode.
00538                         mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
00539                         udelay(200);
00540                         mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
00541                         p->ctl |= 0x03000000;
00542                 }
00543 
00544                 SIS_W32(StationControl, p->ctl);
00545 
00546                 if (tp->features & F_HAS_RGMII) {
00547                         SIS_W32(RGDelay, 0x0441);
00548                         SIS_W32(RGDelay, 0x0440);
00549                 }
00550 
00551                 DBG("sis190: link on %s mode.\n", p->msg);
00552                 netdev_link_up(dev);
00553         }
00554 }

static int sis190_open ( struct net_device dev  )  [static]

Definition at line 556 of file sis190.c.

References cpu_to_le32, DBG, ENOMEM, malloc_dma(), netdev_priv(), RING_ALIGNMENT, sis190_private::rx_dma, RX_RING_BYTES, sis190_private::RxDescRing, sis190_free(), sis190_hw_start(), sis190_init_ring(), sis190_init_rxfilter(), tp, sis190_private::tx_dma, TX_RING_BYTES, sis190_private::TxDescRing, and virt_to_bus().

00557 {
00558         struct sis190_private *tp = netdev_priv(dev);
00559         int rc;
00560 
00561         /* Allocate TX ring */
00562         tp->TxDescRing = malloc_dma(TX_RING_BYTES, RING_ALIGNMENT);
00563         if (!tp->TxDescRing) {
00564                 DBG("sis190: TX ring allocation failed\n");
00565                 rc = -ENOMEM;
00566                 goto out;
00567         }
00568         tp->tx_dma = cpu_to_le32(virt_to_bus(tp->TxDescRing));
00569 
00570         /* Allocate RX ring */
00571         tp->RxDescRing = malloc_dma(RX_RING_BYTES, RING_ALIGNMENT);
00572         if (!tp->RxDescRing) {
00573                 DBG("sis190: RX ring allocation failed\n");
00574                 rc = -ENOMEM;
00575                 goto error;
00576         }
00577         tp->rx_dma = cpu_to_le32(virt_to_bus(tp->RxDescRing));
00578 
00579         rc = sis190_init_ring(dev);
00580         if (rc < 0)
00581                 goto error;
00582 
00583         /* init rx filter, also program MAC address to card */
00584         sis190_init_rxfilter(dev);
00585 
00586         sis190_hw_start(dev);
00587 out:
00588         return rc;
00589 
00590 error:
00591         sis190_free(dev);
00592         goto out;
00593 }

static void sis190_down ( struct net_device dev  )  [static]

Definition at line 595 of file sis190.c.

References IntrMask, ioaddr, sis190_private::mmio_addr, netdev_priv(), sis190_asic_down(), SIS_R32, and tp.

Referenced by sis190_close().

00596 {
00597         struct sis190_private *tp = netdev_priv(dev);
00598         void  *ioaddr = tp->mmio_addr;
00599 
00600         do {
00601                 sis190_asic_down(ioaddr);
00602         } while (SIS_R32(IntrMask));
00603 }

static void sis190_free ( struct net_device dev  )  [static]

Definition at line 605 of file sis190.c.

References sis190_private::cur_rx, sis190_private::cur_tx, sis190_private::dirty_rx, sis190_private::dirty_tx, free_dma(), free_iob(), netdev_priv(), NULL, NUM_RX_DESC, NUM_TX_DESC, sis190_private::rx_dma, sis190_private::Rx_iobuf, RX_RING_BYTES, sis190_private::RxDescRing, tp, sis190_private::tx_dma, sis190_private::Tx_iobuf, TX_RING_BYTES, and sis190_private::TxDescRing.

Referenced by sis190_close(), sis190_init_ring(), and sis190_open().

00606 {
00607         struct sis190_private *tp = netdev_priv(dev);
00608         int i;
00609 
00610         free_dma(tp->TxDescRing, TX_RING_BYTES);
00611         free_dma(tp->RxDescRing, RX_RING_BYTES);
00612 
00613         tp->TxDescRing = NULL;
00614         tp->RxDescRing = NULL;
00615 
00616         tp->tx_dma = 0;
00617         tp->rx_dma = 0;
00618 
00619         tp->cur_tx = tp->dirty_tx = 0;
00620         tp->cur_rx = tp->dirty_rx = 0;
00621 
00622         for (i = 0; i < NUM_RX_DESC; i++) {
00623                 free_iob(tp->Rx_iobuf[i]);
00624                 tp->Rx_iobuf[i] = NULL;
00625         }
00626 
00627         /* tx io_buffers aren't owned by the driver, so don't free them */
00628         for(i = 0; i < NUM_TX_DESC; i++)
00629                 tp->Tx_iobuf[i] = NULL;
00630 }

static void sis190_close ( struct net_device dev  )  [static]

Definition at line 632 of file sis190.c.

References sis190_down(), and sis190_free().

00633 {
00634         sis190_down(dev);
00635         sis190_free(dev);
00636 }

static int sis190_transmit ( struct net_device dev,
struct io_buffer iob 
) [static]

Definition at line 638 of file sis190.c.

References TxDesc::addr, CmdReset, CmdTxEnb, cpu_to_le32, CRCbit, sis190_private::cur_tx, io_buffer::data, DBG, DEFbit, EINVAL, entry, ETH_ZLEN, INTbit, ioaddr, iob_len(), iob_pad(), le32_to_cpu, sis190_private::mmio_addr, netdev_priv(), NUM_TX_DESC, OWNbit, PADbit, TxDesc::PSize, RingEnd, SIS_W32, TxDesc::size, TxDesc::status, tp, sis190_private::Tx_iobuf, TxControl, sis190_private::TxDescRing, u32, virt_to_bus(), and wmb.

00639 {
00640         struct sis190_private *tp = netdev_priv(dev);
00641         void  *ioaddr = tp->mmio_addr;
00642         u32 len, entry;
00643         struct TxDesc *desc;
00644 
00645         len = iob_len(iob);
00646         if (len < ETH_ZLEN) {
00647                 iob_pad(iob, ETH_ZLEN);
00648                 len = ETH_ZLEN;
00649         }
00650 
00651         entry = tp->cur_tx % NUM_TX_DESC;
00652         desc = tp->TxDescRing + entry;
00653 
00654         if (le32_to_cpu(desc->status) & OWNbit) {
00655                 DBG("sis190: Tx Ring full\n");
00656                 return -EINVAL;
00657         }
00658 
00659         tp->Tx_iobuf[entry] = iob;
00660 
00661         desc->PSize = cpu_to_le32(len);
00662         desc->addr = cpu_to_le32(virt_to_bus(iob->data));
00663 
00664         desc->size = cpu_to_le32(len);
00665         if (entry == (NUM_TX_DESC - 1))
00666                 desc->size |= cpu_to_le32(RingEnd);
00667 
00668         wmb();
00669 
00670         desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
00671 
00672         tp->cur_tx++;
00673 
00674         SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
00675 
00676         return 0;
00677 }

static void sis190_free_phy ( struct list_head first_phy  )  [static]

Definition at line 679 of file sis190.c.

References free(), sis190_phy::list, and list_for_each_entry_safe.

Referenced by sis190_mii_probe(), and sis190_mii_remove().

00680 {
00681         struct sis190_phy *cur, *next;
00682 
00683         list_for_each_entry_safe(cur, next, first_phy, list) {
00684                 free(cur);
00685         }
00686 }

static u16 sis190_default_phy ( struct sis190_private tp  )  [static]

sis190_default_phy - Select default PHY for sis190 mac.

: the net device to probe for

Select first detected PHY with link as default. If no one is link on, select PHY whose types is HOME as default. If HOME doesn't exist, select LAN.

Definition at line 696 of file sis190.c.

References BMCR_ANENABLE, BMCR_ISOLATE, BMSR_LSTATUS, DBG, sis190_private::first_phy, HOME, ioaddr, LAN, list_entry, list_for_each_entry, mdio_read(), mdio_read_latched(), mdio_write(), MII_BMCR, MII_BMSR, sis190_private::mii_if, sis190_private::mmio_addr, NULL, mii_if_info::phy_id, sis190_phy::phy_id, sis190_phy::type, u16, and UNKNOWN.

Referenced by sis190_mii_probe().

00697 {
00698         struct sis190_phy *phy, *phy_home, *phy_default, *phy_lan;
00699         struct mii_if_info *mii_if = &tp->mii_if;
00700         void  *ioaddr = tp->mmio_addr;
00701         u16 status;
00702 
00703         phy_home = phy_default = phy_lan = NULL;
00704 
00705         list_for_each_entry(phy, &tp->first_phy, list) {
00706                 status = mdio_read_latched(ioaddr, phy->phy_id, MII_BMSR);
00707 
00708                 // Link ON & Not select default PHY & not ghost PHY.
00709                 if ((status & BMSR_LSTATUS) &&
00710                     !phy_default &&
00711                     (phy->type != UNKNOWN)) {
00712                         phy_default = phy;
00713                 } else {
00714                         status = mdio_read(ioaddr, phy->phy_id, MII_BMCR);
00715                         mdio_write(ioaddr, phy->phy_id, MII_BMCR,
00716                                    status | BMCR_ANENABLE | BMCR_ISOLATE);
00717                         if (phy->type == HOME)
00718                                 phy_home = phy;
00719                         else if (phy->type == LAN)
00720                                 phy_lan = phy;
00721                 }
00722         }
00723 
00724         if (!phy_default) {
00725                 if (phy_home)
00726                         phy_default = phy_home;
00727                 else if (phy_lan)
00728                         phy_default = phy_lan;
00729                 else
00730                         phy_default = list_entry(&tp->first_phy,
00731                                                  struct sis190_phy, list);
00732         }
00733 
00734         if (mii_if->phy_id != phy_default->phy_id) {
00735                 mii_if->phy_id = phy_default->phy_id;
00736                 DBG("sis190: Using transceiver at address %d as default.\n",
00737                      mii_if->phy_id);
00738         }
00739 
00740         status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR);
00741         status &= (~BMCR_ISOLATE);
00742 
00743         mdio_write(ioaddr, mii_if->phy_id, MII_BMCR, status);
00744         status = mdio_read_latched(ioaddr, mii_if->phy_id, MII_BMSR);
00745 
00746         return status;
00747 }

static void sis190_init_phy ( struct sis190_private tp,
struct sis190_phy phy,
unsigned int  phy_id,
u16  mii_status 
) [static]

Definition at line 749 of file sis190.c.

References BMSR_100FULL, BMSR_100HALF, DBG, mii_chip_info::feature, sis190_private::features, HOME, mii_chip_info::id, sis190_phy::id, INIT_LIST_HEAD, ioaddr, LAN, sis190_phy::list, mdio_read(), mii_chip_table, MII_PHYSID1, MII_PHYSID2, MIX, sis190_private::mmio_addr, mii_chip_info::name, sis190_phy::phy_id, sis190_phy::status, sis190_phy::type, mii_chip_info::type, and UNKNOWN.

Referenced by sis190_mii_probe().

00752 {
00753         void *ioaddr = tp->mmio_addr;
00754         struct mii_chip_info *p;
00755 
00756         INIT_LIST_HEAD(&phy->list);
00757         phy->status = mii_status;
00758         phy->phy_id = phy_id;
00759 
00760         phy->id[0] = mdio_read(ioaddr, phy_id, MII_PHYSID1);
00761         phy->id[1] = mdio_read(ioaddr, phy_id, MII_PHYSID2);
00762 
00763         for (p = mii_chip_table; p->type; p++) {
00764                 if ((p->id[0] == phy->id[0]) &&
00765                     (p->id[1] == (phy->id[1] & 0xfff0))) {
00766                         break;
00767                 }
00768         }
00769 
00770         if (p->id[1]) {
00771                 phy->type = (p->type == MIX) ?
00772                         ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
00773                                 LAN : HOME) : p->type;
00774                 tp->features |= p->feature;
00775 
00776                 DBG("sis190: %s transceiver at address %d.\n", p->name, phy_id);
00777         } else {
00778                 phy->type = UNKNOWN;
00779 
00780                 DBG("sis190: unknown PHY 0x%x:0x%x transceiver at address %d\n",
00781                     phy->id[0], (phy->id[1] & 0xfff0), phy_id);
00782         }
00783 }

static void sis190_mii_probe_88e1111_fixup ( struct sis190_private tp  )  [static]

Definition at line 785 of file sis190.c.

References F_HAS_RGMII, F_PHY_88E1111, sis190_private::features, ioaddr, mdio_write(), sis190_private::mii_if, sis190_private::mmio_addr, mii_if_info::phy_id, u16, and udelay().

Referenced by sis190_mii_probe().

00786 {
00787         if (tp->features & F_PHY_88E1111) {
00788                 void *ioaddr = tp->mmio_addr;
00789                 int phy_id = tp->mii_if.phy_id;
00790                 u16 reg[2][2] = {
00791                         { 0x808b, 0x0ce1 },
00792                         { 0x808f, 0x0c60 }
00793                 }, *p;
00794 
00795                 p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
00796 
00797                 mdio_write(ioaddr, phy_id, 0x1b, p[0]);
00798                 udelay(200);
00799                 mdio_write(ioaddr, phy_id, 0x14, p[1]);
00800                 udelay(200);
00801         }
00802 }

static int sis190_mii_probe ( struct net_device dev  )  [static]

sis190_mii_probe - Probe MII PHY for sis190 : the net device to probe for

Search for total of 32 possible mii phy addresses. Identify and set current phy if found one, return error if it failed to found.

Definition at line 812 of file sis190.c.

References __mdio_read(), __mdio_write(), DBG, mii_if_info::dev, EIO, ENOMEM, sis190_private::first_phy, INIT_LIST_HEAD, ioaddr, sis190_phy::list, list_add, list_empty(), mii_if_info::mdio_read, mdio_read_latched(), mii_if_info::mdio_write, MII_BMSR, sis190_private::mii_if, MII_REG_ANY, sis190_private::mmio_addr, netdev_priv(), mii_if_info::phy_id, PHY_ID_ANY, mii_if_info::phy_id_mask, PHY_MAX_ADDR, mii_if_info::reg_num_mask, sis190_default_phy(), sis190_free_phy(), sis190_init_phy(), sis190_mii_probe_88e1111_fixup(), sis190_phy::status, tp, u16, and zalloc().

Referenced by sis190_probe().

00813 {
00814         struct sis190_private *tp = netdev_priv(dev);
00815         struct mii_if_info *mii_if = &tp->mii_if;
00816         void *ioaddr = tp->mmio_addr;
00817         int phy_id;
00818         int rc = 0;
00819 
00820         INIT_LIST_HEAD(&tp->first_phy);
00821 
00822         for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
00823                 struct sis190_phy *phy;
00824                 u16 status;
00825 
00826                 status = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
00827 
00828                 // Try next mii if the current one is not accessible.
00829                 if (status == 0xffff || status == 0x0000)
00830                         continue;
00831 
00832                 phy = zalloc(sizeof(*phy));
00833                 if (!phy) {
00834                         sis190_free_phy(&tp->first_phy);
00835                         rc = -ENOMEM;
00836                         goto out;
00837                 }
00838 
00839                 DBG("sis190: found PHY\n");
00840 
00841                 sis190_init_phy(tp, phy, phy_id, status);
00842 
00843                 list_add(&tp->first_phy, &phy->list);
00844         }
00845 
00846         if (list_empty(&tp->first_phy)) {
00847                 DBG("sis190: No MII transceivers found!\n");
00848                 rc = -EIO;
00849                 goto out;
00850         }
00851 
00852         /* Select default PHY for mac */
00853         sis190_default_phy(tp);
00854 
00855         sis190_mii_probe_88e1111_fixup(tp);
00856 
00857         mii_if->dev = dev;
00858         mii_if->mdio_read = __mdio_read;
00859         mii_if->mdio_write = __mdio_write;
00860         mii_if->phy_id_mask = PHY_ID_ANY;
00861         mii_if->reg_num_mask = MII_REG_ANY;
00862 out:
00863         return rc;
00864 }

static void sis190_mii_remove ( struct net_device dev  )  [static]

Definition at line 866 of file sis190.c.

References sis190_private::first_phy, netdev_priv(), sis190_free_phy(), and tp.

Referenced by sis190_probe(), and sis190_remove().

00867 {
00868         struct sis190_private *tp = netdev_priv(dev);
00869 
00870         sis190_free_phy(&tp->first_phy);
00871 }

static int sis190_init_board ( struct pci_device pdev,
struct net_device **  netdev 
) [static]

Definition at line 873 of file sis190.c.

References adjust_pci_device(), alloc_etherdev(), DBG, sis190_private::dev, pci_device::dev, net_device::dev, EIO, ENOMEM, ioaddr, ioremap(), pci_device::membase, memset(), sis190_private::mmio_addr, netdev_priv(), sis190_private::pci_device, sis190_irq_mask_and_ack(), SIS190_REGS_SIZE, sis190_soft_reset(), and tp.

Referenced by sis190_probe().

00874 {
00875         struct sis190_private *tp;
00876         struct net_device *dev;
00877         void *ioaddr;
00878         int rc;
00879 
00880         dev = alloc_etherdev(sizeof(*tp));
00881         if (!dev) {
00882                 DBG("sis190: unable to alloc new etherdev\n");
00883                 rc = -ENOMEM;
00884                 goto err;
00885         }
00886 
00887         dev->dev = &pdev->dev;
00888 
00889         tp = netdev_priv(dev);
00890         memset(tp, 0, sizeof(*tp));
00891 
00892         tp->dev = dev;
00893 
00894         adjust_pci_device(pdev);
00895 
00896         ioaddr = ioremap(pdev->membase, SIS190_REGS_SIZE);
00897         if (!ioaddr) {
00898                 DBG("sis190: cannot remap MMIO, aborting\n");
00899                 rc = -EIO;
00900                 goto err;
00901         }
00902 
00903         tp->pci_device = pdev;
00904         tp->mmio_addr = ioaddr;
00905 
00906         sis190_irq_mask_and_ack(ioaddr);
00907 
00908         sis190_soft_reset(ioaddr);
00909 
00910         *netdev = dev;
00911 
00912         return 0;
00913 
00914 err:
00915         return rc;
00916 }

static void sis190_set_rgmii ( struct sis190_private tp,
u8  reg 
) [static]

Definition at line 918 of file sis190.c.

References F_HAS_RGMII, and sis190_private::features.

Referenced by sis190_get_mac_addr_from_apc(), and sis190_get_mac_addr_from_eeprom().

00919 {
00920         tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
00921 }

static int sis190_get_mac_addr_from_eeprom ( struct pci_device *pdev  __unused,
struct net_device dev 
) [static]

Definition at line 923 of file sis190.c.

References cpu_to_le16, DBG, EEPROMInfo, EEPROMMACAddr, EEPROMSignature, EIO, ETH_ALEN, net_device::hw_addr, ioaddr, sis190_private::mmio_addr, netdev_priv(), sis190_read_eeprom(), sis190_set_rgmii(), tp, and u16.

Referenced by sis190_get_mac_addr().

00925 {
00926         struct sis190_private *tp = netdev_priv(dev);
00927         void *ioaddr = tp->mmio_addr;
00928         u16 sig;
00929         int i;
00930 
00931         DBG("sis190: Read MAC address from EEPROM\n");
00932 
00933         /* Check to see if there is a sane EEPROM */
00934         sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
00935 
00936         if ((sig == 0xffff) || (sig == 0x0000)) {
00937                 DBG("sis190: Error EEPROM read.\n");
00938                 return -EIO;
00939         }
00940 
00941         /* Get MAC address from EEPROM */
00942         for (i = 0; i < ETH_ALEN / 2; i++) {
00943                 u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
00944 
00945                 ((u16 *)dev->hw_addr)[i] = cpu_to_le16(w);
00946         }
00947 
00948         sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
00949 
00950         return 0;
00951 }

static int sis190_get_mac_addr_from_apc ( struct pci_device pdev,
struct net_device dev 
) [static]

sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model : PCI device : network device to get address for

SiS96x model, use APC CMOS RAM to store MAC address. APC CMOS RAM is accessed through ISA bridge. MAC address is read into ->dev_addr.

Definition at line 962 of file sis190.c.

References container_of, DBG, pci_device::dev, pci_device::device, EIO, ETH_ALEN, net_device::hw_addr, inb, list_for_each_entry, netdev_priv(), NULL, outb, pci_read_config_byte(), pci_write_config_byte(), device::siblings, sis190_set_rgmii(), tp, u8, udelay(), and pci_device::vendor.

Referenced by sis190_get_mac_addr().

00964 {
00965         struct sis190_private *tp = netdev_priv(dev);
00966         struct pci_device *isa_bridge = NULL;
00967         struct device *d;
00968         u8 reg, tmp8;
00969         unsigned int i;
00970 
00971         DBG("sis190: Read MAC address from APC.\n");
00972 
00973         list_for_each_entry(d, &(pdev->dev.siblings), siblings) {
00974                 unsigned int i;
00975                 isa_bridge = container_of(d, struct pci_device, dev);
00976                 for(i = 0; i < sis190_isa_bridge_driver.id_count; i++) {
00977                         if(isa_bridge->vendor ==
00978                              sis190_isa_bridge_driver.ids[i].vendor
00979                              && isa_bridge->device ==
00980                              sis190_isa_bridge_driver.ids[i].device) {
00981                                 DBG("sis190: ISA bridge found\n");
00982                                 break;
00983                         } else {
00984                                 isa_bridge = NULL;
00985                         }
00986                 }
00987                 if(isa_bridge)
00988                         break;
00989         }
00990 
00991         if (!isa_bridge) {
00992                 DBG("sis190: Can not find ISA bridge.\n");
00993                 return -EIO;
00994         }
00995 
00996         /* Enable port 78h & 79h to access APC Registers. */
00997         pci_read_config_byte(isa_bridge, 0x48, &tmp8);
00998         reg = (tmp8 & ~0x02);
00999         pci_write_config_byte(isa_bridge, 0x48, reg);
01000         udelay(50);
01001         pci_read_config_byte(isa_bridge, 0x48, &reg);
01002 
01003         for (i = 0; i < ETH_ALEN; i++) {
01004                 outb(0x9 + i, 0x78);
01005                 dev->hw_addr[i] = inb(0x79);
01006         }
01007 
01008         outb(0x12, 0x78);
01009         reg = inb(0x79);
01010 
01011         sis190_set_rgmii(tp, reg);
01012 
01013         /* Restore the value to ISA Bridge */
01014         pci_write_config_byte(isa_bridge, 0x48, tmp8);
01015 
01016         return 0;
01017 }

static void sis190_init_rxfilter ( struct net_device dev  )  [inline, static]

sis190_init_rxfilter - Initialize the Rx filter : network device to initialize

Set receive filter address to our MAC address and enable packet filtering.

Definition at line 1026 of file sis190.c.

References ETH_ALEN, ioaddr, net_device::ll_addr, sis190_private::mmio_addr, netdev_priv(), RxMacAddr, RxMacControl, SIS_PCI_COMMIT, SIS_R16, SIS_W16, SIS_W8, tp, and u16.

Referenced by sis190_open().

01027 {
01028         struct sis190_private *tp = netdev_priv(dev);
01029         void *ioaddr = tp->mmio_addr;
01030         u16 ctl;
01031         int i;
01032 
01033         ctl = SIS_R16(RxMacControl);
01034         /*
01035          * Disable packet filtering before setting filter.
01036          * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
01037          * only and followed by RxMacAddr (6 bytes). Strange. -- FR
01038          */
01039         SIS_W16(RxMacControl, ctl & ~0x0f00);
01040 
01041         for (i = 0; i < ETH_ALEN; i++)
01042                 SIS_W8(RxMacAddr + i, dev->ll_addr[i]);
01043 
01044         SIS_W16(RxMacControl, ctl);
01045         SIS_PCI_COMMIT();
01046 }

static int sis190_get_mac_addr ( struct pci_device pdev,
struct net_device dev 
) [static]

Definition at line 1048 of file sis190.c.

References pci_read_config_byte(), sis190_get_mac_addr_from_apc(), sis190_get_mac_addr_from_eeprom(), and u8.

Referenced by sis190_probe().

01050 {
01051         int rc;
01052 
01053         rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
01054         if (rc < 0) {
01055                 u8 reg;
01056 
01057                 pci_read_config_byte(pdev, 0x73, &reg);
01058 
01059                 if (reg & 0x00000001)
01060                         rc = sis190_get_mac_addr_from_apc(pdev, dev);
01061         }
01062         return rc;
01063 }

static void sis190_set_speed_auto ( struct net_device dev  )  [static]

Definition at line 1065 of file sis190.c.

References ADVERTISE_1000FULL, ADVERTISE_100FULL, ADVERTISE_100HALF, ADVERTISE_10FULL, ADVERTISE_10HALF, ADVERTISE_SLCT, BMCR_ANENABLE, BMCR_ANRESTART, BMCR_RESET, DBG, ioaddr, mdio_read(), mdio_write(), MII_ADVERTISE, MII_BMCR, MII_CTRL1000, sis190_private::mii_if, sis190_private::mmio_addr, netdev_priv(), mii_if_info::phy_id, and tp.

Referenced by sis190_probe().

01066 {
01067         struct sis190_private *tp = netdev_priv(dev);
01068         void *ioaddr = tp->mmio_addr;
01069         int phy_id = tp->mii_if.phy_id;
01070         int val;
01071 
01072         DBG("sis190: Enabling Auto-negotiation.\n");
01073 
01074         val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
01075 
01076         // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
01077         // unchanged.
01078         mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
01079                    ADVERTISE_100FULL | ADVERTISE_10FULL |
01080                    ADVERTISE_100HALF | ADVERTISE_10HALF);
01081 
01082         // Enable 1000 Full Mode.
01083         mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
01084 
01085         // Enable auto-negotiation and restart auto-negotiation.
01086         mdio_write(ioaddr, phy_id, MII_BMCR,
01087                    BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
01088 }

static void sis190_irq ( struct net_device dev,
int  enable 
) [static]

Definition at line 1090 of file sis190.c.

References IntrMask, IntrStatus, ioaddr, sis190_private::mmio_addr, netdev_priv(), SIS_PCI_COMMIT, SIS_W32, and tp.

01091 {
01092         struct sis190_private *tp = netdev_priv(dev);
01093         void *ioaddr = tp->mmio_addr;
01094 
01095         SIS_W32(IntrStatus, 0xffffffff);
01096 
01097         if (enable == 0)
01098                 SIS_W32(IntrMask, 0x00);
01099         else
01100                 SIS_W32(IntrMask, sis190_intr_mask);
01101 
01102         SIS_PCI_COMMIT();
01103 }

static int sis190_probe ( struct pci_device pdev,
const struct pci_device_id *ent  __unused 
) [static]

Definition at line 1113 of file sis190.c.

References net_device::dev, ioaddr, iounmap(), sis190_private::mmio_addr, netdev_init(), netdev_link_down(), netdev_priv(), pci_set_drvdata(), register_netdev(), sis190_get_mac_addr(), sis190_init_board(), sis190_mii_probe(), sis190_mii_remove(), sis190_phy_task(), sis190_set_speed_auto(), and tp.

01115 {
01116         struct sis190_private *tp;
01117         struct net_device *dev;
01118         void *ioaddr;
01119         int rc;
01120 
01121         rc = sis190_init_board(pdev, &dev);
01122         if (rc < 0)
01123                 goto out;
01124 
01125         pci_set_drvdata(pdev, dev);
01126 
01127         tp = netdev_priv(dev);
01128         ioaddr = tp->mmio_addr;
01129 
01130         rc = sis190_get_mac_addr(pdev, dev);
01131         if (rc < 0)
01132                 goto err;
01133 
01134         rc = sis190_mii_probe(dev);
01135         if (rc < 0)
01136                 goto err;
01137 
01138         rc = register_netdev(dev);
01139         if (rc < 0)
01140                 goto err;
01141 
01142         sis190_set_speed_auto(dev);
01143         sis190_phy_task(tp);
01144 
01145         netdev_init(dev, &sis190_netdev_ops);
01146         netdev_link_down(dev);
01147 out:
01148         return rc;
01149 
01150 err:
01151         sis190_mii_remove(dev);
01152         iounmap(tp->mmio_addr);
01153         goto out;
01154 }

static void sis190_remove ( struct pci_device pdev  )  [static]

Definition at line 1156 of file sis190.c.

References net_device::dev, ioaddr, iounmap(), sis190_private::mmio_addr, netdev_nullify(), netdev_put(), pci_get_drvdata(), net_device::priv, sis190_mii_remove(), sis190_soft_reset(), tp, and unregister_netdev().

01157 {
01158         struct net_device *dev = pci_get_drvdata(pdev);
01159         struct sis190_private *tp = dev->priv;
01160         void *ioaddr = tp->mmio_addr;
01161 
01162         sis190_mii_remove(dev);
01163 
01164         /* shutdown chip, disable interrupts, etc */
01165         sis190_soft_reset(ioaddr);
01166 
01167         iounmap(tp->mmio_addr);
01168 
01169         unregister_netdev(dev);
01170         netdev_nullify(dev);
01171         netdev_put(dev);
01172 }


Variable Documentation

struct pci_device_id sis190_pci_tbl[] [static]

Initial value:

 {
        PCI_ROM (0x1039, 0x0190, "sis190", "sis190", 0),
        PCI_ROM (0x1039, 0x0191, "sis191", "sis191", 0),
}

Definition at line 28 of file sis190.c.

Initial value:

 {
        PCI_ID (0x1039, 0x0965, "", "", 0),
        PCI_ID (0x1039, 0x0966, "", "", 0),
        PCI_ID (0x1039, 0x0968, "", "", 0),
}

Definition at line 44 of file sis190.c.

struct pci_driver sis190_pci_driver __pci_driver [read]

Initial value:

 {
        .ids            = sis190_isa_bridge_tbl,
        .id_count       = (sizeof(sis190_isa_bridge_tbl) /
                           sizeof(sis190_isa_bridge_tbl[0])),
        .probe          = sis190_isa_bridge_probe,
        .remove         = sis190_isa_bridge_remove,
}

Definition at line 61 of file sis190.c.

const u32 sis190_intr_mask [static]

Initial value:

Definition at line 73 of file sis190.c.

const int multicast_filter_limit = 32 [static]

Definition at line 80 of file sis190.c.

Initial value:

 {
        .open = sis190_open,
        .close = sis190_close,
        .poll = sis190_poll,
        .transmit = sis190_transmit,
        .irq = sis190_irq,
}

Definition at line 1105 of file sis190.c.


Generated on Tue Apr 6 20:01:39 2010 for gPXE by  doxygen 1.5.7.1