blob: 0ba018f8382b53b2806b71c0bf4d19b97f10f45a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * SDLA An implementation of a driver for the Sangoma S502/S508 series
3 * multi-protocol PC interface card. Initial offering is with
4 * the DLCI driver, providing Frame Relay support for linux.
5 *
6 * Global definitions for the Frame relay interface.
7 *
8 * Version: @(#)sdla.c 0.30 12 Sep 1996
9 *
10 * Credits: Sangoma Technologies, for the use of 2 cards for an extended
11 * period of time.
12 * David Mandelstam <dm@sangoma.com> for getting me started on
13 * this project, and incentive to complete it.
14 * Gene Kozen <74604.152@compuserve.com> for providing me with
15 * important information about the cards.
16 *
17 * Author: Mike McLagan <mike.mclagan@linux.org>
18 *
19 * Changes:
20 * 0.15 Mike McLagan Improved error handling, packet dropping
21 * 0.20 Mike McLagan New transmit/receive flags for config
22 * If in FR mode, don't accept packets from
23 * non DLCI devices.
24 * 0.25 Mike McLagan Fixed problem with rejecting packets
25 * from non DLCI devices.
26 * 0.30 Mike McLagan Fixed kernel panic when used with modified
27 * ifconfig
28 *
29 * This program is free software; you can redistribute it and/or
30 * modify it under the terms of the GNU General Public License
31 * as published by the Free Software Foundation; either version
32 * 2 of the License, or (at your option) any later version.
33 */
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/types.h>
38#include <linux/fcntl.h>
39#include <linux/interrupt.h>
40#include <linux/ptrace.h>
41#include <linux/ioport.h>
42#include <linux/in.h>
43#include <linux/slab.h>
44#include <linux/string.h>
45#include <linux/timer.h>
46#include <linux/errno.h>
47#include <linux/init.h>
48#include <linux/netdevice.h>
49#include <linux/skbuff.h>
50#include <linux/if_arp.h>
51#include <linux/if_frad.h>
52#include <linux/sdla.h>
53#include <linux/bitops.h>
54
55#include <asm/system.h>
56#include <asm/io.h>
57#include <asm/dma.h>
58#include <asm/uaccess.h>
59
60static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";
61
Randy Dunlap96ebb922006-06-25 05:48:37 -070062static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Randy Dunlap96ebb922006-06-25 05:48:37 -070064static unsigned int valid_mem[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
66 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
67 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
68 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
69 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
70
71static DEFINE_SPINLOCK(sdla_lock);
72
73/*********************************************************
74 *
75 * these are the core routines that access the card itself
76 *
77 *********************************************************/
78
79#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
80
81static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
82{
83 char *temp;
84 const void *base;
85 int offset, bytes;
86
87 temp = buf;
88 while(len)
89 {
90 offset = addr & SDLA_ADDR_MASK;
91 bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
92 base = (const void *) (dev->mem_start + offset);
93
94 SDLA_WINDOW(dev, addr);
95 memcpy(temp, base, bytes);
96
97 addr += bytes;
98 temp += bytes;
99 len -= bytes;
100 }
101}
102
103static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
104{
105 unsigned long flags;
106 spin_lock_irqsave(&sdla_lock, flags);
107 __sdla_read(dev, addr, buf, len);
108 spin_unlock_irqrestore(&sdla_lock, flags);
109}
110
111static void __sdla_write(struct net_device *dev, int addr,
112 const void *buf, short len)
113{
114 const char *temp;
115 void *base;
116 int offset, bytes;
117
118 temp = buf;
119 while(len)
120 {
121 offset = addr & SDLA_ADDR_MASK;
122 bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
123 base = (void *) (dev->mem_start + offset);
124
125 SDLA_WINDOW(dev, addr);
126 memcpy(base, temp, bytes);
127
128 addr += bytes;
129 temp += bytes;
130 len -= bytes;
131 }
132}
133
134static void sdla_write(struct net_device *dev, int addr,
135 const void *buf, short len)
136{
137 unsigned long flags;
138
139 spin_lock_irqsave(&sdla_lock, flags);
140 __sdla_write(dev, addr, buf, len);
141 spin_unlock_irqrestore(&sdla_lock, flags);
142}
143
144
145static void sdla_clear(struct net_device *dev)
146{
147 unsigned long flags;
148 char *base;
149 int len, addr, bytes;
150
151 len = 65536;
152 addr = 0;
153 bytes = SDLA_WINDOW_SIZE;
154 base = (void *) dev->mem_start;
155
156 spin_lock_irqsave(&sdla_lock, flags);
157 while(len)
158 {
159 SDLA_WINDOW(dev, addr);
160 memset(base, 0, bytes);
161
162 addr += bytes;
163 len -= bytes;
164 }
165 spin_unlock_irqrestore(&sdla_lock, flags);
166
167}
168
169static char sdla_byte(struct net_device *dev, int addr)
170{
171 unsigned long flags;
172 char byte, *temp;
173
174 temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));
175
176 spin_lock_irqsave(&sdla_lock, flags);
177 SDLA_WINDOW(dev, addr);
178 byte = *temp;
179 spin_unlock_irqrestore(&sdla_lock, flags);
180
181 return(byte);
182}
183
Adrian Bunk7665a082005-09-09 23:17:28 -0700184static void sdla_stop(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185{
186 struct frad_local *flp;
187
188 flp = dev->priv;
189 switch(flp->type)
190 {
191 case SDLA_S502A:
192 outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
193 flp->state = SDLA_HALT;
194 break;
195 case SDLA_S502E:
196 outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
197 outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
198 flp->state = SDLA_S502E_ENABLE;
199 break;
200 case SDLA_S507:
201 flp->state &= ~SDLA_CPUEN;
202 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
203 break;
204 case SDLA_S508:
205 flp->state &= ~SDLA_CPUEN;
206 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
207 break;
208 }
209}
210
Adrian Bunk7665a082005-09-09 23:17:28 -0700211static void sdla_start(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212{
213 struct frad_local *flp;
214
215 flp = dev->priv;
216 switch(flp->type)
217 {
218 case SDLA_S502A:
219 outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
220 outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
221 flp->state = SDLA_S502A_START;
222 break;
223 case SDLA_S502E:
224 outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
225 outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
226 flp->state = 0;
227 break;
228 case SDLA_S507:
229 flp->state |= SDLA_CPUEN;
230 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
231 break;
232 case SDLA_S508:
233 flp->state |= SDLA_CPUEN;
234 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
235 break;
236 }
237}
238
239/****************************************************
240 *
241 * this is used for the S502A/E cards to determine
242 * the speed of the onboard CPU. Calibration is
243 * necessary for the Frame Relay code uploaded
244 * later. Incorrect results cause timing problems
245 * with link checks & status messages
246 *
247 ***************************************************/
248
Adrian Bunk7665a082005-09-09 23:17:28 -0700249static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250{
251 unsigned long start, done, now;
252 char resp, *temp;
253
254 start = now = jiffies;
255 done = jiffies + jiffs;
256
257 temp = (void *)dev->mem_start;
258 temp += z80_addr & SDLA_ADDR_MASK;
259
260 resp = ~resp1;
261 while (time_before(jiffies, done) && (resp != resp1) && (!resp2 || (resp != resp2)))
262 {
263 if (jiffies != now)
264 {
265 SDLA_WINDOW(dev, z80_addr);
266 now = jiffies;
267 resp = *temp;
268 }
269 }
270 return(time_before(jiffies, done) ? jiffies - start : -1);
271}
272
273/* constants for Z80 CPU speed */
274#define Z80_READY '1' /* Z80 is ready to begin */
275#define LOADER_READY '2' /* driver is ready to begin */
276#define Z80_SCC_OK '3' /* SCC is on board */
277#define Z80_SCC_BAD '4' /* SCC was not found */
278
279static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
280{
281 int jiffs;
282 char data;
283
284 sdla_start(dev);
285 if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
286 return(-EIO);
287
288 data = LOADER_READY;
289 sdla_write(dev, 0, &data, 1);
290
291 if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
292 return(-EIO);
293
294 sdla_stop(dev);
295 sdla_read(dev, 0, &data, 1);
296
297 if (data == Z80_SCC_BAD)
298 {
299 printk("%s: SCC bad\n", dev->name);
300 return(-EIO);
301 }
302
303 if (data != Z80_SCC_OK)
304 return(-EINVAL);
305
306 if (jiffs < 165)
307 ifr->ifr_mtu = SDLA_CPU_16M;
308 else if (jiffs < 220)
309 ifr->ifr_mtu = SDLA_CPU_10M;
310 else if (jiffs < 258)
311 ifr->ifr_mtu = SDLA_CPU_8M;
312 else if (jiffs < 357)
313 ifr->ifr_mtu = SDLA_CPU_7M;
314 else if (jiffs < 467)
315 ifr->ifr_mtu = SDLA_CPU_5M;
316 else
317 ifr->ifr_mtu = SDLA_CPU_3M;
318
319 return(0);
320}
321
322/************************************************
323 *
324 * Direct interaction with the Frame Relay code
325 * starts here.
326 *
327 ************************************************/
328
329struct _dlci_stat
330{
Jan Blunck6a878182006-01-08 01:05:07 -0800331 short dlci;
332 char flags;
333} __attribute__((packed));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
335struct _frad_stat
336{
337 char flags;
338 struct _dlci_stat dlcis[SDLA_MAX_DLCI];
339};
340
341static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data)
342{
343 struct _dlci_stat *pstatus;
344 short *pdlci;
345 int i;
346 char *state, line[30];
347
348 switch (ret)
349 {
350 case SDLA_RET_MODEM:
351 state = data;
352 if (*state & SDLA_MODEM_DCD_LOW)
353 printk(KERN_INFO "%s: Modem DCD unexpectedly low!\n", dev->name);
354 if (*state & SDLA_MODEM_CTS_LOW)
355 printk(KERN_INFO "%s: Modem CTS unexpectedly low!\n", dev->name);
356 /* I should probably do something about this! */
357 break;
358
359 case SDLA_RET_CHANNEL_OFF:
360 printk(KERN_INFO "%s: Channel became inoperative!\n", dev->name);
361 /* same here */
362 break;
363
364 case SDLA_RET_CHANNEL_ON:
365 printk(KERN_INFO "%s: Channel became operative!\n", dev->name);
366 /* same here */
367 break;
368
369 case SDLA_RET_DLCI_STATUS:
370 printk(KERN_INFO "%s: Status change reported by Access Node.\n", dev->name);
371 len /= sizeof(struct _dlci_stat);
372 for(pstatus = data, i=0;i < len;i++,pstatus++)
373 {
374 if (pstatus->flags & SDLA_DLCI_NEW)
375 state = "new";
376 else if (pstatus->flags & SDLA_DLCI_DELETED)
377 state = "deleted";
378 else if (pstatus->flags & SDLA_DLCI_ACTIVE)
379 state = "active";
380 else
381 {
382 sprintf(line, "unknown status: %02X", pstatus->flags);
383 state = line;
384 }
385 printk(KERN_INFO "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
386 /* same here */
387 }
388 break;
389
390 case SDLA_RET_DLCI_UNKNOWN:
391 printk(KERN_INFO "%s: Received unknown DLCIs:", dev->name);
392 len /= sizeof(short);
393 for(pdlci = data,i=0;i < len;i++,pdlci++)
394 printk(" %i", *pdlci);
395 printk("\n");
396 break;
397
398 case SDLA_RET_TIMEOUT:
399 printk(KERN_ERR "%s: Command timed out!\n", dev->name);
400 break;
401
402 case SDLA_RET_BUF_OVERSIZE:
403 printk(KERN_INFO "%s: Bc/CIR overflow, acceptable size is %i\n", dev->name, len);
404 break;
405
406 case SDLA_RET_BUF_TOO_BIG:
407 printk(KERN_INFO "%s: Buffer size over specified max of %i\n", dev->name, len);
408 break;
409
410 case SDLA_RET_CHANNEL_INACTIVE:
411 case SDLA_RET_DLCI_INACTIVE:
412 case SDLA_RET_CIR_OVERFLOW:
413 case SDLA_RET_NO_BUFS:
414 if (cmd == SDLA_INFORMATION_WRITE)
415 break;
416
417 default:
418 printk(KERN_DEBUG "%s: Cmd 0x%2.2X generated return code 0x%2.2X\n", dev->name, cmd, ret);
419 /* Further processing could be done here */
420 break;
421 }
422}
423
424static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
425 void *inbuf, short inlen, void *outbuf, short *outlen)
426{
427 static struct _frad_stat status;
428 struct frad_local *flp;
429 struct sdla_cmd *cmd_buf;
430 unsigned long pflags;
431 unsigned long jiffs;
432 int ret, waiting, len;
433 long window;
434
435 flp = dev->priv;
436 window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
437 cmd_buf = (struct sdla_cmd *)(dev->mem_start + (window & SDLA_ADDR_MASK));
438 ret = 0;
439 len = 0;
440 jiffs = jiffies + HZ; /* 1 second is plenty */
441
442 spin_lock_irqsave(&sdla_lock, pflags);
443 SDLA_WINDOW(dev, window);
444 cmd_buf->cmd = cmd;
445 cmd_buf->dlci = dlci;
446 cmd_buf->flags = flags;
447
448 if (inbuf)
449 memcpy(cmd_buf->data, inbuf, inlen);
450
451 cmd_buf->length = inlen;
452
453 cmd_buf->opp_flag = 1;
454 spin_unlock_irqrestore(&sdla_lock, pflags);
455
456 waiting = 1;
457 len = 0;
458 while (waiting && time_before_eq(jiffies, jiffs))
459 {
460 if (waiting++ % 3)
461 {
462 spin_lock_irqsave(&sdla_lock, pflags);
463 SDLA_WINDOW(dev, window);
464 waiting = ((volatile int)(cmd_buf->opp_flag));
465 spin_unlock_irqrestore(&sdla_lock, pflags);
466 }
467 }
468
469 if (!waiting)
470 {
471
472 spin_lock_irqsave(&sdla_lock, pflags);
473 SDLA_WINDOW(dev, window);
474 ret = cmd_buf->retval;
475 len = cmd_buf->length;
476 if (outbuf && outlen)
477 {
478 *outlen = *outlen >= len ? len : *outlen;
479
480 if (*outlen)
481 memcpy(outbuf, cmd_buf->data, *outlen);
482 }
483
484 /* This is a local copy that's used for error handling */
485 if (ret)
486 memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);
487
488 spin_unlock_irqrestore(&sdla_lock, pflags);
489 }
490 else
491 ret = SDLA_RET_TIMEOUT;
492
493 if (ret != SDLA_RET_OK)
494 sdla_errors(dev, cmd, dlci, ret, len, &status);
495
496 return(ret);
497}
498
499/***********************************************
500 *
501 * these functions are called by the DLCI driver
502 *
503 ***********************************************/
504
505static int sdla_reconfig(struct net_device *dev);
506
Adrian Bunk7665a082005-09-09 23:17:28 -0700507static int sdla_activate(struct net_device *slave, struct net_device *master)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508{
509 struct frad_local *flp;
510 int i;
511
512 flp = slave->priv;
513
514 for(i=0;i<CONFIG_DLCI_MAX;i++)
515 if (flp->master[i] == master)
516 break;
517
518 if (i == CONFIG_DLCI_MAX)
519 return(-ENODEV);
520
521 flp->dlci[i] = abs(flp->dlci[i]);
522
523 if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
524 sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
525
526 return(0);
527}
528
Adrian Bunk7665a082005-09-09 23:17:28 -0700529static int sdla_deactivate(struct net_device *slave, struct net_device *master)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530{
531 struct frad_local *flp;
532 int i;
533
534 flp = slave->priv;
535
536 for(i=0;i<CONFIG_DLCI_MAX;i++)
537 if (flp->master[i] == master)
538 break;
539
540 if (i == CONFIG_DLCI_MAX)
541 return(-ENODEV);
542
543 flp->dlci[i] = -abs(flp->dlci[i]);
544
545 if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
546 sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
547
548 return(0);
549}
550
Adrian Bunk7665a082005-09-09 23:17:28 -0700551static int sdla_assoc(struct net_device *slave, struct net_device *master)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552{
553 struct frad_local *flp;
554 int i;
555
556 if (master->type != ARPHRD_DLCI)
557 return(-EINVAL);
558
559 flp = slave->priv;
560
561 for(i=0;i<CONFIG_DLCI_MAX;i++)
562 {
563 if (!flp->master[i])
564 break;
565 if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
566 return(-EADDRINUSE);
567 }
568
569 if (i == CONFIG_DLCI_MAX)
570 return(-EMLINK); /* #### Alan: Comments on this ?? */
571
572
573 flp->master[i] = master;
574 flp->dlci[i] = -*(short *)(master->dev_addr);
575 master->mtu = slave->mtu;
576
577 if (netif_running(slave)) {
578 if (flp->config.station == FRAD_STATION_CPE)
579 sdla_reconfig(slave);
580 else
581 sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
582 }
583
584 return(0);
585}
586
Adrian Bunk7665a082005-09-09 23:17:28 -0700587static int sdla_deassoc(struct net_device *slave, struct net_device *master)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588{
589 struct frad_local *flp;
590 int i;
591
592 flp = slave->priv;
593
594 for(i=0;i<CONFIG_DLCI_MAX;i++)
595 if (flp->master[i] == master)
596 break;
597
598 if (i == CONFIG_DLCI_MAX)
599 return(-ENODEV);
600
601 flp->master[i] = NULL;
602 flp->dlci[i] = 0;
603
604
605 if (netif_running(slave)) {
606 if (flp->config.station == FRAD_STATION_CPE)
607 sdla_reconfig(slave);
608 else
609 sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
610 }
611
612 return(0);
613}
614
Adrian Bunk7665a082005-09-09 23:17:28 -0700615static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616{
617 struct frad_local *flp;
618 struct dlci_local *dlp;
619 int i;
620 short len, ret;
621
622 flp = slave->priv;
623
624 for(i=0;i<CONFIG_DLCI_MAX;i++)
625 if (flp->master[i] == master)
626 break;
627
628 if (i == CONFIG_DLCI_MAX)
629 return(-ENODEV);
630
631 dlp = master->priv;
632
633 ret = SDLA_RET_OK;
634 len = sizeof(struct dlci_conf);
635 if (netif_running(slave)) {
636 if (get)
637 ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,
638 NULL, 0, &dlp->config, &len);
639 else
640 ret = sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,
641 &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
642 }
643
644 return(ret == SDLA_RET_OK ? 0 : -EIO);
645}
646
647/**************************
648 *
649 * now for the Linux driver
650 *
651 **************************/
652
653/* NOTE: the DLCI driver deals with freeing the SKB!! */
654static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
655{
656 struct frad_local *flp;
657 int ret, addr, accept, i;
658 short size;
659 unsigned long flags;
660 struct buf_entry *pbuf;
661
662 flp = dev->priv;
663 ret = 0;
664 accept = 1;
665
666 netif_stop_queue(dev);
667
668 /*
669 * stupid GateD insists on setting up the multicast router thru us
670 * and we're ill equipped to handle a non Frame Relay packet at this
671 * time!
672 */
673
674 accept = 1;
675 switch (dev->type)
676 {
677 case ARPHRD_FRAD:
678 if (skb->dev->type != ARPHRD_DLCI)
679 {
680 printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type);
681 accept = 0;
682 }
683 break;
684 default:
685 printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type);
686 accept = 0;
687 break;
688 }
689 if (accept)
690 {
691 /* this is frame specific, but till there's a PPP module, it's the default */
692 switch (flp->type)
693 {
694 case SDLA_S502A:
695 case SDLA_S502E:
696 ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
697 break;
698 case SDLA_S508:
699 size = sizeof(addr);
700 ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
701 if (ret == SDLA_RET_OK)
702 {
703
704 spin_lock_irqsave(&sdla_lock, flags);
705 SDLA_WINDOW(dev, addr);
706 pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
707 __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
708 SDLA_WINDOW(dev, addr);
709 pbuf->opp_flag = 1;
710 spin_unlock_irqrestore(&sdla_lock, flags);
711 }
712 break;
713 }
714 switch (ret)
715 {
716 case SDLA_RET_OK:
717 flp->stats.tx_packets++;
718 ret = DLCI_RET_OK;
719 break;
720
721 case SDLA_RET_CIR_OVERFLOW:
722 case SDLA_RET_BUF_OVERSIZE:
723 case SDLA_RET_NO_BUFS:
724 flp->stats.tx_dropped++;
725 ret = DLCI_RET_DROP;
726 break;
727
728 default:
729 flp->stats.tx_errors++;
730 ret = DLCI_RET_ERR;
731 break;
732 }
733 }
734 netif_wake_queue(dev);
735 for(i=0;i<CONFIG_DLCI_MAX;i++)
736 {
737 if(flp->master[i]!=NULL)
738 netif_wake_queue(flp->master[i]);
739 }
740 return(ret);
741}
742
743static void sdla_receive(struct net_device *dev)
744{
745 struct net_device *master;
746 struct frad_local *flp;
747 struct dlci_local *dlp;
748 struct sk_buff *skb;
749
750 struct sdla_cmd *cmd;
751 struct buf_info *pbufi;
752 struct buf_entry *pbuf;
753
754 unsigned long flags;
755 int i=0, received, success, addr, buf_base, buf_top;
756 short dlci, len, len2, split;
757
758 flp = dev->priv;
759 success = 1;
760 received = addr = buf_top = buf_base = 0;
761 len = dlci = 0;
762 skb = NULL;
763 master = NULL;
764 cmd = NULL;
765 pbufi = NULL;
766 pbuf = NULL;
767
768 spin_lock_irqsave(&sdla_lock, flags);
769
770 switch (flp->type)
771 {
772 case SDLA_S502A:
773 case SDLA_S502E:
774 cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & SDLA_ADDR_MASK));
775 SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
776 success = cmd->opp_flag;
777 if (!success)
778 break;
779
780 dlci = cmd->dlci;
781 len = cmd->length;
782 break;
783
784 case SDLA_S508:
785 pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & SDLA_ADDR_MASK));
786 SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
787 pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & SDLA_ADDR_MASK));
788 success = pbuf->opp_flag;
789 if (!success)
790 break;
791
792 buf_top = pbufi->buf_top;
793 buf_base = pbufi->buf_base;
794 dlci = pbuf->dlci;
795 len = pbuf->length;
796 addr = pbuf->buf_addr;
797 break;
798 }
799
800 /* common code, find the DLCI and get the SKB */
801 if (success)
802 {
803 for (i=0;i<CONFIG_DLCI_MAX;i++)
804 if (flp->dlci[i] == dlci)
805 break;
806
807 if (i == CONFIG_DLCI_MAX)
808 {
809 printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci);
810 flp->stats.rx_errors++;
811 success = 0;
812 }
813 }
814
815 if (success)
816 {
817 master = flp->master[i];
818 skb = dev_alloc_skb(len + sizeof(struct frhdr));
819 if (skb == NULL)
820 {
821 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
822 flp->stats.rx_dropped++;
823 success = 0;
824 }
825 else
826 skb_reserve(skb, sizeof(struct frhdr));
827 }
828
829 /* pick up the data */
830 switch (flp->type)
831 {
832 case SDLA_S502A:
833 case SDLA_S502E:
834 if (success)
835 __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
836
837 SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
838 cmd->opp_flag = 0;
839 break;
840
841 case SDLA_S508:
842 if (success)
843 {
844 /* is this buffer split off the end of the internal ring buffer */
845 split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
846 len2 = len - split;
847
848 __sdla_read(dev, addr, skb_put(skb, len2), len2);
849 if (split)
850 __sdla_read(dev, buf_base, skb_put(skb, split), split);
851 }
852
853 /* increment the buffer we're looking at */
854 SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
855 flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
856 pbuf->opp_flag = 0;
857 break;
858 }
859
860 if (success)
861 {
862 flp->stats.rx_packets++;
863 dlp = master->priv;
864 (*dlp->receive)(skb, master);
865 }
866
867 spin_unlock_irqrestore(&sdla_lock, flags);
868}
869
870static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
871{
872 struct net_device *dev;
873 struct frad_local *flp;
874 char byte;
875
876 dev = dev_id;
877
878 if (dev == NULL)
879 {
880 printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
881 return IRQ_NONE;
882 }
883
884 flp = dev->priv;
885
886 if (!flp->initialized)
887 {
888 printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", dev->name, irq);
889 return IRQ_NONE;
890 }
891
892 byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
893 switch (byte)
894 {
895 case SDLA_INTR_RX:
896 sdla_receive(dev);
897 break;
898
899 /* the command will get an error return, which is processed above */
900 case SDLA_INTR_MODEM:
901 case SDLA_INTR_STATUS:
902 sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
903 break;
904
905 case SDLA_INTR_TX:
906 case SDLA_INTR_COMPLETE:
907 case SDLA_INTR_TIMER:
908 printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
909 break;
910 }
911
912 /* the S502E requires a manual acknowledgement of the interrupt */
913 if (flp->type == SDLA_S502E)
914 {
915 flp->state &= ~SDLA_S502E_INTACK;
916 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
917 flp->state |= SDLA_S502E_INTACK;
918 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
919 }
920
921 /* this clears the byte, informing the Z80 we're done */
922 byte = 0;
923 sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
924 return IRQ_HANDLED;
925}
926
927static void sdla_poll(unsigned long device)
928{
929 struct net_device *dev;
930 struct frad_local *flp;
931
932 dev = (struct net_device *) device;
933 flp = dev->priv;
934
935 if (sdla_byte(dev, SDLA_502_RCV_BUF))
936 sdla_receive(dev);
937
938 flp->timer.expires = 1;
939 add_timer(&flp->timer);
940}
941
942static int sdla_close(struct net_device *dev)
943{
944 struct frad_local *flp;
945 struct intr_info intr;
946 int len, i;
947 short dlcis[CONFIG_DLCI_MAX];
948
949 flp = dev->priv;
950
951 len = 0;
952 for(i=0;i<CONFIG_DLCI_MAX;i++)
953 if (flp->dlci[i])
954 dlcis[len++] = abs(flp->dlci[i]);
955 len *= 2;
956
957 if (flp->config.station == FRAD_STATION_NODE)
958 {
959 for(i=0;i<CONFIG_DLCI_MAX;i++)
960 if (flp->dlci[i] > 0)
961 sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
962 sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
963 }
964
965 memset(&intr, 0, sizeof(intr));
966 /* let's start up the reception */
967 switch(flp->type)
968 {
969 case SDLA_S502A:
970 del_timer(&flp->timer);
971 break;
972
973 case SDLA_S502E:
974 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
975 flp->state &= ~SDLA_S502E_INTACK;
976 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
977 break;
978
979 case SDLA_S507:
980 break;
981
982 case SDLA_S508:
983 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
984 flp->state &= ~SDLA_S508_INTEN;
985 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
986 break;
987 }
988
989 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
990
991 netif_stop_queue(dev);
992
993 return(0);
994}
995
996struct conf_data {
997 struct frad_conf config;
998 short dlci[CONFIG_DLCI_MAX];
999};
1000
1001static int sdla_open(struct net_device *dev)
1002{
1003 struct frad_local *flp;
1004 struct dlci_local *dlp;
1005 struct conf_data data;
1006 struct intr_info intr;
1007 int len, i;
1008 char byte;
1009
1010 flp = dev->priv;
1011
1012 if (!flp->initialized)
1013 return(-EPERM);
1014
1015 if (!flp->configured)
1016 return(-EPERM);
1017
1018 /* time to send in the configuration */
1019 len = 0;
1020 for(i=0;i<CONFIG_DLCI_MAX;i++)
1021 if (flp->dlci[i])
1022 data.dlci[len++] = abs(flp->dlci[i]);
1023 len *= 2;
1024
1025 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1026 len += sizeof(struct frad_conf);
1027
1028 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1029 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1030
1031 if (flp->type == SDLA_S508)
1032 flp->buffer = 0;
1033
1034 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1035
1036 /* let's start up the reception */
1037 memset(&intr, 0, sizeof(intr));
1038 switch(flp->type)
1039 {
1040 case SDLA_S502A:
1041 flp->timer.expires = 1;
1042 add_timer(&flp->timer);
1043 break;
1044
1045 case SDLA_S502E:
1046 flp->state |= SDLA_S502E_ENABLE;
1047 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1048 flp->state |= SDLA_S502E_INTACK;
1049 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1050 byte = 0;
1051 sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
1052 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1053 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
1054 break;
1055
1056 case SDLA_S507:
1057 break;
1058
1059 case SDLA_S508:
1060 flp->state |= SDLA_S508_INTEN;
1061 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1062 byte = 0;
1063 sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
1064 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1065 intr.irq = dev->irq;
1066 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
1067 break;
1068 }
1069
1070 if (flp->config.station == FRAD_STATION_CPE)
1071 {
1072 byte = SDLA_ICS_STATUS_ENQ;
1073 sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
1074 }
1075 else
1076 {
1077 sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
1078 for(i=0;i<CONFIG_DLCI_MAX;i++)
1079 if (flp->dlci[i] > 0)
1080 sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
1081 }
1082
1083 /* configure any specific DLCI settings */
1084 for(i=0;i<CONFIG_DLCI_MAX;i++)
1085 if (flp->dlci[i])
1086 {
1087 dlp = flp->master[i]->priv;
1088 if (dlp->configured)
1089 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
1090 }
1091
1092 netif_start_queue(dev);
1093
1094 return(0);
1095}
1096
1097static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
1098{
1099 struct frad_local *flp;
1100 struct conf_data data;
1101 int i;
1102 short size;
1103
1104 if (dev->type == 0xFFFF)
1105 return(-EUNATCH);
1106
1107 flp = dev->priv;
1108
1109 if (!get)
1110 {
1111 if (netif_running(dev))
1112 return(-EBUSY);
1113
1114 if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
1115 return -EFAULT;
1116
1117 if (data.config.station & ~FRAD_STATION_NODE)
1118 return(-EINVAL);
1119
1120 if (data.config.flags & ~FRAD_VALID_FLAGS)
1121 return(-EINVAL);
1122
1123 if ((data.config.kbaud < 0) ||
1124 ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
1125 return(-EINVAL);
1126
1127 if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
1128 return(-EINVAL);
1129
1130 if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
1131 return(-EINVAL);
1132
1133 if ((data.config.T391 < 5) || (data.config.T391 > 30))
1134 return(-EINVAL);
1135
1136 if ((data.config.T392 < 5) || (data.config.T392 > 30))
1137 return(-EINVAL);
1138
1139 if ((data.config.N391 < 1) || (data.config.N391 > 255))
1140 return(-EINVAL);
1141
1142 if ((data.config.N392 < 1) || (data.config.N392 > 10))
1143 return(-EINVAL);
1144
1145 if ((data.config.N393 < 1) || (data.config.N393 > 10))
1146 return(-EINVAL);
1147
1148 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1149 flp->config.flags |= SDLA_DIRECT_RECV;
1150
1151 if (flp->type == SDLA_S508)
1152 flp->config.flags |= SDLA_TX70_RX30;
1153
1154 if (dev->mtu != flp->config.mtu)
1155 {
1156 /* this is required to change the MTU */
1157 dev->mtu = flp->config.mtu;
1158 for(i=0;i<CONFIG_DLCI_MAX;i++)
1159 if (flp->master[i])
1160 flp->master[i]->mtu = flp->config.mtu;
1161 }
1162
1163 flp->config.mtu += sizeof(struct frhdr);
1164
1165 /* off to the races! */
1166 if (!flp->configured)
1167 sdla_start(dev);
1168
1169 flp->configured = 1;
1170 }
1171 else
1172 {
1173 /* no sense reading if the CPU isn't started */
1174 if (netif_running(dev))
1175 {
1176 size = sizeof(data);
1177 if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
1178 return(-EIO);
1179 }
1180 else
1181 if (flp->configured)
1182 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1183 else
1184 memset(&data.config, 0, sizeof(struct frad_conf));
1185
1186 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1187 data.config.flags &= FRAD_VALID_FLAGS;
1188 data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu;
1189 return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
1190 }
1191
1192 return(0);
1193}
1194
1195static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
1196{
1197 struct sdla_mem mem;
1198 char *temp;
1199
1200 if(copy_from_user(&mem, info, sizeof(mem)))
1201 return -EFAULT;
1202
1203 if (read)
1204 {
1205 temp = kmalloc(mem.len, GFP_KERNEL);
1206 if (!temp)
1207 return(-ENOMEM);
1208 memset(temp, 0, mem.len);
1209 sdla_read(dev, mem.addr, temp, mem.len);
1210 if(copy_to_user(mem.data, temp, mem.len))
1211 {
1212 kfree(temp);
1213 return -EFAULT;
1214 }
1215 kfree(temp);
1216 }
1217 else
1218 {
1219 temp = kmalloc(mem.len, GFP_KERNEL);
1220 if (!temp)
1221 return(-ENOMEM);
1222 if(copy_from_user(temp, mem.data, mem.len))
1223 {
1224 kfree(temp);
1225 return -EFAULT;
1226 }
1227 sdla_write(dev, mem.addr, temp, mem.len);
1228 kfree(temp);
1229 }
1230 return(0);
1231}
1232
1233static int sdla_reconfig(struct net_device *dev)
1234{
1235 struct frad_local *flp;
1236 struct conf_data data;
1237 int i, len;
1238
1239 flp = dev->priv;
1240
1241 len = 0;
1242 for(i=0;i<CONFIG_DLCI_MAX;i++)
1243 if (flp->dlci[i])
1244 data.dlci[len++] = flp->dlci[i];
1245 len *= 2;
1246
1247 memcpy(&data, &flp->config, sizeof(struct frad_conf));
1248 len += sizeof(struct frad_conf);
1249
1250 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1251 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1252 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1253
1254 return(0);
1255}
1256
1257static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1258{
1259 struct frad_local *flp;
1260
1261 if(!capable(CAP_NET_ADMIN))
1262 return -EPERM;
1263
1264 flp = dev->priv;
1265
1266 if (!flp->initialized)
1267 return(-EINVAL);
1268
1269 switch (cmd)
1270 {
1271 case FRAD_GET_CONF:
1272 case FRAD_SET_CONF:
1273 return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
1274
1275 case SDLA_IDENTIFY:
1276 ifr->ifr_flags = flp->type;
1277 break;
1278
1279 case SDLA_CPUSPEED:
1280 return(sdla_cpuspeed(dev, ifr));
1281
1282/* ==========================================================
1283NOTE: This is rather a useless action right now, as the
1284 current driver does not support protocols other than
1285 FR. However, Sangoma has modules for a number of
1286 other protocols in the works.
1287============================================================*/
1288 case SDLA_PROTOCOL:
1289 if (flp->configured)
1290 return(-EALREADY);
1291
1292 switch (ifr->ifr_flags)
1293 {
1294 case ARPHRD_FRAD:
1295 dev->type = ifr->ifr_flags;
1296 break;
1297 default:
1298 return(-ENOPROTOOPT);
1299 }
1300 break;
1301
1302 case SDLA_CLEARMEM:
1303 sdla_clear(dev);
1304 break;
1305
1306 case SDLA_WRITEMEM:
1307 case SDLA_READMEM:
1308 if(!capable(CAP_SYS_RAWIO))
1309 return -EPERM;
1310 return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
1311
1312 case SDLA_START:
1313 sdla_start(dev);
1314 break;
1315
1316 case SDLA_STOP:
1317 sdla_stop(dev);
1318 break;
1319
1320 default:
1321 return(-EOPNOTSUPP);
1322 }
1323 return(0);
1324}
1325
Adrian Bunk7665a082005-09-09 23:17:28 -07001326static int sdla_change_mtu(struct net_device *dev, int new_mtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327{
1328 struct frad_local *flp;
1329
1330 flp = dev->priv;
1331
1332 if (netif_running(dev))
1333 return(-EBUSY);
1334
1335 /* for now, you can't change the MTU! */
1336 return(-EOPNOTSUPP);
1337}
1338
Adrian Bunk7665a082005-09-09 23:17:28 -07001339static int sdla_set_config(struct net_device *dev, struct ifmap *map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340{
1341 struct frad_local *flp;
1342 int i;
1343 char byte;
1344 unsigned base;
1345 int err = -EINVAL;
1346
1347 flp = dev->priv;
1348
1349 if (flp->initialized)
1350 return(-EINVAL);
1351
1352 for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
1353 if (valid_port[i] == map->base_addr)
1354 break;
1355
1356 if (i == sizeof(valid_port) / sizeof(int))
1357 return(-EINVAL);
1358
1359 if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
1360 printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
1361 return(-EINVAL);
1362 }
1363 base = map->base_addr;
1364
1365 /* test for card types, S502A, S502E, S507, S508 */
1366 /* these tests shut down the card completely, so clear the state */
1367 flp->type = SDLA_UNKNOWN;
1368 flp->state = 0;
1369
1370 for(i=1;i<SDLA_IO_EXTENTS;i++)
1371 if (inb(base + i) != 0xFF)
1372 break;
1373
1374 if (i == SDLA_IO_EXTENTS) {
1375 outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
1376 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
1377 outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
1378 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
1379 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1380 flp->type = SDLA_S502E;
1381 goto got_type;
1382 }
1383 }
1384 }
1385
1386 for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
1387 if (inb(base + i) != byte)
1388 break;
1389
1390 if (i == SDLA_IO_EXTENTS) {
1391 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1392 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
1393 outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
1394 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
1395 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1396 flp->type = SDLA_S507;
1397 goto got_type;
1398 }
1399 }
1400 }
1401
1402 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1403 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
1404 outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
1405 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
1406 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1407 flp->type = SDLA_S508;
1408 goto got_type;
1409 }
1410 }
1411
1412 outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
1413 if (inb(base + SDLA_S502_STS) == 0x40) {
1414 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1415 if (inb(base + SDLA_S502_STS) == 0x40) {
1416 outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
1417 if (inb(base + SDLA_S502_STS) == 0x44) {
1418 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1419 flp->type = SDLA_S502A;
1420 goto got_type;
1421 }
1422 }
1423 }
1424
1425 printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1426 err = -ENODEV;
1427 goto fail;
1428
1429got_type:
1430 switch(base) {
1431 case 0x270:
1432 case 0x280:
1433 case 0x380:
1434 case 0x390:
1435 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1436 goto fail;
1437 }
1438
1439 switch (map->irq) {
1440 case 2:
1441 if (flp->type != SDLA_S502E)
1442 goto fail;
1443 break;
1444
1445 case 10:
1446 case 11:
1447 case 12:
1448 case 15:
1449 case 4:
1450 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1451 goto fail;
1452 break;
1453 case 3:
1454 case 5:
1455 case 7:
1456 if (flp->type == SDLA_S502A)
1457 goto fail;
1458 break;
1459
1460 default:
1461 goto fail;
1462 }
1463
1464 err = -EAGAIN;
1465 if (request_irq(dev->irq, &sdla_isr, 0, dev->name, dev))
1466 goto fail;
1467
1468 if (flp->type == SDLA_S507) {
1469 switch(dev->irq) {
1470 case 3:
1471 flp->state = SDLA_S507_IRQ3;
1472 break;
1473 case 4:
1474 flp->state = SDLA_S507_IRQ4;
1475 break;
1476 case 5:
1477 flp->state = SDLA_S507_IRQ5;
1478 break;
1479 case 7:
1480 flp->state = SDLA_S507_IRQ7;
1481 break;
1482 case 10:
1483 flp->state = SDLA_S507_IRQ10;
1484 break;
1485 case 11:
1486 flp->state = SDLA_S507_IRQ11;
1487 break;
1488 case 12:
1489 flp->state = SDLA_S507_IRQ12;
1490 break;
1491 case 15:
1492 flp->state = SDLA_S507_IRQ15;
1493 break;
1494 }
1495 }
1496
1497 for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
1498 if (valid_mem[i] == map->mem_start)
1499 break;
1500
1501 err = -EINVAL;
1502 if (i == sizeof(valid_mem) / sizeof(int))
1503 goto fail2;
1504
1505 if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
1506 goto fail2;
1507
1508 if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
1509 goto fail2;
1510
1511 if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
1512 goto fail2;
1513
1514 byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1515 byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1516 switch(flp->type) {
1517 case SDLA_S502A:
1518 case SDLA_S502E:
1519 switch (map->mem_start >> 16) {
1520 case 0x0A:
1521 byte |= SDLA_S502_SEG_A;
1522 break;
1523 case 0x0C:
1524 byte |= SDLA_S502_SEG_C;
1525 break;
1526 case 0x0D:
1527 byte |= SDLA_S502_SEG_D;
1528 break;
1529 case 0x0E:
1530 byte |= SDLA_S502_SEG_E;
1531 break;
1532 }
1533 break;
1534 case SDLA_S507:
1535 switch (map->mem_start >> 16) {
1536 case 0x0A:
1537 byte |= SDLA_S507_SEG_A;
1538 break;
1539 case 0x0B:
1540 byte |= SDLA_S507_SEG_B;
1541 break;
1542 case 0x0C:
1543 byte |= SDLA_S507_SEG_C;
1544 break;
1545 case 0x0E:
1546 byte |= SDLA_S507_SEG_E;
1547 break;
1548 }
1549 break;
1550 case SDLA_S508:
1551 switch (map->mem_start >> 16) {
1552 case 0x0A:
1553 byte |= SDLA_S508_SEG_A;
1554 break;
1555 case 0x0C:
1556 byte |= SDLA_S508_SEG_C;
1557 break;
1558 case 0x0D:
1559 byte |= SDLA_S508_SEG_D;
1560 break;
1561 case 0x0E:
1562 byte |= SDLA_S508_SEG_E;
1563 break;
1564 }
1565 break;
1566 }
1567
1568 /* set the memory bits, and enable access */
1569 outb(byte, base + SDLA_REG_PC_WINDOW);
1570
1571 switch(flp->type)
1572 {
1573 case SDLA_S502E:
1574 flp->state = SDLA_S502E_ENABLE;
1575 break;
1576 case SDLA_S507:
1577 flp->state |= SDLA_MEMEN;
1578 break;
1579 case SDLA_S508:
1580 flp->state = SDLA_MEMEN;
1581 break;
1582 }
1583 outb(flp->state, base + SDLA_REG_CONTROL);
1584
1585 dev->irq = map->irq;
1586 dev->base_addr = base;
1587 dev->mem_start = map->mem_start;
1588 dev->mem_end = dev->mem_start + 0x2000;
1589 flp->initialized = 1;
1590 return 0;
1591
1592fail2:
1593 free_irq(map->irq, dev);
1594fail:
1595 release_region(base, SDLA_IO_EXTENTS);
1596 return err;
1597}
1598
1599static struct net_device_stats *sdla_stats(struct net_device *dev)
1600{
1601 struct frad_local *flp;
1602 flp = dev->priv;
1603
1604 return(&flp->stats);
1605}
1606
1607static void setup_sdla(struct net_device *dev)
1608{
1609 struct frad_local *flp = dev->priv;
1610
1611 netdev_boot_setup_check(dev);
1612
1613 SET_MODULE_OWNER(dev);
1614 dev->flags = 0;
1615 dev->type = 0xFFFF;
1616 dev->hard_header_len = 0;
1617 dev->addr_len = 0;
1618 dev->mtu = SDLA_MAX_MTU;
1619
1620 dev->open = sdla_open;
1621 dev->stop = sdla_close;
1622 dev->do_ioctl = sdla_ioctl;
1623 dev->set_config = sdla_set_config;
1624 dev->get_stats = sdla_stats;
1625 dev->hard_start_xmit = sdla_transmit;
1626 dev->change_mtu = sdla_change_mtu;
1627
1628 flp->activate = sdla_activate;
1629 flp->deactivate = sdla_deactivate;
1630 flp->assoc = sdla_assoc;
1631 flp->deassoc = sdla_deassoc;
1632 flp->dlci_conf = sdla_dlci_conf;
1633
1634 init_timer(&flp->timer);
1635 flp->timer.expires = 1;
1636 flp->timer.data = (unsigned long) dev;
1637 flp->timer.function = sdla_poll;
1638}
1639
1640static struct net_device *sdla;
1641
1642static int __init init_sdla(void)
1643{
1644 int err;
1645
1646 printk("%s.\n", version);
1647
1648 sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
1649 if (!sdla)
1650 return -ENOMEM;
1651
1652 err = register_netdev(sdla);
1653 if (err)
1654 free_netdev(sdla);
1655
1656 return err;
1657}
1658
1659static void __exit exit_sdla(void)
1660{
1661 struct frad_local *flp = sdla->priv;
1662
1663 unregister_netdev(sdla);
1664 if (flp->initialized) {
1665 free_irq(sdla->irq, sdla);
1666 release_region(sdla->base_addr, SDLA_IO_EXTENTS);
1667 }
1668 del_timer_sync(&flp->timer);
1669 free_netdev(sdla);
1670}
1671
1672MODULE_LICENSE("GPL");
1673
1674module_init(init_sdla);
1675module_exit(exit_sdla);