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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [sdla.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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