blob: f78799c4235e9b789891095037889d0ab70709e7 [file] [log] [blame]
Francois Romieu890e8d02005-07-30 13:08:43 +02001/*
2 sis190.c: Silicon Integrated Systems SiS190 ethernet driver
3
4 Copyright (c) 2003 K.M. Liu <kmliu@sis.com>
5 Copyright (c) 2003, 2004 Jeff Garzik <jgarzik@pobox.com>
6 Copyright (c) 2003, 2004, 2005 Francois Romieu <romieu@fr.zoreil.com>
7
Francois Romieu40292fb2005-07-30 13:12:06 +02008 Based on r8169.c, tg3.c, 8139cp.c, skge.c, epic100.c and SiS 190/191
9 genuine driver.
Francois Romieu890e8d02005-07-30 13:08:43 +020010
11 This software may be used and distributed according to the terms of
12 the GNU General Public License (GPL), incorporated herein by reference.
13 Drivers based on or derived from this code fall under the GPL and must
14 retain the authorship, copyright and license notice. This file is not
15 a complete program and may only be used when the entire operating
16 system is licensed under the GPL.
17
18 See the file COPYING in this distribution for more information.
19
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/netdevice.h>
Francois Romieu43afb942005-07-30 13:10:21 +020025#include <linux/rtnetlink.h>
Francois Romieu890e8d02005-07-30 13:08:43 +020026#include <linux/etherdevice.h>
27#include <linux/ethtool.h>
28#include <linux/pci.h>
29#include <linux/mii.h>
30#include <linux/delay.h>
31#include <linux/crc32.h>
32#include <linux/dma-mapping.h>
33#include <asm/irq.h>
34
35#define net_drv(p, arg...) if (netif_msg_drv(p)) \
36 printk(arg)
37#define net_probe(p, arg...) if (netif_msg_probe(p)) \
38 printk(arg)
39#define net_link(p, arg...) if (netif_msg_link(p)) \
40 printk(arg)
41#define net_intr(p, arg...) if (netif_msg_intr(p)) \
42 printk(arg)
43#define net_tx_err(p, arg...) if (netif_msg_tx_err(p)) \
44 printk(arg)
45
46#ifdef CONFIG_SIS190_NAPI
47#define NAPI_SUFFIX "-NAPI"
48#else
49#define NAPI_SUFFIX ""
50#endif
51
52#define DRV_VERSION "1.2" NAPI_SUFFIX
53#define DRV_NAME "sis190"
54#define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
55#define PFX DRV_NAME ": "
56
57#ifdef CONFIG_SIS190_NAPI
58#define sis190_rx_skb netif_receive_skb
59#define sis190_rx_quota(count, quota) min(count, quota)
60#else
61#define sis190_rx_skb netif_rx
62#define sis190_rx_quota(count, quota) count
63#endif
64
65#define MAC_ADDR_LEN 6
66
Francois Romieubcad5e52005-07-30 13:13:47 +020067#define NUM_TX_DESC 64 /* [8..1024] */
68#define NUM_RX_DESC 64 /* [8..8192] */
Francois Romieu890e8d02005-07-30 13:08:43 +020069#define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc))
70#define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc))
71#define RX_BUF_SIZE 1536
Francois Romieu8b5641d2005-07-30 13:13:03 +020072#define RX_BUF_MASK 0xfff8
Francois Romieu890e8d02005-07-30 13:08:43 +020073
74#define SIS190_REGS_SIZE 0x80
75#define SIS190_TX_TIMEOUT (6*HZ)
76#define SIS190_PHY_TIMEOUT (10*HZ)
77#define SIS190_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | \
78 NETIF_MSG_LINK | NETIF_MSG_IFUP | \
79 NETIF_MSG_IFDOWN)
80
81/* Enhanced PHY access register bit definitions */
82#define EhnMIIread 0x0000
83#define EhnMIIwrite 0x0020
84#define EhnMIIdataShift 16
85#define EhnMIIpmdShift 6 /* 7016 only */
86#define EhnMIIregShift 11
87#define EhnMIIreq 0x0010
88#define EhnMIInotDone 0x0010
89
90/* Write/read MMIO register */
91#define SIS_W8(reg, val) writeb ((val), ioaddr + (reg))
92#define SIS_W16(reg, val) writew ((val), ioaddr + (reg))
93#define SIS_W32(reg, val) writel ((val), ioaddr + (reg))
94#define SIS_R8(reg) readb (ioaddr + (reg))
95#define SIS_R16(reg) readw (ioaddr + (reg))
96#define SIS_R32(reg) readl (ioaddr + (reg))
97
98#define SIS_PCI_COMMIT() SIS_R32(IntrControl)
99
100enum sis190_registers {
101 TxControl = 0x00,
102 TxDescStartAddr = 0x04,
Francois Romieu188f23b2005-07-30 13:11:43 +0200103 rsv0 = 0x08, // reserved
104 TxSts = 0x0c, // unused (Control/Status)
Francois Romieu890e8d02005-07-30 13:08:43 +0200105 RxControl = 0x10,
106 RxDescStartAddr = 0x14,
Francois Romieu188f23b2005-07-30 13:11:43 +0200107 rsv1 = 0x18, // reserved
108 RxSts = 0x1c, // unused
Francois Romieu890e8d02005-07-30 13:08:43 +0200109 IntrStatus = 0x20,
110 IntrMask = 0x24,
111 IntrControl = 0x28,
Francois Romieu188f23b2005-07-30 13:11:43 +0200112 IntrTimer = 0x2c, // unused (Interupt Timer)
113 PMControl = 0x30, // unused (Power Mgmt Control/Status)
114 rsv2 = 0x34, // reserved
Francois Romieu890e8d02005-07-30 13:08:43 +0200115 ROMControl = 0x38,
116 ROMInterface = 0x3c,
117 StationControl = 0x40,
118 GMIIControl = 0x44,
Francois Romieu188f23b2005-07-30 13:11:43 +0200119 GIoCR = 0x48, // unused (GMAC IO Compensation)
120 GIoCtrl = 0x4c, // unused (GMAC IO Control)
Francois Romieu890e8d02005-07-30 13:08:43 +0200121 TxMacControl = 0x50,
Francois Romieu188f23b2005-07-30 13:11:43 +0200122 TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit)
123 RGDelay = 0x58, // unused (RGMII Tx Internal Delay)
124 rsv3 = 0x5c, // reserved
Francois Romieu890e8d02005-07-30 13:08:43 +0200125 RxMacControl = 0x60,
126 RxMacAddr = 0x62,
127 RxHashTable = 0x68,
128 // Undocumented = 0x6c,
Francois Romieu188f23b2005-07-30 13:11:43 +0200129 RxWolCtrl = 0x70,
130 RxWolData = 0x74, // unused (Rx WOL Data Access)
131 RxMPSControl = 0x78, // unused (Rx MPS Control)
132 rsv4 = 0x7c, // reserved
Francois Romieu890e8d02005-07-30 13:08:43 +0200133};
134
135enum sis190_register_content {
136 /* IntrStatus */
137 SoftInt = 0x40000000, // unused
138 Timeup = 0x20000000, // unused
139 PauseFrame = 0x00080000, // unused
140 MagicPacket = 0x00040000, // unused
141 WakeupFrame = 0x00020000, // unused
142 LinkChange = 0x00010000,
143 RxQEmpty = 0x00000080,
144 RxQInt = 0x00000040,
145 TxQ1Empty = 0x00000020, // unused
146 TxQ1Int = 0x00000010,
147 TxQ0Empty = 0x00000008, // unused
148 TxQ0Int = 0x00000004,
149 RxHalt = 0x00000002,
150 TxHalt = 0x00000001,
151
Francois Romieu890e8d02005-07-30 13:08:43 +0200152 /* {Rx/Tx}CmdBits */
153 CmdReset = 0x10,
154 CmdRxEnb = 0x08, // unused
155 CmdTxEnb = 0x01,
156 RxBufEmpty = 0x01, // unused
157
158 /* Cfg9346Bits */
159 Cfg9346_Lock = 0x00, // unused
160 Cfg9346_Unlock = 0xc0, // unused
161
162 /* RxMacControl */
163 AcceptErr = 0x20, // unused
164 AcceptRunt = 0x10, // unused
165 AcceptBroadcast = 0x0800,
166 AcceptMulticast = 0x0400,
167 AcceptMyPhys = 0x0200,
168 AcceptAllPhys = 0x0100,
169
170 /* RxConfigBits */
171 RxCfgFIFOShift = 13,
172 RxCfgDMAShift = 8, // 0x1a in RxControl ?
173
174 /* TxConfigBits */
175 TxInterFrameGapShift = 24,
176 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
177
178 /* StationControl */
179 _1000bpsF = 0x1c00,
180 _1000bpsH = 0x0c00,
181 _100bpsF = 0x1800,
182 _100bpsH = 0x0800,
183 _10bpsF = 0x1400,
184 _10bpsH = 0x0400,
185
186 LinkStatus = 0x02, // unused
187 FullDup = 0x01, // unused
188
189 /* TBICSRBit */
190 TBILinkOK = 0x02000000, // unused
191};
192
193struct TxDesc {
Francois Romieu3cec93c2005-07-30 13:14:18 +0200194 __le32 PSize;
195 __le32 status;
196 __le32 addr;
197 __le32 size;
Francois Romieu890e8d02005-07-30 13:08:43 +0200198};
199
200struct RxDesc {
Francois Romieu3cec93c2005-07-30 13:14:18 +0200201 __le32 PSize;
202 __le32 status;
203 __le32 addr;
204 __le32 size;
Francois Romieu890e8d02005-07-30 13:08:43 +0200205};
206
207enum _DescStatusBit {
208 /* _Desc.status */
Francois Romieubcad5e52005-07-30 13:13:47 +0200209 OWNbit = 0x80000000, // RXOWN/TXOWN
210 INTbit = 0x40000000, // RXINT/TXINT
211 CRCbit = 0x00020000, // CRCOFF/CRCEN
212 PADbit = 0x00010000, // PREADD/PADEN
Francois Romieu890e8d02005-07-30 13:08:43 +0200213 /* _Desc.size */
Francois Romieubcad5e52005-07-30 13:13:47 +0200214 RingEnd = 0x80000000,
215 /* TxDesc.status */
216 LSEN = 0x08000000, // TSO ? -- FR
217 IPCS = 0x04000000,
218 TCPCS = 0x02000000,
219 UDPCS = 0x01000000,
220 BSTEN = 0x00800000,
221 EXTEN = 0x00400000,
222 DEFEN = 0x00200000,
223 BKFEN = 0x00100000,
224 CRSEN = 0x00080000,
225 COLEN = 0x00040000,
226 THOL3 = 0x30000000,
227 THOL2 = 0x20000000,
228 THOL1 = 0x10000000,
229 THOL0 = 0x00000000,
230 /* RxDesc.status */
231 IPON = 0x20000000,
232 TCPON = 0x10000000,
233 UDPON = 0x08000000,
234 Wakup = 0x00400000,
235 Magic = 0x00200000,
236 Pause = 0x00100000,
237 DEFbit = 0x00200000,
238 BCAST = 0x000c0000,
239 MCAST = 0x00080000,
240 UCAST = 0x00040000,
241 /* RxDesc.PSize */
242 TAGON = 0x80000000,
243 RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR
244 ABORT = 0x00800000,
245 SHORT = 0x00400000,
246 LIMIT = 0x00200000,
247 MIIER = 0x00100000,
248 OVRUN = 0x00080000,
249 NIBON = 0x00040000,
250 COLON = 0x00020000,
251 CRCOK = 0x00010000,
Francois Romieu890e8d02005-07-30 13:08:43 +0200252 RxSizeMask = 0x0000ffff
Francois Romieubcad5e52005-07-30 13:13:47 +0200253 /*
254 * The asic could apparently do vlan, TSO, jumbo (sis191 only) and
255 * provide two (unused with Linux) Tx queues. No publically
256 * available documentation alas.
257 */
Francois Romieu890e8d02005-07-30 13:08:43 +0200258};
259
Francois Romieu40292fb2005-07-30 13:12:06 +0200260enum sis190_eeprom_access_register_bits {
261 EECS = 0x00000001, // unused
262 EECLK = 0x00000002, // unused
263 EEDO = 0x00000008, // unused
264 EEDI = 0x00000004, // unused
265 EEREQ = 0x00000080,
266 EEROP = 0x00000200,
267 EEWOP = 0x00000100 // unused
268};
269
Francois Romieu830fb7d2005-07-30 13:12:37 +0200270/* EEPROM Addresses */
271enum sis190_eeprom_address {
272 EEPROMSignature = 0x00,
273 EEPROMCLK = 0x01, // unused
274 EEPROMInfo = 0x02,
275 EEPROMMACAddr = 0x03
276};
277
Francois Romieu890e8d02005-07-30 13:08:43 +0200278struct sis190_private {
279 void __iomem *mmio_addr;
280 struct pci_dev *pci_dev;
281 struct net_device_stats stats;
282 spinlock_t lock;
283 u32 rx_buf_sz;
284 u32 cur_rx;
285 u32 cur_tx;
286 u32 dirty_rx;
287 u32 dirty_tx;
288 dma_addr_t rx_dma;
289 dma_addr_t tx_dma;
290 struct RxDesc *RxDescRing;
291 struct TxDesc *TxDescRing;
292 struct sk_buff *Rx_skbuff[NUM_RX_DESC];
293 struct sk_buff *Tx_skbuff[NUM_TX_DESC];
294 struct work_struct phy_task;
295 struct timer_list timer;
296 u32 msg_enable;
Francois Romieu43afb942005-07-30 13:10:21 +0200297 struct mii_if_info mii_if;
Francois Romieu890e8d02005-07-30 13:08:43 +0200298};
299
300const static struct {
301 const char *name;
302 u8 version; /* depend on docs */
303 u32 RxConfigMask; /* clear the bits supported by this chip */
304} sis_chip_info[] = {
305 { DRV_NAME, 0x00, 0xff7e1880, },
306};
307
308static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
309 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
310 { 0, },
311};
312
313MODULE_DEVICE_TABLE(pci, sis190_pci_tbl);
314
315static int rx_copybreak = 200;
316
317static struct {
318 u32 msg_enable;
319} debug = { -1 };
320
321MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver");
322module_param(rx_copybreak, int, 0);
323MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
324module_param_named(debug, debug.msg_enable, int, 0);
325MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
326MODULE_AUTHOR("K.M. Liu <kmliu@sis.com>, Ueimor <romieu@fr.zoreil.com>");
327MODULE_VERSION(DRV_VERSION);
328MODULE_LICENSE("GPL");
329
330static const u32 sis190_intr_mask =
331 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt;
332
333/*
334 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
335 * The chips use a 64 element hash table based on the Ethernet CRC.
336 */
337static int multicast_filter_limit = 32;
338
339static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
340{
341 unsigned int i;
342
343 SIS_W32(GMIIControl, ctl);
344
345 msleep(1);
346
347 for (i = 0; i < 100; i++) {
348 if (!(SIS_R32(GMIIControl) & EhnMIInotDone))
349 break;
350 msleep(1);
351 }
352
353 if (i > 999)
354 printk(KERN_ERR PFX "PHY command failed !\n");
355}
356
Francois Romieu9ede1092005-07-30 13:14:38 +0200357static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val)
Francois Romieu890e8d02005-07-30 13:08:43 +0200358{
Francois Romieu890e8d02005-07-30 13:08:43 +0200359 __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite |
Francois Romieu9ede1092005-07-30 13:14:38 +0200360 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) |
Francois Romieu890e8d02005-07-30 13:08:43 +0200361 (((u32) val) << EhnMIIdataShift));
362}
363
Francois Romieu9ede1092005-07-30 13:14:38 +0200364static int mdio_read(void __iomem *ioaddr, int phy_id, int reg)
Francois Romieu890e8d02005-07-30 13:08:43 +0200365{
Francois Romieu890e8d02005-07-30 13:08:43 +0200366 __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread |
Francois Romieu9ede1092005-07-30 13:14:38 +0200367 (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift));
Francois Romieu890e8d02005-07-30 13:08:43 +0200368
369 return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift);
370}
371
Francois Romieu43afb942005-07-30 13:10:21 +0200372static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val)
373{
374 struct sis190_private *tp = netdev_priv(dev);
375
Francois Romieu9ede1092005-07-30 13:14:38 +0200376 mdio_write(tp->mmio_addr, phy_id, reg, val);
Francois Romieu43afb942005-07-30 13:10:21 +0200377}
378
379static int __mdio_read(struct net_device *dev, int phy_id, int reg)
380{
381 struct sis190_private *tp = netdev_priv(dev);
382
Francois Romieu9ede1092005-07-30 13:14:38 +0200383 return mdio_read(tp->mmio_addr, phy_id, reg);
Francois Romieu43afb942005-07-30 13:10:21 +0200384}
385
Francois Romieu40292fb2005-07-30 13:12:06 +0200386static u16 __devinit sis190_read_eeprom(void __iomem *ioaddr, u32 reg)
Francois Romieu890e8d02005-07-30 13:08:43 +0200387{
Francois Romieu40292fb2005-07-30 13:12:06 +0200388 u16 data = 0xffff;
Francois Romieu890e8d02005-07-30 13:08:43 +0200389 unsigned int i;
Francois Romieu890e8d02005-07-30 13:08:43 +0200390
391 if (!(SIS_R32(ROMControl) & 0x0002))
392 return 0;
393
Francois Romieu40292fb2005-07-30 13:12:06 +0200394 SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
Francois Romieu890e8d02005-07-30 13:08:43 +0200395
396 for (i = 0; i < 200; i++) {
Francois Romieu40292fb2005-07-30 13:12:06 +0200397 if (!(SIS_R32(ROMInterface) & EEREQ)) {
398 data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
Francois Romieu890e8d02005-07-30 13:08:43 +0200399 break;
Francois Romieu40292fb2005-07-30 13:12:06 +0200400 }
Francois Romieu890e8d02005-07-30 13:08:43 +0200401 msleep(1);
402 }
403
Francois Romieu890e8d02005-07-30 13:08:43 +0200404 return data;
405}
406
407static void sis190_irq_mask_and_ack(void __iomem *ioaddr)
408{
409 SIS_W32(IntrMask, 0x00);
410 SIS_W32(IntrStatus, 0xffffffff);
411 SIS_PCI_COMMIT();
412}
413
414static void sis190_asic_down(void __iomem *ioaddr)
415{
416 /* Stop the chip's Tx and Rx DMA processes. */
417
418 SIS_W32(TxControl, 0x1a00);
419 SIS_W32(RxControl, 0x1a00);
420
421 sis190_irq_mask_and_ack(ioaddr);
422}
423
424static void sis190_mark_as_last_descriptor(struct RxDesc *desc)
425{
426 desc->size |= cpu_to_le32(RingEnd);
427}
428
429static inline void sis190_give_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
430{
431 u32 eor = le32_to_cpu(desc->size) & RingEnd;
432
433 desc->PSize = 0x0;
Francois Romieu8b5641d2005-07-30 13:13:03 +0200434 desc->size = cpu_to_le32((rx_buf_sz & RX_BUF_MASK) | eor);
Francois Romieu890e8d02005-07-30 13:08:43 +0200435 wmb();
436 desc->status = cpu_to_le32(OWNbit | INTbit);
437}
438
439static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
440 u32 rx_buf_sz)
441{
442 desc->addr = cpu_to_le32(mapping);
443 sis190_give_to_asic(desc, rx_buf_sz);
444}
445
446static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
447{
448 desc->PSize = 0x0;
449 desc->addr = 0xdeadbeef;
450 desc->size &= cpu_to_le32(RingEnd);
451 wmb();
452 desc->status = 0x0;
453}
454
455static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
456 struct RxDesc *desc, u32 rx_buf_sz)
457{
458 struct sk_buff *skb;
459 dma_addr_t mapping;
460 int ret = 0;
461
462 skb = dev_alloc_skb(rx_buf_sz);
463 if (!skb)
464 goto err_out;
465
466 *sk_buff = skb;
467
468 mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
469 PCI_DMA_FROMDEVICE);
470
471 sis190_map_to_asic(desc, mapping, rx_buf_sz);
472out:
473 return ret;
474
475err_out:
476 ret = -ENOMEM;
477 sis190_make_unusable_by_asic(desc);
478 goto out;
479}
480
481static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
482 u32 start, u32 end)
483{
484 u32 cur;
485
486 for (cur = start; cur < end; cur++) {
487 int ret, i = cur % NUM_RX_DESC;
488
489 if (tp->Rx_skbuff[i])
490 continue;
491
492 ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
493 tp->RxDescRing + i, tp->rx_buf_sz);
494 if (ret < 0)
495 break;
496 }
497 return cur - start;
498}
499
500static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
501 struct RxDesc *desc, int rx_buf_sz)
502{
503 int ret = -1;
504
505 if (pkt_size < rx_copybreak) {
506 struct sk_buff *skb;
507
508 skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
509 if (skb) {
510 skb_reserve(skb, NET_IP_ALIGN);
511 eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
512 *sk_buff = skb;
513 sis190_give_to_asic(desc, rx_buf_sz);
514 ret = 0;
515 }
516 }
517 return ret;
518}
519
Francois Romieubcad5e52005-07-30 13:13:47 +0200520static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
521{
522#define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
523
524 if ((status & CRCOK) && !(status & ErrMask))
525 return 0;
526
527 if (!(status & CRCOK))
528 stats->rx_crc_errors++;
529 else if (status & OVRUN)
530 stats->rx_over_errors++;
531 else if (status & (SHORT | LIMIT))
532 stats->rx_length_errors++;
533 else if (status & (MIIER | NIBON | COLON))
534 stats->rx_frame_errors++;
535
536 stats->rx_errors++;
537 return -1;
538}
539
Francois Romieu890e8d02005-07-30 13:08:43 +0200540static int sis190_rx_interrupt(struct net_device *dev,
541 struct sis190_private *tp, void __iomem *ioaddr)
542{
543 struct net_device_stats *stats = &tp->stats;
544 u32 rx_left, cur_rx = tp->cur_rx;
545 u32 delta, count;
546
547 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
548 rx_left = sis190_rx_quota(rx_left, (u32) dev->quota);
549
550 for (; rx_left > 0; rx_left--, cur_rx++) {
551 unsigned int entry = cur_rx % NUM_RX_DESC;
552 struct RxDesc *desc = tp->RxDescRing + entry;
553 u32 status;
554
555 if (desc->status & OWNbit)
556 break;
557
558 status = le32_to_cpu(desc->PSize);
559
560 // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name,
561 // status);
562
Francois Romieubcad5e52005-07-30 13:13:47 +0200563 if (sis190_rx_pkt_err(status, stats) < 0)
Francois Romieu890e8d02005-07-30 13:08:43 +0200564 sis190_give_to_asic(desc, tp->rx_buf_sz);
Francois Romieubcad5e52005-07-30 13:13:47 +0200565 else {
Francois Romieu890e8d02005-07-30 13:08:43 +0200566 struct sk_buff *skb = tp->Rx_skbuff[entry];
567 int pkt_size = (status & RxSizeMask) - 4;
568 void (*pci_action)(struct pci_dev *, dma_addr_t,
569 size_t, int) = pci_dma_sync_single_for_device;
570
571 if (unlikely(pkt_size > tp->rx_buf_sz)) {
572 net_intr(tp, KERN_INFO
573 "%s: (frag) status = %08x.\n",
574 dev->name, status);
575 stats->rx_dropped++;
576 stats->rx_length_errors++;
577 sis190_give_to_asic(desc, tp->rx_buf_sz);
578 continue;
579 }
580
581 pci_dma_sync_single_for_cpu(tp->pci_dev,
582 le32_to_cpu(desc->addr), tp->rx_buf_sz,
583 PCI_DMA_FROMDEVICE);
584
585 if (sis190_try_rx_copy(&skb, pkt_size, desc,
586 tp->rx_buf_sz)) {
587 pci_action = pci_unmap_single;
588 tp->Rx_skbuff[entry] = NULL;
589 sis190_make_unusable_by_asic(desc);
590 }
591
592 pci_action(tp->pci_dev, le32_to_cpu(desc->addr),
593 tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
594
595 skb->dev = dev;
596 skb_put(skb, pkt_size);
597 skb->protocol = eth_type_trans(skb, dev);
598
599 sis190_rx_skb(skb);
600
601 dev->last_rx = jiffies;
Francois Romieu890e8d02005-07-30 13:08:43 +0200602 stats->rx_packets++;
Francois Romieubcad5e52005-07-30 13:13:47 +0200603 stats->rx_bytes += pkt_size;
604 if ((status & BCAST) == MCAST)
605 stats->multicast++;
Francois Romieu890e8d02005-07-30 13:08:43 +0200606 }
607 }
608 count = cur_rx - tp->cur_rx;
609 tp->cur_rx = cur_rx;
610
611 delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
612 if (!delta && count && netif_msg_intr(tp))
613 printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name);
614 tp->dirty_rx += delta;
615
616 if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp))
617 printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name);
618
619 return count;
620}
621
622static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb,
623 struct TxDesc *desc)
624{
625 unsigned int len;
626
627 len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
628
629 pci_unmap_single(pdev, le32_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
630
631 memset(desc, 0x00, sizeof(*desc));
632}
633
634static void sis190_tx_interrupt(struct net_device *dev,
635 struct sis190_private *tp, void __iomem *ioaddr)
636{
637 u32 pending, dirty_tx = tp->dirty_tx;
638 /*
639 * It would not be needed if queueing was allowed to be enabled
640 * again too early (hint: think preempt and unclocked smp systems).
641 */
642 unsigned int queue_stopped;
643
644 smp_rmb();
645 pending = tp->cur_tx - dirty_tx;
646 queue_stopped = (pending == NUM_TX_DESC);
647
648 for (; pending; pending--, dirty_tx++) {
649 unsigned int entry = dirty_tx % NUM_TX_DESC;
650 struct TxDesc *txd = tp->TxDescRing + entry;
651 struct sk_buff *skb;
652
653 if (le32_to_cpu(txd->status) & OWNbit)
654 break;
655
656 skb = tp->Tx_skbuff[entry];
657
658 tp->stats.tx_packets++;
659 tp->stats.tx_bytes += skb->len;
660
661 sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
662 tp->Tx_skbuff[entry] = NULL;
663 dev_kfree_skb_irq(skb);
664 }
665
666 if (tp->dirty_tx != dirty_tx) {
667 tp->dirty_tx = dirty_tx;
668 smp_wmb();
669 if (queue_stopped)
670 netif_wake_queue(dev);
671 }
672}
673
674/*
675 * The interrupt handler does all of the Rx thread work and cleans up after
676 * the Tx thread.
677 */
678static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs)
679{
680 struct net_device *dev = __dev;
681 struct sis190_private *tp = netdev_priv(dev);
682 void __iomem *ioaddr = tp->mmio_addr;
683 unsigned int handled = 0;
684 u32 status;
685
686 status = SIS_R32(IntrStatus);
687
688 if ((status == 0xffffffff) || !status)
689 goto out;
690
691 handled = 1;
692
693 if (unlikely(!netif_running(dev))) {
694 sis190_asic_down(ioaddr);
695 goto out;
696 }
697
698 SIS_W32(IntrStatus, status);
699
700 // net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status);
701
702 if (status & LinkChange) {
703 net_intr(tp, KERN_INFO "%s: link change.\n", dev->name);
704 schedule_work(&tp->phy_task);
705 }
706
707 if (status & RxQInt)
708 sis190_rx_interrupt(dev, tp, ioaddr);
709
710 if (status & TxQ0Int)
711 sis190_tx_interrupt(dev, tp, ioaddr);
712out:
713 return IRQ_RETVAL(handled);
714}
715
Francois Romieu4405d3b2005-07-30 13:09:20 +0200716#ifdef CONFIG_NET_POLL_CONTROLLER
717static void sis190_netpoll(struct net_device *dev)
718{
719 struct sis190_private *tp = netdev_priv(dev);
720 struct pci_dev *pdev = tp->pci_dev;
721
722 disable_irq(pdev->irq);
723 sis190_interrupt(pdev->irq, dev, NULL);
724 enable_irq(pdev->irq);
725}
726#endif
727
Francois Romieu890e8d02005-07-30 13:08:43 +0200728static void sis190_free_rx_skb(struct sis190_private *tp,
729 struct sk_buff **sk_buff, struct RxDesc *desc)
730{
731 struct pci_dev *pdev = tp->pci_dev;
732
733 pci_unmap_single(pdev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
734 PCI_DMA_FROMDEVICE);
735 dev_kfree_skb(*sk_buff);
736 *sk_buff = NULL;
737 sis190_make_unusable_by_asic(desc);
738}
739
740static void sis190_rx_clear(struct sis190_private *tp)
741{
742 unsigned int i;
743
744 for (i = 0; i < NUM_RX_DESC; i++) {
745 if (!tp->Rx_skbuff[i])
746 continue;
747 sis190_free_rx_skb(tp, tp->Rx_skbuff + i, tp->RxDescRing + i);
748 }
749}
750
751static void sis190_init_ring_indexes(struct sis190_private *tp)
752{
753 tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
754}
755
756static int sis190_init_ring(struct net_device *dev)
757{
758 struct sis190_private *tp = netdev_priv(dev);
759
760 sis190_init_ring_indexes(tp);
761
762 memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
763 memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
764
765 if (sis190_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
766 goto err_rx_clear;
767
768 sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
769
770 return 0;
771
772err_rx_clear:
773 sis190_rx_clear(tp);
774 return -ENOMEM;
775}
776
777static void sis190_set_rx_mode(struct net_device *dev)
778{
779 struct sis190_private *tp = netdev_priv(dev);
780 void __iomem *ioaddr = tp->mmio_addr;
781 unsigned long flags;
782 u32 mc_filter[2]; /* Multicast hash filter */
783 u16 rx_mode;
784
785 if (dev->flags & IFF_PROMISC) {
786 /* Unconditionally log net taps. */
787 net_drv(tp, KERN_NOTICE "%s: Promiscuous mode enabled.\n",
788 dev->name);
789 rx_mode =
790 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
791 AcceptAllPhys;
792 mc_filter[1] = mc_filter[0] = 0xffffffff;
793 } else if ((dev->mc_count > multicast_filter_limit) ||
794 (dev->flags & IFF_ALLMULTI)) {
795 /* Too many to filter perfectly -- accept all multicasts. */
796 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
797 mc_filter[1] = mc_filter[0] = 0xffffffff;
798 } else {
799 struct dev_mc_list *mclist;
800 unsigned int i;
801
802 rx_mode = AcceptBroadcast | AcceptMyPhys;
803 mc_filter[1] = mc_filter[0] = 0;
804 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
805 i++, mclist = mclist->next) {
806 int bit_nr =
807 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
808 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
809 rx_mode |= AcceptMulticast;
810 }
811 }
812
813 spin_lock_irqsave(&tp->lock, flags);
814
815 SIS_W16(RxMacControl, rx_mode | 0x2);
816 SIS_W32(RxHashTable, mc_filter[0]);
817 SIS_W32(RxHashTable + 4, mc_filter[1]);
818
819 spin_unlock_irqrestore(&tp->lock, flags);
820}
821
822static void sis190_soft_reset(void __iomem *ioaddr)
823{
824 SIS_W32(IntrControl, 0x8000);
825 SIS_PCI_COMMIT();
826 msleep(1);
827 SIS_W32(IntrControl, 0x0);
828 sis190_asic_down(ioaddr);
829 msleep(1);
830}
831
832static void sis190_hw_start(struct net_device *dev)
833{
834 struct sis190_private *tp = netdev_priv(dev);
835 void __iomem *ioaddr = tp->mmio_addr;
836
837 sis190_soft_reset(ioaddr);
838
839 SIS_W32(TxDescStartAddr, tp->tx_dma);
840 SIS_W32(RxDescStartAddr, tp->rx_dma);
841
842 SIS_W32(IntrStatus, 0xffffffff);
843 SIS_W32(IntrMask, 0x0);
844 /*
845 * Default is 100Mbps.
846 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
847 */
848 SIS_W16(StationControl, 0x1901);
849 SIS_W32(GMIIControl, 0x0);
850 SIS_W32(TxMacControl, 0x60);
851 SIS_W16(RxMacControl, 0x02);
852 SIS_W32(RxHashTable, 0x0);
853 SIS_W32(0x6c, 0x0);
Francois Romieu188f23b2005-07-30 13:11:43 +0200854 SIS_W32(RxWolCtrl, 0x0);
855 SIS_W32(RxWolData, 0x0);
Francois Romieu890e8d02005-07-30 13:08:43 +0200856
857 SIS_PCI_COMMIT();
858
859 sis190_set_rx_mode(dev);
860
861 /* Enable all known interrupts by setting the interrupt mask. */
862 SIS_W32(IntrMask, sis190_intr_mask);
863
864 SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
865 SIS_W32(RxControl, 0x1a1d);
866
867 netif_start_queue(dev);
868}
869
870static void sis190_phy_task(void * data)
871{
872 struct net_device *dev = data;
873 struct sis190_private *tp = netdev_priv(dev);
874 void __iomem *ioaddr = tp->mmio_addr;
Francois Romieu9ede1092005-07-30 13:14:38 +0200875 int phy_id = tp->mii_if.phy_id;
Francois Romieu890e8d02005-07-30 13:08:43 +0200876 u16 val;
877
Francois Romieu43afb942005-07-30 13:10:21 +0200878 rtnl_lock();
879
Francois Romieu9ede1092005-07-30 13:14:38 +0200880 val = mdio_read(ioaddr, phy_id, MII_BMCR);
Francois Romieu890e8d02005-07-30 13:08:43 +0200881 if (val & BMCR_RESET) {
882 // FIXME: needlessly high ? -- FR 02/07/2005
883 mod_timer(&tp->timer, jiffies + HZ/10);
Francois Romieu9ede1092005-07-30 13:14:38 +0200884 } else if (!(mdio_read(ioaddr, phy_id, MII_BMSR) & BMSR_ANEGCOMPLETE)) {
Francois Romieu890e8d02005-07-30 13:08:43 +0200885 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
886 dev->name);
Francois Romieu9ede1092005-07-30 13:14:38 +0200887 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
Francois Romieu890e8d02005-07-30 13:08:43 +0200888 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
889 } else {
890 /* Rejoice ! */
891 struct {
892 int val;
893 const char *msg;
894 u16 ctl;
895 } reg31[] = {
896 { LPA_1000XFULL | LPA_SLCT,
897 "1000 Mbps Full Duplex",
898 0x01 | _1000bpsF },
899 { LPA_1000XHALF | LPA_SLCT,
900 "1000 Mbps Half Duplex",
901 0x01 | _1000bpsH },
902 { LPA_100FULL,
903 "100 Mbps Full Duplex",
904 0x01 | _100bpsF },
905 { LPA_100HALF,
906 "100 Mbps Half Duplex",
907 0x01 | _100bpsH },
908 { LPA_10FULL,
909 "10 Mbps Full Duplex",
910 0x01 | _10bpsF },
911 { LPA_10HALF,
912 "10 Mbps Half Duplex",
913 0x01 | _10bpsH },
914 { 0, "unknown", 0x0000 }
915 }, *p;
916
Francois Romieu9ede1092005-07-30 13:14:38 +0200917 val = mdio_read(ioaddr, phy_id, 0x1f);
Francois Romieu890e8d02005-07-30 13:08:43 +0200918 net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
919
Francois Romieu9ede1092005-07-30 13:14:38 +0200920 val = mdio_read(ioaddr, phy_id, MII_LPA);
Francois Romieu890e8d02005-07-30 13:08:43 +0200921 net_link(tp, KERN_INFO "%s: mii lpa = %04x.\n", dev->name, val);
922
923 for (p = reg31; p->ctl; p++) {
924 if ((val & p->val) == p->val)
925 break;
926 }
927 if (p->ctl)
928 SIS_W16(StationControl, p->ctl);
929 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
930 p->msg);
931 netif_carrier_on(dev);
932 }
Francois Romieu43afb942005-07-30 13:10:21 +0200933
934 rtnl_unlock();
Francois Romieu890e8d02005-07-30 13:08:43 +0200935}
936
937static void sis190_phy_timer(unsigned long __opaque)
938{
939 struct net_device *dev = (struct net_device *)__opaque;
940 struct sis190_private *tp = netdev_priv(dev);
941
942 if (likely(netif_running(dev)))
943 schedule_work(&tp->phy_task);
944}
945
946static inline void sis190_delete_timer(struct net_device *dev)
947{
948 struct sis190_private *tp = netdev_priv(dev);
949
950 del_timer_sync(&tp->timer);
951}
952
953static inline void sis190_request_timer(struct net_device *dev)
954{
955 struct sis190_private *tp = netdev_priv(dev);
956 struct timer_list *timer = &tp->timer;
957
958 init_timer(timer);
959 timer->expires = jiffies + SIS190_PHY_TIMEOUT;
960 timer->data = (unsigned long)dev;
961 timer->function = sis190_phy_timer;
962 add_timer(timer);
963}
964
965static void sis190_set_rxbufsize(struct sis190_private *tp,
966 struct net_device *dev)
967{
968 unsigned int mtu = dev->mtu;
969
970 tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
Francois Romieu8b5641d2005-07-30 13:13:03 +0200971 /* RxDesc->size has a licence to kill the lower bits */
972 if (tp->rx_buf_sz & 0x07) {
973 tp->rx_buf_sz += 8;
974 tp->rx_buf_sz &= RX_BUF_MASK;
975 }
Francois Romieu890e8d02005-07-30 13:08:43 +0200976}
977
978static int sis190_open(struct net_device *dev)
979{
980 struct sis190_private *tp = netdev_priv(dev);
981 struct pci_dev *pdev = tp->pci_dev;
982 int rc = -ENOMEM;
983
984 sis190_set_rxbufsize(tp, dev);
985
986 /*
987 * Rx and Tx descriptors need 256 bytes alignment.
988 * pci_alloc_consistent() guarantees a stronger alignment.
989 */
990 tp->TxDescRing = pci_alloc_consistent(pdev, TX_RING_BYTES, &tp->tx_dma);
991 if (!tp->TxDescRing)
992 goto out;
993
994 tp->RxDescRing = pci_alloc_consistent(pdev, RX_RING_BYTES, &tp->rx_dma);
995 if (!tp->RxDescRing)
996 goto err_free_tx_0;
997
998 rc = sis190_init_ring(dev);
999 if (rc < 0)
1000 goto err_free_rx_1;
1001
1002 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1003
1004 sis190_request_timer(dev);
1005
1006 rc = request_irq(dev->irq, sis190_interrupt, SA_SHIRQ, dev->name, dev);
1007 if (rc < 0)
1008 goto err_release_timer_2;
1009
1010 sis190_hw_start(dev);
1011out:
1012 return rc;
1013
1014err_release_timer_2:
1015 sis190_delete_timer(dev);
1016 sis190_rx_clear(tp);
1017err_free_rx_1:
1018 pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing,
1019 tp->rx_dma);
1020err_free_tx_0:
1021 pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing,
1022 tp->tx_dma);
1023 goto out;
1024}
1025
1026static void sis190_tx_clear(struct sis190_private *tp)
1027{
1028 unsigned int i;
1029
1030 for (i = 0; i < NUM_TX_DESC; i++) {
1031 struct sk_buff *skb = tp->Tx_skbuff[i];
1032
1033 if (!skb)
1034 continue;
1035
1036 sis190_unmap_tx_skb(tp->pci_dev, skb, tp->TxDescRing + i);
1037 tp->Tx_skbuff[i] = NULL;
1038 dev_kfree_skb(skb);
1039
1040 tp->stats.tx_dropped++;
1041 }
1042 tp->cur_tx = tp->dirty_tx = 0;
1043}
1044
1045static void sis190_down(struct net_device *dev)
1046{
1047 struct sis190_private *tp = netdev_priv(dev);
1048 void __iomem *ioaddr = tp->mmio_addr;
1049 unsigned int poll_locked = 0;
1050
1051 sis190_delete_timer(dev);
1052
1053 netif_stop_queue(dev);
1054
1055 flush_scheduled_work();
1056
1057 do {
1058 spin_lock_irq(&tp->lock);
1059
1060 sis190_asic_down(ioaddr);
1061
1062 spin_unlock_irq(&tp->lock);
1063
1064 synchronize_irq(dev->irq);
1065
1066 if (!poll_locked) {
1067 netif_poll_disable(dev);
1068 poll_locked++;
1069 }
1070
1071 synchronize_sched();
1072
1073 } while (SIS_R32(IntrMask));
1074
1075 sis190_tx_clear(tp);
1076 sis190_rx_clear(tp);
1077}
1078
1079static int sis190_close(struct net_device *dev)
1080{
1081 struct sis190_private *tp = netdev_priv(dev);
1082 struct pci_dev *pdev = tp->pci_dev;
1083
1084 sis190_down(dev);
1085
1086 free_irq(dev->irq, dev);
1087
1088 netif_poll_enable(dev);
1089
1090 pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
1091 pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
1092
1093 tp->TxDescRing = NULL;
1094 tp->RxDescRing = NULL;
1095
1096 return 0;
1097}
1098
1099static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
1100{
1101 struct sis190_private *tp = netdev_priv(dev);
1102 void __iomem *ioaddr = tp->mmio_addr;
1103 u32 len, entry, dirty_tx;
1104 struct TxDesc *desc;
1105 dma_addr_t mapping;
1106
1107 if (unlikely(skb->len < ETH_ZLEN)) {
1108 skb = skb_padto(skb, ETH_ZLEN);
1109 if (!skb) {
1110 tp->stats.tx_dropped++;
1111 goto out;
1112 }
1113 len = ETH_ZLEN;
1114 } else {
1115 len = skb->len;
1116 }
1117
1118 entry = tp->cur_tx % NUM_TX_DESC;
1119 desc = tp->TxDescRing + entry;
1120
1121 if (unlikely(le32_to_cpu(desc->status) & OWNbit)) {
1122 netif_stop_queue(dev);
1123 net_tx_err(tp, KERN_ERR PFX
1124 "%s: BUG! Tx Ring full when queue awake!\n",
1125 dev->name);
1126 return NETDEV_TX_BUSY;
1127 }
1128
1129 mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
1130
1131 tp->Tx_skbuff[entry] = skb;
1132
1133 desc->PSize = cpu_to_le32(len);
1134 desc->addr = cpu_to_le32(mapping);
1135
1136 desc->size = cpu_to_le32(len);
1137 if (entry == (NUM_TX_DESC - 1))
1138 desc->size |= cpu_to_le32(RingEnd);
1139
1140 wmb();
1141
1142 desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
1143
1144 tp->cur_tx++;
1145
1146 smp_wmb();
1147
1148 SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
1149
1150 dev->trans_start = jiffies;
1151
1152 dirty_tx = tp->dirty_tx;
1153 if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
1154 netif_stop_queue(dev);
1155 smp_rmb();
1156 if (dirty_tx != tp->dirty_tx)
1157 netif_wake_queue(dev);
1158 }
1159out:
1160 return NETDEV_TX_OK;
1161}
1162
1163static struct net_device_stats *sis190_get_stats(struct net_device *dev)
1164{
1165 struct sis190_private *tp = netdev_priv(dev);
1166
1167 return &tp->stats;
1168}
1169
1170static void sis190_release_board(struct pci_dev *pdev)
1171{
1172 struct net_device *dev = pci_get_drvdata(pdev);
1173 struct sis190_private *tp = netdev_priv(dev);
1174
1175 iounmap(tp->mmio_addr);
1176 pci_release_regions(pdev);
1177 pci_disable_device(pdev);
1178 free_netdev(dev);
1179}
1180
1181static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
1182{
1183 struct sis190_private *tp;
1184 struct net_device *dev;
1185 void __iomem *ioaddr;
1186 int rc;
1187
1188 dev = alloc_etherdev(sizeof(*tp));
1189 if (!dev) {
1190 net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n");
1191 rc = -ENOMEM;
1192 goto err_out_0;
1193 }
1194
1195 SET_MODULE_OWNER(dev);
1196 SET_NETDEV_DEV(dev, &pdev->dev);
1197
1198 tp = netdev_priv(dev);
1199 tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT);
1200
1201 rc = pci_enable_device(pdev);
1202 if (rc < 0) {
1203 net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev));
1204 goto err_free_dev_1;
1205 }
1206
1207 rc = -ENODEV;
1208
1209 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1210 net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n",
1211 pci_name(pdev));
1212 goto err_pci_disable_2;
1213 }
1214 if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) {
1215 net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n",
1216 pci_name(pdev));
1217 goto err_pci_disable_2;
1218 }
1219
1220 rc = pci_request_regions(pdev, DRV_NAME);
1221 if (rc < 0) {
1222 net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n",
1223 pci_name(pdev));
1224 goto err_pci_disable_2;
1225 }
1226
1227 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1228 if (rc < 0) {
1229 net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n",
1230 pci_name(pdev));
1231 goto err_free_res_3;
1232 }
1233
1234 pci_set_master(pdev);
1235
1236 ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE);
1237 if (!ioaddr) {
1238 net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n",
1239 pci_name(pdev));
1240 rc = -EIO;
1241 goto err_free_res_3;
1242 }
1243
1244 tp->pci_dev = pdev;
1245 tp->mmio_addr = ioaddr;
1246
Francois Romieu43afb942005-07-30 13:10:21 +02001247 tp->mii_if.dev = dev;
1248 tp->mii_if.mdio_read = __mdio_read;
1249 tp->mii_if.mdio_write = __mdio_write;
Francois Romieu9ede1092005-07-30 13:14:38 +02001250 tp->mii_if.phy_id = 1;
Francois Romieu43afb942005-07-30 13:10:21 +02001251 tp->mii_if.phy_id_mask = 0x1f;
1252 tp->mii_if.reg_num_mask = 0x1f;
1253
Francois Romieu890e8d02005-07-30 13:08:43 +02001254 sis190_irq_mask_and_ack(ioaddr);
1255
1256 sis190_soft_reset(ioaddr);
1257out:
1258 return dev;
1259
1260err_free_res_3:
1261 pci_release_regions(pdev);
1262err_pci_disable_2:
1263 pci_disable_device(pdev);
1264err_free_dev_1:
1265 free_netdev(dev);
1266err_out_0:
1267 dev = ERR_PTR(rc);
1268 goto out;
1269}
1270
1271static void sis190_tx_timeout(struct net_device *dev)
1272{
1273 struct sis190_private *tp = netdev_priv(dev);
1274 void __iomem *ioaddr = tp->mmio_addr;
1275 u8 tmp8;
1276
1277 /* Disable Tx, if not already */
1278 tmp8 = SIS_R8(TxControl);
1279 if (tmp8 & CmdTxEnb)
1280 SIS_W8(TxControl, tmp8 & ~CmdTxEnb);
1281
Francois Romieu188f23b2005-07-30 13:11:43 +02001282
1283 net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n",
1284 dev->name, SIS_R32(TxControl), SIS_R32(TxSts));
1285
Francois Romieu890e8d02005-07-30 13:08:43 +02001286 /* Disable interrupts by clearing the interrupt mask. */
1287 SIS_W32(IntrMask, 0x0000);
1288
1289 /* Stop a shared interrupt from scavenging while we are. */
1290 spin_lock_irq(&tp->lock);
1291 sis190_tx_clear(tp);
1292 spin_unlock_irq(&tp->lock);
1293
1294 /* ...and finally, reset everything. */
1295 sis190_hw_start(dev);
1296
1297 netif_wake_queue(dev);
1298}
1299
Francois Romieu830fb7d2005-07-30 13:12:37 +02001300static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1301 struct net_device *dev)
1302{
1303 struct sis190_private *tp = netdev_priv(dev);
1304 void __iomem *ioaddr = tp->mmio_addr;
1305 u16 sig;
1306 int i;
1307
1308 net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n",
1309 pci_name(pdev));
1310
1311 /* Check to see if there is a sane EEPROM */
1312 sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
1313
1314 if ((sig == 0xffff) || (sig == 0x0000)) {
1315 net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n",
1316 pci_name(pdev), sig);
1317 return -EIO;
1318 }
1319
1320 /* Get MAC address from EEPROM */
1321 for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
Francois Romieu3cec93c2005-07-30 13:14:18 +02001322 __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
Francois Romieu830fb7d2005-07-30 13:12:37 +02001323
1324 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1325 }
1326
1327 return 0;
1328}
1329
1330/**
1331 * sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
1332 * @pdev: PCI device
1333 * @dev: network device to get address for
1334 *
1335 * SiS965 model, use APC CMOS RAM to store MAC address.
1336 * APC CMOS RAM is accessed through ISA bridge.
1337 * MAC address is read into @net_dev->dev_addr.
1338 */
1339static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1340 struct net_device *dev)
1341{
1342 struct sis190_private *tp = netdev_priv(dev);
1343 struct pci_dev *isa_bridge;
1344 u8 reg, tmp8;
1345 int i;
1346
1347 net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
1348 pci_name(pdev));
1349
1350 isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
1351 if (!isa_bridge) {
1352 net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
1353 pci_name(pdev));
1354 return -EIO;
1355 }
1356
1357 /* Enable port 78h & 79h to access APC Registers. */
1358 pci_read_config_byte(isa_bridge, 0x48, &tmp8);
1359 reg = (tmp8 & ~0x02);
1360 pci_write_config_byte(isa_bridge, 0x48, reg);
1361 udelay(50);
1362 pci_read_config_byte(isa_bridge, 0x48, &reg);
1363
1364 for (i = 0; i < MAC_ADDR_LEN; i++) {
1365 outb(0x9 + i, 0x78);
1366 dev->dev_addr[i] = inb(0x79);
1367 }
1368
1369 outb(0x12, 0x78);
1370 reg = inb(0x79);
1371
1372 /* Restore the value to ISA Bridge */
1373 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1374 pci_dev_put(isa_bridge);
1375
1376 return 0;
1377}
1378
1379/**
1380 * sis190_init_rxfilter - Initialize the Rx filter
1381 * @dev: network device to initialize
1382 *
1383 * Set receive filter address to our MAC address
1384 * and enable packet filtering.
1385 */
1386static inline void sis190_init_rxfilter(struct net_device *dev)
1387{
1388 struct sis190_private *tp = netdev_priv(dev);
1389 void __iomem *ioaddr = tp->mmio_addr;
1390 u16 ctl;
1391 int i;
1392
1393 ctl = SIS_R16(RxMacControl);
1394 /*
1395 * Disable packet filtering before setting filter.
1396 * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
1397 * only and followed by RxMacAddr (6 bytes). Strange. -- FR
1398 */
1399 SIS_W16(RxMacControl, ctl & ~0x0f00);
1400
1401 for (i = 0; i < MAC_ADDR_LEN; i++)
1402 SIS_W8(RxMacAddr + i, dev->dev_addr[i]);
1403
1404 SIS_W16(RxMacControl, ctl);
1405 SIS_PCI_COMMIT();
1406}
1407
1408static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
1409{
1410 u8 from;
1411
1412 pci_read_config_byte(pdev, 0x73, &from);
1413
1414 return (from & 0x00000001) ?
1415 sis190_get_mac_addr_from_apc(pdev, dev) :
1416 sis190_get_mac_addr_from_eeprom(pdev, dev);
1417}
1418
Francois Romieu890e8d02005-07-30 13:08:43 +02001419static void sis190_set_speed_auto(struct net_device *dev)
1420{
1421 struct sis190_private *tp = netdev_priv(dev);
1422 void __iomem *ioaddr = tp->mmio_addr;
Francois Romieu9ede1092005-07-30 13:14:38 +02001423 int phy_id = tp->mii_if.phy_id;
Francois Romieu890e8d02005-07-30 13:08:43 +02001424 int val;
1425
1426 net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name);
1427
Francois Romieu9ede1092005-07-30 13:14:38 +02001428 val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
Francois Romieu890e8d02005-07-30 13:08:43 +02001429
1430 // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
1431 // unchanged.
Francois Romieu9ede1092005-07-30 13:14:38 +02001432 mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
Francois Romieu890e8d02005-07-30 13:08:43 +02001433 ADVERTISE_100FULL | ADVERTISE_10FULL |
1434 ADVERTISE_100HALF | ADVERTISE_10HALF);
1435
1436 // Enable 1000 Full Mode.
Francois Romieu9ede1092005-07-30 13:14:38 +02001437 mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
Francois Romieu890e8d02005-07-30 13:08:43 +02001438
1439 // Enable auto-negotiation and restart auto-negotiation.
Francois Romieu9ede1092005-07-30 13:14:38 +02001440 mdio_write(ioaddr, phy_id, MII_BMCR,
Francois Romieu890e8d02005-07-30 13:08:43 +02001441 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
1442}
1443
Francois Romieu43afb942005-07-30 13:10:21 +02001444static int sis190_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1445{
1446 struct sis190_private *tp = netdev_priv(dev);
1447
1448 return mii_ethtool_gset(&tp->mii_if, cmd);
1449}
1450
1451static int sis190_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1452{
1453 struct sis190_private *tp = netdev_priv(dev);
1454
1455 return mii_ethtool_sset(&tp->mii_if, cmd);
1456}
1457
Francois Romieu890e8d02005-07-30 13:08:43 +02001458static void sis190_get_drvinfo(struct net_device *dev,
1459 struct ethtool_drvinfo *info)
1460{
1461 struct sis190_private *tp = netdev_priv(dev);
1462
1463 strcpy(info->driver, DRV_NAME);
1464 strcpy(info->version, DRV_VERSION);
1465 strcpy(info->bus_info, pci_name(tp->pci_dev));
1466}
1467
1468static int sis190_get_regs_len(struct net_device *dev)
1469{
1470 return SIS190_REGS_SIZE;
1471}
1472
1473static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1474 void *p)
1475{
1476 struct sis190_private *tp = netdev_priv(dev);
1477 unsigned long flags;
1478
1479 if (regs->len > SIS190_REGS_SIZE)
1480 regs->len = SIS190_REGS_SIZE;
1481
1482 spin_lock_irqsave(&tp->lock, flags);
1483 memcpy_fromio(p, tp->mmio_addr, regs->len);
1484 spin_unlock_irqrestore(&tp->lock, flags);
1485}
1486
Francois Romieu43afb942005-07-30 13:10:21 +02001487static int sis190_nway_reset(struct net_device *dev)
1488{
1489 struct sis190_private *tp = netdev_priv(dev);
1490
1491 return mii_nway_restart(&tp->mii_if);
1492}
1493
Francois Romieu890e8d02005-07-30 13:08:43 +02001494static u32 sis190_get_msglevel(struct net_device *dev)
1495{
1496 struct sis190_private *tp = netdev_priv(dev);
1497
1498 return tp->msg_enable;
1499}
1500
1501static void sis190_set_msglevel(struct net_device *dev, u32 value)
1502{
1503 struct sis190_private *tp = netdev_priv(dev);
1504
1505 tp->msg_enable = value;
1506}
1507
1508static struct ethtool_ops sis190_ethtool_ops = {
Francois Romieu43afb942005-07-30 13:10:21 +02001509 .get_settings = sis190_get_settings,
1510 .set_settings = sis190_set_settings,
Francois Romieu890e8d02005-07-30 13:08:43 +02001511 .get_drvinfo = sis190_get_drvinfo,
1512 .get_regs_len = sis190_get_regs_len,
1513 .get_regs = sis190_get_regs,
1514 .get_link = ethtool_op_get_link,
1515 .get_msglevel = sis190_get_msglevel,
1516 .set_msglevel = sis190_set_msglevel,
Francois Romieu43afb942005-07-30 13:10:21 +02001517 .nway_reset = sis190_nway_reset,
Francois Romieu890e8d02005-07-30 13:08:43 +02001518};
1519
Francois Romieu43afb942005-07-30 13:10:21 +02001520static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1521{
1522 struct sis190_private *tp = netdev_priv(dev);
1523
1524 return !netif_running(dev) ? -EINVAL :
1525 generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
1526}
1527
Francois Romieu890e8d02005-07-30 13:08:43 +02001528static int __devinit sis190_init_one(struct pci_dev *pdev,
1529 const struct pci_device_id *ent)
1530{
1531 static int printed_version = 0;
1532 struct sis190_private *tp;
1533 struct net_device *dev;
1534 void __iomem *ioaddr;
Francois Romieu830fb7d2005-07-30 13:12:37 +02001535 int rc;
Francois Romieu890e8d02005-07-30 13:08:43 +02001536
1537 if (!printed_version) {
1538 net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
1539 printed_version = 1;
1540 }
1541
1542 dev = sis190_init_board(pdev);
1543 if (IS_ERR(dev)) {
1544 rc = PTR_ERR(dev);
1545 goto out;
1546 }
1547
1548 tp = netdev_priv(dev);
1549 ioaddr = tp->mmio_addr;
1550
Francois Romieu830fb7d2005-07-30 13:12:37 +02001551 rc = sis190_get_mac_addr(pdev, dev);
1552 if (rc < 0)
1553 goto err_release_board;
Francois Romieu890e8d02005-07-30 13:08:43 +02001554
Francois Romieu830fb7d2005-07-30 13:12:37 +02001555 sis190_init_rxfilter(dev);
Francois Romieu890e8d02005-07-30 13:08:43 +02001556
1557 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1558
1559 dev->open = sis190_open;
1560 dev->stop = sis190_close;
Francois Romieu43afb942005-07-30 13:10:21 +02001561 dev->do_ioctl = sis190_ioctl;
Francois Romieu890e8d02005-07-30 13:08:43 +02001562 dev->get_stats = sis190_get_stats;
1563 dev->tx_timeout = sis190_tx_timeout;
1564 dev->watchdog_timeo = SIS190_TX_TIMEOUT;
1565 dev->hard_start_xmit = sis190_start_xmit;
Francois Romieu4405d3b2005-07-30 13:09:20 +02001566#ifdef CONFIG_NET_POLL_CONTROLLER
1567 dev->poll_controller = sis190_netpoll;
1568#endif
Francois Romieu890e8d02005-07-30 13:08:43 +02001569 dev->set_multicast_list = sis190_set_rx_mode;
1570 SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
1571 dev->irq = pdev->irq;
1572 dev->base_addr = (unsigned long) 0xdead;
1573
1574 spin_lock_init(&tp->lock);
1575 rc = register_netdev(dev);
Francois Romieu830fb7d2005-07-30 13:12:37 +02001576 if (rc < 0)
1577 goto err_release_board;
Francois Romieu890e8d02005-07-30 13:08:43 +02001578
1579 pci_set_drvdata(pdev, dev);
1580
1581 net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
1582 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1583 pci_name(pdev), sis_chip_info[ent->driver_data].name,
1584 ioaddr, dev->irq,
1585 dev->dev_addr[0], dev->dev_addr[1],
1586 dev->dev_addr[2], dev->dev_addr[3],
1587 dev->dev_addr[4], dev->dev_addr[5]);
1588
1589 netif_carrier_off(dev);
1590
1591 sis190_set_speed_auto(dev);
1592out:
1593 return rc;
Francois Romieu830fb7d2005-07-30 13:12:37 +02001594
1595err_release_board:
1596 sis190_release_board(pdev);
1597 goto out;
Francois Romieu890e8d02005-07-30 13:08:43 +02001598}
1599
1600static void __devexit sis190_remove_one(struct pci_dev *pdev)
1601{
1602 struct net_device *dev = pci_get_drvdata(pdev);
1603
1604 unregister_netdev(dev);
1605 sis190_release_board(pdev);
1606 pci_set_drvdata(pdev, NULL);
1607}
1608
1609static struct pci_driver sis190_pci_driver = {
1610 .name = DRV_NAME,
1611 .id_table = sis190_pci_tbl,
1612 .probe = sis190_init_one,
1613 .remove = __devexit_p(sis190_remove_one),
1614};
1615
1616static int __init sis190_init_module(void)
1617{
1618 return pci_module_init(&sis190_pci_driver);
1619}
1620
1621static void __exit sis190_cleanup_module(void)
1622{
1623 pci_unregister_driver(&sis190_pci_driver);
1624}
1625
1626module_init(sis190_init_module);
1627module_exit(sis190_cleanup_module);