blob: 6a485f0556f4b70a5815740f80a80cf457c8d8b0 [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
David Howells7d12e782006-10-05 14:55:46 +0100870static irqreturn_t sdla_isr(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871{
872 struct net_device *dev;
873 struct frad_local *flp;
874 char byte;
875
876 dev = dev_id;
877
Jeff Garzikc31f28e2006-10-06 14:56:04 -0400878 flp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880 if (!flp->initialized)
881 {
882 printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", dev->name, irq);
883 return IRQ_NONE;
884 }
885
886 byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
887 switch (byte)
888 {
889 case SDLA_INTR_RX:
890 sdla_receive(dev);
891 break;
892
893 /* the command will get an error return, which is processed above */
894 case SDLA_INTR_MODEM:
895 case SDLA_INTR_STATUS:
896 sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
897 break;
898
899 case SDLA_INTR_TX:
900 case SDLA_INTR_COMPLETE:
901 case SDLA_INTR_TIMER:
902 printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
903 break;
904 }
905
906 /* the S502E requires a manual acknowledgement of the interrupt */
907 if (flp->type == SDLA_S502E)
908 {
909 flp->state &= ~SDLA_S502E_INTACK;
910 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
911 flp->state |= SDLA_S502E_INTACK;
912 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
913 }
914
915 /* this clears the byte, informing the Z80 we're done */
916 byte = 0;
917 sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
918 return IRQ_HANDLED;
919}
920
921static void sdla_poll(unsigned long device)
922{
923 struct net_device *dev;
924 struct frad_local *flp;
925
926 dev = (struct net_device *) device;
927 flp = dev->priv;
928
929 if (sdla_byte(dev, SDLA_502_RCV_BUF))
930 sdla_receive(dev);
931
932 flp->timer.expires = 1;
933 add_timer(&flp->timer);
934}
935
936static int sdla_close(struct net_device *dev)
937{
938 struct frad_local *flp;
939 struct intr_info intr;
940 int len, i;
941 short dlcis[CONFIG_DLCI_MAX];
942
943 flp = dev->priv;
944
945 len = 0;
946 for(i=0;i<CONFIG_DLCI_MAX;i++)
947 if (flp->dlci[i])
948 dlcis[len++] = abs(flp->dlci[i]);
949 len *= 2;
950
951 if (flp->config.station == FRAD_STATION_NODE)
952 {
953 for(i=0;i<CONFIG_DLCI_MAX;i++)
954 if (flp->dlci[i] > 0)
955 sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
956 sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
957 }
958
959 memset(&intr, 0, sizeof(intr));
960 /* let's start up the reception */
961 switch(flp->type)
962 {
963 case SDLA_S502A:
964 del_timer(&flp->timer);
965 break;
966
967 case SDLA_S502E:
968 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
969 flp->state &= ~SDLA_S502E_INTACK;
970 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
971 break;
972
973 case SDLA_S507:
974 break;
975
976 case SDLA_S508:
977 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
978 flp->state &= ~SDLA_S508_INTEN;
979 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
980 break;
981 }
982
983 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
984
985 netif_stop_queue(dev);
986
987 return(0);
988}
989
990struct conf_data {
991 struct frad_conf config;
992 short dlci[CONFIG_DLCI_MAX];
993};
994
995static int sdla_open(struct net_device *dev)
996{
997 struct frad_local *flp;
998 struct dlci_local *dlp;
999 struct conf_data data;
1000 struct intr_info intr;
1001 int len, i;
1002 char byte;
1003
1004 flp = dev->priv;
1005
1006 if (!flp->initialized)
1007 return(-EPERM);
1008
1009 if (!flp->configured)
1010 return(-EPERM);
1011
1012 /* time to send in the configuration */
1013 len = 0;
1014 for(i=0;i<CONFIG_DLCI_MAX;i++)
1015 if (flp->dlci[i])
1016 data.dlci[len++] = abs(flp->dlci[i]);
1017 len *= 2;
1018
1019 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1020 len += sizeof(struct frad_conf);
1021
1022 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1023 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1024
1025 if (flp->type == SDLA_S508)
1026 flp->buffer = 0;
1027
1028 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1029
1030 /* let's start up the reception */
1031 memset(&intr, 0, sizeof(intr));
1032 switch(flp->type)
1033 {
1034 case SDLA_S502A:
1035 flp->timer.expires = 1;
1036 add_timer(&flp->timer);
1037 break;
1038
1039 case SDLA_S502E:
1040 flp->state |= SDLA_S502E_ENABLE;
1041 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1042 flp->state |= SDLA_S502E_INTACK;
1043 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1044 byte = 0;
1045 sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
1046 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1047 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
1048 break;
1049
1050 case SDLA_S507:
1051 break;
1052
1053 case SDLA_S508:
1054 flp->state |= SDLA_S508_INTEN;
1055 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1056 byte = 0;
1057 sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
1058 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1059 intr.irq = dev->irq;
1060 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
1061 break;
1062 }
1063
1064 if (flp->config.station == FRAD_STATION_CPE)
1065 {
1066 byte = SDLA_ICS_STATUS_ENQ;
1067 sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
1068 }
1069 else
1070 {
1071 sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
1072 for(i=0;i<CONFIG_DLCI_MAX;i++)
1073 if (flp->dlci[i] > 0)
1074 sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
1075 }
1076
1077 /* configure any specific DLCI settings */
1078 for(i=0;i<CONFIG_DLCI_MAX;i++)
1079 if (flp->dlci[i])
1080 {
1081 dlp = flp->master[i]->priv;
1082 if (dlp->configured)
1083 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
1084 }
1085
1086 netif_start_queue(dev);
1087
1088 return(0);
1089}
1090
1091static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
1092{
1093 struct frad_local *flp;
1094 struct conf_data data;
1095 int i;
1096 short size;
1097
1098 if (dev->type == 0xFFFF)
1099 return(-EUNATCH);
1100
1101 flp = dev->priv;
1102
1103 if (!get)
1104 {
1105 if (netif_running(dev))
1106 return(-EBUSY);
1107
1108 if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
1109 return -EFAULT;
1110
1111 if (data.config.station & ~FRAD_STATION_NODE)
1112 return(-EINVAL);
1113
1114 if (data.config.flags & ~FRAD_VALID_FLAGS)
1115 return(-EINVAL);
1116
1117 if ((data.config.kbaud < 0) ||
1118 ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
1119 return(-EINVAL);
1120
1121 if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
1122 return(-EINVAL);
1123
1124 if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
1125 return(-EINVAL);
1126
1127 if ((data.config.T391 < 5) || (data.config.T391 > 30))
1128 return(-EINVAL);
1129
1130 if ((data.config.T392 < 5) || (data.config.T392 > 30))
1131 return(-EINVAL);
1132
1133 if ((data.config.N391 < 1) || (data.config.N391 > 255))
1134 return(-EINVAL);
1135
1136 if ((data.config.N392 < 1) || (data.config.N392 > 10))
1137 return(-EINVAL);
1138
1139 if ((data.config.N393 < 1) || (data.config.N393 > 10))
1140 return(-EINVAL);
1141
1142 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1143 flp->config.flags |= SDLA_DIRECT_RECV;
1144
1145 if (flp->type == SDLA_S508)
1146 flp->config.flags |= SDLA_TX70_RX30;
1147
1148 if (dev->mtu != flp->config.mtu)
1149 {
1150 /* this is required to change the MTU */
1151 dev->mtu = flp->config.mtu;
1152 for(i=0;i<CONFIG_DLCI_MAX;i++)
1153 if (flp->master[i])
1154 flp->master[i]->mtu = flp->config.mtu;
1155 }
1156
1157 flp->config.mtu += sizeof(struct frhdr);
1158
1159 /* off to the races! */
1160 if (!flp->configured)
1161 sdla_start(dev);
1162
1163 flp->configured = 1;
1164 }
1165 else
1166 {
1167 /* no sense reading if the CPU isn't started */
1168 if (netif_running(dev))
1169 {
1170 size = sizeof(data);
1171 if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
1172 return(-EIO);
1173 }
1174 else
1175 if (flp->configured)
1176 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1177 else
1178 memset(&data.config, 0, sizeof(struct frad_conf));
1179
1180 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1181 data.config.flags &= FRAD_VALID_FLAGS;
1182 data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu;
1183 return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
1184 }
1185
1186 return(0);
1187}
1188
1189static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
1190{
1191 struct sdla_mem mem;
1192 char *temp;
1193
1194 if(copy_from_user(&mem, info, sizeof(mem)))
1195 return -EFAULT;
1196
1197 if (read)
1198 {
1199 temp = kmalloc(mem.len, GFP_KERNEL);
1200 if (!temp)
1201 return(-ENOMEM);
1202 memset(temp, 0, mem.len);
1203 sdla_read(dev, mem.addr, temp, mem.len);
1204 if(copy_to_user(mem.data, temp, mem.len))
1205 {
1206 kfree(temp);
1207 return -EFAULT;
1208 }
1209 kfree(temp);
1210 }
1211 else
1212 {
1213 temp = kmalloc(mem.len, GFP_KERNEL);
1214 if (!temp)
1215 return(-ENOMEM);
1216 if(copy_from_user(temp, mem.data, mem.len))
1217 {
1218 kfree(temp);
1219 return -EFAULT;
1220 }
1221 sdla_write(dev, mem.addr, temp, mem.len);
1222 kfree(temp);
1223 }
1224 return(0);
1225}
1226
1227static int sdla_reconfig(struct net_device *dev)
1228{
1229 struct frad_local *flp;
1230 struct conf_data data;
1231 int i, len;
1232
1233 flp = dev->priv;
1234
1235 len = 0;
1236 for(i=0;i<CONFIG_DLCI_MAX;i++)
1237 if (flp->dlci[i])
1238 data.dlci[len++] = flp->dlci[i];
1239 len *= 2;
1240
1241 memcpy(&data, &flp->config, sizeof(struct frad_conf));
1242 len += sizeof(struct frad_conf);
1243
1244 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1245 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1246 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1247
1248 return(0);
1249}
1250
1251static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1252{
1253 struct frad_local *flp;
1254
1255 if(!capable(CAP_NET_ADMIN))
1256 return -EPERM;
1257
1258 flp = dev->priv;
1259
1260 if (!flp->initialized)
1261 return(-EINVAL);
1262
1263 switch (cmd)
1264 {
1265 case FRAD_GET_CONF:
1266 case FRAD_SET_CONF:
1267 return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
1268
1269 case SDLA_IDENTIFY:
1270 ifr->ifr_flags = flp->type;
1271 break;
1272
1273 case SDLA_CPUSPEED:
1274 return(sdla_cpuspeed(dev, ifr));
1275
1276/* ==========================================================
1277NOTE: This is rather a useless action right now, as the
1278 current driver does not support protocols other than
1279 FR. However, Sangoma has modules for a number of
1280 other protocols in the works.
1281============================================================*/
1282 case SDLA_PROTOCOL:
1283 if (flp->configured)
1284 return(-EALREADY);
1285
1286 switch (ifr->ifr_flags)
1287 {
1288 case ARPHRD_FRAD:
1289 dev->type = ifr->ifr_flags;
1290 break;
1291 default:
1292 return(-ENOPROTOOPT);
1293 }
1294 break;
1295
1296 case SDLA_CLEARMEM:
1297 sdla_clear(dev);
1298 break;
1299
1300 case SDLA_WRITEMEM:
1301 case SDLA_READMEM:
1302 if(!capable(CAP_SYS_RAWIO))
1303 return -EPERM;
1304 return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
1305
1306 case SDLA_START:
1307 sdla_start(dev);
1308 break;
1309
1310 case SDLA_STOP:
1311 sdla_stop(dev);
1312 break;
1313
1314 default:
1315 return(-EOPNOTSUPP);
1316 }
1317 return(0);
1318}
1319
Adrian Bunk7665a082005-09-09 23:17:28 -07001320static int sdla_change_mtu(struct net_device *dev, int new_mtu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321{
1322 struct frad_local *flp;
1323
1324 flp = dev->priv;
1325
1326 if (netif_running(dev))
1327 return(-EBUSY);
1328
1329 /* for now, you can't change the MTU! */
1330 return(-EOPNOTSUPP);
1331}
1332
Adrian Bunk7665a082005-09-09 23:17:28 -07001333static int sdla_set_config(struct net_device *dev, struct ifmap *map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334{
1335 struct frad_local *flp;
1336 int i;
1337 char byte;
1338 unsigned base;
1339 int err = -EINVAL;
1340
1341 flp = dev->priv;
1342
1343 if (flp->initialized)
1344 return(-EINVAL);
1345
1346 for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
1347 if (valid_port[i] == map->base_addr)
1348 break;
1349
1350 if (i == sizeof(valid_port) / sizeof(int))
1351 return(-EINVAL);
1352
1353 if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
1354 printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
1355 return(-EINVAL);
1356 }
1357 base = map->base_addr;
1358
1359 /* test for card types, S502A, S502E, S507, S508 */
1360 /* these tests shut down the card completely, so clear the state */
1361 flp->type = SDLA_UNKNOWN;
1362 flp->state = 0;
1363
1364 for(i=1;i<SDLA_IO_EXTENTS;i++)
1365 if (inb(base + i) != 0xFF)
1366 break;
1367
1368 if (i == SDLA_IO_EXTENTS) {
1369 outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
1370 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
1371 outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
1372 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
1373 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1374 flp->type = SDLA_S502E;
1375 goto got_type;
1376 }
1377 }
1378 }
1379
1380 for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
1381 if (inb(base + i) != byte)
1382 break;
1383
1384 if (i == SDLA_IO_EXTENTS) {
1385 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1386 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
1387 outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
1388 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
1389 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1390 flp->type = SDLA_S507;
1391 goto got_type;
1392 }
1393 }
1394 }
1395
1396 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1397 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
1398 outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
1399 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
1400 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1401 flp->type = SDLA_S508;
1402 goto got_type;
1403 }
1404 }
1405
1406 outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
1407 if (inb(base + SDLA_S502_STS) == 0x40) {
1408 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1409 if (inb(base + SDLA_S502_STS) == 0x40) {
1410 outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
1411 if (inb(base + SDLA_S502_STS) == 0x44) {
1412 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1413 flp->type = SDLA_S502A;
1414 goto got_type;
1415 }
1416 }
1417 }
1418
1419 printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1420 err = -ENODEV;
1421 goto fail;
1422
1423got_type:
1424 switch(base) {
1425 case 0x270:
1426 case 0x280:
1427 case 0x380:
1428 case 0x390:
1429 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1430 goto fail;
1431 }
1432
1433 switch (map->irq) {
1434 case 2:
1435 if (flp->type != SDLA_S502E)
1436 goto fail;
1437 break;
1438
1439 case 10:
1440 case 11:
1441 case 12:
1442 case 15:
1443 case 4:
1444 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1445 goto fail;
1446 break;
1447 case 3:
1448 case 5:
1449 case 7:
1450 if (flp->type == SDLA_S502A)
1451 goto fail;
1452 break;
1453
1454 default:
1455 goto fail;
1456 }
1457
1458 err = -EAGAIN;
1459 if (request_irq(dev->irq, &sdla_isr, 0, dev->name, dev))
1460 goto fail;
1461
1462 if (flp->type == SDLA_S507) {
1463 switch(dev->irq) {
1464 case 3:
1465 flp->state = SDLA_S507_IRQ3;
1466 break;
1467 case 4:
1468 flp->state = SDLA_S507_IRQ4;
1469 break;
1470 case 5:
1471 flp->state = SDLA_S507_IRQ5;
1472 break;
1473 case 7:
1474 flp->state = SDLA_S507_IRQ7;
1475 break;
1476 case 10:
1477 flp->state = SDLA_S507_IRQ10;
1478 break;
1479 case 11:
1480 flp->state = SDLA_S507_IRQ11;
1481 break;
1482 case 12:
1483 flp->state = SDLA_S507_IRQ12;
1484 break;
1485 case 15:
1486 flp->state = SDLA_S507_IRQ15;
1487 break;
1488 }
1489 }
1490
1491 for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
1492 if (valid_mem[i] == map->mem_start)
1493 break;
1494
1495 err = -EINVAL;
1496 if (i == sizeof(valid_mem) / sizeof(int))
1497 goto fail2;
1498
1499 if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
1500 goto fail2;
1501
1502 if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
1503 goto fail2;
1504
1505 if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
1506 goto fail2;
1507
1508 byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1509 byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1510 switch(flp->type) {
1511 case SDLA_S502A:
1512 case SDLA_S502E:
1513 switch (map->mem_start >> 16) {
1514 case 0x0A:
1515 byte |= SDLA_S502_SEG_A;
1516 break;
1517 case 0x0C:
1518 byte |= SDLA_S502_SEG_C;
1519 break;
1520 case 0x0D:
1521 byte |= SDLA_S502_SEG_D;
1522 break;
1523 case 0x0E:
1524 byte |= SDLA_S502_SEG_E;
1525 break;
1526 }
1527 break;
1528 case SDLA_S507:
1529 switch (map->mem_start >> 16) {
1530 case 0x0A:
1531 byte |= SDLA_S507_SEG_A;
1532 break;
1533 case 0x0B:
1534 byte |= SDLA_S507_SEG_B;
1535 break;
1536 case 0x0C:
1537 byte |= SDLA_S507_SEG_C;
1538 break;
1539 case 0x0E:
1540 byte |= SDLA_S507_SEG_E;
1541 break;
1542 }
1543 break;
1544 case SDLA_S508:
1545 switch (map->mem_start >> 16) {
1546 case 0x0A:
1547 byte |= SDLA_S508_SEG_A;
1548 break;
1549 case 0x0C:
1550 byte |= SDLA_S508_SEG_C;
1551 break;
1552 case 0x0D:
1553 byte |= SDLA_S508_SEG_D;
1554 break;
1555 case 0x0E:
1556 byte |= SDLA_S508_SEG_E;
1557 break;
1558 }
1559 break;
1560 }
1561
1562 /* set the memory bits, and enable access */
1563 outb(byte, base + SDLA_REG_PC_WINDOW);
1564
1565 switch(flp->type)
1566 {
1567 case SDLA_S502E:
1568 flp->state = SDLA_S502E_ENABLE;
1569 break;
1570 case SDLA_S507:
1571 flp->state |= SDLA_MEMEN;
1572 break;
1573 case SDLA_S508:
1574 flp->state = SDLA_MEMEN;
1575 break;
1576 }
1577 outb(flp->state, base + SDLA_REG_CONTROL);
1578
1579 dev->irq = map->irq;
1580 dev->base_addr = base;
1581 dev->mem_start = map->mem_start;
1582 dev->mem_end = dev->mem_start + 0x2000;
1583 flp->initialized = 1;
1584 return 0;
1585
1586fail2:
1587 free_irq(map->irq, dev);
1588fail:
1589 release_region(base, SDLA_IO_EXTENTS);
1590 return err;
1591}
1592
1593static struct net_device_stats *sdla_stats(struct net_device *dev)
1594{
1595 struct frad_local *flp;
1596 flp = dev->priv;
1597
1598 return(&flp->stats);
1599}
1600
1601static void setup_sdla(struct net_device *dev)
1602{
1603 struct frad_local *flp = dev->priv;
1604
1605 netdev_boot_setup_check(dev);
1606
1607 SET_MODULE_OWNER(dev);
1608 dev->flags = 0;
1609 dev->type = 0xFFFF;
1610 dev->hard_header_len = 0;
1611 dev->addr_len = 0;
1612 dev->mtu = SDLA_MAX_MTU;
1613
1614 dev->open = sdla_open;
1615 dev->stop = sdla_close;
1616 dev->do_ioctl = sdla_ioctl;
1617 dev->set_config = sdla_set_config;
1618 dev->get_stats = sdla_stats;
1619 dev->hard_start_xmit = sdla_transmit;
1620 dev->change_mtu = sdla_change_mtu;
1621
1622 flp->activate = sdla_activate;
1623 flp->deactivate = sdla_deactivate;
1624 flp->assoc = sdla_assoc;
1625 flp->deassoc = sdla_deassoc;
1626 flp->dlci_conf = sdla_dlci_conf;
1627
1628 init_timer(&flp->timer);
1629 flp->timer.expires = 1;
1630 flp->timer.data = (unsigned long) dev;
1631 flp->timer.function = sdla_poll;
1632}
1633
1634static struct net_device *sdla;
1635
1636static int __init init_sdla(void)
1637{
1638 int err;
1639
1640 printk("%s.\n", version);
1641
1642 sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
1643 if (!sdla)
1644 return -ENOMEM;
1645
1646 err = register_netdev(sdla);
1647 if (err)
1648 free_netdev(sdla);
1649
1650 return err;
1651}
1652
1653static void __exit exit_sdla(void)
1654{
1655 struct frad_local *flp = sdla->priv;
1656
1657 unregister_netdev(sdla);
1658 if (flp->initialized) {
1659 free_irq(sdla->irq, sdla);
1660 release_region(sdla->base_addr, SDLA_IO_EXTENTS);
1661 }
1662 del_timer_sync(&flp->timer);
1663 free_netdev(sdla);
1664}
1665
1666MODULE_LICENSE("GPL");
1667
1668module_init(init_sdla);
1669module_exit(exit_sdla);