blob: 392110ede7b7375b5880736ac164e20ffc9ab8f7 [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 Romieufc10c392005-07-30 13:15:01 +0200386static u16 mdio_read_latched(void __iomem *ioaddr, int phy_id, int reg)
387{
388 mdio_read(ioaddr, phy_id, reg);
389 return mdio_read(ioaddr, phy_id, reg);
390}
391
Francois Romieu40292fb2005-07-30 13:12:06 +0200392static u16 __devinit sis190_read_eeprom(void __iomem *ioaddr, u32 reg)
Francois Romieu890e8d02005-07-30 13:08:43 +0200393{
Francois Romieu40292fb2005-07-30 13:12:06 +0200394 u16 data = 0xffff;
Francois Romieu890e8d02005-07-30 13:08:43 +0200395 unsigned int i;
Francois Romieu890e8d02005-07-30 13:08:43 +0200396
397 if (!(SIS_R32(ROMControl) & 0x0002))
398 return 0;
399
Francois Romieu40292fb2005-07-30 13:12:06 +0200400 SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10));
Francois Romieu890e8d02005-07-30 13:08:43 +0200401
402 for (i = 0; i < 200; i++) {
Francois Romieu40292fb2005-07-30 13:12:06 +0200403 if (!(SIS_R32(ROMInterface) & EEREQ)) {
404 data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16;
Francois Romieu890e8d02005-07-30 13:08:43 +0200405 break;
Francois Romieu40292fb2005-07-30 13:12:06 +0200406 }
Francois Romieu890e8d02005-07-30 13:08:43 +0200407 msleep(1);
408 }
409
Francois Romieu890e8d02005-07-30 13:08:43 +0200410 return data;
411}
412
413static void sis190_irq_mask_and_ack(void __iomem *ioaddr)
414{
415 SIS_W32(IntrMask, 0x00);
416 SIS_W32(IntrStatus, 0xffffffff);
417 SIS_PCI_COMMIT();
418}
419
420static void sis190_asic_down(void __iomem *ioaddr)
421{
422 /* Stop the chip's Tx and Rx DMA processes. */
423
424 SIS_W32(TxControl, 0x1a00);
425 SIS_W32(RxControl, 0x1a00);
426
427 sis190_irq_mask_and_ack(ioaddr);
428}
429
430static void sis190_mark_as_last_descriptor(struct RxDesc *desc)
431{
432 desc->size |= cpu_to_le32(RingEnd);
433}
434
435static inline void sis190_give_to_asic(struct RxDesc *desc, u32 rx_buf_sz)
436{
437 u32 eor = le32_to_cpu(desc->size) & RingEnd;
438
439 desc->PSize = 0x0;
Francois Romieu8b5641d2005-07-30 13:13:03 +0200440 desc->size = cpu_to_le32((rx_buf_sz & RX_BUF_MASK) | eor);
Francois Romieu890e8d02005-07-30 13:08:43 +0200441 wmb();
442 desc->status = cpu_to_le32(OWNbit | INTbit);
443}
444
445static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
446 u32 rx_buf_sz)
447{
448 desc->addr = cpu_to_le32(mapping);
449 sis190_give_to_asic(desc, rx_buf_sz);
450}
451
452static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
453{
454 desc->PSize = 0x0;
455 desc->addr = 0xdeadbeef;
456 desc->size &= cpu_to_le32(RingEnd);
457 wmb();
458 desc->status = 0x0;
459}
460
461static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
462 struct RxDesc *desc, u32 rx_buf_sz)
463{
464 struct sk_buff *skb;
465 dma_addr_t mapping;
466 int ret = 0;
467
468 skb = dev_alloc_skb(rx_buf_sz);
469 if (!skb)
470 goto err_out;
471
472 *sk_buff = skb;
473
474 mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
475 PCI_DMA_FROMDEVICE);
476
477 sis190_map_to_asic(desc, mapping, rx_buf_sz);
478out:
479 return ret;
480
481err_out:
482 ret = -ENOMEM;
483 sis190_make_unusable_by_asic(desc);
484 goto out;
485}
486
487static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
488 u32 start, u32 end)
489{
490 u32 cur;
491
492 for (cur = start; cur < end; cur++) {
493 int ret, i = cur % NUM_RX_DESC;
494
495 if (tp->Rx_skbuff[i])
496 continue;
497
498 ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
499 tp->RxDescRing + i, tp->rx_buf_sz);
500 if (ret < 0)
501 break;
502 }
503 return cur - start;
504}
505
506static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
507 struct RxDesc *desc, int rx_buf_sz)
508{
509 int ret = -1;
510
511 if (pkt_size < rx_copybreak) {
512 struct sk_buff *skb;
513
514 skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
515 if (skb) {
516 skb_reserve(skb, NET_IP_ALIGN);
517 eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
518 *sk_buff = skb;
519 sis190_give_to_asic(desc, rx_buf_sz);
520 ret = 0;
521 }
522 }
523 return ret;
524}
525
Francois Romieubcad5e52005-07-30 13:13:47 +0200526static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
527{
528#define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT)
529
530 if ((status & CRCOK) && !(status & ErrMask))
531 return 0;
532
533 if (!(status & CRCOK))
534 stats->rx_crc_errors++;
535 else if (status & OVRUN)
536 stats->rx_over_errors++;
537 else if (status & (SHORT | LIMIT))
538 stats->rx_length_errors++;
539 else if (status & (MIIER | NIBON | COLON))
540 stats->rx_frame_errors++;
541
542 stats->rx_errors++;
543 return -1;
544}
545
Francois Romieu890e8d02005-07-30 13:08:43 +0200546static int sis190_rx_interrupt(struct net_device *dev,
547 struct sis190_private *tp, void __iomem *ioaddr)
548{
549 struct net_device_stats *stats = &tp->stats;
550 u32 rx_left, cur_rx = tp->cur_rx;
551 u32 delta, count;
552
553 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
554 rx_left = sis190_rx_quota(rx_left, (u32) dev->quota);
555
556 for (; rx_left > 0; rx_left--, cur_rx++) {
557 unsigned int entry = cur_rx % NUM_RX_DESC;
558 struct RxDesc *desc = tp->RxDescRing + entry;
559 u32 status;
560
561 if (desc->status & OWNbit)
562 break;
563
564 status = le32_to_cpu(desc->PSize);
565
566 // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name,
567 // status);
568
Francois Romieubcad5e52005-07-30 13:13:47 +0200569 if (sis190_rx_pkt_err(status, stats) < 0)
Francois Romieu890e8d02005-07-30 13:08:43 +0200570 sis190_give_to_asic(desc, tp->rx_buf_sz);
Francois Romieubcad5e52005-07-30 13:13:47 +0200571 else {
Francois Romieu890e8d02005-07-30 13:08:43 +0200572 struct sk_buff *skb = tp->Rx_skbuff[entry];
573 int pkt_size = (status & RxSizeMask) - 4;
574 void (*pci_action)(struct pci_dev *, dma_addr_t,
575 size_t, int) = pci_dma_sync_single_for_device;
576
577 if (unlikely(pkt_size > tp->rx_buf_sz)) {
578 net_intr(tp, KERN_INFO
579 "%s: (frag) status = %08x.\n",
580 dev->name, status);
581 stats->rx_dropped++;
582 stats->rx_length_errors++;
583 sis190_give_to_asic(desc, tp->rx_buf_sz);
584 continue;
585 }
586
587 pci_dma_sync_single_for_cpu(tp->pci_dev,
588 le32_to_cpu(desc->addr), tp->rx_buf_sz,
589 PCI_DMA_FROMDEVICE);
590
591 if (sis190_try_rx_copy(&skb, pkt_size, desc,
592 tp->rx_buf_sz)) {
593 pci_action = pci_unmap_single;
594 tp->Rx_skbuff[entry] = NULL;
595 sis190_make_unusable_by_asic(desc);
596 }
597
598 pci_action(tp->pci_dev, le32_to_cpu(desc->addr),
599 tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
600
601 skb->dev = dev;
602 skb_put(skb, pkt_size);
603 skb->protocol = eth_type_trans(skb, dev);
604
605 sis190_rx_skb(skb);
606
607 dev->last_rx = jiffies;
Francois Romieu890e8d02005-07-30 13:08:43 +0200608 stats->rx_packets++;
Francois Romieubcad5e52005-07-30 13:13:47 +0200609 stats->rx_bytes += pkt_size;
610 if ((status & BCAST) == MCAST)
611 stats->multicast++;
Francois Romieu890e8d02005-07-30 13:08:43 +0200612 }
613 }
614 count = cur_rx - tp->cur_rx;
615 tp->cur_rx = cur_rx;
616
617 delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
618 if (!delta && count && netif_msg_intr(tp))
619 printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name);
620 tp->dirty_rx += delta;
621
622 if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp))
623 printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name);
624
625 return count;
626}
627
628static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb,
629 struct TxDesc *desc)
630{
631 unsigned int len;
632
633 len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
634
635 pci_unmap_single(pdev, le32_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
636
637 memset(desc, 0x00, sizeof(*desc));
638}
639
640static void sis190_tx_interrupt(struct net_device *dev,
641 struct sis190_private *tp, void __iomem *ioaddr)
642{
643 u32 pending, dirty_tx = tp->dirty_tx;
644 /*
645 * It would not be needed if queueing was allowed to be enabled
646 * again too early (hint: think preempt and unclocked smp systems).
647 */
648 unsigned int queue_stopped;
649
650 smp_rmb();
651 pending = tp->cur_tx - dirty_tx;
652 queue_stopped = (pending == NUM_TX_DESC);
653
654 for (; pending; pending--, dirty_tx++) {
655 unsigned int entry = dirty_tx % NUM_TX_DESC;
656 struct TxDesc *txd = tp->TxDescRing + entry;
657 struct sk_buff *skb;
658
659 if (le32_to_cpu(txd->status) & OWNbit)
660 break;
661
662 skb = tp->Tx_skbuff[entry];
663
664 tp->stats.tx_packets++;
665 tp->stats.tx_bytes += skb->len;
666
667 sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
668 tp->Tx_skbuff[entry] = NULL;
669 dev_kfree_skb_irq(skb);
670 }
671
672 if (tp->dirty_tx != dirty_tx) {
673 tp->dirty_tx = dirty_tx;
674 smp_wmb();
675 if (queue_stopped)
676 netif_wake_queue(dev);
677 }
678}
679
680/*
681 * The interrupt handler does all of the Rx thread work and cleans up after
682 * the Tx thread.
683 */
684static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs)
685{
686 struct net_device *dev = __dev;
687 struct sis190_private *tp = netdev_priv(dev);
688 void __iomem *ioaddr = tp->mmio_addr;
689 unsigned int handled = 0;
690 u32 status;
691
692 status = SIS_R32(IntrStatus);
693
694 if ((status == 0xffffffff) || !status)
695 goto out;
696
697 handled = 1;
698
699 if (unlikely(!netif_running(dev))) {
700 sis190_asic_down(ioaddr);
701 goto out;
702 }
703
704 SIS_W32(IntrStatus, status);
705
706 // net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status);
707
708 if (status & LinkChange) {
709 net_intr(tp, KERN_INFO "%s: link change.\n", dev->name);
710 schedule_work(&tp->phy_task);
711 }
712
713 if (status & RxQInt)
714 sis190_rx_interrupt(dev, tp, ioaddr);
715
716 if (status & TxQ0Int)
717 sis190_tx_interrupt(dev, tp, ioaddr);
718out:
719 return IRQ_RETVAL(handled);
720}
721
Francois Romieu4405d3b2005-07-30 13:09:20 +0200722#ifdef CONFIG_NET_POLL_CONTROLLER
723static void sis190_netpoll(struct net_device *dev)
724{
725 struct sis190_private *tp = netdev_priv(dev);
726 struct pci_dev *pdev = tp->pci_dev;
727
728 disable_irq(pdev->irq);
729 sis190_interrupt(pdev->irq, dev, NULL);
730 enable_irq(pdev->irq);
731}
732#endif
733
Francois Romieu890e8d02005-07-30 13:08:43 +0200734static void sis190_free_rx_skb(struct sis190_private *tp,
735 struct sk_buff **sk_buff, struct RxDesc *desc)
736{
737 struct pci_dev *pdev = tp->pci_dev;
738
739 pci_unmap_single(pdev, le32_to_cpu(desc->addr), tp->rx_buf_sz,
740 PCI_DMA_FROMDEVICE);
741 dev_kfree_skb(*sk_buff);
742 *sk_buff = NULL;
743 sis190_make_unusable_by_asic(desc);
744}
745
746static void sis190_rx_clear(struct sis190_private *tp)
747{
748 unsigned int i;
749
750 for (i = 0; i < NUM_RX_DESC; i++) {
751 if (!tp->Rx_skbuff[i])
752 continue;
753 sis190_free_rx_skb(tp, tp->Rx_skbuff + i, tp->RxDescRing + i);
754 }
755}
756
757static void sis190_init_ring_indexes(struct sis190_private *tp)
758{
759 tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
760}
761
762static int sis190_init_ring(struct net_device *dev)
763{
764 struct sis190_private *tp = netdev_priv(dev);
765
766 sis190_init_ring_indexes(tp);
767
768 memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
769 memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
770
771 if (sis190_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
772 goto err_rx_clear;
773
774 sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1);
775
776 return 0;
777
778err_rx_clear:
779 sis190_rx_clear(tp);
780 return -ENOMEM;
781}
782
783static void sis190_set_rx_mode(struct net_device *dev)
784{
785 struct sis190_private *tp = netdev_priv(dev);
786 void __iomem *ioaddr = tp->mmio_addr;
787 unsigned long flags;
788 u32 mc_filter[2]; /* Multicast hash filter */
789 u16 rx_mode;
790
791 if (dev->flags & IFF_PROMISC) {
792 /* Unconditionally log net taps. */
793 net_drv(tp, KERN_NOTICE "%s: Promiscuous mode enabled.\n",
794 dev->name);
795 rx_mode =
796 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
797 AcceptAllPhys;
798 mc_filter[1] = mc_filter[0] = 0xffffffff;
799 } else if ((dev->mc_count > multicast_filter_limit) ||
800 (dev->flags & IFF_ALLMULTI)) {
801 /* Too many to filter perfectly -- accept all multicasts. */
802 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
803 mc_filter[1] = mc_filter[0] = 0xffffffff;
804 } else {
805 struct dev_mc_list *mclist;
806 unsigned int i;
807
808 rx_mode = AcceptBroadcast | AcceptMyPhys;
809 mc_filter[1] = mc_filter[0] = 0;
810 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
811 i++, mclist = mclist->next) {
812 int bit_nr =
813 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
814 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
815 rx_mode |= AcceptMulticast;
816 }
817 }
818
819 spin_lock_irqsave(&tp->lock, flags);
820
821 SIS_W16(RxMacControl, rx_mode | 0x2);
822 SIS_W32(RxHashTable, mc_filter[0]);
823 SIS_W32(RxHashTable + 4, mc_filter[1]);
824
825 spin_unlock_irqrestore(&tp->lock, flags);
826}
827
828static void sis190_soft_reset(void __iomem *ioaddr)
829{
830 SIS_W32(IntrControl, 0x8000);
831 SIS_PCI_COMMIT();
832 msleep(1);
833 SIS_W32(IntrControl, 0x0);
834 sis190_asic_down(ioaddr);
835 msleep(1);
836}
837
838static void sis190_hw_start(struct net_device *dev)
839{
840 struct sis190_private *tp = netdev_priv(dev);
841 void __iomem *ioaddr = tp->mmio_addr;
842
843 sis190_soft_reset(ioaddr);
844
845 SIS_W32(TxDescStartAddr, tp->tx_dma);
846 SIS_W32(RxDescStartAddr, tp->rx_dma);
847
848 SIS_W32(IntrStatus, 0xffffffff);
849 SIS_W32(IntrMask, 0x0);
850 /*
851 * Default is 100Mbps.
852 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
853 */
854 SIS_W16(StationControl, 0x1901);
855 SIS_W32(GMIIControl, 0x0);
856 SIS_W32(TxMacControl, 0x60);
857 SIS_W16(RxMacControl, 0x02);
858 SIS_W32(RxHashTable, 0x0);
859 SIS_W32(0x6c, 0x0);
Francois Romieu188f23b2005-07-30 13:11:43 +0200860 SIS_W32(RxWolCtrl, 0x0);
861 SIS_W32(RxWolData, 0x0);
Francois Romieu890e8d02005-07-30 13:08:43 +0200862
863 SIS_PCI_COMMIT();
864
865 sis190_set_rx_mode(dev);
866
867 /* Enable all known interrupts by setting the interrupt mask. */
868 SIS_W32(IntrMask, sis190_intr_mask);
869
870 SIS_W32(TxControl, 0x1a00 | CmdTxEnb);
871 SIS_W32(RxControl, 0x1a1d);
872
873 netif_start_queue(dev);
874}
875
876static void sis190_phy_task(void * data)
877{
878 struct net_device *dev = data;
879 struct sis190_private *tp = netdev_priv(dev);
880 void __iomem *ioaddr = tp->mmio_addr;
Francois Romieu9ede1092005-07-30 13:14:38 +0200881 int phy_id = tp->mii_if.phy_id;
Francois Romieu890e8d02005-07-30 13:08:43 +0200882 u16 val;
883
Francois Romieu43afb942005-07-30 13:10:21 +0200884 rtnl_lock();
885
Francois Romieu9ede1092005-07-30 13:14:38 +0200886 val = mdio_read(ioaddr, phy_id, MII_BMCR);
Francois Romieu890e8d02005-07-30 13:08:43 +0200887 if (val & BMCR_RESET) {
888 // FIXME: needlessly high ? -- FR 02/07/2005
889 mod_timer(&tp->timer, jiffies + HZ/10);
Francois Romieufc10c392005-07-30 13:15:01 +0200890 } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
891 BMSR_ANEGCOMPLETE)) {
Francois Romieu890e8d02005-07-30 13:08:43 +0200892 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
893 dev->name);
Francois Romieu9ede1092005-07-30 13:14:38 +0200894 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
Francois Romieu890e8d02005-07-30 13:08:43 +0200895 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
896 } else {
897 /* Rejoice ! */
898 struct {
899 int val;
900 const char *msg;
901 u16 ctl;
902 } reg31[] = {
903 { LPA_1000XFULL | LPA_SLCT,
904 "1000 Mbps Full Duplex",
905 0x01 | _1000bpsF },
906 { LPA_1000XHALF | LPA_SLCT,
907 "1000 Mbps Half Duplex",
908 0x01 | _1000bpsH },
909 { LPA_100FULL,
910 "100 Mbps Full Duplex",
911 0x01 | _100bpsF },
912 { LPA_100HALF,
913 "100 Mbps Half Duplex",
914 0x01 | _100bpsH },
915 { LPA_10FULL,
916 "10 Mbps Full Duplex",
917 0x01 | _10bpsF },
918 { LPA_10HALF,
919 "10 Mbps Half Duplex",
920 0x01 | _10bpsH },
921 { 0, "unknown", 0x0000 }
922 }, *p;
923
Francois Romieu9ede1092005-07-30 13:14:38 +0200924 val = mdio_read(ioaddr, phy_id, 0x1f);
Francois Romieu890e8d02005-07-30 13:08:43 +0200925 net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
926
Francois Romieu9ede1092005-07-30 13:14:38 +0200927 val = mdio_read(ioaddr, phy_id, MII_LPA);
Francois Romieu890e8d02005-07-30 13:08:43 +0200928 net_link(tp, KERN_INFO "%s: mii lpa = %04x.\n", dev->name, val);
929
930 for (p = reg31; p->ctl; p++) {
931 if ((val & p->val) == p->val)
932 break;
933 }
934 if (p->ctl)
935 SIS_W16(StationControl, p->ctl);
936 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
937 p->msg);
938 netif_carrier_on(dev);
939 }
Francois Romieu43afb942005-07-30 13:10:21 +0200940
941 rtnl_unlock();
Francois Romieu890e8d02005-07-30 13:08:43 +0200942}
943
944static void sis190_phy_timer(unsigned long __opaque)
945{
946 struct net_device *dev = (struct net_device *)__opaque;
947 struct sis190_private *tp = netdev_priv(dev);
948
949 if (likely(netif_running(dev)))
950 schedule_work(&tp->phy_task);
951}
952
953static inline void sis190_delete_timer(struct net_device *dev)
954{
955 struct sis190_private *tp = netdev_priv(dev);
956
957 del_timer_sync(&tp->timer);
958}
959
960static inline void sis190_request_timer(struct net_device *dev)
961{
962 struct sis190_private *tp = netdev_priv(dev);
963 struct timer_list *timer = &tp->timer;
964
965 init_timer(timer);
966 timer->expires = jiffies + SIS190_PHY_TIMEOUT;
967 timer->data = (unsigned long)dev;
968 timer->function = sis190_phy_timer;
969 add_timer(timer);
970}
971
972static void sis190_set_rxbufsize(struct sis190_private *tp,
973 struct net_device *dev)
974{
975 unsigned int mtu = dev->mtu;
976
977 tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
Francois Romieu8b5641d2005-07-30 13:13:03 +0200978 /* RxDesc->size has a licence to kill the lower bits */
979 if (tp->rx_buf_sz & 0x07) {
980 tp->rx_buf_sz += 8;
981 tp->rx_buf_sz &= RX_BUF_MASK;
982 }
Francois Romieu890e8d02005-07-30 13:08:43 +0200983}
984
985static int sis190_open(struct net_device *dev)
986{
987 struct sis190_private *tp = netdev_priv(dev);
988 struct pci_dev *pdev = tp->pci_dev;
989 int rc = -ENOMEM;
990
991 sis190_set_rxbufsize(tp, dev);
992
993 /*
994 * Rx and Tx descriptors need 256 bytes alignment.
995 * pci_alloc_consistent() guarantees a stronger alignment.
996 */
997 tp->TxDescRing = pci_alloc_consistent(pdev, TX_RING_BYTES, &tp->tx_dma);
998 if (!tp->TxDescRing)
999 goto out;
1000
1001 tp->RxDescRing = pci_alloc_consistent(pdev, RX_RING_BYTES, &tp->rx_dma);
1002 if (!tp->RxDescRing)
1003 goto err_free_tx_0;
1004
1005 rc = sis190_init_ring(dev);
1006 if (rc < 0)
1007 goto err_free_rx_1;
1008
1009 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1010
1011 sis190_request_timer(dev);
1012
1013 rc = request_irq(dev->irq, sis190_interrupt, SA_SHIRQ, dev->name, dev);
1014 if (rc < 0)
1015 goto err_release_timer_2;
1016
1017 sis190_hw_start(dev);
1018out:
1019 return rc;
1020
1021err_release_timer_2:
1022 sis190_delete_timer(dev);
1023 sis190_rx_clear(tp);
1024err_free_rx_1:
1025 pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing,
1026 tp->rx_dma);
1027err_free_tx_0:
1028 pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing,
1029 tp->tx_dma);
1030 goto out;
1031}
1032
1033static void sis190_tx_clear(struct sis190_private *tp)
1034{
1035 unsigned int i;
1036
1037 for (i = 0; i < NUM_TX_DESC; i++) {
1038 struct sk_buff *skb = tp->Tx_skbuff[i];
1039
1040 if (!skb)
1041 continue;
1042
1043 sis190_unmap_tx_skb(tp->pci_dev, skb, tp->TxDescRing + i);
1044 tp->Tx_skbuff[i] = NULL;
1045 dev_kfree_skb(skb);
1046
1047 tp->stats.tx_dropped++;
1048 }
1049 tp->cur_tx = tp->dirty_tx = 0;
1050}
1051
1052static void sis190_down(struct net_device *dev)
1053{
1054 struct sis190_private *tp = netdev_priv(dev);
1055 void __iomem *ioaddr = tp->mmio_addr;
1056 unsigned int poll_locked = 0;
1057
1058 sis190_delete_timer(dev);
1059
1060 netif_stop_queue(dev);
1061
1062 flush_scheduled_work();
1063
1064 do {
1065 spin_lock_irq(&tp->lock);
1066
1067 sis190_asic_down(ioaddr);
1068
1069 spin_unlock_irq(&tp->lock);
1070
1071 synchronize_irq(dev->irq);
1072
1073 if (!poll_locked) {
1074 netif_poll_disable(dev);
1075 poll_locked++;
1076 }
1077
1078 synchronize_sched();
1079
1080 } while (SIS_R32(IntrMask));
1081
1082 sis190_tx_clear(tp);
1083 sis190_rx_clear(tp);
1084}
1085
1086static int sis190_close(struct net_device *dev)
1087{
1088 struct sis190_private *tp = netdev_priv(dev);
1089 struct pci_dev *pdev = tp->pci_dev;
1090
1091 sis190_down(dev);
1092
1093 free_irq(dev->irq, dev);
1094
1095 netif_poll_enable(dev);
1096
1097 pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
1098 pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
1099
1100 tp->TxDescRing = NULL;
1101 tp->RxDescRing = NULL;
1102
1103 return 0;
1104}
1105
1106static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
1107{
1108 struct sis190_private *tp = netdev_priv(dev);
1109 void __iomem *ioaddr = tp->mmio_addr;
1110 u32 len, entry, dirty_tx;
1111 struct TxDesc *desc;
1112 dma_addr_t mapping;
1113
1114 if (unlikely(skb->len < ETH_ZLEN)) {
1115 skb = skb_padto(skb, ETH_ZLEN);
1116 if (!skb) {
1117 tp->stats.tx_dropped++;
1118 goto out;
1119 }
1120 len = ETH_ZLEN;
1121 } else {
1122 len = skb->len;
1123 }
1124
1125 entry = tp->cur_tx % NUM_TX_DESC;
1126 desc = tp->TxDescRing + entry;
1127
1128 if (unlikely(le32_to_cpu(desc->status) & OWNbit)) {
1129 netif_stop_queue(dev);
1130 net_tx_err(tp, KERN_ERR PFX
1131 "%s: BUG! Tx Ring full when queue awake!\n",
1132 dev->name);
1133 return NETDEV_TX_BUSY;
1134 }
1135
1136 mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
1137
1138 tp->Tx_skbuff[entry] = skb;
1139
1140 desc->PSize = cpu_to_le32(len);
1141 desc->addr = cpu_to_le32(mapping);
1142
1143 desc->size = cpu_to_le32(len);
1144 if (entry == (NUM_TX_DESC - 1))
1145 desc->size |= cpu_to_le32(RingEnd);
1146
1147 wmb();
1148
1149 desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit);
1150
1151 tp->cur_tx++;
1152
1153 smp_wmb();
1154
1155 SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
1156
1157 dev->trans_start = jiffies;
1158
1159 dirty_tx = tp->dirty_tx;
1160 if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
1161 netif_stop_queue(dev);
1162 smp_rmb();
1163 if (dirty_tx != tp->dirty_tx)
1164 netif_wake_queue(dev);
1165 }
1166out:
1167 return NETDEV_TX_OK;
1168}
1169
1170static struct net_device_stats *sis190_get_stats(struct net_device *dev)
1171{
1172 struct sis190_private *tp = netdev_priv(dev);
1173
1174 return &tp->stats;
1175}
1176
1177static void sis190_release_board(struct pci_dev *pdev)
1178{
1179 struct net_device *dev = pci_get_drvdata(pdev);
1180 struct sis190_private *tp = netdev_priv(dev);
1181
1182 iounmap(tp->mmio_addr);
1183 pci_release_regions(pdev);
1184 pci_disable_device(pdev);
1185 free_netdev(dev);
1186}
1187
1188static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
1189{
1190 struct sis190_private *tp;
1191 struct net_device *dev;
1192 void __iomem *ioaddr;
1193 int rc;
1194
1195 dev = alloc_etherdev(sizeof(*tp));
1196 if (!dev) {
1197 net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n");
1198 rc = -ENOMEM;
1199 goto err_out_0;
1200 }
1201
1202 SET_MODULE_OWNER(dev);
1203 SET_NETDEV_DEV(dev, &pdev->dev);
1204
1205 tp = netdev_priv(dev);
1206 tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT);
1207
1208 rc = pci_enable_device(pdev);
1209 if (rc < 0) {
1210 net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev));
1211 goto err_free_dev_1;
1212 }
1213
1214 rc = -ENODEV;
1215
1216 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1217 net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n",
1218 pci_name(pdev));
1219 goto err_pci_disable_2;
1220 }
1221 if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) {
1222 net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n",
1223 pci_name(pdev));
1224 goto err_pci_disable_2;
1225 }
1226
1227 rc = pci_request_regions(pdev, DRV_NAME);
1228 if (rc < 0) {
1229 net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n",
1230 pci_name(pdev));
1231 goto err_pci_disable_2;
1232 }
1233
1234 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1235 if (rc < 0) {
1236 net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n",
1237 pci_name(pdev));
1238 goto err_free_res_3;
1239 }
1240
1241 pci_set_master(pdev);
1242
1243 ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE);
1244 if (!ioaddr) {
1245 net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n",
1246 pci_name(pdev));
1247 rc = -EIO;
1248 goto err_free_res_3;
1249 }
1250
1251 tp->pci_dev = pdev;
1252 tp->mmio_addr = ioaddr;
1253
Francois Romieu43afb942005-07-30 13:10:21 +02001254 tp->mii_if.dev = dev;
1255 tp->mii_if.mdio_read = __mdio_read;
1256 tp->mii_if.mdio_write = __mdio_write;
Francois Romieu9ede1092005-07-30 13:14:38 +02001257 tp->mii_if.phy_id = 1;
Francois Romieu43afb942005-07-30 13:10:21 +02001258 tp->mii_if.phy_id_mask = 0x1f;
1259 tp->mii_if.reg_num_mask = 0x1f;
1260
Francois Romieu890e8d02005-07-30 13:08:43 +02001261 sis190_irq_mask_and_ack(ioaddr);
1262
1263 sis190_soft_reset(ioaddr);
1264out:
1265 return dev;
1266
1267err_free_res_3:
1268 pci_release_regions(pdev);
1269err_pci_disable_2:
1270 pci_disable_device(pdev);
1271err_free_dev_1:
1272 free_netdev(dev);
1273err_out_0:
1274 dev = ERR_PTR(rc);
1275 goto out;
1276}
1277
1278static void sis190_tx_timeout(struct net_device *dev)
1279{
1280 struct sis190_private *tp = netdev_priv(dev);
1281 void __iomem *ioaddr = tp->mmio_addr;
1282 u8 tmp8;
1283
1284 /* Disable Tx, if not already */
1285 tmp8 = SIS_R8(TxControl);
1286 if (tmp8 & CmdTxEnb)
1287 SIS_W8(TxControl, tmp8 & ~CmdTxEnb);
1288
Francois Romieu188f23b2005-07-30 13:11:43 +02001289
1290 net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n",
1291 dev->name, SIS_R32(TxControl), SIS_R32(TxSts));
1292
Francois Romieu890e8d02005-07-30 13:08:43 +02001293 /* Disable interrupts by clearing the interrupt mask. */
1294 SIS_W32(IntrMask, 0x0000);
1295
1296 /* Stop a shared interrupt from scavenging while we are. */
1297 spin_lock_irq(&tp->lock);
1298 sis190_tx_clear(tp);
1299 spin_unlock_irq(&tp->lock);
1300
1301 /* ...and finally, reset everything. */
1302 sis190_hw_start(dev);
1303
1304 netif_wake_queue(dev);
1305}
1306
Francois Romieu830fb7d2005-07-30 13:12:37 +02001307static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1308 struct net_device *dev)
1309{
1310 struct sis190_private *tp = netdev_priv(dev);
1311 void __iomem *ioaddr = tp->mmio_addr;
1312 u16 sig;
1313 int i;
1314
1315 net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n",
1316 pci_name(pdev));
1317
1318 /* Check to see if there is a sane EEPROM */
1319 sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature);
1320
1321 if ((sig == 0xffff) || (sig == 0x0000)) {
1322 net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n",
1323 pci_name(pdev), sig);
1324 return -EIO;
1325 }
1326
1327 /* Get MAC address from EEPROM */
1328 for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
Francois Romieu3cec93c2005-07-30 13:14:18 +02001329 __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
Francois Romieu830fb7d2005-07-30 13:12:37 +02001330
1331 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1332 }
1333
1334 return 0;
1335}
1336
1337/**
1338 * sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
1339 * @pdev: PCI device
1340 * @dev: network device to get address for
1341 *
1342 * SiS965 model, use APC CMOS RAM to store MAC address.
1343 * APC CMOS RAM is accessed through ISA bridge.
1344 * MAC address is read into @net_dev->dev_addr.
1345 */
1346static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1347 struct net_device *dev)
1348{
1349 struct sis190_private *tp = netdev_priv(dev);
1350 struct pci_dev *isa_bridge;
1351 u8 reg, tmp8;
1352 int i;
1353
1354 net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
1355 pci_name(pdev));
1356
1357 isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
1358 if (!isa_bridge) {
1359 net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
1360 pci_name(pdev));
1361 return -EIO;
1362 }
1363
1364 /* Enable port 78h & 79h to access APC Registers. */
1365 pci_read_config_byte(isa_bridge, 0x48, &tmp8);
1366 reg = (tmp8 & ~0x02);
1367 pci_write_config_byte(isa_bridge, 0x48, reg);
1368 udelay(50);
1369 pci_read_config_byte(isa_bridge, 0x48, &reg);
1370
1371 for (i = 0; i < MAC_ADDR_LEN; i++) {
1372 outb(0x9 + i, 0x78);
1373 dev->dev_addr[i] = inb(0x79);
1374 }
1375
1376 outb(0x12, 0x78);
1377 reg = inb(0x79);
1378
1379 /* Restore the value to ISA Bridge */
1380 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1381 pci_dev_put(isa_bridge);
1382
1383 return 0;
1384}
1385
1386/**
1387 * sis190_init_rxfilter - Initialize the Rx filter
1388 * @dev: network device to initialize
1389 *
1390 * Set receive filter address to our MAC address
1391 * and enable packet filtering.
1392 */
1393static inline void sis190_init_rxfilter(struct net_device *dev)
1394{
1395 struct sis190_private *tp = netdev_priv(dev);
1396 void __iomem *ioaddr = tp->mmio_addr;
1397 u16 ctl;
1398 int i;
1399
1400 ctl = SIS_R16(RxMacControl);
1401 /*
1402 * Disable packet filtering before setting filter.
1403 * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits
1404 * only and followed by RxMacAddr (6 bytes). Strange. -- FR
1405 */
1406 SIS_W16(RxMacControl, ctl & ~0x0f00);
1407
1408 for (i = 0; i < MAC_ADDR_LEN; i++)
1409 SIS_W8(RxMacAddr + i, dev->dev_addr[i]);
1410
1411 SIS_W16(RxMacControl, ctl);
1412 SIS_PCI_COMMIT();
1413}
1414
1415static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
1416{
1417 u8 from;
1418
1419 pci_read_config_byte(pdev, 0x73, &from);
1420
1421 return (from & 0x00000001) ?
1422 sis190_get_mac_addr_from_apc(pdev, dev) :
1423 sis190_get_mac_addr_from_eeprom(pdev, dev);
1424}
1425
Francois Romieu890e8d02005-07-30 13:08:43 +02001426static void sis190_set_speed_auto(struct net_device *dev)
1427{
1428 struct sis190_private *tp = netdev_priv(dev);
1429 void __iomem *ioaddr = tp->mmio_addr;
Francois Romieu9ede1092005-07-30 13:14:38 +02001430 int phy_id = tp->mii_if.phy_id;
Francois Romieu890e8d02005-07-30 13:08:43 +02001431 int val;
1432
1433 net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name);
1434
Francois Romieu9ede1092005-07-30 13:14:38 +02001435 val = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
Francois Romieu890e8d02005-07-30 13:08:43 +02001436
1437 // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0
1438 // unchanged.
Francois Romieu9ede1092005-07-30 13:14:38 +02001439 mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) |
Francois Romieu890e8d02005-07-30 13:08:43 +02001440 ADVERTISE_100FULL | ADVERTISE_10FULL |
1441 ADVERTISE_100HALF | ADVERTISE_10HALF);
1442
1443 // Enable 1000 Full Mode.
Francois Romieu9ede1092005-07-30 13:14:38 +02001444 mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL);
Francois Romieu890e8d02005-07-30 13:08:43 +02001445
1446 // Enable auto-negotiation and restart auto-negotiation.
Francois Romieu9ede1092005-07-30 13:14:38 +02001447 mdio_write(ioaddr, phy_id, MII_BMCR,
Francois Romieu890e8d02005-07-30 13:08:43 +02001448 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET);
1449}
1450
Francois Romieu43afb942005-07-30 13:10:21 +02001451static int sis190_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1452{
1453 struct sis190_private *tp = netdev_priv(dev);
1454
1455 return mii_ethtool_gset(&tp->mii_if, cmd);
1456}
1457
1458static int sis190_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1459{
1460 struct sis190_private *tp = netdev_priv(dev);
1461
1462 return mii_ethtool_sset(&tp->mii_if, cmd);
1463}
1464
Francois Romieu890e8d02005-07-30 13:08:43 +02001465static void sis190_get_drvinfo(struct net_device *dev,
1466 struct ethtool_drvinfo *info)
1467{
1468 struct sis190_private *tp = netdev_priv(dev);
1469
1470 strcpy(info->driver, DRV_NAME);
1471 strcpy(info->version, DRV_VERSION);
1472 strcpy(info->bus_info, pci_name(tp->pci_dev));
1473}
1474
1475static int sis190_get_regs_len(struct net_device *dev)
1476{
1477 return SIS190_REGS_SIZE;
1478}
1479
1480static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1481 void *p)
1482{
1483 struct sis190_private *tp = netdev_priv(dev);
1484 unsigned long flags;
1485
1486 if (regs->len > SIS190_REGS_SIZE)
1487 regs->len = SIS190_REGS_SIZE;
1488
1489 spin_lock_irqsave(&tp->lock, flags);
1490 memcpy_fromio(p, tp->mmio_addr, regs->len);
1491 spin_unlock_irqrestore(&tp->lock, flags);
1492}
1493
Francois Romieu43afb942005-07-30 13:10:21 +02001494static int sis190_nway_reset(struct net_device *dev)
1495{
1496 struct sis190_private *tp = netdev_priv(dev);
1497
1498 return mii_nway_restart(&tp->mii_if);
1499}
1500
Francois Romieu890e8d02005-07-30 13:08:43 +02001501static u32 sis190_get_msglevel(struct net_device *dev)
1502{
1503 struct sis190_private *tp = netdev_priv(dev);
1504
1505 return tp->msg_enable;
1506}
1507
1508static void sis190_set_msglevel(struct net_device *dev, u32 value)
1509{
1510 struct sis190_private *tp = netdev_priv(dev);
1511
1512 tp->msg_enable = value;
1513}
1514
1515static struct ethtool_ops sis190_ethtool_ops = {
Francois Romieu43afb942005-07-30 13:10:21 +02001516 .get_settings = sis190_get_settings,
1517 .set_settings = sis190_set_settings,
Francois Romieu890e8d02005-07-30 13:08:43 +02001518 .get_drvinfo = sis190_get_drvinfo,
1519 .get_regs_len = sis190_get_regs_len,
1520 .get_regs = sis190_get_regs,
1521 .get_link = ethtool_op_get_link,
1522 .get_msglevel = sis190_get_msglevel,
1523 .set_msglevel = sis190_set_msglevel,
Francois Romieu43afb942005-07-30 13:10:21 +02001524 .nway_reset = sis190_nway_reset,
Francois Romieu890e8d02005-07-30 13:08:43 +02001525};
1526
Francois Romieu43afb942005-07-30 13:10:21 +02001527static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1528{
1529 struct sis190_private *tp = netdev_priv(dev);
1530
1531 return !netif_running(dev) ? -EINVAL :
1532 generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
1533}
1534
Francois Romieu890e8d02005-07-30 13:08:43 +02001535static int __devinit sis190_init_one(struct pci_dev *pdev,
1536 const struct pci_device_id *ent)
1537{
1538 static int printed_version = 0;
1539 struct sis190_private *tp;
1540 struct net_device *dev;
1541 void __iomem *ioaddr;
Francois Romieu830fb7d2005-07-30 13:12:37 +02001542 int rc;
Francois Romieu890e8d02005-07-30 13:08:43 +02001543
1544 if (!printed_version) {
1545 net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
1546 printed_version = 1;
1547 }
1548
1549 dev = sis190_init_board(pdev);
1550 if (IS_ERR(dev)) {
1551 rc = PTR_ERR(dev);
1552 goto out;
1553 }
1554
1555 tp = netdev_priv(dev);
1556 ioaddr = tp->mmio_addr;
1557
Francois Romieu830fb7d2005-07-30 13:12:37 +02001558 rc = sis190_get_mac_addr(pdev, dev);
1559 if (rc < 0)
1560 goto err_release_board;
Francois Romieu890e8d02005-07-30 13:08:43 +02001561
Francois Romieu830fb7d2005-07-30 13:12:37 +02001562 sis190_init_rxfilter(dev);
Francois Romieu890e8d02005-07-30 13:08:43 +02001563
1564 INIT_WORK(&tp->phy_task, sis190_phy_task, dev);
1565
1566 dev->open = sis190_open;
1567 dev->stop = sis190_close;
Francois Romieu43afb942005-07-30 13:10:21 +02001568 dev->do_ioctl = sis190_ioctl;
Francois Romieu890e8d02005-07-30 13:08:43 +02001569 dev->get_stats = sis190_get_stats;
1570 dev->tx_timeout = sis190_tx_timeout;
1571 dev->watchdog_timeo = SIS190_TX_TIMEOUT;
1572 dev->hard_start_xmit = sis190_start_xmit;
Francois Romieu4405d3b2005-07-30 13:09:20 +02001573#ifdef CONFIG_NET_POLL_CONTROLLER
1574 dev->poll_controller = sis190_netpoll;
1575#endif
Francois Romieu890e8d02005-07-30 13:08:43 +02001576 dev->set_multicast_list = sis190_set_rx_mode;
1577 SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
1578 dev->irq = pdev->irq;
1579 dev->base_addr = (unsigned long) 0xdead;
1580
1581 spin_lock_init(&tp->lock);
1582 rc = register_netdev(dev);
Francois Romieu830fb7d2005-07-30 13:12:37 +02001583 if (rc < 0)
1584 goto err_release_board;
Francois Romieu890e8d02005-07-30 13:08:43 +02001585
1586 pci_set_drvdata(pdev, dev);
1587
1588 net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
1589 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1590 pci_name(pdev), sis_chip_info[ent->driver_data].name,
1591 ioaddr, dev->irq,
1592 dev->dev_addr[0], dev->dev_addr[1],
1593 dev->dev_addr[2], dev->dev_addr[3],
1594 dev->dev_addr[4], dev->dev_addr[5]);
1595
1596 netif_carrier_off(dev);
1597
1598 sis190_set_speed_auto(dev);
1599out:
1600 return rc;
Francois Romieu830fb7d2005-07-30 13:12:37 +02001601
1602err_release_board:
1603 sis190_release_board(pdev);
1604 goto out;
Francois Romieu890e8d02005-07-30 13:08:43 +02001605}
1606
1607static void __devexit sis190_remove_one(struct pci_dev *pdev)
1608{
1609 struct net_device *dev = pci_get_drvdata(pdev);
1610
1611 unregister_netdev(dev);
1612 sis190_release_board(pdev);
1613 pci_set_drvdata(pdev, NULL);
1614}
1615
1616static struct pci_driver sis190_pci_driver = {
1617 .name = DRV_NAME,
1618 .id_table = sis190_pci_tbl,
1619 .probe = sis190_init_one,
1620 .remove = __devexit_p(sis190_remove_one),
1621};
1622
1623static int __init sis190_init_module(void)
1624{
1625 return pci_module_init(&sis190_pci_driver);
1626}
1627
1628static void __exit sis190_cleanup_module(void)
1629{
1630 pci_unregister_driver(&sis190_pci_driver);
1631}
1632
1633module_init(sis190_init_module);
1634module_exit(sis190_cleanup_module);