diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/ne2k-pci.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/ne2k-pci.c')
-rw-r--r-- | drivers/net/ne2k-pci.c | 712 |
1 files changed, 712 insertions, 0 deletions
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c new file mode 100644 index 000000000000..a1a6c08e7dcf --- /dev/null +++ b/drivers/net/ne2k-pci.c | |||
@@ -0,0 +1,712 @@ | |||
1 | /* ne2k-pci.c: A NE2000 clone on PCI bus driver for Linux. */ | ||
2 | /* | ||
3 | A Linux device driver for PCI NE2000 clones. | ||
4 | |||
5 | Authors and other copyright holders: | ||
6 | 1992-2000 by Donald Becker, NE2000 core and various modifications. | ||
7 | 1995-1998 by Paul Gortmaker, core modifications and PCI support. | ||
8 | Copyright 1993 assigned to the United States Government as represented | ||
9 | by the Director, National Security Agency. | ||
10 | |||
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 | The author may be reached as becker@scyld.com, or C/O | ||
19 | Scyld Computing Corporation | ||
20 | 410 Severn Ave., Suite 210 | ||
21 | Annapolis MD 21403 | ||
22 | |||
23 | Issues remaining: | ||
24 | People are making PCI ne2000 clones! Oh the horror, the horror... | ||
25 | Limited full-duplex support. | ||
26 | */ | ||
27 | |||
28 | #define DRV_NAME "ne2k-pci" | ||
29 | #define DRV_VERSION "1.03" | ||
30 | #define DRV_RELDATE "9/22/2003" | ||
31 | |||
32 | |||
33 | /* The user-configurable values. | ||
34 | These may be modified when a driver module is loaded.*/ | ||
35 | |||
36 | static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ | ||
37 | |||
38 | #define MAX_UNITS 8 /* More are supported, limit only on options */ | ||
39 | /* Used to pass the full-duplex flag, etc. */ | ||
40 | static int full_duplex[MAX_UNITS]; | ||
41 | static int options[MAX_UNITS]; | ||
42 | |||
43 | /* Force a non std. amount of memory. Units are 256 byte pages. */ | ||
44 | /* #define PACKETBUF_MEMSIZE 0x40 */ | ||
45 | |||
46 | |||
47 | #include <linux/module.h> | ||
48 | #include <linux/kernel.h> | ||
49 | #include <linux/errno.h> | ||
50 | #include <linux/pci.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/interrupt.h> | ||
53 | #include <linux/ethtool.h> | ||
54 | #include <linux/netdevice.h> | ||
55 | #include <linux/etherdevice.h> | ||
56 | |||
57 | #include <asm/system.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/irq.h> | ||
60 | #include <asm/uaccess.h> | ||
61 | |||
62 | #include "8390.h" | ||
63 | |||
64 | /* These identify the driver base version and may not be removed. */ | ||
65 | static char version[] __devinitdata = | ||
66 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n" | ||
67 | KERN_INFO " http://www.scyld.com/network/ne2k-pci.html\n"; | ||
68 | |||
69 | #if defined(__powerpc__) | ||
70 | #define inl_le(addr) le32_to_cpu(inl(addr)) | ||
71 | #define inw_le(addr) le16_to_cpu(inw(addr)) | ||
72 | #endif | ||
73 | |||
74 | #define PFX DRV_NAME ": " | ||
75 | |||
76 | MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); | ||
77 | MODULE_DESCRIPTION("PCI NE2000 clone driver"); | ||
78 | MODULE_LICENSE("GPL"); | ||
79 | |||
80 | module_param(debug, int, 0); | ||
81 | module_param_array(options, int, NULL, 0); | ||
82 | module_param_array(full_duplex, int, NULL, 0); | ||
83 | MODULE_PARM_DESC(debug, "debug level (1-2)"); | ||
84 | MODULE_PARM_DESC(options, "Bit 5: full duplex"); | ||
85 | MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)"); | ||
86 | |||
87 | /* Some defines that people can play with if so inclined. */ | ||
88 | |||
89 | /* Use 32 bit data-movement operations instead of 16 bit. */ | ||
90 | #define USE_LONGIO | ||
91 | |||
92 | /* Do we implement the read before write bugfix ? */ | ||
93 | /* #define NE_RW_BUGFIX */ | ||
94 | |||
95 | /* Flags. We rename an existing ei_status field to store flags! */ | ||
96 | /* Thus only the low 8 bits are usable for non-init-time flags. */ | ||
97 | #define ne2k_flags reg0 | ||
98 | enum { | ||
99 | ONLY_16BIT_IO=8, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */ | ||
100 | FORCE_FDX=0x20, /* User override. */ | ||
101 | REALTEK_FDX=0x40, HOLTEK_FDX=0x80, | ||
102 | STOP_PG_0x60=0x100, | ||
103 | }; | ||
104 | |||
105 | enum ne2k_pci_chipsets { | ||
106 | CH_RealTek_RTL_8029 = 0, | ||
107 | CH_Winbond_89C940, | ||
108 | CH_Compex_RL2000, | ||
109 | CH_KTI_ET32P2, | ||
110 | CH_NetVin_NV5000SC, | ||
111 | CH_Via_86C926, | ||
112 | CH_SureCom_NE34, | ||
113 | CH_Winbond_W89C940F, | ||
114 | CH_Holtek_HT80232, | ||
115 | CH_Holtek_HT80229, | ||
116 | CH_Winbond_89C940_8c4a, | ||
117 | }; | ||
118 | |||
119 | |||
120 | static struct { | ||
121 | char *name; | ||
122 | int flags; | ||
123 | } pci_clone_list[] __devinitdata = { | ||
124 | {"RealTek RTL-8029", REALTEK_FDX}, | ||
125 | {"Winbond 89C940", 0}, | ||
126 | {"Compex RL2000", 0}, | ||
127 | {"KTI ET32P2", 0}, | ||
128 | {"NetVin NV5000SC", 0}, | ||
129 | {"Via 86C926", ONLY_16BIT_IO}, | ||
130 | {"SureCom NE34", 0}, | ||
131 | {"Winbond W89C940F", 0}, | ||
132 | {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, | ||
133 | {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, | ||
134 | {"Winbond W89C940(misprogrammed)", 0}, | ||
135 | {NULL,} | ||
136 | }; | ||
137 | |||
138 | |||
139 | static struct pci_device_id ne2k_pci_tbl[] = { | ||
140 | { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 }, | ||
141 | { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 }, | ||
142 | { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 }, | ||
143 | { 0x8e2e, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_KTI_ET32P2 }, | ||
144 | { 0x4a14, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_NetVin_NV5000SC }, | ||
145 | { 0x1106, 0x0926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Via_86C926 }, | ||
146 | { 0x10bd, 0x0e34, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_SureCom_NE34 }, | ||
147 | { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F }, | ||
148 | { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 }, | ||
149 | { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 }, | ||
150 | { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a }, | ||
151 | { 0, } | ||
152 | }; | ||
153 | MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl); | ||
154 | |||
155 | |||
156 | /* ---- No user-serviceable parts below ---- */ | ||
157 | |||
158 | #define NE_BASE (dev->base_addr) | ||
159 | #define NE_CMD 0x00 | ||
160 | #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
161 | #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
162 | #define NE_IO_EXTENT 0x20 | ||
163 | |||
164 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
165 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
166 | |||
167 | |||
168 | static int ne2k_pci_open(struct net_device *dev); | ||
169 | static int ne2k_pci_close(struct net_device *dev); | ||
170 | |||
171 | static void ne2k_pci_reset_8390(struct net_device *dev); | ||
172 | static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
173 | int ring_page); | ||
174 | static void ne2k_pci_block_input(struct net_device *dev, int count, | ||
175 | struct sk_buff *skb, int ring_offset); | ||
176 | static void ne2k_pci_block_output(struct net_device *dev, const int count, | ||
177 | const unsigned char *buf, const int start_page); | ||
178 | static struct ethtool_ops ne2k_pci_ethtool_ops; | ||
179 | |||
180 | |||
181 | |||
182 | /* There is no room in the standard 8390 structure for extra info we need, | ||
183 | so we build a meta/outer-wrapper structure.. */ | ||
184 | struct ne2k_pci_card { | ||
185 | struct net_device *dev; | ||
186 | struct pci_dev *pci_dev; | ||
187 | }; | ||
188 | |||
189 | |||
190 | |||
191 | /* | ||
192 | NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet | ||
193 | buffer memory space. By-the-spec NE2000 clones have 0x57,0x57 in bytes | ||
194 | 0x0e,0x0f of the SAPROM, while other supposed NE2000 clones must be | ||
195 | detected by their SA prefix. | ||
196 | |||
197 | Reading the SAPROM from a word-wide card with the 8390 set in byte-wide | ||
198 | mode results in doubled values, which can be detected and compensated for. | ||
199 | |||
200 | The probe is also responsible for initializing the card and filling | ||
201 | in the 'dev' and 'ei_status' structures. | ||
202 | */ | ||
203 | |||
204 | |||
205 | static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, | ||
206 | const struct pci_device_id *ent) | ||
207 | { | ||
208 | struct net_device *dev; | ||
209 | int i; | ||
210 | unsigned char SA_prom[32]; | ||
211 | int start_page, stop_page; | ||
212 | int irq, reg0, chip_idx = ent->driver_data; | ||
213 | static unsigned int fnd_cnt; | ||
214 | long ioaddr; | ||
215 | int flags = pci_clone_list[chip_idx].flags; | ||
216 | |||
217 | /* when built into the kernel, we only print version if device is found */ | ||
218 | #ifndef MODULE | ||
219 | static int printed_version; | ||
220 | if (!printed_version++) | ||
221 | printk(version); | ||
222 | #endif | ||
223 | |||
224 | fnd_cnt++; | ||
225 | |||
226 | i = pci_enable_device (pdev); | ||
227 | if (i) | ||
228 | return i; | ||
229 | |||
230 | ioaddr = pci_resource_start (pdev, 0); | ||
231 | irq = pdev->irq; | ||
232 | |||
233 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { | ||
234 | printk (KERN_ERR PFX "no I/O resource at PCI BAR #0\n"); | ||
235 | return -ENODEV; | ||
236 | } | ||
237 | |||
238 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { | ||
239 | printk (KERN_ERR PFX "I/O resource 0x%x @ 0x%lx busy\n", | ||
240 | NE_IO_EXTENT, ioaddr); | ||
241 | return -EBUSY; | ||
242 | } | ||
243 | |||
244 | reg0 = inb(ioaddr); | ||
245 | if (reg0 == 0xFF) | ||
246 | goto err_out_free_res; | ||
247 | |||
248 | /* Do a preliminary verification that we have a 8390. */ | ||
249 | { | ||
250 | int regd; | ||
251 | outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); | ||
252 | regd = inb(ioaddr + 0x0d); | ||
253 | outb(0xff, ioaddr + 0x0d); | ||
254 | outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); | ||
255 | inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ | ||
256 | if (inb(ioaddr + EN0_COUNTER0) != 0) { | ||
257 | outb(reg0, ioaddr); | ||
258 | outb(regd, ioaddr + 0x0d); /* Restore the old values. */ | ||
259 | goto err_out_free_res; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ | ||
264 | dev = alloc_ei_netdev(); | ||
265 | if (!dev) { | ||
266 | printk (KERN_ERR PFX "cannot allocate ethernet device\n"); | ||
267 | goto err_out_free_res; | ||
268 | } | ||
269 | SET_MODULE_OWNER(dev); | ||
270 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
271 | |||
272 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
273 | { | ||
274 | unsigned long reset_start_time = jiffies; | ||
275 | |||
276 | outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); | ||
277 | |||
278 | /* This looks like a horrible timing loop, but it should never take | ||
279 | more than a few cycles. | ||
280 | */ | ||
281 | while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0) | ||
282 | /* Limit wait: '2' avoids jiffy roll-over. */ | ||
283 | if (jiffies - reset_start_time > 2) { | ||
284 | printk(KERN_ERR PFX "Card failure (no reset ack).\n"); | ||
285 | goto err_out_free_netdev; | ||
286 | } | ||
287 | |||
288 | outb(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ | ||
289 | } | ||
290 | |||
291 | /* Read the 16 bytes of station address PROM. | ||
292 | We must first initialize registers, similar to NS8390_init(eifdev, 0). | ||
293 | We can't reliably read the SAPROM address without this. | ||
294 | (I learned the hard way!). */ | ||
295 | { | ||
296 | struct {unsigned char value, offset; } program_seq[] = { | ||
297 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
298 | {0x49, EN0_DCFG}, /* Set word-wide access. */ | ||
299 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
300 | {0x00, EN0_RCNTHI}, | ||
301 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
302 | {0xFF, EN0_ISR}, | ||
303 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
304 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
305 | {32, EN0_RCNTLO}, | ||
306 | {0x00, EN0_RCNTHI}, | ||
307 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
308 | {0x00, EN0_RSARHI}, | ||
309 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
310 | }; | ||
311 | for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) | ||
312 | outb(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
313 | |||
314 | } | ||
315 | |||
316 | /* Note: all PCI cards have at least 16 bit access, so we don't have | ||
317 | to check for 8 bit cards. Most cards permit 32 bit access. */ | ||
318 | if (flags & ONLY_32BIT_IO) { | ||
319 | for (i = 0; i < 4 ; i++) | ||
320 | ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); | ||
321 | } else | ||
322 | for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++) | ||
323 | SA_prom[i] = inb(ioaddr + NE_DATAPORT); | ||
324 | |||
325 | /* We always set the 8390 registers for word mode. */ | ||
326 | outb(0x49, ioaddr + EN0_DCFG); | ||
327 | start_page = NESM_START_PG; | ||
328 | |||
329 | stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; | ||
330 | |||
331 | /* Set up the rest of the parameters. */ | ||
332 | dev->irq = irq; | ||
333 | dev->base_addr = ioaddr; | ||
334 | pci_set_drvdata(pdev, dev); | ||
335 | |||
336 | ei_status.name = pci_clone_list[chip_idx].name; | ||
337 | ei_status.tx_start_page = start_page; | ||
338 | ei_status.stop_page = stop_page; | ||
339 | ei_status.word16 = 1; | ||
340 | ei_status.ne2k_flags = flags; | ||
341 | if (fnd_cnt < MAX_UNITS) { | ||
342 | if (full_duplex[fnd_cnt] > 0 || (options[fnd_cnt] & FORCE_FDX)) | ||
343 | ei_status.ne2k_flags |= FORCE_FDX; | ||
344 | } | ||
345 | |||
346 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
347 | #ifdef PACKETBUF_MEMSIZE | ||
348 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
349 | ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; | ||
350 | #endif | ||
351 | |||
352 | ei_status.reset_8390 = &ne2k_pci_reset_8390; | ||
353 | ei_status.block_input = &ne2k_pci_block_input; | ||
354 | ei_status.block_output = &ne2k_pci_block_output; | ||
355 | ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr; | ||
356 | ei_status.priv = (unsigned long) pdev; | ||
357 | dev->open = &ne2k_pci_open; | ||
358 | dev->stop = &ne2k_pci_close; | ||
359 | dev->ethtool_ops = &ne2k_pci_ethtool_ops; | ||
360 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
361 | dev->poll_controller = ei_poll; | ||
362 | #endif | ||
363 | NS8390_init(dev, 0); | ||
364 | |||
365 | i = register_netdev(dev); | ||
366 | if (i) | ||
367 | goto err_out_free_netdev; | ||
368 | |||
369 | printk("%s: %s found at %#lx, IRQ %d, ", | ||
370 | dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq); | ||
371 | for(i = 0; i < 6; i++) { | ||
372 | printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":"); | ||
373 | dev->dev_addr[i] = SA_prom[i]; | ||
374 | } | ||
375 | |||
376 | return 0; | ||
377 | |||
378 | err_out_free_netdev: | ||
379 | free_netdev (dev); | ||
380 | err_out_free_res: | ||
381 | release_region (ioaddr, NE_IO_EXTENT); | ||
382 | pci_set_drvdata (pdev, NULL); | ||
383 | return -ENODEV; | ||
384 | |||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Magic incantation sequence for full duplex on the supported cards. | ||
389 | */ | ||
390 | static inline int set_realtek_fdx(struct net_device *dev) | ||
391 | { | ||
392 | long ioaddr = dev->base_addr; | ||
393 | |||
394 | outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */ | ||
395 | outb(0xC0, ioaddr + 0x01); /* Enable writes to CONFIG3 */ | ||
396 | outb(0x40, ioaddr + 0x06); /* Enable full duplex */ | ||
397 | outb(0x00, ioaddr + 0x01); /* Disable writes to CONFIG3 */ | ||
398 | outb(E8390_PAGE0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 0 */ | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static inline int set_holtek_fdx(struct net_device *dev) | ||
403 | { | ||
404 | long ioaddr = dev->base_addr; | ||
405 | |||
406 | outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static int ne2k_pci_set_fdx(struct net_device *dev) | ||
411 | { | ||
412 | if (ei_status.ne2k_flags & REALTEK_FDX) | ||
413 | return set_realtek_fdx(dev); | ||
414 | else if (ei_status.ne2k_flags & HOLTEK_FDX) | ||
415 | return set_holtek_fdx(dev); | ||
416 | |||
417 | return -EOPNOTSUPP; | ||
418 | } | ||
419 | |||
420 | static int ne2k_pci_open(struct net_device *dev) | ||
421 | { | ||
422 | int ret = request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev); | ||
423 | if (ret) | ||
424 | return ret; | ||
425 | |||
426 | if (ei_status.ne2k_flags & FORCE_FDX) | ||
427 | ne2k_pci_set_fdx(dev); | ||
428 | |||
429 | ei_open(dev); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static int ne2k_pci_close(struct net_device *dev) | ||
434 | { | ||
435 | ei_close(dev); | ||
436 | free_irq(dev->irq, dev); | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | /* Hard reset the card. This used to pause for the same period that a | ||
441 | 8390 reset command required, but that shouldn't be necessary. */ | ||
442 | static void ne2k_pci_reset_8390(struct net_device *dev) | ||
443 | { | ||
444 | unsigned long reset_start_time = jiffies; | ||
445 | |||
446 | if (debug > 1) printk("%s: Resetting the 8390 t=%ld...", | ||
447 | dev->name, jiffies); | ||
448 | |||
449 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
450 | |||
451 | ei_status.txing = 0; | ||
452 | ei_status.dmaing = 0; | ||
453 | |||
454 | /* This check _should_not_ be necessary, omit eventually. */ | ||
455 | while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) | ||
456 | if (jiffies - reset_start_time > 2) { | ||
457 | printk("%s: ne2k_pci_reset_8390() did not complete.\n", dev->name); | ||
458 | break; | ||
459 | } | ||
460 | outb(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
461 | } | ||
462 | |||
463 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
464 | we don't need to be concerned with ring wrap as the header will be at | ||
465 | the start of a page, so we optimize accordingly. */ | ||
466 | |||
467 | static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
468 | { | ||
469 | |||
470 | long nic_base = dev->base_addr; | ||
471 | |||
472 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
473 | if (ei_status.dmaing) { | ||
474 | printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr " | ||
475 | "[DMAstat:%d][irqlock:%d].\n", | ||
476 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
477 | return; | ||
478 | } | ||
479 | |||
480 | ei_status.dmaing |= 0x01; | ||
481 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
482 | outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
483 | outb(0, nic_base + EN0_RCNTHI); | ||
484 | outb(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
485 | outb(ring_page, nic_base + EN0_RSARHI); | ||
486 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
487 | |||
488 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
489 | insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
490 | } else { | ||
491 | *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT)); | ||
492 | le16_to_cpus(&hdr->count); | ||
493 | } | ||
494 | |||
495 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
496 | ei_status.dmaing &= ~0x01; | ||
497 | } | ||
498 | |||
499 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
500 | are porting to a new ethercard, look at the packet driver source for hints. | ||
501 | The NEx000 doesn't share the on-board packet memory -- you have to put | ||
502 | the packet out through the "remote DMA" dataport using outb. */ | ||
503 | |||
504 | static void ne2k_pci_block_input(struct net_device *dev, int count, | ||
505 | struct sk_buff *skb, int ring_offset) | ||
506 | { | ||
507 | long nic_base = dev->base_addr; | ||
508 | char *buf = skb->data; | ||
509 | |||
510 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
511 | if (ei_status.dmaing) { | ||
512 | printk("%s: DMAing conflict in ne2k_pci_block_input " | ||
513 | "[DMAstat:%d][irqlock:%d].\n", | ||
514 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
515 | return; | ||
516 | } | ||
517 | ei_status.dmaing |= 0x01; | ||
518 | if (ei_status.ne2k_flags & ONLY_32BIT_IO) | ||
519 | count = (count + 3) & 0xFFFC; | ||
520 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
521 | outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
522 | outb(count >> 8, nic_base + EN0_RCNTHI); | ||
523 | outb(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
524 | outb(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
525 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
526 | |||
527 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
528 | insw(NE_BASE + NE_DATAPORT,buf,count>>1); | ||
529 | if (count & 0x01) { | ||
530 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
531 | } | ||
532 | } else { | ||
533 | insl(NE_BASE + NE_DATAPORT, buf, count>>2); | ||
534 | if (count & 3) { | ||
535 | buf += count & ~3; | ||
536 | if (count & 2) { | ||
537 | u16 *b = (u16 *)buf; | ||
538 | |||
539 | *b++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT)); | ||
540 | buf = (char *)b; | ||
541 | } | ||
542 | if (count & 1) | ||
543 | *buf = inb(NE_BASE + NE_DATAPORT); | ||
544 | } | ||
545 | } | ||
546 | |||
547 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
548 | ei_status.dmaing &= ~0x01; | ||
549 | } | ||
550 | |||
551 | static void ne2k_pci_block_output(struct net_device *dev, int count, | ||
552 | const unsigned char *buf, const int start_page) | ||
553 | { | ||
554 | long nic_base = NE_BASE; | ||
555 | unsigned long dma_start; | ||
556 | |||
557 | /* On little-endian it's always safe to round the count up for | ||
558 | word writes. */ | ||
559 | if (ei_status.ne2k_flags & ONLY_32BIT_IO) | ||
560 | count = (count + 3) & 0xFFFC; | ||
561 | else | ||
562 | if (count & 0x01) | ||
563 | count++; | ||
564 | |||
565 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
566 | if (ei_status.dmaing) { | ||
567 | printk("%s: DMAing conflict in ne2k_pci_block_output." | ||
568 | "[DMAstat:%d][irqlock:%d]\n", | ||
569 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
570 | return; | ||
571 | } | ||
572 | ei_status.dmaing |= 0x01; | ||
573 | /* We should already be in page 0, but to be safe... */ | ||
574 | outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
575 | |||
576 | #ifdef NE8390_RW_BUGFIX | ||
577 | /* Handle the read-before-write bug the same way as the | ||
578 | Crynwr packet driver -- the NatSemi method doesn't work. | ||
579 | Actually this doesn't always work either, but if you have | ||
580 | problems with your NEx000 this is better than nothing! */ | ||
581 | outb(0x42, nic_base + EN0_RCNTLO); | ||
582 | outb(0x00, nic_base + EN0_RCNTHI); | ||
583 | outb(0x42, nic_base + EN0_RSARLO); | ||
584 | outb(0x00, nic_base + EN0_RSARHI); | ||
585 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
586 | #endif | ||
587 | outb(ENISR_RDC, nic_base + EN0_ISR); | ||
588 | |||
589 | /* Now the normal output. */ | ||
590 | outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
591 | outb(count >> 8, nic_base + EN0_RCNTHI); | ||
592 | outb(0x00, nic_base + EN0_RSARLO); | ||
593 | outb(start_page, nic_base + EN0_RSARHI); | ||
594 | outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
595 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
596 | outsw(NE_BASE + NE_DATAPORT, buf, count>>1); | ||
597 | } else { | ||
598 | outsl(NE_BASE + NE_DATAPORT, buf, count>>2); | ||
599 | if (count & 3) { | ||
600 | buf += count & ~3; | ||
601 | if (count & 2) { | ||
602 | u16 *b = (u16 *)buf; | ||
603 | |||
604 | outw(cpu_to_le16(*b++), NE_BASE + NE_DATAPORT); | ||
605 | buf = (char *)b; | ||
606 | } | ||
607 | } | ||
608 | } | ||
609 | |||
610 | dma_start = jiffies; | ||
611 | |||
612 | while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) | ||
613 | if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ | ||
614 | printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); | ||
615 | ne2k_pci_reset_8390(dev); | ||
616 | NS8390_init(dev,1); | ||
617 | break; | ||
618 | } | ||
619 | |||
620 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
621 | ei_status.dmaing &= ~0x01; | ||
622 | return; | ||
623 | } | ||
624 | |||
625 | static void ne2k_pci_get_drvinfo(struct net_device *dev, | ||
626 | struct ethtool_drvinfo *info) | ||
627 | { | ||
628 | struct ei_device *ei = dev->priv; | ||
629 | struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; | ||
630 | |||
631 | strcpy(info->driver, DRV_NAME); | ||
632 | strcpy(info->version, DRV_VERSION); | ||
633 | strcpy(info->bus_info, pci_name(pci_dev)); | ||
634 | } | ||
635 | |||
636 | static struct ethtool_ops ne2k_pci_ethtool_ops = { | ||
637 | .get_drvinfo = ne2k_pci_get_drvinfo, | ||
638 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
639 | .get_sg = ethtool_op_get_sg, | ||
640 | }; | ||
641 | |||
642 | static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) | ||
643 | { | ||
644 | struct net_device *dev = pci_get_drvdata(pdev); | ||
645 | |||
646 | if (!dev) | ||
647 | BUG(); | ||
648 | |||
649 | unregister_netdev(dev); | ||
650 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
651 | free_netdev(dev); | ||
652 | pci_disable_device(pdev); | ||
653 | pci_set_drvdata(pdev, NULL); | ||
654 | } | ||
655 | |||
656 | #ifdef CONFIG_PM | ||
657 | static int ne2k_pci_suspend (struct pci_dev *pdev, pm_message_t state) | ||
658 | { | ||
659 | struct net_device *dev = pci_get_drvdata (pdev); | ||
660 | |||
661 | netif_device_detach(dev); | ||
662 | pci_save_state(pdev); | ||
663 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | static int ne2k_pci_resume (struct pci_dev *pdev) | ||
669 | { | ||
670 | struct net_device *dev = pci_get_drvdata (pdev); | ||
671 | |||
672 | pci_set_power_state(pdev, 0); | ||
673 | pci_restore_state(pdev); | ||
674 | NS8390_init(dev, 1); | ||
675 | netif_device_attach(dev); | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | #endif /* CONFIG_PM */ | ||
681 | |||
682 | |||
683 | static struct pci_driver ne2k_driver = { | ||
684 | .name = DRV_NAME, | ||
685 | .probe = ne2k_pci_init_one, | ||
686 | .remove = __devexit_p(ne2k_pci_remove_one), | ||
687 | .id_table = ne2k_pci_tbl, | ||
688 | #ifdef CONFIG_PM | ||
689 | .suspend = ne2k_pci_suspend, | ||
690 | .resume = ne2k_pci_resume, | ||
691 | #endif /* CONFIG_PM */ | ||
692 | |||
693 | }; | ||
694 | |||
695 | |||
696 | static int __init ne2k_pci_init(void) | ||
697 | { | ||
698 | /* when a module, this is printed whether or not devices are found in probe */ | ||
699 | #ifdef MODULE | ||
700 | printk(version); | ||
701 | #endif | ||
702 | return pci_module_init (&ne2k_driver); | ||
703 | } | ||
704 | |||
705 | |||
706 | static void __exit ne2k_pci_cleanup(void) | ||
707 | { | ||
708 | pci_unregister_driver (&ne2k_driver); | ||
709 | } | ||
710 | |||
711 | module_init(ne2k_pci_init); | ||
712 | module_exit(ne2k_pci_cleanup); | ||