drivers/net: return operator cleanup
[GitHub/mt8127/android_kernel_alcatel_ttab.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
807540ba 181 return byte;
1da177e4
LT
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 }
807540ba 270 return time_before(jiffies, done) ? jiffies - start : -1;
1da177e4
LT
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)
807540ba 286 return -EIO;
1da177e4
LT
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)
807540ba 292 return -EIO;
1da177e4
LT
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);
807540ba 300 return -EIO;
1da177e4
LT
301 }
302
303 if (data != Z80_SCC_OK)
807540ba 304 return -EINVAL;
1da177e4
LT
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
807540ba 319 return 0;
1da177e4
LT
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;
ba2d3587 333} __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
807540ba 496 return ret;
1da177e4
LT
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)
807540ba 519 return -ENODEV;
1da177e4
LT
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
807540ba 526 return 0;
1da177e4
LT
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)
807540ba 541 return -ENODEV;
1da177e4
LT
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
807540ba 548 return 0;
1da177e4
LT
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)
807540ba 557 return -EINVAL;
1da177e4 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))
807540ba 566 return -EADDRINUSE;
1da177e4
LT
567 }
568
569 if (i == CONFIG_DLCI_MAX)
807540ba 570 return -EMLINK; /* #### Alan: Comments on this ?? */
1da177e4
LT
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
807540ba 584 return 0;
1da177e4
LT
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)
807540ba 599 return -ENODEV;
1da177e4
LT
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
807540ba 612 return 0;
1da177e4
LT
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)
807540ba 629 return -ENODEV;
1da177e4 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
807540ba 644 return ret == SDLA_RET_OK ? 0 : -EIO;
1da177e4
LT
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
807540ba 989 return 0;
1da177e4
LT
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)
807540ba 1009 return -EPERM;
1da177e4
LT
1010
1011 if (!flp->configured)
807540ba 1012 return -EPERM;
1da177e4
LT
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
807540ba 1090 return 0;
1da177e4
LT
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)
807540ba 1101 return -EUNATCH;
1da177e4 1102
8f15ea42 1103 flp = netdev_priv(dev);
1da177e4
LT
1104
1105 if (!get)
1106 {
1107 if (netif_running(dev))
807540ba 1108 return -EBUSY;
1da177e4
LT
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)
807540ba 1114 return -EINVAL;
1da177e4
LT
1115
1116 if (data.config.flags & ~FRAD_VALID_FLAGS)
807540ba 1117 return -EINVAL;
1da177e4
LT
1118
1119 if ((data.config.kbaud < 0) ||
1120 ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
807540ba 1121 return -EINVAL;
1da177e4
LT
1122
1123 if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
807540ba 1124 return -EINVAL;
1da177e4
LT
1125
1126 if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
807540ba 1127 return -EINVAL;
1da177e4
LT
1128
1129 if ((data.config.T391 < 5) || (data.config.T391 > 30))
807540ba 1130 return -EINVAL;
1da177e4
LT
1131
1132 if ((data.config.T392 < 5) || (data.config.T392 > 30))
807540ba 1133 return -EINVAL;
1da177e4
LT
1134
1135 if ((data.config.N391 < 1) || (data.config.N391 > 255))
807540ba 1136 return -EINVAL;
1da177e4
LT
1137
1138 if ((data.config.N392 < 1) || (data.config.N392 > 10))
807540ba 1139 return -EINVAL;
1da177e4
LT
1140
1141 if ((data.config.N393 < 1) || (data.config.N393 > 10))
807540ba 1142 return -EINVAL;
1da177e4
LT
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)
807540ba 1174 return -EIO;
1da177e4
LT
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
807540ba 1188 return 0;
1da177e4
LT
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 1202 if (!temp)
807540ba 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 {
c146fc9f
JL
1214 temp = memdup_user(mem.data, mem.len);
1215 if (IS_ERR(temp))
1216 return PTR_ERR(temp);
1da177e4
LT
1217 sdla_write(dev, mem.addr, temp, mem.len);
1218 kfree(temp);
1219 }
807540ba 1220 return 0;
1da177e4
LT
1221}
1222
1223static int sdla_reconfig(struct net_device *dev)
1224{
1225 struct frad_local *flp;
1226 struct conf_data data;
1227 int i, len;
1228
8f15ea42 1229 flp = netdev_priv(dev);
1da177e4
LT
1230
1231 len = 0;
1232 for(i=0;i<CONFIG_DLCI_MAX;i++)
1233 if (flp->dlci[i])
1234 data.dlci[len++] = flp->dlci[i];
1235 len *= 2;
1236
1237 memcpy(&data, &flp->config, sizeof(struct frad_conf));
1238 len += sizeof(struct frad_conf);
1239
1240 sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1241 sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1242 sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1243
807540ba 1244 return 0;
1da177e4
LT
1245}
1246
1247static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1248{
1249 struct frad_local *flp;
1250
1251 if(!capable(CAP_NET_ADMIN))
1252 return -EPERM;
1253
8f15ea42 1254 flp = netdev_priv(dev);
1da177e4
LT
1255
1256 if (!flp->initialized)
807540ba 1257 return -EINVAL;
1da177e4
LT
1258
1259 switch (cmd)
1260 {
1261 case FRAD_GET_CONF:
1262 case FRAD_SET_CONF:
807540ba 1263 return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF);
1da177e4
LT
1264
1265 case SDLA_IDENTIFY:
1266 ifr->ifr_flags = flp->type;
1267 break;
1268
1269 case SDLA_CPUSPEED:
807540ba 1270 return sdla_cpuspeed(dev, ifr);
1da177e4
LT
1271
1272/* ==========================================================
1273NOTE: This is rather a useless action right now, as the
1274 current driver does not support protocols other than
1275 FR. However, Sangoma has modules for a number of
1276 other protocols in the works.
1277============================================================*/
1278 case SDLA_PROTOCOL:
1279 if (flp->configured)
807540ba 1280 return -EALREADY;
1da177e4
LT
1281
1282 switch (ifr->ifr_flags)
1283 {
1284 case ARPHRD_FRAD:
1285 dev->type = ifr->ifr_flags;
1286 break;
1287 default:
807540ba 1288 return -ENOPROTOOPT;
1da177e4
LT
1289 }
1290 break;
1291
1292 case SDLA_CLEARMEM:
1293 sdla_clear(dev);
1294 break;
1295
1296 case SDLA_WRITEMEM:
1297 case SDLA_READMEM:
1298 if(!capable(CAP_SYS_RAWIO))
1299 return -EPERM;
807540ba 1300 return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM);
1da177e4
LT
1301
1302 case SDLA_START:
1303 sdla_start(dev);
1304 break;
1305
1306 case SDLA_STOP:
1307 sdla_stop(dev);
1308 break;
1309
1310 default:
807540ba 1311 return -EOPNOTSUPP;
1da177e4 1312 }
807540ba 1313 return 0;
1da177e4
LT
1314}
1315
7665a089 1316static int sdla_change_mtu(struct net_device *dev, int new_mtu)
1da177e4
LT
1317{
1318 struct frad_local *flp;
1319
8f15ea42 1320 flp = netdev_priv(dev);
1da177e4
LT
1321
1322 if (netif_running(dev))
807540ba 1323 return -EBUSY;
1da177e4
LT
1324
1325 /* for now, you can't change the MTU! */
807540ba 1326 return -EOPNOTSUPP;
1da177e4
LT
1327}
1328
7665a089 1329static int sdla_set_config(struct net_device *dev, struct ifmap *map)
1da177e4
LT
1330{
1331 struct frad_local *flp;
1332 int i;
1333 char byte;
1334 unsigned base;
1335 int err = -EINVAL;
1336
8f15ea42 1337 flp = netdev_priv(dev);
1da177e4
LT
1338
1339 if (flp->initialized)
807540ba 1340 return -EINVAL;
1da177e4 1341
e9edda69 1342 for(i=0; i < ARRAY_SIZE(valid_port); i++)
1da177e4
LT
1343 if (valid_port[i] == map->base_addr)
1344 break;
1345
e9edda69 1346 if (i == ARRAY_SIZE(valid_port))
807540ba 1347 return -EINVAL;
1da177e4
LT
1348
1349 if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
2381a55c 1350 printk(KERN_WARNING "SDLA: io-port 0x%04lx in use\n", dev->base_addr);
807540ba 1351 return -EINVAL;
1da177e4
LT
1352 }
1353 base = map->base_addr;
1354
1355 /* test for card types, S502A, S502E, S507, S508 */
1356 /* these tests shut down the card completely, so clear the state */
1357 flp->type = SDLA_UNKNOWN;
1358 flp->state = 0;
1359
1360 for(i=1;i<SDLA_IO_EXTENTS;i++)
1361 if (inb(base + i) != 0xFF)
1362 break;
1363
1364 if (i == SDLA_IO_EXTENTS) {
1365 outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
1366 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
1367 outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
1368 if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
1369 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1370 flp->type = SDLA_S502E;
1371 goto got_type;
1372 }
1373 }
1374 }
1375
1376 for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
1377 if (inb(base + i) != byte)
1378 break;
1379
1380 if (i == SDLA_IO_EXTENTS) {
1381 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1382 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
1383 outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
1384 if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
1385 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1386 flp->type = SDLA_S507;
1387 goto got_type;
1388 }
1389 }
1390 }
1391
1392 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1393 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
1394 outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
1395 if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
1396 outb(SDLA_HALT, base + SDLA_REG_CONTROL);
1397 flp->type = SDLA_S508;
1398 goto got_type;
1399 }
1400 }
1401
1402 outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
1403 if (inb(base + SDLA_S502_STS) == 0x40) {
1404 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1405 if (inb(base + SDLA_S502_STS) == 0x40) {
1406 outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
1407 if (inb(base + SDLA_S502_STS) == 0x44) {
1408 outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
1409 flp->type = SDLA_S502A;
1410 goto got_type;
1411 }
1412 }
1413 }
1414
1415 printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1416 err = -ENODEV;
1417 goto fail;
1418
1419got_type:
1420 switch(base) {
1421 case 0x270:
1422 case 0x280:
1423 case 0x380:
1424 case 0x390:
1425 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1426 goto fail;
1427 }
1428
1429 switch (map->irq) {
1430 case 2:
1431 if (flp->type != SDLA_S502E)
1432 goto fail;
1433 break;
1434
1435 case 10:
1436 case 11:
1437 case 12:
1438 case 15:
1439 case 4:
1440 if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
1441 goto fail;
1442 break;
1443 case 3:
1444 case 5:
1445 case 7:
1446 if (flp->type == SDLA_S502A)
1447 goto fail;
1448 break;
1449
1450 default:
1451 goto fail;
1452 }
1453
1454 err = -EAGAIN;
a0607fd3 1455 if (request_irq(dev->irq, sdla_isr, 0, dev->name, dev))
1da177e4
LT
1456 goto fail;
1457
1458 if (flp->type == SDLA_S507) {
1459 switch(dev->irq) {
1460 case 3:
1461 flp->state = SDLA_S507_IRQ3;
1462 break;
1463 case 4:
1464 flp->state = SDLA_S507_IRQ4;
1465 break;
1466 case 5:
1467 flp->state = SDLA_S507_IRQ5;
1468 break;
1469 case 7:
1470 flp->state = SDLA_S507_IRQ7;
1471 break;
1472 case 10:
1473 flp->state = SDLA_S507_IRQ10;
1474 break;
1475 case 11:
1476 flp->state = SDLA_S507_IRQ11;
1477 break;
1478 case 12:
1479 flp->state = SDLA_S507_IRQ12;
1480 break;
1481 case 15:
1482 flp->state = SDLA_S507_IRQ15;
1483 break;
1484 }
1485 }
1486
e9edda69 1487 for(i=0; i < ARRAY_SIZE(valid_mem); i++)
1da177e4
LT
1488 if (valid_mem[i] == map->mem_start)
1489 break;
1490
1491 err = -EINVAL;
e9edda69 1492 if (i == ARRAY_SIZE(valid_mem))
1da177e4
LT
1493 goto fail2;
1494
1495 if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
1496 goto fail2;
1497
1498 if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
1499 goto fail2;
1500
1501 if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
1502 goto fail2;
1503
1504 byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1505 byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1506 switch(flp->type) {
1507 case SDLA_S502A:
1508 case SDLA_S502E:
1509 switch (map->mem_start >> 16) {
1510 case 0x0A:
1511 byte |= SDLA_S502_SEG_A;
1512 break;
1513 case 0x0C:
1514 byte |= SDLA_S502_SEG_C;
1515 break;
1516 case 0x0D:
1517 byte |= SDLA_S502_SEG_D;
1518 break;
1519 case 0x0E:
1520 byte |= SDLA_S502_SEG_E;
1521 break;
1522 }
1523 break;
1524 case SDLA_S507:
1525 switch (map->mem_start >> 16) {
1526 case 0x0A:
1527 byte |= SDLA_S507_SEG_A;
1528 break;
1529 case 0x0B:
1530 byte |= SDLA_S507_SEG_B;
1531 break;
1532 case 0x0C:
1533 byte |= SDLA_S507_SEG_C;
1534 break;
1535 case 0x0E:
1536 byte |= SDLA_S507_SEG_E;
1537 break;
1538 }
1539 break;
1540 case SDLA_S508:
1541 switch (map->mem_start >> 16) {
1542 case 0x0A:
1543 byte |= SDLA_S508_SEG_A;
1544 break;
1545 case 0x0C:
1546 byte |= SDLA_S508_SEG_C;
1547 break;
1548 case 0x0D:
1549 byte |= SDLA_S508_SEG_D;
1550 break;
1551 case 0x0E:
1552 byte |= SDLA_S508_SEG_E;
1553 break;
1554 }
1555 break;
1556 }
1557
1558 /* set the memory bits, and enable access */
1559 outb(byte, base + SDLA_REG_PC_WINDOW);
1560
1561 switch(flp->type)
1562 {
1563 case SDLA_S502E:
1564 flp->state = SDLA_S502E_ENABLE;
1565 break;
1566 case SDLA_S507:
1567 flp->state |= SDLA_MEMEN;
1568 break;
1569 case SDLA_S508:
1570 flp->state = SDLA_MEMEN;
1571 break;
1572 }
1573 outb(flp->state, base + SDLA_REG_CONTROL);
1574
1575 dev->irq = map->irq;
1576 dev->base_addr = base;
1577 dev->mem_start = map->mem_start;
1578 dev->mem_end = dev->mem_start + 0x2000;
1579 flp->initialized = 1;
1580 return 0;
1581
1582fail2:
1583 free_irq(map->irq, dev);
1584fail:
1585 release_region(base, SDLA_IO_EXTENTS);
1586 return err;
1587}
1588
ac99533f
SH
1589static const struct net_device_ops sdla_netdev_ops = {
1590 .ndo_open = sdla_open,
1591 .ndo_stop = sdla_close,
1592 .ndo_do_ioctl = sdla_ioctl,
1593 .ndo_set_config = sdla_set_config,
1594 .ndo_start_xmit = sdla_transmit,
1595 .ndo_change_mtu = sdla_change_mtu,
1596};
1da177e4
LT
1597
1598static void setup_sdla(struct net_device *dev)
1599{
8f15ea42 1600 struct frad_local *flp = netdev_priv(dev);
1da177e4
LT
1601
1602 netdev_boot_setup_check(dev);
1603
ac99533f 1604 dev->netdev_ops = &sdla_netdev_ops;
1da177e4
LT
1605 dev->flags = 0;
1606 dev->type = 0xFFFF;
1607 dev->hard_header_len = 0;
1608 dev->addr_len = 0;
1609 dev->mtu = SDLA_MAX_MTU;
1610
1da177e4
LT
1611 flp->activate = sdla_activate;
1612 flp->deactivate = sdla_deactivate;
1613 flp->assoc = sdla_assoc;
1614 flp->deassoc = sdla_deassoc;
1615 flp->dlci_conf = sdla_dlci_conf;
1616
1617 init_timer(&flp->timer);
1618 flp->timer.expires = 1;
1619 flp->timer.data = (unsigned long) dev;
1620 flp->timer.function = sdla_poll;
1621}
1622
1623static struct net_device *sdla;
1624
1625static int __init init_sdla(void)
1626{
1627 int err;
1628
1629 printk("%s.\n", version);
1630
1631 sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
1632 if (!sdla)
1633 return -ENOMEM;
1634
1635 err = register_netdev(sdla);
1636 if (err)
1637 free_netdev(sdla);
1638
1639 return err;
1640}
1641
1642static void __exit exit_sdla(void)
1643{
8f15ea42 1644 struct frad_local *flp = netdev_priv(sdla);
1da177e4
LT
1645
1646 unregister_netdev(sdla);
1647 if (flp->initialized) {
1648 free_irq(sdla->irq, sdla);
1649 release_region(sdla->base_addr, SDLA_IO_EXTENTS);
1650 }
1651 del_timer_sync(&flp->timer);
1652 free_netdev(sdla);
1653}
1654
1655MODULE_LICENSE("GPL");
1656
1657module_init(init_sdla);
1658module_exit(exit_sdla);