* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / net / pcmcia / pcnet_cs.c
blobf5d4b3c49c7ea88a873ce0b8288d8ff96299f146
1 /*======================================================================
3 A PCMCIA ethernet driver for NS8390-based cards
5 This driver supports the D-Link DE-650 and Linksys EthernetCard
6 cards, the newer D-Link and Linksys combo cards, Accton EN2212
7 cards, the RPTI EP400, and the PreMax PE-200 in non-shared-memory
8 mode, and the IBM Credit Card Adapter, the NE4100, the Thomas
9 Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory
10 mode. It will also handle the Socket EA card in either mode.
12 Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu
14 pcnet_cs.c 1.99 1999/09/15 15:33:09
16 The network driver code is based on Donald Becker's NE2000 code:
18 Written 1992,1993 by Donald Becker.
19 Copyright 1993 United States Government as represented by the
20 Director, National Security Agency. This software may be used and
21 distributed according to the terms of the GNU Public License,
22 incorporated herein by reference.
23 Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov
25 Based also on Keith Moore's changes to Don Becker's code, for IBM
26 CCAE support. Drivers merged back together, and shared-memory
27 Socket EA support added, by Ken Raeburn, September 1995.
29 ======================================================================*/
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/ptrace.h>
36 #include <linux/malloc.h>
37 #include <linux/string.h>
38 #include <linux/timer.h>
39 #include <linux/delay.h>
40 #include <asm/io.h>
41 #include <asm/system.h>
43 #include <linux/netdevice.h>
44 #include <../drivers/net/8390.h>
46 #include <pcmcia/version.h>
47 #include <pcmcia/cs_types.h>
48 #include <pcmcia/cs.h>
49 #include <pcmcia/cistpl.h>
50 #include <pcmcia/ciscode.h>
51 #include <pcmcia/ds.h>
52 #include <pcmcia/cisreg.h>
54 #define PCNET_CMD 0x00
55 #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */
56 #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */
57 #define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */
59 #define PCNET_START_PG 0x40 /* First page of TX buffer */
60 #define PCNET_STOP_PG 0x80 /* Last page +1 of RX ring */
62 /* Socket EA cards have a larger packet buffer */
63 #define SOCKET_START_PG 0x01
64 #define SOCKET_STOP_PG 0xff
66 #define PCNET_RDC_TIMEOUT 0x02 /* Max wait in jiffies for Tx RDC */
68 static char *if_names[] = { "auto", "10baseT", "10base2"};
70 #ifdef PCMCIA_DEBUG
71 static int pc_debug = PCMCIA_DEBUG;
72 MODULE_PARM(pc_debug, "i");
73 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
74 static char *version =
75 "pcnet_cs.c 1.99 1999/09/15 15:33:09 (David Hinds)";
76 #else
77 #define DEBUG(n, args...)
78 #endif
80 /*====================================================================*/
82 /* Parameters that can be set with 'insmod' */
84 /* Bit map of interrupts to choose from */
85 static u_int irq_mask = 0xdeb8;
86 static int irq_list[4] = { -1 };
88 /* Transceiver type, for Socket EA and IBM CC cards. */
89 static int if_port = 1;
91 /* Use 64K packet buffer, for Socket EA cards. */
92 static int use_big_buf = 1;
94 /* Shared memory speed, in ns */
95 static int mem_speed = 0;
97 /* Insert a pause in block_output after sending a packet */
98 static int delay_output = 0;
100 /* Length of delay, in microseconds */
101 static int delay_time = 4;
103 /* Use shared memory, if available? */
104 static int use_shmem = -1;
106 /* Ugh! Let the user hardwire the hardware address for queer cards */
107 static int hw_addr[6] = { 0, /* ... */ };
109 MODULE_PARM(irq_mask, "i");
110 MODULE_PARM(irq_list, "1-4i");
111 MODULE_PARM(if_port, "i");
112 MODULE_PARM(use_big_buf, "i");
113 MODULE_PARM(mem_speed, "i");
114 MODULE_PARM(delay_output, "i");
115 MODULE_PARM(delay_time, "i");
116 MODULE_PARM(use_shmem, "i");
117 MODULE_PARM(hw_addr, "6i");
119 /*====================================================================*/
121 static void pcnet_config(dev_link_t *link);
122 static void pcnet_release(u_long arg);
123 static int pcnet_event(event_t event, int priority,
124 event_callback_args_t *args);
126 static int pcnet_open(struct net_device *dev);
127 static int pcnet_close(struct net_device *dev);
128 static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
129 static void ei_watchdog(u_long arg);
131 static void pcnet_reset_8390(struct net_device *dev);
133 static int set_config(struct net_device *dev, struct ifmap *map);
135 static int setup_shmem_window(dev_link_t *link, int start_pg,
136 int stop_pg, int cm_offset);
137 static int setup_dma_config(dev_link_t *link, int start_pg,
138 int stop_pg);
140 static dev_info_t dev_info = "pcnet_cs";
142 static dev_link_t *pcnet_attach(void);
143 static void pcnet_detach(dev_link_t *);
145 static dev_link_t *dev_list;
147 /*====================================================================*/
149 typedef struct hw_info_t {
150 u_long offset;
151 u_char a0, a1, a2;
152 u_long flags;
153 } hw_info_t;
155 #define DELAY_OUTPUT 0x01
156 #define HAS_MISC_REG 0x02
157 #define USE_BIG_BUF 0x04
158 #define HAS_IBM_MISC 0x08
159 #define IS_DL10019A 0x10
160 #define USE_SHMEM 0x80 /* autodetected */
162 static hw_info_t hw_info[] = {
163 { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
164 { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
165 { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
166 { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
167 DELAY_OUTPUT | HAS_IBM_MISC },
168 { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
169 { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
170 { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
171 { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
172 { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
173 { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
174 { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
175 HAS_MISC_REG | HAS_IBM_MISC },
176 { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
177 { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
178 { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
179 HAS_MISC_REG | HAS_IBM_MISC },
180 { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
181 HAS_MISC_REG | HAS_IBM_MISC },
182 { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
183 HAS_MISC_REG | HAS_IBM_MISC },
184 { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
185 HAS_MISC_REG | HAS_IBM_MISC },
186 { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
187 HAS_MISC_REG | HAS_IBM_MISC },
188 { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
189 HAS_MISC_REG | HAS_IBM_MISC },
190 { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
191 HAS_MISC_REG | HAS_IBM_MISC },
192 { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
193 HAS_MISC_REG | HAS_IBM_MISC },
194 { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
195 HAS_MISC_REG | HAS_IBM_MISC },
196 { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
197 { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
198 { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
199 HAS_MISC_REG | HAS_IBM_MISC },
200 { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
201 HAS_MISC_REG | HAS_IBM_MISC },
202 { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
203 { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
204 { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
205 { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
206 { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
207 HAS_MISC_REG | HAS_IBM_MISC },
208 { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
209 HAS_MISC_REG | HAS_IBM_MISC },
210 { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
211 { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
212 { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
213 { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
214 DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
215 { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
216 { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }
219 #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t))
221 static hw_info_t default_info =
222 { /* Unknown NE2000 Clone */ 0x00, 0x00, 0x00, 0x00, 0 };
223 static hw_info_t dl_fast_info =
224 { /* D-Link EtherFast */ 0x00, 0x00, 0x00, 0x00, IS_DL10019A };
226 typedef struct pcnet_dev_t {
227 struct net_device dev;
228 dev_node_t node;
229 u_long flags;
230 caddr_t base;
231 struct timer_list watchdog;
232 int stale;
233 u_short fast_poll;
234 } pcnet_dev_t;
236 /*======================================================================
238 This bit of code is used to avoid unregistering network devices
239 at inappropriate times. 2.2 and later kernels are fairly picky
240 about when this can happen.
242 ======================================================================*/
244 static void flush_stale_links(void)
246 dev_link_t *link, *next;
247 for (link = dev_list; link; link = next) {
248 next = link->next;
249 if (link->state & DEV_STALE_LINK)
250 pcnet_detach(link);
254 /*====================================================================*/
256 static void cs_error(client_handle_t handle, int func, int ret)
258 error_info_t err = { func, ret };
259 CardServices(ReportError, handle, &err);
262 /*======================================================================
264 We never need to do anything when a pcnet device is "initialized"
265 by the net software, because we only register already-found cards.
267 ======================================================================*/
269 static int pcnet_init(struct net_device *dev)
271 return 0;
274 /*======================================================================
276 pcnet_attach() creates an "instance" of the driver, allocating
277 local data structures for one device. The device is registered
278 with Card Services.
280 ======================================================================*/
282 static dev_link_t *pcnet_attach(void)
284 client_reg_t client_reg;
285 dev_link_t *link;
286 pcnet_dev_t *info;
287 struct net_device *dev;
288 int i, ret;
290 DEBUG(0, "pcnet_attach()\n");
291 flush_stale_links();
293 /* Create new ethernet device */
294 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
295 memset(link, 0, sizeof(struct dev_link_t));
296 link->release.function = &pcnet_release;
297 link->release.data = (u_long)link;
298 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
299 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
300 if (irq_list[0] == -1)
301 link->irq.IRQInfo2 = irq_mask;
302 else
303 for (i = 0; i < 4; i++)
304 link->irq.IRQInfo2 |= 1 << irq_list[i];
305 link->conf.Attributes = CONF_ENABLE_IRQ;
306 link->conf.Vcc = 50;
307 link->conf.IntType = INT_MEMORY_AND_IO;
309 info = kmalloc(sizeof(struct pcnet_dev_t), GFP_KERNEL);
310 memset(info, 0, sizeof(struct pcnet_dev_t));
311 dev = &info->dev;
312 ethdev_init(dev);
313 dev->name = info->node.dev_name;
314 dev->init = &pcnet_init;
315 dev->open = &pcnet_open;
316 dev->stop = &pcnet_close;
317 dev->set_config = &set_config;
318 dev->tbusy = 1;
319 link->priv = info;
321 /* Register with Card Services */
322 link->next = dev_list;
323 dev_list = link;
324 client_reg.dev_info = &dev_info;
325 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
326 client_reg.EventMask =
327 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
328 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
329 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
330 client_reg.event_handler = &pcnet_event;
331 client_reg.Version = 0x0210;
332 client_reg.event_callback_args.client_data = link;
333 ret = CardServices(RegisterClient, &link->handle, &client_reg);
334 if (ret != CS_SUCCESS) {
335 cs_error(link->handle, RegisterClient, ret);
336 pcnet_detach(link);
337 return NULL;
340 return link;
341 } /* pcnet_attach */
343 /*======================================================================
345 This deletes a driver "instance". The device is de-registered
346 with Card Services. If it has been released, all local data
347 structures are freed. Otherwise, the structures will be freed
348 when the device is released.
350 ======================================================================*/
352 static void pcnet_detach(dev_link_t *link)
354 dev_link_t **linkp;
355 long flags;
357 DEBUG(0, "pcnet_detach(0x%p)\n", link);
359 /* Locate device structure */
360 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
361 if (*linkp == link) break;
362 if (*linkp == NULL)
363 return;
365 save_flags(flags);
366 cli();
367 if (link->state & DEV_RELEASE_PENDING) {
368 del_timer(&link->release);
369 link->state &= ~DEV_RELEASE_PENDING;
371 restore_flags(flags);
373 if (link->state & DEV_CONFIG) {
374 pcnet_release((u_long)link);
375 if (link->state & DEV_STALE_CONFIG) {
376 link->state |= DEV_STALE_LINK;
377 return;
381 if (link->handle)
382 CardServices(DeregisterClient, link->handle);
384 /* Unlink device structure, free bits */
385 *linkp = link->next;
386 if (link->priv) {
387 struct net_device *dev = link->priv;
388 if (link->dev != NULL)
389 unregister_netdev(dev);
390 if (dev->priv)
391 kfree_s(dev->priv, sizeof(struct ei_device));
392 kfree_s(dev, sizeof(struct pcnet_dev_t));
394 kfree_s(link, sizeof(struct dev_link_t));
396 } /* pcnet_detach */
398 /*======================================================================
400 For the Linksys EtherFast 10/100 card
402 ======================================================================*/
404 static hw_info_t *get_dl_fast(dev_link_t *link)
406 struct net_device *dev = link->priv;
407 int i;
408 u_char sum;
410 for (sum = 0, i = 0x14; i < 0x1c; i++)
411 sum += inb_p(dev->base_addr + i);
412 if (sum != 0xff)
413 return NULL;
414 for (i = 0; i < 6; i++)
415 dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i);
416 return &dl_fast_info;
419 /*======================================================================
421 This probes for a card's hardware address, for card types that
422 encode this information in their CIS.
424 ======================================================================*/
426 static hw_info_t *get_hwinfo(dev_link_t *link)
428 struct net_device *dev = link->priv;
429 win_req_t req;
430 memreq_t mem;
431 u_char *base, *virt;
432 int i, j;
434 /* Allocate a small memory window */
435 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
436 req.Base = 0; req.Size = 0;
437 req.AccessSpeed = 0;
438 link->win = (window_handle_t)link->handle;
439 i = CardServices(RequestWindow, &link->win, &req);
440 if (i != CS_SUCCESS) {
441 cs_error(link->handle, RequestWindow, i);
442 return NULL;
445 virt = ioremap(req.Base, req.Size);
446 mem.Page = 0;
447 for (i = 0; i < NR_INFO; i++) {
448 mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
449 CardServices(MapMemPage, link->win, &mem);
450 base = &virt[hw_info[i].offset & (req.Size-1)];
451 if ((readb(base+0) == hw_info[i].a0) &&
452 (readb(base+2) == hw_info[i].a1) &&
453 (readb(base+4) == hw_info[i].a2))
454 break;
456 if (i < NR_INFO) {
457 for (j = 0; j < 6; j++)
458 dev->dev_addr[j] = readb(base + (j<<1));
461 iounmap(virt);
462 j = CardServices(ReleaseWindow, link->win);
463 if (j != CS_SUCCESS)
464 cs_error(link->handle, ReleaseWindow, j);
465 return (i < NR_INFO) ? hw_info+i : NULL;
466 } /* get_hwinfo */
468 /*======================================================================
470 This probes for a card's hardware address by reading the PROM.
471 It checks the address against a list of known types, then falls
472 back to a simple NE2000 clone signature check.
474 ======================================================================*/
476 static hw_info_t *get_prom(dev_link_t *link)
478 struct net_device *dev = link->priv;
479 unsigned char prom[32];
480 int i, j, ioaddr;
482 /* This is lifted straight from drivers/net/ne.c */
483 struct {
484 unsigned char value, offset;
485 } program_seq[] = {
486 {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
487 {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
488 {0x00, EN0_RCNTLO}, /* Clear the count regs. */
489 {0x00, EN0_RCNTHI},
490 {0x00, EN0_IMR}, /* Mask completion irq. */
491 {0xFF, EN0_ISR},
492 {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
493 {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
494 {32, EN0_RCNTLO},
495 {0x00, EN0_RCNTHI},
496 {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
497 {0x00, EN0_RSARHI},
498 {E8390_RREAD+E8390_START, E8390_CMD},
501 ioaddr = dev->base_addr;
503 pcnet_reset_8390(dev);
504 udelay(10000);
506 for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
507 outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
509 for (i = 0; i < 32; i++)
510 prom[i] = inb(ioaddr + PCNET_DATAPORT);
511 for (i = 0; i < NR_INFO; i++) {
512 if ((prom[0] == hw_info[i].a0) &&
513 (prom[2] == hw_info[i].a1) &&
514 (prom[4] == hw_info[i].a2))
515 break;
517 if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
518 for (j = 0; j < 6; j++)
519 dev->dev_addr[j] = prom[j<<1];
520 return (i < NR_INFO) ? hw_info+i : &default_info;
522 return NULL;
523 } /* get_prom */
525 /*======================================================================
527 This should be totally unnecessary... but when we can't figure
528 out the hardware address any other way, we'll let the user hard
529 wire it when the module is initialized.
531 ======================================================================*/
533 static hw_info_t *get_hwired(dev_link_t *link)
535 struct net_device *dev = link->priv;
536 int i;
538 for (i = 0; i < 6; i++)
539 if (hw_addr[i] != 0) break;
540 if (i == 6)
541 return NULL;
543 for (i = 0; i < 6; i++)
544 dev->dev_addr[i] = hw_addr[i];
546 return &default_info;
547 } /* get_hwired */
549 /*======================================================================
551 pcnet_config() is scheduled to run after a CARD_INSERTION event
552 is received, to configure the PCMCIA socket, and to make the
553 ethernet device available to the system.
555 ======================================================================*/
557 #define CS_CHECK(fn, args...) \
558 while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
560 #define CFG_CHECK(fn, args...) \
561 if (CardServices(fn, args) != 0) goto next_entry
563 static int try_io_port(dev_link_t *link)
565 int j, ret;
566 if (link->io.NumPorts1 == 32) {
567 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
568 if (link->io.NumPorts2 > 0) {
569 /* for master/slave multifunction cards */
570 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
571 link->irq.Attributes =
572 IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
574 } else {
575 /* This should be two 16-port windows */
576 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
577 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
579 if (link->io.BasePort1 == 0) {
580 for (j = 0; j < 0x400; j += 0x20) {
581 link->io.BasePort1 = j ^ 0x300;
582 link->io.BasePort2 = (j ^ 0x300) + 0x10;
583 ret = CardServices(RequestIO, link->handle, &link->io);
584 if (ret == CS_SUCCESS) return ret;
586 return ret;
587 } else {
588 return CardServices(RequestIO, link->handle, &link->io);
592 static void pcnet_config(dev_link_t *link)
594 client_handle_t handle;
595 tuple_t tuple;
596 cisparse_t parse;
597 pcnet_dev_t *info;
598 struct net_device *dev;
599 int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
600 int manfid = 0, prodid = 0, has_shmem = 0;
601 u_short buf[64];
602 hw_info_t *hw_info;
604 handle = link->handle;
605 info = link->priv;
606 dev = &info->dev;
608 DEBUG(0, "pcnet_config(0x%p)\n", link);
610 tuple.Attributes = 0;
611 tuple.TupleData = (cisdata_t *)buf;
612 tuple.TupleDataMax = sizeof(buf);
613 tuple.TupleOffset = 0;
614 tuple.DesiredTuple = CISTPL_CONFIG;
615 CS_CHECK(GetFirstTuple, handle, &tuple);
616 CS_CHECK(GetTupleData, handle, &tuple);
617 CS_CHECK(ParseTuple, handle, &tuple, &parse);
618 link->conf.ConfigBase = parse.config.base;
619 link->conf.Present = parse.config.rmask[0];
621 /* Configure card */
622 link->state |= DEV_CONFIG;
624 tuple.DesiredTuple = CISTPL_MANFID;
625 tuple.Attributes = TUPLE_RETURN_COMMON;
626 if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) &&
627 (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) {
628 manfid = le16_to_cpu(buf[0]);
629 prodid = le16_to_cpu(buf[1]);
632 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
633 tuple.Attributes = 0;
634 CS_CHECK(GetFirstTuple, handle, &tuple);
635 while (last_ret == CS_SUCCESS) {
636 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
637 cistpl_io_t *io = &(parse.cftable_entry.io);
639 CFG_CHECK(GetTupleData, handle, &tuple);
640 CFG_CHECK(ParseTuple, handle, &tuple, &parse);
641 if ((cfg->index == 0) || (cfg->io.nwin == 0))
642 goto next_entry;
644 link->conf.ConfigIndex = cfg->index;
645 /* For multifunction cards, by convention, we configure the
646 network function with window 0, and serial with window 1 */
647 if (io->nwin > 1) {
648 i = (io->win[1].len > io->win[0].len);
649 link->io.BasePort2 = io->win[1-i].base;
650 link->io.NumPorts2 = io->win[1-i].len;
651 } else {
652 i = link->io.NumPorts2 = 0;
654 has_shmem = ((cfg->mem.nwin == 1) &&
655 (cfg->mem.win[0].len >= 0x4000));
656 link->io.BasePort1 = io->win[i].base;
657 link->io.NumPorts1 = io->win[i].len;
658 if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
659 last_ret = try_io_port(link);
660 if (last_ret == CS_SUCCESS) break;
662 next_entry:
663 last_ret = CardServices(GetNextTuple, handle, &tuple);
665 if (last_ret != CS_SUCCESS) {
666 cs_error(handle, RequestIO, last_ret);
667 goto failed;
670 CS_CHECK(RequestIRQ, handle, &link->irq);
672 if (link->io.NumPorts2 == 8) {
673 link->conf.Attributes |= CONF_ENABLE_SPKR;
674 link->conf.Status = CCSR_AUDIO_ENA;
676 if ((manfid == MANFID_IBM) &&
677 (prodid == PRODID_IBM_HOME_AND_AWAY))
678 link->conf.ConfigIndex |= 0x10;
680 CS_CHECK(RequestConfiguration, handle, &link->conf);
681 dev->irq = link->irq.AssignedIRQ;
682 dev->base_addr = link->io.BasePort1;
683 if ((if_port == 1) || (if_port == 2))
684 dev->if_port = if_port;
685 else
686 printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
687 dev->tbusy = 0;
688 if (register_netdev(dev) != 0) {
689 printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
690 goto failed;
693 hw_info = get_hwinfo(link);
694 if (hw_info == NULL)
695 hw_info = get_prom(link);
696 if (hw_info == NULL)
697 hw_info = get_dl_fast(link);
698 if (hw_info == NULL)
699 hw_info = get_hwired(link);
701 if (hw_info == NULL) {
702 printk(KERN_NOTICE "pcnet_cs: unable to read hardware net address\n");
703 goto config_undo;
706 info->flags = hw_info->flags;
707 /* Check for user overrides */
708 info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
709 if ((manfid == MANFID_SOCKET) && (prodid == PRODID_SOCKET_LPE))
710 info->flags &= ~USE_BIG_BUF;
711 if (!use_big_buf)
712 info->flags &= ~USE_BIG_BUF;
714 if (info->flags & USE_BIG_BUF) {
715 start_pg = SOCKET_START_PG;
716 stop_pg = SOCKET_STOP_PG;
717 cm_offset = 0x10000;
718 } else {
719 start_pg = PCNET_START_PG;
720 stop_pg = PCNET_STOP_PG;
721 cm_offset = 0;
724 /* has_shmem is ignored if use_shmem != -1 */
725 if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) ||
726 (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0))
727 setup_dma_config(link, start_pg, stop_pg);
729 ei_status.name = "NE2000";
730 ei_status.word16 = 1;
731 ei_status.reset_8390 = &pcnet_reset_8390;
733 link->dev = &info->node;
734 link->state &= ~DEV_CONFIG_PENDING;
736 printk(KERN_INFO "%s: NE2000 Compatible: io %#3lx, irq %d,",
737 dev->name, dev->base_addr, dev->irq);
738 if (info->flags & USE_SHMEM)
739 printk (" mem %#5lx,", dev->mem_start);
740 if (info->flags & HAS_MISC_REG)
741 printk(" %s xcvr,", if_names[dev->if_port]);
742 printk(" hw_addr ");
743 for (i = 0; i < 6; i++)
744 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
745 return;
747 config_undo:
748 unregister_netdev(dev);
749 goto failed;
750 cs_failed:
751 cs_error(link->handle, last_fn, last_ret);
752 failed:
753 pcnet_release((u_long)link);
754 return;
755 } /* pcnet_config */
757 /*======================================================================
759 After a card is removed, pcnet_release() will unregister the net
760 device, and release the PCMCIA configuration. If the device is
761 still open, this will be postponed until it is closed.
763 ======================================================================*/
765 static void pcnet_release(u_long arg)
767 dev_link_t *link = (dev_link_t *)arg;
768 pcnet_dev_t *info = link->priv;
770 DEBUG(0, "pcnet_release(0x%p)\n", link);
772 if (link->open) {
773 DEBUG(1, "pcnet_cs: release postponed, '%s' still open\n",
774 info->node.dev_name);
775 link->state |= DEV_STALE_CONFIG;
776 return;
779 if (info->flags & USE_SHMEM) {
780 iounmap(info->base);
781 CardServices(ReleaseWindow, link->win);
783 CardServices(ReleaseConfiguration, link->handle);
784 CardServices(ReleaseIO, link->handle, &link->io);
785 CardServices(ReleaseIRQ, link->handle, &link->irq);
787 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
789 } /* pcnet_release */
791 /*======================================================================
793 The card status event handler. Mostly, this schedules other
794 stuff to run after an event is received. A CARD_REMOVAL event
795 also sets some flags to discourage the net drivers from trying
796 to talk to the card any more.
798 ======================================================================*/
800 static int pcnet_event(event_t event, int priority,
801 event_callback_args_t *args)
803 dev_link_t *link = args->client_data;
804 pcnet_dev_t *info = link->priv;
806 DEBUG(2, "pcnet_event(0x%06x)\n", event);
808 switch (event) {
809 case CS_EVENT_CARD_REMOVAL:
810 link->state &= ~DEV_PRESENT;
811 if (link->state & DEV_CONFIG) {
812 info->dev.tbusy = 1; info->dev.start = 0;
813 link->release.expires = jiffies + HZ/20;
814 link->state |= DEV_RELEASE_PENDING;
815 add_timer(&link->release);
817 break;
818 case CS_EVENT_CARD_INSERTION:
819 link->state |= DEV_PRESENT;
820 pcnet_config(link);
821 break;
822 case CS_EVENT_PM_SUSPEND:
823 link->state |= DEV_SUSPEND;
824 /* Fall through... */
825 case CS_EVENT_RESET_PHYSICAL:
826 if (link->state & DEV_CONFIG) {
827 if (link->open) {
828 info->dev.tbusy = 1; info->dev.start = 0;
830 CardServices(ReleaseConfiguration, link->handle);
832 break;
833 case CS_EVENT_PM_RESUME:
834 link->state &= ~DEV_SUSPEND;
835 /* Fall through... */
836 case CS_EVENT_CARD_RESET:
837 if (link->state & DEV_CONFIG) {
838 CardServices(RequestConfiguration, link->handle, &link->conf);
839 if (link->open) {
840 pcnet_reset_8390(&info->dev);
841 NS8390_init(&info->dev, 1);
842 info->dev.tbusy = 0; info->dev.start = 1;
845 break;
847 return 0;
848 } /* pcnet_event */
850 /*====================================================================*/
852 static void set_misc_reg(struct net_device *dev)
854 int nic_base = dev->base_addr;
855 pcnet_dev_t *info = (pcnet_dev_t *)dev;
856 u_char tmp;
858 if (info->flags & HAS_MISC_REG) {
859 tmp = inb_p(nic_base + PCNET_MISC) & ~3;
860 if (dev->if_port == 2)
861 tmp |= 1;
862 if (info->flags & USE_BIG_BUF)
863 tmp |= 2;
864 if (info->flags & HAS_IBM_MISC)
865 tmp |= 8;
866 outb_p(tmp, nic_base + PCNET_MISC);
870 /*====================================================================*/
872 static int pcnet_open(struct net_device *dev)
874 pcnet_dev_t *info = (pcnet_dev_t *)dev;
875 dev_link_t *link;
877 DEBUG(2, "pcnet_open('%s')\n", dev->name);
879 for (link = dev_list; link; link = link->next)
880 if (link->priv == dev) break;
881 if (!DEV_OK(link))
882 return -ENODEV;
884 link->open++;
885 MOD_INC_USE_COUNT;
887 /* For D-Link EtherFast, wait for something(?) to happen */
888 if (info->flags & IS_DL10019A) {
889 int i;
890 for (i = 0; i < 20; i++) {
891 if ((inb(dev->base_addr+0x1c) & 0x01) == 0) break;
892 current->state = TASK_INTERRUPTIBLE;
893 schedule_timeout(HZ/10);
897 set_misc_reg(dev);
898 request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
900 info->watchdog.function = &ei_watchdog;
901 info->watchdog.data = (u_long)info;
902 info->watchdog.expires = jiffies + HZ;
903 add_timer(&info->watchdog);
905 return ei_open(dev);
906 } /* pcnet_open */
908 /*====================================================================*/
910 static int pcnet_close(struct net_device *dev)
912 dev_link_t *link;
914 DEBUG(2, "pcnet_close('%s')\n", dev->name);
916 for (link = dev_list; link; link = link->next)
917 if (link->priv == dev) break;
918 if (link == NULL)
919 return -ENODEV;
920 free_irq(dev->irq, dev);
922 link->open--; dev->start = 0;
923 del_timer(&((pcnet_dev_t *)dev)->watchdog);
924 if (link->state & DEV_STALE_CONFIG) {
925 link->release.expires = jiffies + HZ/20;
926 link->state |= DEV_RELEASE_PENDING;
927 add_timer(&link->release);
930 MOD_DEC_USE_COUNT;
932 return 0;
933 } /* pcnet_close */
935 /*======================================================================
937 Hard reset the card. This used to pause for the same period that
938 a 8390 reset command required, but that shouldn't be necessary.
940 ======================================================================*/
942 static void pcnet_reset_8390(struct net_device *dev)
944 int nic_base = dev->base_addr;
945 int i;
947 ei_status.txing = ei_status.dmaing = 0;
949 outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET);
951 for (i = 0; i < 100; i++) {
952 if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0)
953 break;
954 udelay(100L);
956 outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
958 if (i == 100)
959 printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
960 dev->name);
961 set_misc_reg(dev);
963 } /* pcnet_reset_8390 */
965 /* ======================================================================= */
967 static int set_config(struct net_device *dev, struct ifmap *map)
969 pcnet_dev_t *info = (pcnet_dev_t *)dev;
970 if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
971 if ((map->port != 0) && !(info->flags & HAS_MISC_REG)) {
972 printk(KERN_NOTICE "%s: transceiver selection not "
973 "implemented\n", dev->name);
974 return -EINVAL;
976 if ((map->port == 1) || (map->port == 2)) {
977 dev->if_port = map->port;
978 printk(KERN_INFO "%s: switched to %s port\n",
979 dev->name, if_names[dev->if_port]);
980 } else
981 return -EINVAL;
983 return 0;
986 /* ======================================================================= */
988 static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
990 pcnet_dev_t *info = dev_id;
991 info->stale = 0;
992 ei_interrupt(irq, dev_id, regs);
995 static void ei_watchdog(u_long arg)
997 pcnet_dev_t *info = (pcnet_dev_t *)(arg);
998 struct net_device *dev = &info->dev;
999 int nic_base = dev->base_addr;
1001 if (dev->start == 0) goto reschedule;
1003 /* Check for pending interrupt with expired latency timer: with
1004 this, we can limp along even if the interrupt is blocked */
1005 outb_p(E8390_NODMA+E8390_PAGE0, nic_base + E8390_CMD);
1006 if (info->stale++ && inb_p(nic_base + EN0_ISR)) {
1007 if (!info->fast_poll)
1008 printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
1009 ei_irq_wrapper(dev->irq, dev, NULL);
1010 info->fast_poll = HZ;
1012 if (info->fast_poll) {
1013 info->fast_poll--;
1014 info->watchdog.expires = jiffies + 1;
1015 add_timer(&info->watchdog);
1016 return;
1019 reschedule:
1020 info->watchdog.expires = jiffies + HZ;
1021 add_timer(&info->watchdog);
1024 /* ======================================================================= */
1026 static void dma_get_8390_hdr(struct net_device *dev,
1027 struct e8390_pkt_hdr *hdr,
1028 int ring_page)
1030 int nic_base = dev->base_addr;
1032 if (ei_status.dmaing) {
1033 printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1034 "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n",
1035 dev->name, ei_status.dmaing, ei_status.irqlock,
1036 (long)dev->interrupt);
1037 return;
1040 ei_status.dmaing |= 0x01;
1041 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1042 outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
1043 outb_p(0, nic_base + EN0_RCNTHI);
1044 outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
1045 outb_p(ring_page, nic_base + EN0_RSARHI);
1046 outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1048 insw(nic_base + PCNET_DATAPORT, hdr,
1049 sizeof(struct e8390_pkt_hdr)>>1);
1050 /* Fix for big endian systems */
1051 hdr->count = le16_to_cpu(hdr->count);
1053 outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
1054 ei_status.dmaing &= ~0x01;
1057 /* ======================================================================= */
1059 static void dma_block_input(struct net_device *dev, int count,
1060 struct sk_buff *skb, int ring_offset)
1062 int nic_base = dev->base_addr;
1063 int xfer_count = count;
1064 char *buf = skb->data;
1066 #ifdef PCMCIA_DEBUG
1067 if ((ei_debug > 4) && (count != 4))
1068 printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
1069 #endif
1070 if (ei_status.dmaing) {
1071 printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
1072 "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n",
1073 dev->name, ei_status.dmaing, ei_status.irqlock,
1074 (long)dev->interrupt);
1075 return;
1077 ei_status.dmaing |= 0x01;
1078 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD);
1079 outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1080 outb_p(count >> 8, nic_base + EN0_RCNTHI);
1081 outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
1082 outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
1083 outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD);
1085 insw(nic_base + PCNET_DATAPORT,buf,count>>1);
1086 if (count & 0x01)
1087 buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++;
1089 /* This was for the ALPHA version only, but enough people have
1090 encountering problems that it is still here. */
1091 #ifdef PCMCIA_DEBUG
1092 if (ei_debug > 4) { /* DMA termination address check... */
1093 int addr, tries = 20;
1094 do {
1095 /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
1096 -- it's broken for Rx on some cards! */
1097 int high = inb_p(nic_base + EN0_RSARHI);
1098 int low = inb_p(nic_base + EN0_RSARLO);
1099 addr = (high << 8) + low;
1100 if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff))
1101 break;
1102 } while (--tries > 0);
1103 if (tries <= 0)
1104 printk(KERN_NOTICE "%s: RX transfer address mismatch,"
1105 "%#4.4x (expected) vs. %#4.4x (actual).\n",
1106 dev->name, ring_offset + xfer_count, addr);
1108 #endif
1109 outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
1110 ei_status.dmaing &= ~0x01;
1111 } /* dma_block_input */
1113 /*====================================================================*/
1115 static void dma_block_output(struct net_device *dev, int count,
1116 const unsigned char *buf,
1117 const int start_page)
1119 int nic_base = dev->base_addr;
1120 pcnet_dev_t *info = (pcnet_dev_t *)dev;
1121 #ifdef PCMCIA_DEBUG
1122 int retries = 0;
1123 #endif
1124 u_long dma_start;
1126 #ifdef PCMCIA_DEBUG
1127 if (ei_debug > 4)
1128 printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
1129 #endif
1131 /* Round the count up for word writes. Do we need to do this?
1132 What effect will an odd byte count have on the 8390?
1133 I should check someday. */
1134 if (count & 0x01)
1135 count++;
1136 if (ei_status.dmaing) {
1137 printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
1138 "[DMAstat:%1x][irqlock:%1x][intr:%ld]\n",
1139 dev->name, ei_status.dmaing, ei_status.irqlock,
1140 (long)dev->interrupt);
1141 return;
1143 ei_status.dmaing |= 0x01;
1144 /* We should already be in page 0, but to be safe... */
1145 outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD);
1147 #ifdef PCMCIA_DEBUG
1148 retry:
1149 #endif
1151 outb_p(ENISR_RDC, nic_base + EN0_ISR);
1153 /* Now the normal output. */
1154 outb_p(count & 0xff, nic_base + EN0_RCNTLO);
1155 outb_p(count >> 8, nic_base + EN0_RCNTHI);
1156 outb_p(0x00, nic_base + EN0_RSARLO);
1157 outb_p(start_page, nic_base + EN0_RSARHI);
1159 outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD);
1160 outsw(nic_base + PCNET_DATAPORT, buf, count>>1);
1162 dma_start = jiffies;
1164 #ifdef PCMCIA_DEBUG
1165 /* This was for the ALPHA version only, but enough people have
1166 encountering problems that it is still here. */
1167 if (ei_debug > 4) { /* DMA termination address check... */
1168 int addr, tries = 20;
1169 do {
1170 int high = inb_p(nic_base + EN0_RSARHI);
1171 int low = inb_p(nic_base + EN0_RSARLO);
1172 addr = (high << 8) + low;
1173 if ((start_page << 8) + count == addr)
1174 break;
1175 } while (--tries > 0);
1176 if (tries <= 0) {
1177 printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
1178 "%#4.4x (expected) vs. %#4.4x (actual).\n",
1179 dev->name, (start_page << 8) + count, addr);
1180 if (retries++ == 0)
1181 goto retry;
1184 #endif
1186 while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
1187 if (jiffies - dma_start > PCNET_RDC_TIMEOUT) {
1188 printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
1189 dev->name);
1190 pcnet_reset_8390(dev);
1191 NS8390_init(dev, 1);
1192 break;
1195 outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
1196 if (info->flags & DELAY_OUTPUT)
1197 udelay((long)delay_time);
1198 ei_status.dmaing &= ~0x01;
1201 /*====================================================================*/
1203 static int setup_dma_config(dev_link_t *link, int start_pg,
1204 int stop_pg)
1206 struct net_device *dev = link->priv;
1208 ei_status.tx_start_page = start_pg;
1209 ei_status.rx_start_page = start_pg + TX_PAGES;
1210 ei_status.stop_page = stop_pg;
1212 /* set up block i/o functions */
1213 ei_status.get_8390_hdr = &dma_get_8390_hdr;
1214 ei_status.block_input = &dma_block_input;
1215 ei_status.block_output = &dma_block_output;
1217 return 0;
1220 /*====================================================================*/
1222 static void copyin(unsigned char *dest, unsigned char *src, int c)
1224 unsigned short *d = (unsigned short *) dest;
1225 unsigned short *s = (unsigned short *) src;
1226 int odd;
1228 if (c <= 0)
1229 return;
1230 odd = (c & 01); c >>= 1;
1232 if (c) {
1233 do { *d++ = __raw_readw(s++); } while (--c);
1235 /* get last byte by fetching a word and masking */
1236 if (odd)
1237 *((unsigned char *)d) = readw(s) & 0xff;
1240 static void copyout(unsigned char *dest, const unsigned char *src, int c)
1242 volatile unsigned short *d = (unsigned short *) dest;
1243 unsigned short *s = (unsigned short *) src;
1244 int odd;
1246 if (c <= 0)
1247 return;
1248 odd = (c & 01); c >>= 1;
1250 if (c) {
1251 do { __raw_writew(*s++, d++); } while (--c);
1253 /* copy last byte doing a read-modify-write */
1254 if (odd)
1255 writew((readw(d) & 0xff00) | *(u_char *)s, d);
1258 /*====================================================================*/
1260 static void shmem_get_8390_hdr(struct net_device *dev,
1261 struct e8390_pkt_hdr *hdr,
1262 int ring_page)
1264 void *xfer_start = (void *)(dev->rmem_start + (ring_page << 8)
1265 - (ei_status.rx_start_page << 8));
1267 copyin((void *)hdr, xfer_start, sizeof(struct e8390_pkt_hdr));
1268 /* Fix for big endian systems */
1269 hdr->count = le16_to_cpu(hdr->count);
1272 /*====================================================================*/
1274 static void shmem_block_input(struct net_device *dev, int count,
1275 struct sk_buff *skb, int ring_offset)
1277 void *xfer_start = (void *)(dev->rmem_start + ring_offset
1278 - (ei_status.rx_start_page << 8));
1279 char *buf = skb->data;
1281 if (xfer_start + count > (void *)dev->rmem_end) {
1282 /* We must wrap the input move. */
1283 int semi_count = (void*)dev->rmem_end - xfer_start;
1284 copyin(buf, xfer_start, semi_count);
1285 buf += semi_count;
1286 ring_offset = ei_status.rx_start_page << 8;
1287 xfer_start = (void *)dev->rmem_start;
1288 count -= semi_count;
1290 copyin(buf, xfer_start, count);
1293 /*====================================================================*/
1295 static void shmem_block_output(struct net_device *dev, int count,
1296 const unsigned char *buf,
1297 const int start_page)
1299 void *shmem = (void *)dev->mem_start + (start_page << 8);
1300 shmem -= ei_status.tx_start_page << 8;
1302 if (ei_debug > 4)
1303 printk(KERN_DEBUG "[bo=%d @ %x]\n", count, start_page);
1305 copyout(shmem, buf, count);
1308 /*====================================================================*/
1310 static int setup_shmem_window(dev_link_t *link, int start_pg,
1311 int stop_pg, int cm_offset)
1313 struct net_device *dev = link->priv;
1314 pcnet_dev_t *info = link->priv;
1315 win_req_t req;
1316 memreq_t mem;
1317 int i, window_size, offset, last_ret, last_fn;
1319 window_size = (stop_pg - start_pg) << 8;
1320 if (window_size > 32 * 1024)
1321 window_size = 32 * 1024;
1323 /* Make sure it's a power of two. */
1324 while ((window_size & (window_size - 1)) != 0)
1325 window_size += window_size & ~(window_size - 1);
1327 /* Allocate a memory window */
1328 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
1329 req.Attributes |= WIN_USE_WAIT;
1330 req.Base = 0; req.Size = window_size;
1331 req.AccessSpeed = mem_speed;
1332 link->win = (window_handle_t)link->handle;
1333 CS_CHECK(RequestWindow, &link->win, &req);
1335 mem.CardOffset = (start_pg << 8) + cm_offset;
1336 offset = mem.CardOffset % window_size;
1337 mem.CardOffset -= offset;
1338 mem.Page = 0;
1339 CS_CHECK(MapMemPage, link->win, &mem);
1341 /* Try scribbling on the buffer */
1342 info->base = ioremap(req.Base, window_size);
1343 for (i = 0; i < (TX_PAGES<<8); i += 2)
1344 __raw_writew((i>>1), info->base+offset+i);
1345 udelay(100);
1346 for (i = 0; i < (TX_PAGES<<8); i += 2)
1347 if (__raw_readw(info->base+offset+i) != (i>>1)) break;
1348 pcnet_reset_8390(dev);
1349 if (i != (TX_PAGES<<8)) {
1350 iounmap(info->base);
1351 CardServices(ReleaseWindow, link->win);
1352 info->base = NULL; link->win = NULL;
1353 goto failed;
1356 dev->mem_start = (u_long)info->base + offset;
1357 dev->rmem_start = dev->mem_start + (TX_PAGES<<8);
1358 dev->mem_end = dev->rmem_end = (u_long)info->base + req.Size;
1360 ei_status.tx_start_page = start_pg;
1361 ei_status.rx_start_page = start_pg + TX_PAGES;
1362 ei_status.stop_page = start_pg + ((req.Size - offset) >> 8);
1364 /* set up block i/o functions */
1365 ei_status.get_8390_hdr = &shmem_get_8390_hdr;
1366 ei_status.block_input = &shmem_block_input;
1367 ei_status.block_output = &shmem_block_output;
1369 info->flags |= USE_SHMEM;
1370 return 0;
1372 cs_failed:
1373 cs_error(link->handle, last_fn, last_ret);
1374 failed:
1375 return 1;
1378 /*====================================================================*/
1380 static int __init init_pcnet_cs(void)
1382 servinfo_t serv;
1383 DEBUG(0, "%s\n", version);
1384 CardServices(GetCardServicesInfo, &serv);
1385 if (serv.Revision != CS_RELEASE_CODE) {
1386 printk(KERN_NOTICE "pcnet_cs: Card Services release "
1387 "does not match!\n");
1388 return -1;
1390 register_pccard_driver(&dev_info, &pcnet_attach, &pcnet_detach);
1391 return 0;
1394 static void __exit exit_pcnet_cs(void)
1396 DEBUG(0, "pcnet_cs: unloading\n");
1397 unregister_pccard_driver(&dev_info);
1398 while (dev_list != NULL)
1399 pcnet_detach(dev_list);
1402 module_init(init_pcnet_cs);
1403 module_exit(exit_pcnet_cs);