The LDT fixes in particular fix some potentially random strange behaviour.
[davej-history.git] / drivers / net / wan / sdladrv.c
blob89951542e156ad411c9ec82541cc66aa61d2f098
1 /*****************************************************************************
2 * sdladrv.c SDLA Support Module. Main module.
4 * This module is a library of common hardware-specific functions
5 * used by all Sangoma drivers.
7 * Author: Gideon Hack
9 * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 * ============================================================================
16 * Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
17 * Updates for Linux 2.2.X kernels.
18 * Sep 17, 1998 Jaspreet Singh Updates for linux 2.2.X kernels
19 * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
20 * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
21 * Jun 12, 1996 Gene Kozin Added support for S503 card.
22 * Apr 30, 1996 Gene Kozin SDLA hardware interrupt is acknowledged before
23 * calling protocolspecific ISR.
24 * Register I/O ports with Linux kernel.
25 * Miscellaneous bug fixes.
26 * Dec 20, 1995 Gene Kozin Fixed a bug in interrupt routine.
27 * Oct 14, 1995 Gene Kozin Initial version.
28 *****************************************************************************/
30 /*****************************************************************************
31 * Notes:
32 * ------
33 * 1. This code is ment to be system-independent (as much as possible). To
34 * achive this, various macros are used to hide system-specific interfaces.
35 * To compile this code, one of the following constants must be defined:
37 * Platform Define
38 * -------- ------
39 * Linux _LINUX_
40 * SCO Unix _SCO_UNIX_
42 * 2. Supported adapter types:
44 * S502A
45 * ES502A (S502E)
46 * S503
47 * S507
48 * S508 (S509)
50 * 3. S502A Notes:
52 * There is no separate DPM window enable/disable control in S502A. It
53 * opens immediately after a window number it written to the HMCR
54 * register. To close the window, HMCR has to be written a value
55 * ????1111b (e.g. 0x0F or 0xFF).
57 * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
59 * There should be a delay of ??? before reading back S502A status
60 * register.
62 * 4. S502E Notes:
64 * S502E has a h/w bug: although default IRQ line state is HIGH, enabling
65 * interrupts by setting bit 1 of the control register (BASE) to '1'
66 * causes it to go LOW! Therefore, disabling interrupts by setting that
67 * bit to '0' causes low-to-high transition on IRQ line (ghosty
68 * interrupt). The same occurs when disabling CPU by resetting bit 0 of
69 * CPU control register (BASE+3) - see the next note.
71 * S502E CPU and DPM control is limited:
73 * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
74 * control register (BASE+3) shuts the board down entirely, including
75 * DPM;
77 * o DPM access cannot be controlled dynamically. Ones CPU is started,
78 * bit 1 of the control register (BASE) is used to enable/disable IRQ,
79 * so that access to shared memory cannot be disabled while CPU is
80 * running.
81 ****************************************************************************/
83 #define _LINUX_
85 #if defined(_LINUX_) /****** Linux *******************************/
87 #include <linux/config.h>
88 #include <linux/version.h>
89 #include <linux/kernel.h> /* printk(), and other useful stuff */
90 #include <linux/stddef.h> /* offsetof(), etc. */
91 #include <linux/errno.h> /* return codes */
92 #include <linux/string.h> /* inline memset(), etc. */
93 #include <linux/module.h> /* support for loadable modules */
94 #include <linux/sched.h> /* for jiffies, HZ, etc. */
95 #include <linux/sdladrv.h> /* API definitions */
96 #include <linux/sdlasfm.h> /* SDLA firmware module definitions */
97 #include <linux/sdlapci.h> /* SDLA PCI hardware definitions */
98 #include <linux/pci.h> /* PCI defines and function prototypes */
99 #include <asm/io.h> /* for inb(), outb(), etc. */
101 #define _INB(port) (inb(port))
102 #define _OUTB(port, byte) (outb((byte),(port)))
103 #define SYSTEM_TICK jiffies
105 #include <linux/init.h>
107 #elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
109 #if !defined(INKERNEL)
110 #error This code MUST be compiled in kernel mode!
111 #endif
112 #include <sys/sdladrv.h> /* API definitions */
113 #include <sys/sdlasfm.h> /* SDLA firmware module definitions */
114 #include <sys/inline.h> /* for inb(), outb(), etc. */
115 #define _INB(port) (inb(port))
116 #define _OUTB(port, byte) (outb((port),(byte)))
117 #define SYSTEM_TICK lbolt
119 #else
120 #error Unknown system type!
121 #endif
123 #define MOD_VERSION 3
124 #define MOD_RELEASE 0
126 #define SDLA_IODELAY 100 /* I/O Rd/Wr delay, 10 works for 486DX2-66 */
127 #define EXEC_DELAY 20 /* shared memory access delay, mks */
128 #define EXEC_TIMEOUT (HZ*2) /* command timeout, in ticks */
130 /* I/O port address range */
131 #define S502A_IORANGE 3
132 #define S502E_IORANGE 4
133 #define S503_IORANGE 3
134 #define S507_IORANGE 4
135 #define S508_IORANGE 4
137 /* Maximum amount of memory */
138 #define S502_MAXMEM 0x10000L
139 #define S503_MAXMEM 0x10000L
140 #define S507_MAXMEM 0x40000L
141 #define S508_MAXMEM 0x40000L
143 /* Minimum amount of memory */
144 #define S502_MINMEM 0x8000L
145 #define S503_MINMEM 0x8000L
146 #define S507_MINMEM 0x20000L
147 #define S508_MINMEM 0x20000L
148 #define NO_PORT -1
154 /****** Function Prototypes *************************************************/
156 /* Module entry points. These are called by the OS and must be public. */
157 int init_module (void);
158 void cleanup_module (void);
160 /* Hardware-specific functions */
161 static int sdla_detect (sdlahw_t* hw);
162 static int sdla_autodpm (sdlahw_t* hw);
163 static int sdla_setdpm (sdlahw_t* hw);
164 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);
165 static int sdla_init (sdlahw_t* hw);
166 static unsigned long sdla_memtest (sdlahw_t* hw);
167 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
168 static unsigned char make_config_byte (sdlahw_t* hw);
169 static int sdla_start (sdlahw_t* hw, unsigned addr);
171 static int init_s502a (sdlahw_t* hw);
172 static int init_s502e (sdlahw_t* hw);
173 static int init_s503 (sdlahw_t* hw);
174 static int init_s507 (sdlahw_t* hw);
175 static int init_s508 (sdlahw_t* hw);
177 static int detect_s502a (int port);
178 static int detect_s502e (int port);
179 static int detect_s503 (int port);
180 static int detect_s507 (int port);
181 static int detect_s508 (int port);
182 static int detect_s514 (sdlahw_t* hw);
183 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
185 /* Miscellaneous functions */
186 static void peek_by_4 (unsigned long src, void* buf, unsigned len);
187 static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
188 static int calibrate_delay (int mks);
189 static int get_option_index (unsigned* optlist, unsigned optval);
190 static unsigned check_memregion (void* ptr, unsigned len);
191 static unsigned test_memregion (void* ptr, unsigned len);
192 static unsigned short checksum (unsigned char* buf, unsigned len);
194 /****** Global Data **********************************************************
195 * Note: All data must be explicitly initialized!!!
198 /* private data */
199 static char modname[] = "sdladrv";
200 static char fullname[] = "SDLA Support Module";
201 static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
202 static unsigned exec_idle;
204 /* Hardware configuration options.
205 * These are arrays of configuration options used by verification routines.
206 * The first element of each array is its size (i.e. number of options).
208 static unsigned s502_port_options[] =
209 { 4, 0x250, 0x300, 0x350, 0x360 }
211 static unsigned s503_port_options[] =
212 { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
214 static unsigned s508_port_options[] =
215 { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
218 static unsigned s502a_irq_options[] = { 0 };
219 static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
220 static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 };
221 static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
223 static unsigned s502a_dpmbase_options[] =
226 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
227 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
228 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
229 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
231 static unsigned s507_dpmbase_options[] =
234 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
235 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
236 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
237 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
239 static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */
242 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
243 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
244 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
245 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
249 static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
250 static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
251 static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
254 static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
255 static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
256 static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 };
257 static unsigned s507_pclk_options[] = { 1, 12288 };
258 static unsigned s508_pclk_options[] = { 1, 16000 };
260 /* Host memory control register masks */
261 static unsigned char s502a_hmcr[] =
263 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, /* A0000 - AC000 */
264 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, /* C0000 - CC000 */
265 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, /* D0000 - DC000 */
266 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, /* E0000 - EC000 */
268 static unsigned char s502e_hmcr[] =
270 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */
271 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */
272 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */
273 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */
275 static unsigned char s507_hmcr[] =
277 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */
278 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */
279 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */
280 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */
282 static unsigned char s508_hmcr[] =
284 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */
285 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */
286 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */
287 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */
290 static unsigned char s507_irqmask[] =
292 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
295 /******* Kernel Loadable Module Entry Points ********************************/
297 /*============================================================================
298 * Module 'insert' entry point.
299 * o print announcement
300 * o initialize static data
301 * o calibrate SDLA shared memory access delay.
303 * Return: 0 Ok
304 * < 0 error.
305 * Context: process
308 #ifdef MODULE
309 int init_module (void)
310 #else
311 int __init wanpipe_init(void)
312 #endif
314 printk(KERN_INFO "%s v%u.%u %s\n",
315 fullname, MOD_VERSION, MOD_RELEASE, copyright);
316 exec_idle = calibrate_delay(EXEC_DELAY);
317 #ifdef WANDEBUG
318 printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
319 #endif
320 return 0;
323 #ifdef MODULE
324 /*============================================================================
325 * Module 'remove' entry point.
326 * o release all remaining system resources
328 void cleanup_module (void)
331 #endif
333 /******* Kernel APIs ********************************************************/
335 /*============================================================================
336 * Set up adapter.
337 * o detect adapter type
338 * o verify hardware configuration options
339 * o check for hardware conflicts
340 * o set up adapter shared memory
341 * o test adapter memory
342 * o load firmware
343 * Return: 0 ok.
344 * < 0 error
347 EXPORT_SYMBOL(sdla_setup);
349 int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
351 unsigned* irq_opt = NULL; /* IRQ options */
352 unsigned* dpmbase_opt = NULL; /* DPM window base options */
353 unsigned* pclk_opt = NULL; /* CPU clock rate options */
354 int err=0;
356 if (sdla_detect(hw)) {
357 if(hw->type != SDLA_S514)
358 printk(KERN_ERR "%s: no SDLA card found at port 0x%X\n",
359 modname, hw->port);
360 return -EINVAL;
363 if(hw->type != SDLA_S514) {
364 printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
365 modname, hw->type, hw->port);
367 hw->dpmsize = SDLA_WINDOWSIZE;
368 switch (hw->type) {
369 case SDLA_S502A:
370 hw->io_range = S502A_IORANGE;
371 irq_opt = s502a_irq_options;
372 dpmbase_opt = s502a_dpmbase_options;
373 pclk_opt = s502a_pclk_options;
374 break;
376 case SDLA_S502E:
377 hw->io_range = S502E_IORANGE;
378 irq_opt = s502e_irq_options;
379 dpmbase_opt = s508_dpmbase_options;
380 pclk_opt = s502e_pclk_options;
381 break;
383 case SDLA_S503:
384 hw->io_range = S503_IORANGE;
385 irq_opt = s503_irq_options;
386 dpmbase_opt = s508_dpmbase_options;
387 pclk_opt = s503_pclk_options;
388 break;
390 case SDLA_S507:
391 hw->io_range = S507_IORANGE;
392 irq_opt = s508_irq_options;
393 dpmbase_opt = s507_dpmbase_options;
394 pclk_opt = s507_pclk_options;
395 break;
397 case SDLA_S508:
398 hw->io_range = S508_IORANGE;
399 irq_opt = s508_irq_options;
400 dpmbase_opt = s508_dpmbase_options;
401 pclk_opt = s508_pclk_options;
402 break;
405 /* Verify IRQ configuration options */
406 if (!get_option_index(irq_opt, hw->irq)) {
407 printk(KERN_ERR "%s: IRQ %d is illegal!\n",
408 modname, hw->irq);
409 return -EINVAL;
412 /* Verify CPU clock rate configuration options */
413 if (hw->pclk == 0)
414 hw->pclk = pclk_opt[1]; /* use default */
416 else if (!get_option_index(pclk_opt, hw->pclk)) {
417 printk(KERN_ERR "%s: CPU clock %u is illegal!\n",
418 modname, hw->pclk);
419 return -EINVAL;
421 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
422 modname, hw->pclk);
424 /* Setup adapter dual-port memory window and test memory */
425 if (hw->dpmbase == 0) {
426 err = sdla_autodpm(hw);
427 if (err) {
428 printk(KERN_ERR
429 "%s: can't find available memory region!\n",
430 modname);
431 return err;
434 else if (!get_option_index(dpmbase_opt,
435 virt_to_phys(hw->dpmbase))) {
436 printk(KERN_ERR
437 "%s: memory address 0x%lX is illegal!\n",
438 modname, virt_to_phys(hw->dpmbase));
439 return -EINVAL;
441 else if (sdla_setdpm(hw)) {
442 printk(KERN_ERR
443 "%s: 8K memory region at 0x%lX is not available!\n",
444 modname, virt_to_phys(hw->dpmbase));
445 return -EINVAL;
447 printk(KERN_INFO
448 "%s: dual-port memory window is set at 0x%lX.\n",
449 modname, virt_to_phys(hw->dpmbase));
452 else {
453 hw->memory = test_memregion((void*)hw->dpmbase,
454 MAX_SIZEOF_S514_MEMORY);
455 if(hw->memory < (256 * 1024)) {
456 printk(KERN_ERR
457 "%s: error in testing S514 memory (0x%lX)\n",
458 modname, hw->memory);
459 sdla_down(hw);
460 return -EINVAL;
464 printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
465 modname, hw->memory / 1024);
467 /* Load firmware. If loader fails then shut down adapter */
468 err = sdla_load(hw, sfm, len);
469 if (err) sdla_down(hw); /* shutdown adapter */
471 return err;
474 /*============================================================================
475 * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
478 EXPORT_SYMBOL(sdla_down);
480 int sdla_down (sdlahw_t* hw)
482 unsigned port = hw->port;
483 int i;
484 unsigned char CPU_no;
485 u32 int_config, int_status;
487 if(!port && (hw->type != SDLA_S514))
488 return -EFAULT;
490 switch (hw->type) {
491 case SDLA_S502A:
492 _OUTB(port, 0x08); /* halt CPU */
493 _OUTB(port, 0x08);
494 _OUTB(port, 0x08);
495 hw->regs[0] = 0x08;
496 _OUTB(port + 1, 0xFF); /* close memory window */
497 hw->regs[1] = 0xFF;
498 break;
500 case SDLA_S502E:
501 _OUTB(port + 3, 0); /* stop CPU */
502 _OUTB(port, 0); /* reset board */
503 for (i = 0; i < S502E_IORANGE; ++i)
504 hw->regs[i] = 0
506 break;
508 case SDLA_S503:
509 case SDLA_S507:
510 case SDLA_S508:
511 _OUTB(port, 0); /* reset board logic */
512 hw->regs[0] = 0;
513 break;
515 case SDLA_S514:
516 /* halt the adapter */
517 *(char *)hw->vector = S514_CPU_HALT;
518 CPU_no = hw->S514_cpu_no[0];
520 /* disable the PCI IRQ and disable memory access */
521 pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config);
522 int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B;
523 pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config);
524 read_S514_int_stat(hw, &int_status);
525 S514_intack(hw, int_status);
526 if(CPU_no == S514_CPU_A)
527 pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD,
528 PCI_CPU_A_MEM_DISABLE);
529 else
530 pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
531 PCI_CPU_B_MEM_DISABLE);
533 /* free up the allocated virtual memory */
534 iounmap((void *)hw->dpmbase);
535 iounmap((void *)hw->vector);
536 break;
539 default:
540 return -EINVAL;
542 return 0;
545 /*============================================================================
546 * Map shared memory window into SDLA address space.
549 EXPORT_SYMBOL(sdla_mapmem);
551 int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
553 unsigned port = hw->port;
554 register int tmp;
556 switch (hw->type) {
557 case SDLA_S502A:
558 case SDLA_S502E:
559 if (addr < S502_MAXMEM) { /* verify parameter */
560 tmp = addr >> 13; /* convert to register mask */
561 _OUTB(port + 2, tmp);
562 hw->regs[2] = tmp;
564 else return -EINVAL;
565 break;
567 case SDLA_S503:
568 if (addr < S503_MAXMEM) { /* verify parameter */
569 tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
570 _OUTB(port, tmp);
571 hw->regs[0] = tmp;
573 else return -EINVAL;
574 break;
576 case SDLA_S507:
577 if (addr < S507_MAXMEM) {
578 if (!(_INB(port) & 0x02))
579 return -EIO;
580 tmp = addr >> 13; /* convert to register mask */
581 _OUTB(port + 2, tmp);
582 hw->regs[2] = tmp;
584 else return -EINVAL;
585 break;
587 case SDLA_S508:
588 if (addr < S508_MAXMEM) {
589 tmp = addr >> 13; /* convert to register mask */
590 _OUTB(port + 2, tmp);
591 hw->regs[2] = tmp;
593 else return -EINVAL;
594 break;
596 case SDLA_S514:
597 return 0;
599 default:
600 return -EINVAL;
602 hw->vector = addr & 0xFFFFE000L;
603 return 0;
606 /*============================================================================
607 * Enable interrupt generation.
610 EXPORT_SYMBOL(sdla_inten);
612 int sdla_inten (sdlahw_t* hw)
614 unsigned port = hw->port;
615 int tmp, i;
617 switch (hw->type) {
618 case SDLA_S502E:
619 /* Note thar interrupt control operations on S502E are allowed
620 * only if CPU is enabled (bit 0 of status register is set).
622 if (_INB(port) & 0x01) {
623 _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
624 _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
625 hw->regs[0] = 0x06;
627 else return -EIO;
628 break;
630 case SDLA_S503:
631 tmp = hw->regs[0] | 0x04;
632 _OUTB(port, tmp);
633 hw->regs[0] = tmp; /* update mirror */
634 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
635 if (!(_INB(port) & 0x02)) /* verify */
636 return -EIO;
637 break;
639 case SDLA_S508:
640 tmp = hw->regs[0] | 0x10;
641 _OUTB(port, tmp);
642 hw->regs[0] = tmp; /* update mirror */
643 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
644 if (!(_INB(port + 1) & 0x10)) /* verify */
645 return -EIO;
646 break;
648 case SDLA_S502A:
649 case SDLA_S507:
650 break;
652 case SDLA_S514:
653 break;
655 default:
656 return -EINVAL;
659 return 0;
662 /*============================================================================
663 * Disable interrupt generation.
666 EXPORT_SYMBOL(sdla_intde);
668 int sdla_intde (sdlahw_t* hw)
670 unsigned port = hw->port;
671 int tmp, i;
673 switch (hw->type) {
674 case SDLA_S502E:
675 /* Notes:
676 * 1) interrupt control operations are allowed only if CPU is
677 * enabled (bit 0 of status register is set).
678 * 2) disabling interrupts using bit 1 of control register
679 * causes IRQ line go high, therefore we are going to use
680 * 0x04 instead: lower it to inhibit interrupts to PC.
682 if (_INB(port) & 0x01) {
683 _OUTB(port, hw->regs[0] & ~0x04);
684 hw->regs[0] &= ~0x04;
686 else return -EIO;
687 break;
689 case SDLA_S503:
690 tmp = hw->regs[0] & ~0x04;
691 _OUTB(port, tmp);
692 hw->regs[0] = tmp; /* update mirror */
693 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
694 if (_INB(port) & 0x02) /* verify */
695 return -EIO;
696 break;
698 case SDLA_S508:
699 tmp = hw->regs[0] & ~0x10;
700 _OUTB(port, tmp);
701 hw->regs[0] = tmp; /* update mirror */
702 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
703 if (_INB(port) & 0x10) /* verify */
704 return -EIO;
705 break;
707 case SDLA_S502A:
708 case SDLA_S507:
709 break;
711 default:
712 return -EINVAL;
714 return 0;
717 /*============================================================================
718 * Acknowledge SDLA hardware interrupt.
721 EXPORT_SYMBOL(sdla_intack);
723 int sdla_intack (sdlahw_t* hw)
725 unsigned port = hw->port;
726 int tmp;
728 switch (hw->type) {
729 case SDLA_S502E:
730 /* To acknoledge hardware interrupt we have to toggle bit 3 of
731 * control register: \_/
732 * Note that interrupt control operations on S502E are allowed
733 * only if CPU is enabled (bit 1 of status register is set).
735 if (_INB(port) & 0x01) {
736 tmp = hw->regs[0] & ~0x04;
737 _OUTB(port, tmp);
738 tmp |= 0x04;
739 _OUTB(port, tmp);
740 hw->regs[0] = tmp;
742 else return -EIO;
743 break;
745 case SDLA_S503:
746 if (_INB(port) & 0x04) {
747 tmp = hw->regs[0] & ~0x08;
748 _OUTB(port, tmp);
749 tmp |= 0x08;
750 _OUTB(port, tmp);
751 hw->regs[0] = tmp;
753 break;
755 case SDLA_S502A:
756 case SDLA_S507:
757 case SDLA_S508:
758 break;
760 default:
761 return -EINVAL;
763 return 0;
767 /*============================================================================
768 * Acknowledge S514 hardware interrupt.
771 EXPORT_SYMBOL(S514_intack);
773 void S514_intack (sdlahw_t* hw, u32 int_status)
775 pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
779 /*============================================================================
780 * Read the S514 hardware interrupt status.
783 EXPORT_SYMBOL(read_S514_int_stat);
785 void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
787 pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
791 /*============================================================================
792 * Generate an interrupt to adapter's CPU.
795 EXPORT_SYMBOL(sdla_intr);
797 int sdla_intr (sdlahw_t* hw)
799 unsigned port = hw->port;
801 switch (hw->type) {
802 case SDLA_S502A:
803 if (!(_INB(port) & 0x40)) {
804 _OUTB(port, 0x10); /* issue NMI to CPU */
805 hw->regs[0] = 0x10;
807 else return -EIO;
808 break;
810 case SDLA_S507:
811 if ((_INB(port) & 0x06) == 0x06) {
812 _OUTB(port + 3, 0);
814 else return -EIO;
815 break;
817 case SDLA_S508:
818 if (_INB(port + 1) & 0x02) {
819 _OUTB(port, 0x08);
821 else return -EIO;
822 break;
824 case SDLA_S502E:
825 case SDLA_S503:
826 default:
827 return -EINVAL;
829 return 0;
832 /*============================================================================
833 * Execute Adapter Command.
834 * o Set exec flag.
835 * o Busy-wait until flag is reset.
836 * o Return number of loops made, or 0 if command timed out.
839 EXPORT_SYMBOL(sdla_exec);
841 int sdla_exec (void* opflag)
843 volatile unsigned char* flag = opflag;
844 unsigned long tstop;
845 int nloops;
847 if(readb(flag) != 0x00) {
848 printk(KERN_INFO
849 "WANPIPE: opp flag set on entry to sdla_exec\n");
850 return 0;
853 writeb(0x01, flag);
855 tstop = SYSTEM_TICK + EXEC_TIMEOUT;
857 for (nloops = 1; (readb(flag) == 0x01); ++ nloops) {
858 unsigned delay = exec_idle;
859 while (-- delay); /* delay */
860 if (SYSTEM_TICK > tstop) return 0; /* time is up! */
862 return nloops;
865 /*============================================================================
866 * Read absolute adapter memory.
867 * Transfer data from adapter's memory to data buffer.
869 * Note:
870 * Care should be taken when crossing dual-port memory window boundary.
871 * This function is not atomic, so caller must disable interrupt if
872 * interrupt routines are accessing adapter shared memory.
875 EXPORT_SYMBOL(sdla_peek);
877 int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
880 if (addr + len > hw->memory) /* verify arguments */
881 return -EINVAL;
883 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
884 peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
885 return 0;
888 else { /* copy data for the S508 adapter */
889 unsigned long oldvec = hw->vector;
890 unsigned winsize = hw->dpmsize;
891 unsigned curpos, curlen; /* current offset and block size */
892 unsigned long curvec; /* current DPM window vector */
893 int err = 0;
895 while (len && !err) {
896 curpos = addr % winsize; /* current window offset */
897 curvec = addr - curpos; /* current window vector */
898 curlen = (len > (winsize - curpos)) ?
899 (winsize - curpos) : len;
900 /* Relocate window and copy block of data */
901 err = sdla_mapmem(hw, curvec);
902 peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
903 curlen);
904 addr += curlen;
905 (char*)buf += curlen;
906 len -= curlen;
909 /* Restore DPM window position */
910 sdla_mapmem(hw, oldvec);
911 return err;
916 /*============================================================================
917 * Read data from adapter's memory to a data buffer in 4-byte chunks.
918 * Note that we ensure that the SDLA memory address is on a 4-byte boundary
919 * before we begin moving the data in 4-byte chunks.
922 static void peek_by_4 (unsigned long src, void* buf, unsigned len)
925 /* byte copy data until we get to a 4-byte boundary */
926 while (len && (src & 0x03)) {
927 *(char *)buf ++ = readb(src ++);
928 len --;
931 /* copy data in 4-byte chunks */
932 while (len >= 4) {
933 *(unsigned long *)buf = readl(src);
934 buf += 4;
935 src += 4;
936 len -= 4;
939 /* byte copy any remaining data */
940 while (len) {
941 *(char *)buf ++ = readb(src ++);
942 len --;
947 /*============================================================================
948 * Write Absolute Adapter Memory.
949 * Transfer data from data buffer to adapter's memory.
951 * Note:
952 * Care should be taken when crossing dual-port memory window boundary.
953 * This function is not atomic, so caller must disable interrupt if
954 * interrupt routines are accessing adapter shared memory.
957 EXPORT_SYMBOL(sdla_poke);
959 int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
962 if (addr + len > hw->memory) /* verify arguments */
963 return -EINVAL;
965 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
966 poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
967 return 0;
970 else { /* copy data for the S508 adapter */
971 unsigned long oldvec = hw->vector;
972 unsigned winsize = hw->dpmsize;
973 unsigned curpos, curlen; /* current offset and block size */
974 unsigned long curvec; /* current DPM window vector */
975 int err = 0;
977 while (len && !err) {
978 curpos = addr % winsize; /* current window offset */
979 curvec = addr - curpos; /* current window vector */
980 curlen = (len > (winsize - curpos)) ?
981 (winsize - curpos) : len;
982 /* Relocate window and copy block of data */
983 sdla_mapmem(hw, curvec);
984 poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
985 curlen);
986 addr += curlen;
987 (char*)buf += curlen;
988 len -= curlen;
991 /* Restore DPM window position */
992 sdla_mapmem(hw, oldvec);
993 return err;
998 /*============================================================================
999 * Write from a data buffer to adapter's memory in 4-byte chunks.
1000 * Note that we ensure that the SDLA memory address is on a 4-byte boundary
1001 * before we begin moving the data in 4-byte chunks.
1004 static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
1007 /* byte copy data until we get to a 4-byte boundary */
1008 while (len && (dest & 0x03)) {
1009 writeb (*(char *)buf ++, dest ++);
1010 len --;
1013 /* copy data in 4-byte chunks */
1014 while (len >= 4) {
1015 writel (*(unsigned long *)buf, dest);
1016 dest += 4;
1017 buf += 4;
1018 len -= 4;
1021 /* byte copy any remaining data */
1022 while (len) {
1023 writeb (*(char *)buf ++ , dest ++);
1024 len --;
1029 #ifdef DONT_COMPIPLE_THIS
1030 #endif /* DONT_COMPIPLE_THIS */
1032 /****** Hardware-Specific Functions *****************************************/
1034 /*============================================================================
1035 * Detect adapter type.
1036 * o if adapter type is specified then call detection routine for that adapter
1037 * type. Otherwise call detection routines for every adapter types until
1038 * adapter is detected.
1040 * Notes:
1041 * 1) Detection tests are destructive! Adapter will be left in shutdown state
1042 * after the test.
1044 static int sdla_detect (sdlahw_t* hw)
1046 unsigned port = hw->port;
1047 int err = 0;
1049 if (!port && (hw->type != SDLA_S514))
1050 return -EFAULT;
1052 switch (hw->type) {
1053 case SDLA_S502A:
1054 if (!detect_s502a(port)) err = -ENODEV;
1055 break;
1057 case SDLA_S502E:
1058 if (!detect_s502e(port)) err = -ENODEV;
1059 break;
1061 case SDLA_S503:
1062 if (!detect_s503(port)) err = -ENODEV;
1063 break;
1065 case SDLA_S507:
1066 if (!detect_s507(port)) err = -ENODEV;
1067 break;
1069 case SDLA_S508:
1070 if (!detect_s508(port)) err = -ENODEV;
1071 break;
1073 case SDLA_S514:
1074 if (!detect_s514(hw)) err = -ENODEV;
1075 break;
1077 default:
1078 if (detect_s502a(port))
1079 hw->type = SDLA_S502A;
1080 else if (detect_s502e(port))
1081 hw->type = SDLA_S502E;
1082 else if (detect_s503(port))
1083 hw->type = SDLA_S503;
1084 else if (detect_s507(port))
1085 hw->type = SDLA_S507;
1086 else if (detect_s508(port))
1087 hw->type = SDLA_S508;
1088 else err = -ENODEV;
1090 return err;
1093 /*============================================================================
1094 * Autoselect memory region.
1095 * o try all available DMP address options from the top down until success.
1097 static int sdla_autodpm (sdlahw_t* hw)
1099 int i, err = -EINVAL;
1100 unsigned* opt;
1102 switch (hw->type) {
1103 case SDLA_S502A:
1104 opt = s502a_dpmbase_options;
1105 break;
1107 case SDLA_S502E:
1108 case SDLA_S503:
1109 case SDLA_S508:
1110 opt = s508_dpmbase_options;
1111 break;
1113 case SDLA_S507:
1114 opt = s507_dpmbase_options;
1115 break;
1117 default:
1118 return -EINVAL;
1121 for (i = opt[0]; i && err; --i) {
1122 hw->dpmbase = phys_to_virt(opt[i]);
1123 err = sdla_setdpm(hw);
1125 return err;
1128 /*============================================================================
1129 * Set up adapter dual-port memory window.
1130 * o shut down adapter
1131 * o make sure that no physical memory exists in this region, i.e entire
1132 * region reads 0xFF and is not writable when adapter is shut down.
1133 * o initialize adapter hardware
1134 * o make sure that region is usable with SDLA card, i.e. we can write to it
1135 * when adapter is configured.
1137 static int sdla_setdpm (sdlahw_t* hw)
1139 int err;
1141 /* Shut down card and verify memory region */
1142 sdla_down(hw);
1143 if (check_memregion(hw->dpmbase, hw->dpmsize))
1144 return -EINVAL;
1146 /* Initialize adapter and test on-board memory segment by segment.
1147 * If memory size appears to be less than shared memory window size,
1148 * assume that memory region is unusable.
1150 err = sdla_init(hw);
1151 if (err) return err;
1153 if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */
1154 sdla_down(hw);
1155 return -EIO;
1157 sdla_mapmem(hw, 0L); /* set window vector at bottom */
1158 return 0;
1161 /*============================================================================
1162 * Load adapter from the memory image of the SDLA firmware module.
1163 * o verify firmware integrity and compatibility
1164 * o start adapter up
1166 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1169 int i;
1171 /* Verify firmware signature */
1172 if (strcmp(sfm->signature, SFM_SIGNATURE)) {
1173 printk(KERN_ERR "%s: not SDLA firmware!\n",
1174 modname);
1175 return -EINVAL;
1178 /* Verify firmware module format version */
1179 if (sfm->version != SFM_VERSION) {
1180 printk(KERN_ERR
1181 "%s: firmware format %u rejected! Expecting %u.\n",
1182 modname, sfm->version, SFM_VERSION);
1183 return -EINVAL;
1186 /* Verify firmware module length and checksum */
1187 if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
1188 (checksum((void*)&sfm->info,
1189 sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) {
1190 printk(KERN_ERR "%s: firmware corrupted!\n", modname);
1191 return -EINVAL;
1194 /* Announce */
1195 printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1196 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1197 sfm->info.codeid);
1199 if(hw->type == SDLA_S514)
1200 printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
1201 modname, hw->S514_cpu_no[0]);
1203 /* Scan through the list of compatible adapters and make sure our
1204 * adapter type is listed.
1206 for (i = 0;
1207 (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1208 ++i)
1210 if (i == SFM_MAX_SDLA) {
1211 printk(KERN_ERR "%s: firmware is not compatible with S%u!\n",
1212 modname, hw->type);
1214 return -EINVAL;
1218 /* Make sure there is enough on-board memory */
1219 if (hw->memory < sfm->info.memsize) {
1220 printk(KERN_ERR
1221 "%s: firmware needs %lu bytes of on-board memory!\n",
1222 modname, sfm->info.memsize);
1223 return -EINVAL;
1226 /* Move code onto adapter */
1227 if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) {
1228 printk(KERN_ERR "%s: failed to load code segment!\n",
1229 modname);
1230 return -EIO;
1233 /* Prepare boot-time configuration data and kick-off CPU */
1234 sdla_bootcfg(hw, &sfm->info);
1235 if (sdla_start(hw, sfm->info.startoffs)) {
1236 printk(KERN_ERR "%s: Damn... Adapter won't start!\n",
1237 modname);
1238 return -EIO;
1241 /* position DPM window over the mailbox and enable interrupts */
1242 if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) {
1243 printk(KERN_ERR "%s: adapter hardware failure!\n",
1244 modname);
1245 return -EIO;
1247 hw->fwid = sfm->info.codeid; /* set firmware ID */
1248 return 0;
1251 /*============================================================================
1252 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1254 static int sdla_init (sdlahw_t* hw)
1256 int i;
1258 for (i = 0; i < SDLA_MAXIORANGE; ++i)
1259 hw->regs[i] = 0;
1261 switch (hw->type) {
1262 case SDLA_S502A: return init_s502a(hw);
1263 case SDLA_S502E: return init_s502e(hw);
1264 case SDLA_S503: return init_s503(hw);
1265 case SDLA_S507: return init_s507(hw);
1266 case SDLA_S508: return init_s508(hw);
1268 return -EINVAL;
1271 /*============================================================================
1272 * Test adapter on-board memory.
1273 * o slide DPM window from the bottom up and test adapter memory segment by
1274 * segment.
1275 * Return adapter memory size.
1277 static unsigned long sdla_memtest (sdlahw_t* hw)
1279 unsigned long memsize;
1280 unsigned winsize;
1282 for (memsize = 0, winsize = hw->dpmsize;
1283 !sdla_mapmem(hw, memsize) &&
1284 (test_memregion(hw->dpmbase, winsize) == winsize)
1286 memsize += winsize)
1288 hw->memory = memsize;
1289 return memsize;
1292 /*============================================================================
1293 * Prepare boot-time firmware configuration data.
1294 * o position DPM window
1295 * o initialize configuration data area
1297 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1299 unsigned char* data;
1301 if (!sfminfo->datasize) return 0; /* nothing to do */
1303 if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1304 return -EIO;
1306 if(hw->type == SDLA_S514)
1307 data = (void*)(hw->dpmbase + sfminfo->dataoffs);
1308 else
1309 data = (void*)((u8 *)hw->dpmbase +
1310 (sfminfo->dataoffs - hw->vector));
1312 memset_io (data, 0, sfminfo->datasize);
1314 writeb (make_config_byte(hw), &data[0x00]);
1316 switch (sfminfo->codeid) {
1317 case SFID_X25_502:
1318 case SFID_X25_508:
1319 writeb (3, &data[0x01]); /* T1 timer */
1320 writeb (10, &data[0x03]); /* N2 */
1321 writeb (7, &data[0x06]); /* HDLC window size */
1322 writeb (1, &data[0x0B]); /* DTE */
1323 writeb (2, &data[0x0C]); /* X.25 packet window size */
1324 writew (128, &data[0x0D]); /* default X.25 data size */
1325 writew (128, &data[0x0F]); /* maximum X.25 data size */
1326 break;
1328 return 0;
1331 /*============================================================================
1332 * Prepare configuration byte identifying adapter type and CPU clock rate.
1334 static unsigned char make_config_byte (sdlahw_t* hw)
1336 unsigned char byte = 0;
1338 switch (hw->pclk) {
1339 case 5000: byte = 0x01; break;
1340 case 7200: byte = 0x02; break;
1341 case 8000: byte = 0x03; break;
1342 case 10000: byte = 0x04; break;
1343 case 16000: byte = 0x05; break;
1346 switch (hw->type) {
1347 case SDLA_S502E: byte |= 0x80; break;
1348 case SDLA_S503: byte |= 0x40; break;
1350 return byte;
1353 /*============================================================================
1354 * Start adapter's CPU.
1355 * o calculate a pointer to adapter's cold boot entry point
1356 * o position DPM window
1357 * o place boot instruction (jp addr) at cold boot entry point
1358 * o start CPU
1360 static int sdla_start (sdlahw_t* hw, unsigned addr)
1362 unsigned port = hw->port;
1363 unsigned char *bootp;
1364 int err, tmp, i;
1366 if (!port && (hw->type != SDLA_S514)) return -EFAULT;
1368 switch (hw->type) {
1369 case SDLA_S502A:
1370 bootp = hw->dpmbase;
1371 bootp += 0x66;
1372 break;
1374 case SDLA_S502E:
1375 case SDLA_S503:
1376 case SDLA_S507:
1377 case SDLA_S508:
1378 case SDLA_S514:
1379 bootp = hw->dpmbase;
1380 break;
1382 default:
1383 return -EINVAL;
1386 err = sdla_mapmem(hw, 0);
1387 if (err) return err;
1389 writeb (0xC3, bootp); /* Z80: 'jp' opcode */
1390 bootp ++;
1391 writew (addr, bootp);
1393 switch (hw->type) {
1394 case SDLA_S502A:
1395 _OUTB(port, 0x10); /* issue NMI to CPU */
1396 hw->regs[0] = 0x10;
1397 break;
1399 case SDLA_S502E:
1400 _OUTB(port + 3, 0x01); /* start CPU */
1401 hw->regs[3] = 0x01;
1402 for (i = 0; i < SDLA_IODELAY; ++i);
1403 if (_INB(port) & 0x01) { /* verify */
1405 * Enabling CPU changes functionality of the
1406 * control register, so we have to reset its
1407 * mirror.
1409 _OUTB(port, 0); /* disable interrupts */
1410 hw->regs[0] = 0;
1412 else return -EIO;
1413 break;
1415 case SDLA_S503:
1416 tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */
1417 _OUTB(port, tmp);
1418 hw->regs[0] = tmp; /* update mirror */
1419 for (i = 0; i < SDLA_IODELAY; ++i);
1420 if (!(_INB(port) & 0x01)) /* verify */
1421 return -EIO;
1422 break;
1424 case SDLA_S507:
1425 tmp = hw->regs[0] | 0x02;
1426 _OUTB(port, tmp);
1427 hw->regs[0] = tmp; /* update mirror */
1428 for (i = 0; i < SDLA_IODELAY; ++i);
1429 if (!(_INB(port) & 0x04)) /* verify */
1430 return -EIO;
1431 break;
1433 case SDLA_S508:
1434 tmp = hw->regs[0] | 0x02;
1435 _OUTB(port, tmp);
1436 hw->regs[0] = tmp; /* update mirror */
1437 for (i = 0; i < SDLA_IODELAY; ++i);
1438 if (!(_INB(port + 1) & 0x02)) /* verify */
1439 return -EIO;
1440 break;
1442 case SDLA_S514:
1443 writeb (S514_CPU_START, hw->vector);
1444 break;
1446 default:
1447 return -EINVAL;
1449 return 0;
1452 /*============================================================================
1453 * Initialize S502A adapter.
1455 static int init_s502a (sdlahw_t* hw)
1457 unsigned port = hw->port;
1458 int tmp, i;
1460 if (!detect_s502a(port))
1461 return -ENODEV;
1463 hw->regs[0] = 0x08;
1464 hw->regs[1] = 0xFF;
1466 /* Verify configuration options */
1467 i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1468 if (i == 0)
1469 return -EINVAL;
1471 tmp = s502a_hmcr[i - 1];
1472 switch (hw->dpmsize) {
1473 case 0x2000:
1474 tmp |= 0x01;
1475 break;
1477 case 0x10000L:
1478 break;
1480 default:
1481 return -EINVAL;
1484 /* Setup dual-port memory window (this also enables memory access) */
1485 _OUTB(port + 1, tmp);
1486 hw->regs[1] = tmp;
1487 hw->regs[0] = 0x08;
1488 return 0;
1491 /*============================================================================
1492 * Initialize S502E adapter.
1494 static int init_s502e (sdlahw_t* hw)
1496 unsigned port = hw->port;
1497 int tmp, i;
1499 if (!detect_s502e(port))
1500 return -ENODEV;
1502 /* Verify configuration options */
1503 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1504 if (i == 0)
1505 return -EINVAL;
1507 tmp = s502e_hmcr[i - 1];
1508 switch (hw->dpmsize) {
1509 case 0x2000:
1510 tmp |= 0x01;
1511 break;
1513 case 0x10000L:
1514 break;
1516 default:
1517 return -EINVAL;
1520 /* Setup dual-port memory window */
1521 _OUTB(port + 1, tmp);
1522 hw->regs[1] = tmp;
1524 /* Enable memory access */
1525 _OUTB(port, 0x02);
1526 hw->regs[0] = 0x02;
1527 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1528 return (_INB(port) & 0x02) ? 0 : -EIO;
1531 /*============================================================================
1532 * Initialize S503 adapter.
1533 * ---------------------------------------------------------------------------
1535 static int init_s503 (sdlahw_t* hw)
1537 unsigned port = hw->port;
1538 int tmp, i;
1540 if (!detect_s503(port))
1541 return -ENODEV;
1543 /* Verify configuration options */
1544 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1545 if (i == 0)
1546 return -EINVAL;
1548 tmp = s502e_hmcr[i - 1];
1549 switch (hw->dpmsize) {
1550 case 0x2000:
1551 tmp |= 0x01;
1552 break;
1554 case 0x10000L:
1555 break;
1557 default:
1558 return -EINVAL;
1561 /* Setup dual-port memory window */
1562 _OUTB(port + 1, tmp);
1563 hw->regs[1] = tmp;
1565 /* Enable memory access */
1566 _OUTB(port, 0x02);
1567 hw->regs[0] = 0x02; /* update mirror */
1568 return 0;
1571 /*============================================================================
1572 * Initialize S507 adapter.
1574 static int init_s507 (sdlahw_t* hw)
1576 unsigned port = hw->port;
1577 int tmp, i;
1579 if (!detect_s507(port))
1580 return -ENODEV;
1582 /* Verify configuration options */
1583 i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1584 if (i == 0)
1585 return -EINVAL;
1587 tmp = s507_hmcr[i - 1];
1588 switch (hw->dpmsize) {
1589 case 0x2000:
1590 tmp |= 0x01;
1591 break;
1593 case 0x10000L:
1594 break;
1596 default:
1597 return -EINVAL;
1600 /* Enable adapter's logic */
1601 _OUTB(port, 0x01);
1602 hw->regs[0] = 0x01;
1603 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1604 if (!(_INB(port) & 0x20))
1605 return -EIO;
1607 /* Setup dual-port memory window */
1608 _OUTB(port + 1, tmp);
1609 hw->regs[1] = tmp;
1611 /* Enable memory access */
1612 tmp = hw->regs[0] | 0x04;
1613 if (hw->irq) {
1614 i = get_option_index(s508_irq_options, hw->irq);
1615 if (i) tmp |= s507_irqmask[i - 1];
1617 _OUTB(port, tmp);
1618 hw->regs[0] = tmp; /* update mirror */
1619 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1620 return (_INB(port) & 0x08) ? 0 : -EIO;
1623 /*============================================================================
1624 * Initialize S508 adapter.
1626 static int init_s508 (sdlahw_t* hw)
1628 unsigned port = hw->port;
1629 int tmp, i;
1631 if (!detect_s508(port))
1632 return -ENODEV;
1634 /* Verify configuration options */
1635 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1636 if (i == 0)
1637 return -EINVAL;
1639 /* Setup memory configuration */
1640 tmp = s508_hmcr[i - 1];
1641 _OUTB(port + 1, tmp);
1642 hw->regs[1] = tmp;
1644 /* Enable memory access */
1645 _OUTB(port, 0x04);
1646 hw->regs[0] = 0x04; /* update mirror */
1647 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1648 return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1651 /*============================================================================
1652 * Detect S502A adapter.
1653 * Following tests are used to detect S502A adapter:
1654 * 1. All registers other than status (BASE) should read 0xFF
1655 * 2. After writing 00001000b to control register, status register should
1656 * read 01000000b.
1657 * 3. After writing 0 to control register, status register should still
1658 * read 01000000b.
1659 * 4. After writing 00000100b to control register, status register should
1660 * read 01000100b.
1661 * Return 1 if detected o.k. or 0 if failed.
1662 * Note: This test is destructive! Adapter will be left in shutdown
1663 * state after the test.
1665 static int detect_s502a (int port)
1667 int i, j;
1669 if (!get_option_index(s502_port_options, port))
1670 return 0;
1672 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1673 if (_INB(port + j) != 0xFF)
1674 return 0;
1675 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1678 _OUTB(port, 0x08); /* halt CPU */
1679 _OUTB(port, 0x08);
1680 _OUTB(port, 0x08);
1681 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1682 if (_INB(port) != 0x40)
1683 return 0;
1684 _OUTB(port, 0x00);
1685 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1686 if (_INB(port) != 0x40)
1687 return 0;
1688 _OUTB(port, 0x04);
1689 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1690 if (_INB(port) != 0x44)
1691 return 0;
1693 /* Reset adapter */
1694 _OUTB(port, 0x08);
1695 _OUTB(port, 0x08);
1696 _OUTB(port, 0x08);
1697 _OUTB(port + 1, 0xFF);
1698 return 1;
1701 /*============================================================================
1702 * Detect S502E adapter.
1703 * Following tests are used to verify adapter presence:
1704 * 1. All registers other than status (BASE) should read 0xFF.
1705 * 2. After writing 0 to CPU control register (BASE+3), status register
1706 * (BASE) should read 11111000b.
1707 * 3. After writing 00000100b to port BASE (set bit 2), status register
1708 * (BASE) should read 11111100b.
1709 * Return 1 if detected o.k. or 0 if failed.
1710 * Note: This test is destructive! Adapter will be left in shutdown
1711 * state after the test.
1713 static int detect_s502e (int port)
1715 int i, j;
1717 if (!get_option_index(s502_port_options, port))
1718 return 0;
1719 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1720 if (_INB(port + j) != 0xFF)
1721 return 0;
1722 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1725 _OUTB(port + 3, 0); /* CPU control reg. */
1726 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1727 if (_INB(port) != 0xF8) /* read status */
1728 return 0;
1729 _OUTB(port, 0x04); /* set bit 2 */
1730 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1731 if (_INB(port) != 0xFC) /* verify */
1732 return 0;
1734 /* Reset adapter */
1735 _OUTB(port, 0);
1736 return 1;
1739 /*============================================================================
1740 * Detect s503 adapter.
1741 * Following tests are used to verify adapter presence:
1742 * 1. All registers other than status (BASE) should read 0xFF.
1743 * 2. After writing 0 to control register (BASE), status register (BASE)
1744 * should read 11110000b.
1745 * 3. After writing 00000100b (set bit 2) to control register (BASE),
1746 * status register should read 11110010b.
1747 * Return 1 if detected o.k. or 0 if failed.
1748 * Note: This test is destructive! Adapter will be left in shutdown
1749 * state after the test.
1751 static int detect_s503 (int port)
1753 int i, j;
1755 if (!get_option_index(s503_port_options, port))
1756 return 0;
1757 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1758 if (_INB(port + j) != 0xFF)
1759 return 0;
1760 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1763 _OUTB(port, 0); /* reset control reg.*/
1764 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1765 if (_INB(port) != 0xF0) /* read status */
1766 return 0;
1767 _OUTB(port, 0x04); /* set bit 2 */
1768 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1769 if (_INB(port) != 0xF2) /* verify */
1770 return 0;
1772 /* Reset adapter */
1773 _OUTB(port, 0);
1774 return 1;
1777 /*============================================================================
1778 * Detect s507 adapter.
1779 * Following tests are used to detect s507 adapter:
1780 * 1. All ports should read the same value.
1781 * 2. After writing 0x00 to control register, status register should read
1782 * ?011000?b.
1783 * 3. After writing 0x01 to control register, status register should read
1784 * ?011001?b.
1785 * Return 1 if detected o.k. or 0 if failed.
1786 * Note: This test is destructive! Adapter will be left in shutdown
1787 * state after the test.
1789 static int detect_s507 (int port)
1791 int tmp, i, j;
1793 if (!get_option_index(s508_port_options, port))
1794 return 0;
1795 tmp = _INB(port);
1796 for (j = 1; j < S507_IORANGE; ++j) {
1797 if (_INB(port + j) != tmp)
1798 return 0;
1799 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1802 _OUTB(port, 0x00);
1803 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1804 if ((_INB(port) & 0x7E) != 0x30)
1805 return 0;
1806 _OUTB(port, 0x01);
1807 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1808 if ((_INB(port) & 0x7E) != 0x32)
1809 return 0;
1811 /* Reset adapter */
1812 _OUTB(port, 0x00);
1813 return 1;
1816 /*============================================================================
1817 * Detect s508 adapter.
1818 * Following tests are used to detect s508 adapter:
1819 * 1. After writing 0x00 to control register, status register should read
1820 * ??000000b.
1821 * 2. After writing 0x10 to control register, status register should read
1822 * ??010000b
1823 * Return 1 if detected o.k. or 0 if failed.
1824 * Note: This test is destructive! Adapter will be left in shutdown
1825 * state after the test.
1827 static int detect_s508 (int port)
1829 int i;
1831 if (!get_option_index(s508_port_options, port))
1832 return 0;
1833 _OUTB(port, 0x00);
1834 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1835 if ((_INB(port + 1) & 0x3F) != 0x00)
1836 return 0;
1837 _OUTB(port, 0x10);
1838 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1839 if ((_INB(port + 1) & 0x3F) != 0x10)
1840 return 0;
1842 /* Reset adapter */
1843 _OUTB(port, 0x00);
1844 return 1;
1847 /*============================================================================
1848 * Detect s514 PCI adapter.
1849 * Return 1 if detected o.k. or 0 if failed.
1850 * Note: This test is destructive! Adapter will be left in shutdown
1851 * state after the test.
1853 static int detect_s514 (sdlahw_t* hw)
1855 unsigned char CPU_no, slot_no;
1856 int number_S514_cards = 0;
1857 u32 S514_mem_base_addr = 0;
1858 u32 ut_u32;
1860 struct pci_dev *pci_dev;
1863 #ifdef CONFIG_PCI
1864 if(!pci_present())
1866 printk(KERN_ERR "%s: PCI BIOS not present!\n", modname);
1867 return 0;
1869 #else
1870 printk(KERN_ERR "%s: Linux not compiled for PCI usage!\n", modname);
1871 return 0;
1872 #endif
1875 The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
1876 slot number defined in 'router.conf' via the 'port' definition.
1878 CPU_no = hw->S514_cpu_no[0];
1879 slot_no = hw->S514_slot_no;
1881 printk(KERN_INFO "%s: detecting S514 card, CPU %c, slot #%d\n",
1882 modname, CPU_no, slot_no);
1884 /* check to see that CPU A or B has been selected in 'router.conf' */
1885 switch(CPU_no) {
1886 case S514_CPU_A:
1887 case S514_CPU_B:
1888 break;
1890 default:
1891 printk(KERN_ERR "%s: S514 CPU definition invalid.\n",
1892 modname);
1893 printk(KERN_ERR "Must be 'A' or 'B'\n");
1894 return 0;
1897 number_S514_cards = find_s514_adapter(hw, 0);
1898 if(!number_S514_cards)
1899 return 0;
1901 /* we are using a single S514 adapter with a slot of 0 so re-read the */ /* location of this adapter */
1902 if((number_S514_cards == 1) && !slot_no) {
1903 number_S514_cards = find_s514_adapter(hw, 1);
1904 if(!number_S514_cards) {
1905 printk(KERN_ERR "%s: Error finding PCI card\n",
1906 modname);
1907 return 0;
1911 pci_dev = hw->pci_dev;
1912 /* read the physical memory base address */
1913 S514_mem_base_addr = (CPU_no == S514_CPU_A) ?
1914 (pci_dev->resource[1].start) :
1915 (pci_dev->resource[2].start);
1917 printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n",
1918 modname, S514_mem_base_addr);
1919 if(!S514_mem_base_addr) {
1920 if(CPU_no == S514_CPU_B)
1921 printk(KERN_ERR "%s: CPU #B not present on the card\n", modname);
1922 else
1923 printk(KERN_ERR "%s: No PCI memory allocated to card\n", modname);
1924 return 0;
1927 /* enable the PCI memory */
1928 pci_read_config_dword(pci_dev,
1929 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1930 &ut_u32);
1931 pci_write_config_dword(pci_dev,
1932 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1933 (ut_u32 | PCI_MEMORY_ENABLE));
1935 /* check the IRQ allocated and enable IRQ usage */
1936 if(!(hw->irq = pci_dev->irq)) {
1937 printk(KERN_ERR "%s: IRQ not allocated to S514 adapter\n",
1938 modname);
1939 return 0;
1941 pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32);
1942 ut_u32 |= (CPU_no == S514_CPU_A) ?
1943 PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B;
1944 pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32);
1946 printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
1947 modname, hw->irq);
1949 /* map the physical PCI memory to virtual memory */
1950 (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
1951 (unsigned long)MAX_SIZEOF_S514_MEMORY);
1952 /* map the physical control register memory to virtual memory */
1953 (void *)hw->vector = ioremap(
1954 (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE),
1955 (unsigned long)16);
1957 if(!hw->dpmbase || !hw->vector) {
1958 printk(KERN_ERR "%s: PCI virtual memory allocation failed\n",
1959 modname);
1960 return 0;
1963 /* halt the adapter */
1964 writeb (S514_CPU_HALT, hw->vector);
1966 return 1;
1969 /*============================================================================
1970 * Find the S514 PCI adapter in the PCI bus.
1971 * Return the number of S514 adapters found (0 if no adapter found).
1973 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
1975 unsigned char slot_no;
1976 int number_S514_cards = 0;
1977 char S514_found_in_slot = 0;
1978 u16 PCI_subsys_vendor;
1980 struct pci_dev *pci_dev = NULL;
1982 slot_no = hw->S514_slot_no;
1984 while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
1985 != NULL) {
1986 if (pci_enable_device(pci_dev))
1987 continue;
1988 PCI_subsys_vendor = pci_dev->subsystem_vendor;
1989 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
1990 continue;
1991 hw->pci_dev = pci_dev;
1992 if(find_first_S514_card)
1993 return(1);
1994 number_S514_cards ++;
1995 printk(KERN_INFO
1996 "%s: S514 card found, slot #%d (devfn 0x%X)\n",
1997 modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
1998 pci_dev->devfn);
1999 if(slot_no && (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) ==
2000 slot_no)) {
2001 S514_found_in_slot = 1;
2002 break;
2006 /* if no S514 adapter has been found, then exit */
2007 if(!number_S514_cards) {
2008 printk(KERN_ERR "%s: no S514 adapters found\n", modname);
2009 return 0;
2011 /* if more than one S514 card has been found, then the user must have */ /* defined a slot number so that the correct adapter is used */
2012 else if((number_S514_cards > 1) && !slot_no) {
2013 printk(KERN_ERR "%s: More than one S514 adapter found\n",
2014 modname);
2015 printk(KERN_ERR "Define a PCI slot number for this adapter\n");
2016 return 0;
2018 /* if the user has specified a slot number and the S514 adapter has */
2019 /* not been found in that slot, then exit */
2020 else if (slot_no && !S514_found_in_slot) {
2021 printk(KERN_ERR
2022 "%s: S514 card not found in specified slot #%d\n",
2023 modname, slot_no);
2024 return 0;
2027 return (number_S514_cards);
2032 /******* Miscellaneous ******************************************************/
2034 /*============================================================================
2035 * Calibrate SDLA memory access delay.
2036 * Count number of idle loops made within 1 second and then calculate the
2037 * number of loops that should be made to achive desired delay.
2039 static int calibrate_delay (int mks)
2041 unsigned int delay;
2042 unsigned long stop;
2044 for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
2045 return (delay/(1000000L/mks) + 1);
2048 /*============================================================================
2049 * Get option's index into the options list.
2050 * Return option's index (1 .. N) or zero if option is invalid.
2052 static int get_option_index (unsigned* optlist, unsigned optval)
2054 int i;
2056 for (i = 1; i <= optlist[0]; ++i)
2057 if ( optlist[i] == optval)
2058 return i;
2059 return 0;
2062 /*============================================================================
2063 * Check memory region to see if it's available.
2064 * Return: 0 ok.
2066 static unsigned check_memregion (void* ptr, unsigned len)
2068 volatile unsigned char* p = ptr;
2070 for (; len && (readb (p) == 0xFF); --len, ++p) {
2071 writeb (0, p); /* attempt to write 0 */
2072 if (readb(p) != 0xFF) { /* still has to read 0xFF */
2073 writeb (0xFF, p);/* restore original value */
2074 break; /* not good */
2078 return len;
2081 /*============================================================================
2082 * Test memory region.
2083 * Return: size of the region that passed the test.
2084 * Note: Region size must be multiple of 2 !
2086 static unsigned test_memregion (void* ptr, unsigned len)
2088 volatile unsigned short* w_ptr;
2089 unsigned len_w = len >> 1; /* region len in words */
2090 unsigned i;
2092 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2093 writew (0xAA55, w_ptr);
2095 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2096 if (readw (w_ptr) != 0xAA55) {
2097 len_w = i;
2098 break;
2101 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2102 writew (0x55AA, w_ptr);
2104 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2105 if (readw(w_ptr) != 0x55AA) {
2106 len_w = i;
2107 break;
2110 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2111 writew (0, w_ptr);
2113 return len_w << 1;
2116 /*============================================================================
2117 * Calculate 16-bit CRC using CCITT polynomial.
2119 static unsigned short checksum (unsigned char* buf, unsigned len)
2121 unsigned short crc = 0;
2122 unsigned mask, flag;
2124 for (; len; --len, ++buf) {
2125 for (mask = 0x80; mask; mask >>= 1) {
2126 flag = (crc & 0x8000);
2127 crc <<= 1;
2128 crc |= ((*buf & mask) ? 1 : 0);
2129 if (flag) crc ^= 0x1021;
2132 return crc;
2136 /****** End *****************************************************************/