OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wan/] [sdla.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.