Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[linux-2.6-block.git] / drivers / net / wan / sdla.c
CommitLineData
1da177e4
LT
1/*
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
1da177e4
LT
35#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
96ebb928 62static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
1da177e4 63
96ebb928 64static unsigned int valid_mem[] = {
1da177e4
LT
65 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
7665a089 184static void sdla_stop(struct net_device *dev)
1da177e4
LT
185{
186 struct frad_local *flp;
187
8f15ea42 188 flp = netdev_priv(dev);
1da177e4
LT
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
7665a089 211static void sdla_start(struct net_device *dev)
1da177e4
LT
212{
213 struct frad_local *flp;
214
8f15ea42 215 flp = netdev_priv(dev);
1da177e4
LT
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
7665a089 249static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
1da177e4
LT
250{
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{
6a878184
JB
331 short dlci;
332 char flags;
333} __attribute__((packed));
1da177e4
LT
334
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
8f15ea42 435 flp = netdev_priv(dev);
1da177e4
LT
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
7665a089 507static int sdla_activate(struct net_device *slave, struct net_device *master)
1da177e4
LT
508{
509 struct frad_local *flp;
510 int i;
511
8f15ea42 512 flp = netdev_priv(slave);
1da177e4
LT
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
7665a089 529static int sdla_deactivate(struct net_device *slave, struct net_device *master)
1da177e4
LT
530{
531 struct frad_local *flp;
532 int i;
533
8f15ea42 534 flp = netdev_priv(slave);
1da177e4
LT
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
7665a089 551static int sdla_assoc(struct net_device *slave, struct net_device *master)
1da177e4
LT
552{
553 struct frad_local *flp;
554 int i;
555
556 if (master->type != ARPHRD_DLCI)
557 return(-EINVAL);
558
8f15ea42 559 flp = netdev_priv(slave);
1da177e4
LT
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
7665a089 587static int sdla_deassoc(struct net_device *slave, struct net_device *master)
1da177e4
LT
588{
589 struct frad_local *flp;
590 int i;
591
8f15ea42 592 flp = netdev_priv(slave);
1da177e4
LT
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
7665a089 615static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
1da177e4
LT
616{
617 struct frad_local *flp;
618 struct dlci_local *dlp;
619 int i;
620 short len, ret;
621
8f15ea42 622 flp = netdev_priv(slave);
1da177e4
LT
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
8f15ea42 631 dlp = netdev_priv(master);
1da177e4
LT
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!! */
d71a6749 654static netdev_tx_t sdla_transmit(struct sk_buff *skb,
38482428 655 struct net_device *dev)
1da177e4
LT
656{
657 struct frad_local *flp;
658 int ret, addr, accept, i;
659 short size;
660 unsigned long flags;
661 struct buf_entry *pbuf;
662
8f15ea42 663 flp = netdev_priv(dev);
1da177e4
LT
664 ret = 0;
665 accept = 1;
666
667 netif_stop_queue(dev);
668
669 /*
670 * stupid GateD insists on setting up the multicast router thru us
671 * and we're ill equipped to handle a non Frame Relay packet at this
672 * time!
673 */
674
675 accept = 1;
676 switch (dev->type)
677 {
678 case ARPHRD_FRAD:
679 if (skb->dev->type != ARPHRD_DLCI)
680 {
681 printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type);
682 accept = 0;
683 }
684 break;
685 default:
686 printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type);
687 accept = 0;
688 break;
689 }
690 if (accept)
691 {
692 /* this is frame specific, but till there's a PPP module, it's the default */
693 switch (flp->type)
694 {
695 case SDLA_S502A:
696 case SDLA_S502E:
697 ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
698 break;
699 case SDLA_S508:
700 size = sizeof(addr);
701 ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
702 if (ret == SDLA_RET_OK)
703 {
704
705 spin_lock_irqsave(&sdla_lock, flags);
706 SDLA_WINDOW(dev, addr);
707 pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
708 __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
709 SDLA_WINDOW(dev, addr);
710 pbuf->opp_flag = 1;
711 spin_unlock_irqrestore(&sdla_lock, flags);
712 }
713 break;
714 }
38482428 715
1da177e4
LT
716 switch (ret)
717 {
718 case SDLA_RET_OK:
ac99533f 719 dev->stats.tx_packets++;
1da177e4
LT
720 break;
721
722 case SDLA_RET_CIR_OVERFLOW:
723 case SDLA_RET_BUF_OVERSIZE:
724 case SDLA_RET_NO_BUFS:
ac99533f 725 dev->stats.tx_dropped++;
1da177e4
LT
726 break;
727
728 default:
ac99533f 729 dev->stats.tx_errors++;
1da177e4
LT
730 break;
731 }
732 }
733 netif_wake_queue(dev);
734 for(i=0;i<CONFIG_DLCI_MAX;i++)
735 {
736 if(flp->master[i]!=NULL)
737 netif_wake_queue(flp->master[i]);
738 }
38482428
SH
739
740 dev_kfree_skb(skb);
d71a6749 741 return NETDEV_TX_OK;
1da177e4
LT
742}
743
744static void sdla_receive(struct net_device *dev)
745{
746 struct net_device *master;
747 struct frad_local *flp;
748 struct dlci_local *dlp;
749 struct sk_buff *skb;
750
751 struct sdla_cmd *cmd;
752 struct buf_info *pbufi;
753 struct buf_entry *pbuf;
754
755 unsigned long flags;
756 int i=0, received, success, addr, buf_base, buf_top;
757 short dlci, len, len2, split;
758
8f15ea42 759 flp = netdev_priv(dev);
1da177e4
LT
760 success = 1;
761 received = addr = buf_top = buf_base = 0;
762 len = dlci = 0;
763 skb = NULL;
764 master = NULL;
765 cmd = NULL;
766 pbufi = NULL;
767 pbuf = NULL;
768
769 spin_lock_irqsave(&sdla_lock, flags);
770
771 switch (flp->type)
772 {
773 case SDLA_S502A:
774 case SDLA_S502E:
775 cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & SDLA_ADDR_MASK));
776 SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
777 success = cmd->opp_flag;
778 if (!success)
779 break;
780
781 dlci = cmd->dlci;
782 len = cmd->length;
783 break;
784
785 case SDLA_S508:
786 pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & SDLA_ADDR_MASK));
787 SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
788 pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & SDLA_ADDR_MASK));
789 success = pbuf->opp_flag;
790 if (!success)
791 break;
792
793 buf_top = pbufi->buf_top;
794 buf_base = pbufi->buf_base;
795 dlci = pbuf->dlci;
796 len = pbuf->length;
797 addr = pbuf->buf_addr;
798 break;
799 }
800
801 /* common code, find the DLCI and get the SKB */
802 if (success)
803 {
804 for (i=0;i<CONFIG_DLCI_MAX;i++)
805 if (flp->dlci[i] == dlci)
806 break;
807
808 if (i == CONFIG_DLCI_MAX)
809 {
810 printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci);
ac99533f 811 dev->stats.rx_errors++;
1da177e4
LT
812 success = 0;
813 }
814 }
815
816 if (success)
817 {
818 master = flp->master[i];
819 skb = dev_alloc_skb(len + sizeof(struct frhdr));
820 if (skb == NULL)
821 {
822 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
ac99533f 823 dev->stats.rx_dropped++;
1da177e4
LT
824 success = 0;
825 }
826 else
827 skb_reserve(skb, sizeof(struct frhdr));
828 }
829
830 /* pick up the data */
831 switch (flp->type)
832 {
833 case SDLA_S502A:
834 case SDLA_S502E:
835 if (success)
836 __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
837
838 SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
839 cmd->opp_flag = 0;
840 break;
841
842 case SDLA_S508:
843 if (success)
844 {
845 /* is this buffer split off the end of the internal ring buffer */
846 split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
847 len2 = len - split;
848
849 __sdla_read(dev, addr, skb_put(skb, len2), len2);
850 if (split)
851 __sdla_read(dev, buf_base, skb_put(skb, split), split);
852 }
853
854 /* increment the buffer we're looking at */
855 SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
856 flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
857 pbuf->opp_flag = 0;
858 break;
859 }
860
861 if (success)
862 {
ac99533f 863 dev->stats.rx_packets++;
8f15ea42 864 dlp = netdev_priv(master);
1da177e4
LT
865 (*dlp->receive)(skb, master);
866 }
867
868 spin_unlock_irqrestore(&sdla_lock, flags);
869}
870
28fc1f5a 871static irqreturn_t sdla_isr(int dummy, void *dev_id)
1da177e4
LT
872{
873 struct net_device *dev;
874 struct frad_local *flp;
875 char byte;
876
877 dev = dev_id;
878
c31f28e7 879 flp = netdev_priv(dev);
1da177e4
LT
880
881 if (!flp->initialized)
882 {
28fc1f5a
JG
883 printk(KERN_WARNING "%s: irq %d for uninitialized device.\n",
884 dev->name, dev->irq);
1da177e4
LT
885 return IRQ_NONE;
886 }
887
888 byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
889 switch (byte)
890 {
891 case SDLA_INTR_RX:
892 sdla_receive(dev);
893 break;
894
895 /* the command will get an error return, which is processed above */
896 case SDLA_INTR_MODEM:
897 case SDLA_INTR_STATUS:
898 sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
899 break;
900
901 case SDLA_INTR_TX:
902 case SDLA_INTR_COMPLETE:
903 case SDLA_INTR_TIMER:
904 printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
905 break;
906 }
907
908 /* the S502E requires a manual acknowledgement of the interrupt */
909 if (flp->type == SDLA_S502E)
910 {
911 flp->state &= ~SDLA_S502E_INTACK;
912 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
913 flp->state |= SDLA_S502E_INTACK;
914 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
915 }
916
917 /* this clears the byte, informing the Z80 we're done */
918 byte = 0;
919 sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
920 return IRQ_HANDLED;
921}
922
923static void sdla_poll(unsigned long device)
924{
925 struct net_device *dev;
926 struct frad_local *flp;
927
928 dev = (struct net_device *) device;
8f15ea42 929 flp = netdev_priv(dev);
1da177e4
LT
930
931 if (sdla_byte(dev, SDLA_502_RCV_BUF))
932 sdla_receive(dev);
933
934 flp->timer.expires = 1;
935 add_timer(&flp->timer);
936}
937
938static int sdla_close(struct net_device *dev)
939{
940 struct frad_local *flp;
941 struct intr_info intr;
942 int len, i;
943 short dlcis[CONFIG_DLCI_MAX];
944
8f15ea42 945 flp = netdev_priv(dev);
1da177e4
LT
946
947 len = 0;
948 for(i=0;i<CONFIG_DLCI_MAX;i++)
949 if (flp->dlci[i])
950 dlcis[len++] = abs(flp->dlci[i]);
951 len *= 2;
952
953 if (flp->config.station == FRAD_STATION_NODE)
954 {
955 for(i=0;i<CONFIG_DLCI_MAX;i++)
956 if (flp->dlci[i] > 0)
957 sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
958 sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
959 }
960
961 memset(&intr, 0, sizeof(intr));
962 /* let's start up the reception */
963 switch(flp->type)
964 {
965 case SDLA_S502A:
966 del_timer(&flp->timer);
967 break;
968
969 case SDLA_S502E:
970 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
971 flp->state &= ~SDLA_S502E_INTACK;
972 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
973 break;
974
975 case SDLA_S507:
976 break;
977
978 case SDLA_S508:
979 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
980 flp->state &= ~SDLA_S508_INTEN;
981 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
982 break;
983 }
984
985 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
986
987 netif_stop_queue(dev);
988
989 return(0);
990}
991
992struct conf_data {
993 struct frad_conf config;
994 short dlci[CONFIG_DLCI_MAX];
995};
996
997static int sdla_open(struct net_device *dev)
998{
999 struct frad_local *flp;
1000 struct dlci_local *dlp;
1001 struct conf_data data;
1002 struct intr_info intr;
1003 int len, i;
1004 char byte;
1005
8f15ea42 1006 flp = netdev_priv(dev);
1da177e4
LT
1007
1008 if (!flp->initialized)
1009 return(-EPERM);
1010
1011 if (!flp->configured)
1012 return(-EPERM);
1013
1014 /* time to send in the configuration */
1015 len = 0;
1016 for(i=0;i<CONFIG_DLCI_MAX;i++)
1017 if (flp->dlci[i])
1018 data.dlci[len++] = abs(flp->dlci[i]);
1019 len *= 2;
1020
1021 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1022 len += sizeof(struct frad_conf);
1023
1024 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1025 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1026
1027 if (flp->type == SDLA_S508)
1028 flp->buffer = 0;
1029
1030 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1031
1032 /* let's start up the reception */
1033 memset(&intr, 0, sizeof(intr));
1034 switch(flp->type)
1035 {
1036 case SDLA_S502A:
1037 flp->timer.expires = 1;
1038 add_timer(&flp->timer);
1039 break;
1040
1041 case SDLA_S502E:
1042 flp->state |= SDLA_S502E_ENABLE;
1043 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1044 flp->state |= SDLA_S502E_INTACK;
1045 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1046 byte = 0;
1047 sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
1048 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1049 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
1050 break;
1051
1052 case SDLA_S507:
1053 break;
1054
1055 case SDLA_S508:
1056 flp->state |= SDLA_S508_INTEN;
1057 outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1058 byte = 0;
1059 sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
1060 intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1061 intr.irq = dev->irq;
1062 sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
1063 break;
1064 }
1065
1066 if (flp->config.station == FRAD_STATION_CPE)
1067 {
1068 byte = SDLA_ICS_STATUS_ENQ;
1069 sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
1070 }
1071 else
1072 {
1073 sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
1074 for(i=0;i<CONFIG_DLCI_MAX;i++)
1075 if (flp->dlci[i] > 0)
1076 sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
1077 }
1078
1079 /* configure any specific DLCI settings */
1080 for(i=0;i<CONFIG_DLCI_MAX;i++)
1081 if (flp->dlci[i])
1082 {
8f15ea42 1083 dlp = netdev_priv(flp->master[i]);
1da177e4
LT
1084 if (dlp->configured)
1085 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
1086 }
1087
1088 netif_start_queue(dev);
1089
1090 return(0);
1091}
1092
1093static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
1094{
1095 struct frad_local *flp;
1096 struct conf_data data;
1097 int i;
1098 short size;
1099
1100 if (dev->type == 0xFFFF)
1101 return(-EUNATCH);
1102
8f15ea42 1103 flp = netdev_priv(dev);
1da177e4
LT
1104
1105 if (!get)
1106 {
1107 if (netif_running(dev))
1108 return(-EBUSY);
1109
1110 if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
1111 return -EFAULT;
1112
1113 if (data.config.station & ~FRAD_STATION_NODE)
1114 return(-EINVAL);
1115
1116 if (data.config.flags & ~FRAD_VALID_FLAGS)
1117 return(-EINVAL);
1118
1119 if ((data.config.kbaud < 0) ||
1120 ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
1121 return(-EINVAL);
1122
1123 if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
1124 return(-EINVAL);
1125
1126 if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
1127 return(-EINVAL);
1128
1129 if ((data.config.T391 < 5) || (data.config.T391 > 30))
1130 return(-EINVAL);
1131
1132 if ((data.config.T392 < 5) || (data.config.T392 > 30))
1133 return(-EINVAL);
1134
1135 if ((data.config.N391 < 1) || (data.config.N391 > 255))
1136 return(-EINVAL);
1137
1138 if ((data.config.N392 < 1) || (data.config.N392 > 10))
1139 return(-EINVAL);
1140
1141 if ((data.config.N393 < 1) || (data.config.N393 > 10))
1142 return(-EINVAL);
1143
1144 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1145 flp->config.flags |= SDLA_DIRECT_RECV;
1146
1147 if (flp->type == SDLA_S508)
1148 flp->config.flags |= SDLA_TX70_RX30;
1149
1150 if (dev->mtu != flp->config.mtu)
1151 {
1152 /* this is required to change the MTU */
1153 dev->mtu = flp->config.mtu;
1154 for(i=0;i<CONFIG_DLCI_MAX;i++)
1155 if (flp->master[i])
1156 flp->master[i]->mtu = flp->config.mtu;
1157 }
1158
1159 flp->config.mtu += sizeof(struct frhdr);
1160
1161 /* off to the races! */
1162 if (!flp->configured)
1163 sdla_start(dev);
1164
1165 flp->configured = 1;
1166 }
1167 else
1168 {
1169 /* no sense reading if the CPU isn't started */
1170 if (netif_running(dev))
1171 {
1172 size = sizeof(data);
1173 if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
1174 return(-EIO);
1175 }
1176 else
1177 if (flp->configured)
1178 memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
1179 else
1180 memset(&data.config, 0, sizeof(struct frad_conf));
1181
1182 memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1183 data.config.flags &= FRAD_VALID_FLAGS;
1184 data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu;
1185 return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
1186 }
1187
1188 return(0);
1189}
1190
1191static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
1192{
1193 struct sdla_mem mem;
1194 char *temp;
1195
1196 if(copy_from_user(&mem, info, sizeof(mem)))
1197 return -EFAULT;
1198
1199 if (read)
1200 {
dd00cc48 1201 temp = kzalloc(mem.len, GFP_KERNEL);
1da177e4
LT
1202 if (!temp)
1203 return(-ENOMEM);
1da177e4
LT
1204 sdla_read(dev, mem.addr, temp, mem.len);
1205 if(copy_to_user(mem.data, temp, mem.len))
1206 {
1207 kfree(temp);
1208 return -EFAULT;
1209 }
1210 kfree(temp);
1211 }
1212 else
1213 {
1214 temp = kmalloc(mem.len, GFP_KERNEL);
1215 if (!temp)
1216 return(-ENOMEM);
1217 if(copy_from_user(temp, mem.data, mem.len))
1218 {
1219 kfree(temp);
1220 return -EFAULT;
1221 }
1222 sdla_write(dev, mem.addr, temp, mem.len);
1223 kfree(temp);
1224 }
1225 return(0);
1226}
1227
1228static int sdla_reconfig(struct net_device *dev)
1229{
1230 struct frad_local *flp;
1231 struct conf_data data;
1232 int i, len;
1233
8f15ea42 1234 flp = netdev_priv(dev);
1da177e4
LT
1235
1236 len = 0;
1237 for(i=0;i<CONFIG_DLCI_MAX;i++)
1238 if (flp->dlci[i])
1239 data.dlci[len++] = flp->dlci[i];
1240 len *= 2;
1241
1242 memcpy(&data, &flp->config, sizeof(struct frad_conf));
1243 len += sizeof(struct frad_conf);
1244
1245 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1246 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1247 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1248
1249 return(0);
1250}
1251
1252static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1253{
1254 struct frad_local *flp;
1255
1256 if(!capable(CAP_NET_ADMIN))
1257 return -EPERM;
1258
8f15ea42 1259 flp = netdev_priv(dev);
1da177e4
LT
1260
1261 if (!flp->initialized)
1262 return(-EINVAL);
1263
1264 switch (cmd)
1265 {
1266 case FRAD_GET_CONF:
1267 case FRAD_SET_CONF:
1268 return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
1269
1270 case SDLA_IDENTIFY:
1271 ifr->ifr_flags = flp->type;
1272 break;
1273
1274 case SDLA_CPUSPEED:
1275 return(sdla_cpuspeed(dev, ifr));
1276
1277/* ==========================================================
1278NOTE: This is rather a useless action right now, as the
1279 current driver does not support protocols other than
1280 FR. However, Sangoma has modules for a number of
1281 other protocols in the works.
1282============================================================*/
1283 case SDLA_PROTOCOL:
1284 if (flp->configured)
1285 return(-EALREADY);
1286
1287 switch (ifr->ifr_flags)
1288 {
1289 case ARPHRD_FRAD:
1290 dev->type = ifr->ifr_flags;
1291 break;
1292 default:
1293 return(-ENOPROTOOPT);
1294 }
1295 break;
1296
1297 case SDLA_CLEARMEM:
1298 sdla_clear(dev);
1299 break;
1300
1301 case SDLA_WRITEMEM:
1302 case SDLA_READMEM:
1303 if(!capable(CAP_SYS_RAWIO))
1304 return -EPERM;
1305 return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
1306
1307 case SDLA_START:
1308 sdla_start(dev);
1309 break;
1310
1311 case SDLA_STOP:
1312 sdla_stop(dev);
1313 break;
1314
1315 default:
1316 return(-EOPNOTSUPP);
1317 }
1318 return(0);
1319}
1320
7665a089 1321static int sdla_change_mtu(struct net_device *dev, int new_mtu)
1da177e4
LT
1322{
1323 struct frad_local *flp;
1324
8f15ea42 1325 flp = netdev_priv(dev);
1da177e4
LT
1326
1327 if (netif_running(dev))
1328 return(-EBUSY);
1329
1330 /* for now, you can't change the MTU! */
1331 return(-EOPNOTSUPP);
1332}
1333
7665a089 1334static int sdla_set_config(struct net_device *dev, struct ifmap *map)
1da177e4
LT
1335{
1336 struct frad_local *flp;
1337 int i;
1338 char byte;
1339 unsigned base;
1340 int err = -EINVAL;
1341
8f15ea42 1342 flp = netdev_priv(dev);
1da177e4
LT
1343
1344 if (flp->initialized)
1345 return(-EINVAL);
1346
e9edda69 1347 for(i=0; i < ARRAY_SIZE(valid_port); i++)
1da177e4
LT
1348 if (valid_port[i] == map->base_addr)
1349 break;
1350
e9edda69 1351 if (i == ARRAY_SIZE(valid_port))
1da177e4
LT
1352 return(-EINVAL);
1353
1354 if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
1355 printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
1356 return(-EINVAL);
1357 }
1358 base = map->base_addr;
1359
1360 /* test for card types, S502A, S502E, S507, S508 */
1361 /* these tests shut down the card completely, so clear the state */
1362 flp->type = SDLA_UNKNOWN;
1363 flp->state = 0;
1364
1365 for(i=1;i<SDLA_IO_EXTENTS;i++)
1366 if (inb(base + i) != 0xFF)
1367 break;
1368
1369 if (i == SDLA_IO_EXTENTS) {
1370 outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
1371 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
1372 outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
1373 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
1374 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1375 flp->type = SDLA_S502E;
1376 goto got_type;
1377 }
1378 }
1379 }
1380
1381 for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
1382 if (inb(base + i) != byte)
1383 break;
1384
1385 if (i == SDLA_IO_EXTENTS) {
1386 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1387 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
1388 outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
1389 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
1390 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1391 flp->type = SDLA_S507;
1392 goto got_type;
1393 }
1394 }
1395 }
1396
1397 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1398 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
1399 outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
1400 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
1401 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1402 flp->type = SDLA_S508;
1403 goto got_type;
1404 }
1405 }
1406
1407 outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
1408 if (inb(base + SDLA_S502_STS) == 0x40) {
1409 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1410 if (inb(base + SDLA_S502_STS) == 0x40) {
1411 outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
1412 if (inb(base + SDLA_S502_STS) == 0x44) {
1413 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1414 flp->type = SDLA_S502A;
1415 goto got_type;
1416 }
1417 }
1418 }
1419
1420 printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1421 err = -ENODEV;
1422 goto fail;
1423
1424got_type:
1425 switch(base) {
1426 case 0x270:
1427 case 0x280:
1428 case 0x380:
1429 case 0x390:
1430 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1431 goto fail;
1432 }
1433
1434 switch (map->irq) {
1435 case 2:
1436 if (flp->type != SDLA_S502E)
1437 goto fail;
1438 break;
1439
1440 case 10:
1441 case 11:
1442 case 12:
1443 case 15:
1444 case 4:
1445 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1446 goto fail;
1447 break;
1448 case 3:
1449 case 5:
1450 case 7:
1451 if (flp->type == SDLA_S502A)
1452 goto fail;
1453 break;
1454
1455 default:
1456 goto fail;
1457 }
1458
1459 err = -EAGAIN;
a0607fd3 1460 if (request_irq(dev->irq, sdla_isr, 0, dev->name, dev))
1da177e4
LT
1461 goto fail;
1462
1463 if (flp->type == SDLA_S507) {
1464 switch(dev->irq) {
1465 case 3:
1466 flp->state = SDLA_S507_IRQ3;
1467 break;
1468 case 4:
1469 flp->state = SDLA_S507_IRQ4;
1470 break;
1471 case 5:
1472 flp->state = SDLA_S507_IRQ5;
1473 break;
1474 case 7:
1475 flp->state = SDLA_S507_IRQ7;
1476 break;
1477 case 10:
1478 flp->state = SDLA_S507_IRQ10;
1479 break;
1480 case 11:
1481 flp->state = SDLA_S507_IRQ11;
1482 break;
1483 case 12:
1484 flp->state = SDLA_S507_IRQ12;
1485 break;
1486 case 15:
1487 flp->state = SDLA_S507_IRQ15;
1488 break;
1489 }
1490 }
1491
e9edda69 1492 for(i=0; i < ARRAY_SIZE(valid_mem); i++)
1da177e4
LT
1493 if (valid_mem[i] == map->mem_start)
1494 break;
1495
1496 err = -EINVAL;
e9edda69 1497 if (i == ARRAY_SIZE(valid_mem))
1da177e4
LT
1498 goto fail2;
1499
1500 if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
1501 goto fail2;
1502
1503 if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
1504 goto fail2;
1505
1506 if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
1507 goto fail2;
1508
1509 byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1510 byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1511 switch(flp->type) {
1512 case SDLA_S502A:
1513 case SDLA_S502E:
1514 switch (map->mem_start >> 16) {
1515 case 0x0A:
1516 byte |= SDLA_S502_SEG_A;
1517 break;
1518 case 0x0C:
1519 byte |= SDLA_S502_SEG_C;
1520 break;
1521 case 0x0D:
1522 byte |= SDLA_S502_SEG_D;
1523 break;
1524 case 0x0E:
1525 byte |= SDLA_S502_SEG_E;
1526 break;
1527 }
1528 break;
1529 case SDLA_S507:
1530 switch (map->mem_start >> 16) {
1531 case 0x0A:
1532 byte |= SDLA_S507_SEG_A;
1533 break;
1534 case 0x0B:
1535 byte |= SDLA_S507_SEG_B;
1536 break;
1537 case 0x0C:
1538 byte |= SDLA_S507_SEG_C;
1539 break;
1540 case 0x0E:
1541 byte |= SDLA_S507_SEG_E;
1542 break;
1543 }
1544 break;
1545 case SDLA_S508:
1546 switch (map->mem_start >> 16) {
1547 case 0x0A:
1548 byte |= SDLA_S508_SEG_A;
1549 break;
1550 case 0x0C:
1551 byte |= SDLA_S508_SEG_C;
1552 break;
1553 case 0x0D:
1554 byte |= SDLA_S508_SEG_D;
1555 break;
1556 case 0x0E:
1557 byte |= SDLA_S508_SEG_E;
1558 break;
1559 }
1560 break;
1561 }
1562
1563 /* set the memory bits, and enable access */
1564 outb(byte, base + SDLA_REG_PC_WINDOW);
1565
1566 switch(flp->type)
1567 {
1568 case SDLA_S502E:
1569 flp->state = SDLA_S502E_ENABLE;
1570 break;
1571 case SDLA_S507:
1572 flp->state |= SDLA_MEMEN;
1573 break;
1574 case SDLA_S508:
1575 flp->state = SDLA_MEMEN;
1576 break;
1577 }
1578 outb(flp->state, base + SDLA_REG_CONTROL);
1579
1580 dev->irq = map->irq;
1581 dev->base_addr = base;
1582 dev->mem_start = map->mem_start;
1583 dev->mem_end = dev->mem_start + 0x2000;
1584 flp->initialized = 1;
1585 return 0;
1586
1587fail2:
1588 free_irq(map->irq, dev);
1589fail:
1590 release_region(base, SDLA_IO_EXTENTS);
1591 return err;
1592}
1593
ac99533f
SH
1594static const struct net_device_ops sdla_netdev_ops = {
1595 .ndo_open = sdla_open,
1596 .ndo_stop = sdla_close,
1597 .ndo_do_ioctl = sdla_ioctl,
1598 .ndo_set_config = sdla_set_config,
1599 .ndo_start_xmit = sdla_transmit,
1600 .ndo_change_mtu = sdla_change_mtu,
1601};
1da177e4
LT
1602
1603static void setup_sdla(struct net_device *dev)
1604{
8f15ea42 1605 struct frad_local *flp = netdev_priv(dev);
1da177e4
LT
1606
1607 netdev_boot_setup_check(dev);
1608
ac99533f 1609 dev->netdev_ops = &sdla_netdev_ops;
1da177e4
LT
1610 dev->flags = 0;
1611 dev->type = 0xFFFF;
1612 dev->hard_header_len = 0;
1613 dev->addr_len = 0;
1614 dev->mtu = SDLA_MAX_MTU;
1615
1da177e4
LT
1616 flp->activate = sdla_activate;
1617 flp->deactivate = sdla_deactivate;
1618 flp->assoc = sdla_assoc;
1619 flp->deassoc = sdla_deassoc;
1620 flp->dlci_conf = sdla_dlci_conf;
1621
1622 init_timer(&flp->timer);
1623 flp->timer.expires = 1;
1624 flp->timer.data = (unsigned long) dev;
1625 flp->timer.function = sdla_poll;
1626}
1627
1628static struct net_device *sdla;
1629
1630static int __init init_sdla(void)
1631{
1632 int err;
1633
1634 printk("%s.\n", version);
1635
1636 sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
1637 if (!sdla)
1638 return -ENOMEM;
1639
1640 err = register_netdev(sdla);
1641 if (err)
1642 free_netdev(sdla);
1643
1644 return err;
1645}
1646
1647static void __exit exit_sdla(void)
1648{
8f15ea42 1649 struct frad_local *flp = netdev_priv(sdla);
1da177e4
LT
1650
1651 unregister_netdev(sdla);
1652 if (flp->initialized) {
1653 free_irq(sdla->irq, sdla);
1654 release_region(sdla->base_addr, SDLA_IO_EXTENTS);
1655 }
1656 del_timer_sync(&flp->timer);
1657 free_netdev(sdla);
1658}
1659
1660MODULE_LICENSE("GPL");
1661
1662module_init(init_sdla);
1663module_exit(exit_sdla);