#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_buffer * | sis190_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 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().
| FILE_LICENCE | ( | GPL_ANY | ) |
| static int sis190_isa_bridge_probe | ( | struct pci_device *pdev | __unused, | |
| const struct pci_device_id *ent | __unused | |||
| ) | [static] |
| static void sis190_isa_bridge_remove | ( | struct pci_device *pdev | __unused | ) | [static] |
| 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().
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 }
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 }
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] |
| 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().
| 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, ®); 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, ®); 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 }
struct pci_device_id sis190_pci_tbl[] [static] |
struct pci_device_id sis190_isa_bridge_tbl[] [static] |
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,
}
const u32 sis190_intr_mask [static] |
const int multicast_filter_limit = 32 [static] |
struct net_device_operations sis190_netdev_ops [static] |
Initial value:
{
.open = sis190_open,
.close = sis190_close,
.poll = sis190_poll,
.transmit = sis190_transmit,
.irq = sis190_irq,
}
1.5.7.1