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