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