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.
9 * Copyright: (c) 1995-2000 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 * Mar 20, 2001 Nenad Corbic Added the auto_pci_cfg filed, to support
18 * Apr 04, 2000 Nenad Corbic Fixed the auto memory detection code.
19 * The memory test at address 0xC8000.
20 * Mar 09, 2000 Nenad Corbic Added Gideon's Bug Fix: clear pci
21 * interrupt flags on initial load.
22 * Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
23 * Updates for Linux 2.2.X kernels.
24 * Sep 17, 1998 Jaspreet Singh Updates for linux 2.2.X kernels
25 * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
26 * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
27 * Jun 12, 1996 Gene Kozin Added support for S503 card.
28 * Apr 30, 1996 Gene Kozin SDLA hardware interrupt is acknowledged before
29 * calling protocolspecific ISR.
30 * Register I/O ports with Linux kernel.
31 * Miscellaneous bug fixes.
32 * Dec 20, 1995 Gene Kozin Fixed a bug in interrupt routine.
33 * Oct 14, 1995 Gene Kozin Initial version.
34 *****************************************************************************/
36 /*****************************************************************************
39 * 1. This code is ment to be system-independent (as much as possible). To
40 * achive this, various macros are used to hide system-specific interfaces.
41 * To compile this code, one of the following constants must be defined:
48 * 2. Supported adapter types:
58 * There is no separate DPM window enable/disable control in S502A. It
59 * opens immediately after a window number it written to the HMCR
60 * register. To close the window, HMCR has to be written a value
61 * ????1111b (e.g. 0x0F or 0xFF).
63 * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
65 * There should be a delay of ??? before reading back S502A status
70 * S502E has a h/w bug: although default IRQ line state is HIGH, enabling
71 * interrupts by setting bit 1 of the control register (BASE) to '1'
72 * causes it to go LOW! Therefore, disabling interrupts by setting that
73 * bit to '0' causes low-to-high transition on IRQ line (ghosty
74 * interrupt). The same occurs when disabling CPU by resetting bit 0 of
75 * CPU control register (BASE+3) - see the next note.
77 * S502E CPU and DPM control is limited:
79 * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
80 * control register (BASE+3) shuts the board down entirely, including
83 * o DPM access cannot be controlled dynamically. Ones CPU is started,
84 * bit 1 of the control register (BASE) is used to enable/disable IRQ,
85 * so that access to shared memory cannot be disabled while CPU is
87 ****************************************************************************/
91 #if defined(_LINUX_) /****** Linux *******************************/
93 #include <linux/config.h>
94 #include <linux/kernel.h> /* printk(), and other useful stuff */
95 #include <linux/stddef.h> /* offsetof(), etc. */
96 #include <linux/errno.h> /* return codes */
97 #include <linux/string.h> /* inline memset(), etc. */
98 #include <linux/module.h> /* support for loadable modules */
99 #include <linux/jiffies.h> /* for jiffies, HZ, etc. */
100 #include <linux/sdladrv.h> /* API definitions */
101 #include <linux/sdlasfm.h> /* SDLA firmware module definitions */
102 #include <linux/sdlapci.h> /* SDLA PCI hardware definitions */
103 #include <linux/pci.h> /* PCI defines and function prototypes */
104 #include <asm/io.h> /* for inb(), outb(), etc. */
106 #define _INB(port) (inb(port))
107 #define _OUTB(port, byte) (outb((byte),(port)))
108 #define SYSTEM_TICK jiffies
110 #include <linux/init.h>
113 #elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
115 #if !defined(INKERNEL)
116 #error This code MUST be compiled in kernel mode!
118 #include <sys/sdladrv.h> /* API definitions */
119 #include <sys/sdlasfm.h> /* SDLA firmware module definitions */
120 #include <sys/inline.h> /* for inb(), outb(), etc. */
121 #define _INB(port) (inb(port))
122 #define _OUTB(port, byte) (outb((port),(byte)))
123 #define SYSTEM_TICK lbolt
126 #error Unknown system type!
129 #define MOD_VERSION 3
130 #define MOD_RELEASE 0
132 #define SDLA_IODELAY 100 /* I/O Rd/Wr delay, 10 works for 486DX2-66 */
133 #define EXEC_DELAY 20 /* shared memory access delay, mks */
134 #define EXEC_TIMEOUT (HZ*2) /* command timeout, in ticks */
136 /* I/O port address range */
137 #define S502A_IORANGE 3
138 #define S502E_IORANGE 4
139 #define S503_IORANGE 3
140 #define S507_IORANGE 4
141 #define S508_IORANGE 4
143 /* Maximum amount of memory */
144 #define S502_MAXMEM 0x10000L
145 #define S503_MAXMEM 0x10000L
146 #define S507_MAXMEM 0x40000L
147 #define S508_MAXMEM 0x40000L
149 /* Minimum amount of memory */
150 #define S502_MINMEM 0x8000L
151 #define S503_MINMEM 0x8000L
152 #define S507_MINMEM 0x20000L
153 #define S508_MINMEM 0x20000L
160 /****** Function Prototypes *************************************************/
162 /* Hardware-specific functions */
163 static int sdla_detect (sdlahw_t* hw);
164 static int sdla_autodpm (sdlahw_t* hw);
165 static int sdla_setdpm (sdlahw_t* hw);
166 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);
167 static int sdla_init (sdlahw_t* hw);
168 static unsigned long sdla_memtest (sdlahw_t* hw);
169 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
170 static unsigned char make_config_byte (sdlahw_t* hw);
171 static int sdla_start (sdlahw_t* hw, unsigned addr);
173 static int init_s502a (sdlahw_t* hw);
174 static int init_s502e (sdlahw_t* hw);
175 static int init_s503 (sdlahw_t* hw);
176 static int init_s507 (sdlahw_t* hw);
177 static int init_s508 (sdlahw_t* hw);
179 static int detect_s502a (int port);
180 static int detect_s502e (int port);
181 static int detect_s503 (int port);
182 static int detect_s507 (int port);
183 static int detect_s508 (int port);
184 static int detect_s514 (sdlahw_t* hw);
185 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
187 /* Miscellaneous functions */
188 static void peek_by_4 (unsigned long src, void* buf, unsigned len);
189 static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
190 static int calibrate_delay (int mks);
191 static int get_option_index (unsigned* optlist, unsigned optval);
192 static unsigned check_memregion (void* ptr, unsigned len);
193 static unsigned test_memregion (void* ptr, unsigned len);
194 static unsigned short checksum (unsigned char* buf, unsigned len);
195 static int init_pci_slot(sdlahw_t *);
197 static int pci_probe(sdlahw_t *hw);
199 /****** Global Data **********************************************************
200 * Note: All data must be explicitly initialized!!!
203 static struct pci_device_id sdladrv_pci_tbl[] = {
204 { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
205 { } /* Terminating entry */
207 MODULE_DEVICE_TABLE(pci, sdladrv_pci_tbl);
209 MODULE_LICENSE("GPL");
212 static char modname[] = "sdladrv";
213 static char fullname[] = "SDLA Support Module";
214 static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
215 static unsigned exec_idle;
217 /* Hardware configuration options.
218 * These are arrays of configuration options used by verification routines.
219 * The first element of each array is its size (i.e. number of options).
221 static unsigned s502_port_options[] =
222 { 4, 0x250, 0x300, 0x350, 0x360 }
224 static unsigned s503_port_options[] =
225 { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
227 static unsigned s508_port_options[] =
228 { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
231 static unsigned s502a_irq_options[] = { 0 };
232 static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
233 static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 };
234 static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
236 static unsigned s502a_dpmbase_options[] =
239 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
240 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
241 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
242 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
244 static unsigned s507_dpmbase_options[] =
247 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
248 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
249 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
250 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
252 static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */
255 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
256 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
257 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
258 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
262 static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
263 static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
264 static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
267 static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
268 static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
269 static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 };
270 static unsigned s507_pclk_options[] = { 1, 12288 };
271 static unsigned s508_pclk_options[] = { 1, 16000 };
273 /* Host memory control register masks */
274 static unsigned char s502a_hmcr[] =
276 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, /* A0000 - AC000 */
277 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, /* C0000 - CC000 */
278 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, /* D0000 - DC000 */
279 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, /* E0000 - EC000 */
281 static unsigned char s502e_hmcr[] =
283 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, /* A0000 - AE000 */
284 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, /* C0000 - CE000 */
285 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* D0000 - DE000 */
286 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, /* E0000 - EE000 */
288 static unsigned char s507_hmcr[] =
290 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, /* A0000 - AE000 */
291 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, /* B0000 - BE000 */
292 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, /* C0000 - CE000 */
293 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, /* E0000 - EE000 */
295 static unsigned char s508_hmcr[] =
297 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A0000 - AE000 */
298 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* C0000 - CE000 */
299 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* D0000 - DE000 */
300 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* E0000 - EE000 */
303 static unsigned char s507_irqmask[] =
305 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
308 static int pci_slot_ar[MAX_S514_CARDS];
310 /******* Kernel Loadable Module Entry Points ********************************/
312 /*============================================================================
313 * Module 'insert' entry point.
314 * o print announcement
315 * o initialize static data
316 * o calibrate SDLA shared memory access delay.
323 static int __init sdladrv_init(void)
327 printk(KERN_INFO "%s v%u.%u %s\n",
328 fullname, MOD_VERSION, MOD_RELEASE, copyright);
329 exec_idle = calibrate_delay(EXEC_DELAY);
331 printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
334 /* Initialize the PCI Card array, which
335 * will store flags, used to mark
336 * card initialization state */
337 for (i=0; i<MAX_S514_CARDS; i++)
338 pci_slot_ar[i] = 0xFF;
343 /*============================================================================
344 * Module 'remove' entry point.
345 * o release all remaining system resources
347 static void __exit sdladrv_cleanup(void)
351 module_init(sdladrv_init);
352 module_exit(sdladrv_cleanup);
354 /******* Kernel APIs ********************************************************/
356 /*============================================================================
358 * o detect adapter type
359 * o verify hardware configuration options
360 * o check for hardware conflicts
361 * o set up adapter shared memory
362 * o test adapter memory
368 EXPORT_SYMBOL(sdla_setup);
370 int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
372 unsigned* irq_opt = NULL; /* IRQ options */
373 unsigned* dpmbase_opt = NULL; /* DPM window base options */
374 unsigned* pclk_opt = NULL; /* CPU clock rate options */
377 if (sdla_detect(hw)) {
378 if(hw->type != SDLA_S514)
379 printk(KERN_INFO "%s: no SDLA card found at port 0x%X\n",
384 if(hw->type != SDLA_S514) {
385 printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
386 modname, hw->type, hw->port);
388 hw->dpmsize = SDLA_WINDOWSIZE;
391 hw->io_range = S502A_IORANGE;
392 irq_opt = s502a_irq_options;
393 dpmbase_opt = s502a_dpmbase_options;
394 pclk_opt = s502a_pclk_options;
398 hw->io_range = S502E_IORANGE;
399 irq_opt = s502e_irq_options;
400 dpmbase_opt = s508_dpmbase_options;
401 pclk_opt = s502e_pclk_options;
405 hw->io_range = S503_IORANGE;
406 irq_opt = s503_irq_options;
407 dpmbase_opt = s508_dpmbase_options;
408 pclk_opt = s503_pclk_options;
412 hw->io_range = S507_IORANGE;
413 irq_opt = s508_irq_options;
414 dpmbase_opt = s507_dpmbase_options;
415 pclk_opt = s507_pclk_options;
419 hw->io_range = S508_IORANGE;
420 irq_opt = s508_irq_options;
421 dpmbase_opt = s508_dpmbase_options;
422 pclk_opt = s508_pclk_options;
426 /* Verify IRQ configuration options */
427 if (!get_option_index(irq_opt, hw->irq)) {
428 printk(KERN_INFO "%s: IRQ %d is invalid!\n",
433 /* Verify CPU clock rate configuration options */
435 hw->pclk = pclk_opt[1]; /* use default */
437 else if (!get_option_index(pclk_opt, hw->pclk)) {
438 printk(KERN_INFO "%s: CPU clock %u is invalid!\n",
442 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
445 /* Setup adapter dual-port memory window and test memory */
446 if (hw->dpmbase == 0) {
447 err = sdla_autodpm(hw);
450 "%s: can't find available memory region!\n",
455 else if (!get_option_index(dpmbase_opt,
456 virt_to_phys(hw->dpmbase))) {
458 "%s: memory address 0x%lX is invalid!\n",
459 modname, virt_to_phys(hw->dpmbase));
462 else if (sdla_setdpm(hw)) {
464 "%s: 8K memory region at 0x%lX is not available!\n",
465 modname, virt_to_phys(hw->dpmbase));
469 "%s: dual-port memory window is set at 0x%lX.\n",
470 modname, virt_to_phys(hw->dpmbase));
473 /* If we find memory in 0xE**** Memory region,
474 * warn the user to disable the SHADOW RAM.
475 * Since memory corruption can occur if SHADOW is
476 * enabled. This can causes random crashes ! */
477 if (virt_to_phys(hw->dpmbase) >= 0xE0000){
478 printk(KERN_WARNING "\n%s: !!!!!!!! WARNING !!!!!!!!\n",modname);
479 printk(KERN_WARNING "%s: WANPIPE is using 0x%lX memory region !!!\n",
480 modname, virt_to_phys(hw->dpmbase));
481 printk(KERN_WARNING " Please disable the SHADOW RAM, otherwise\n");
482 printk(KERN_WARNING " your system might crash randomly from time to time !\n");
483 printk(KERN_WARNING "%s: !!!!!!!! WARNING !!!!!!!!\n\n",modname);
488 hw->memory = test_memregion((void*)hw->dpmbase,
489 MAX_SIZEOF_S514_MEMORY);
490 if(hw->memory < (256 * 1024)) {
492 "%s: error in testing S514 memory (0x%lX)\n",
493 modname, hw->memory);
499 printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
500 modname, hw->memory / 1024);
502 /* Load firmware. If loader fails then shut down adapter */
503 err = sdla_load(hw, sfm, len);
504 if (err) sdla_down(hw); /* shutdown adapter */
509 /*============================================================================
510 * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
513 EXPORT_SYMBOL(sdla_down);
515 int sdla_down (sdlahw_t* hw)
517 unsigned port = hw->port;
519 unsigned char CPU_no;
520 u32 int_config, int_status;
522 if(!port && (hw->type != SDLA_S514))
527 _OUTB(port, 0x08); /* halt CPU */
531 _OUTB(port + 1, 0xFF); /* close memory window */
536 _OUTB(port + 3, 0); /* stop CPU */
537 _OUTB(port, 0); /* reset board */
538 for (i = 0; i < S502E_IORANGE; ++i)
546 _OUTB(port, 0); /* reset board logic */
551 /* halt the adapter */
552 *(char *)hw->vector = S514_CPU_HALT;
553 CPU_no = hw->S514_cpu_no[0];
555 /* disable the PCI IRQ and disable memory access */
556 pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config);
557 int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B;
558 pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config);
559 read_S514_int_stat(hw, &int_status);
560 S514_intack(hw, int_status);
561 if(CPU_no == S514_CPU_A)
562 pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD,
563 PCI_CPU_A_MEM_DISABLE);
565 pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
566 PCI_CPU_B_MEM_DISABLE);
568 /* free up the allocated virtual memory */
569 iounmap((void *)hw->dpmbase);
570 iounmap((void *)hw->vector);
580 /*============================================================================
581 * Map shared memory window into SDLA address space.
584 EXPORT_SYMBOL(sdla_mapmem);
586 int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
588 unsigned port = hw->port;
594 if (addr < S502_MAXMEM) { /* verify parameter */
595 tmp = addr >> 13; /* convert to register mask */
596 _OUTB(port + 2, tmp);
603 if (addr < S503_MAXMEM) { /* verify parameter */
604 tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
612 if (addr < S507_MAXMEM) {
613 if (!(_INB(port) & 0x02))
615 tmp = addr >> 13; /* convert to register mask */
616 _OUTB(port + 2, tmp);
623 if (addr < S508_MAXMEM) {
624 tmp = addr >> 13; /* convert to register mask */
625 _OUTB(port + 2, tmp);
637 hw->vector = addr & 0xFFFFE000L;
641 /*============================================================================
642 * Enable interrupt generation.
645 EXPORT_SYMBOL(sdla_inten);
647 int sdla_inten (sdlahw_t* hw)
649 unsigned port = hw->port;
654 /* Note thar interrupt control operations on S502E are allowed
655 * only if CPU is enabled (bit 0 of status register is set).
657 if (_INB(port) & 0x01) {
658 _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
659 _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
666 tmp = hw->regs[0] | 0x04;
668 hw->regs[0] = tmp; /* update mirror */
669 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
670 if (!(_INB(port) & 0x02)) /* verify */
675 tmp = hw->regs[0] | 0x10;
677 hw->regs[0] = tmp; /* update mirror */
678 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
679 if (!(_INB(port + 1) & 0x10)) /* verify */
697 /*============================================================================
698 * Disable interrupt generation.
701 EXPORT_SYMBOL(sdla_intde);
703 int sdla_intde (sdlahw_t* hw)
705 unsigned port = hw->port;
711 * 1) interrupt control operations are allowed only if CPU is
712 * enabled (bit 0 of status register is set).
713 * 2) disabling interrupts using bit 1 of control register
714 * causes IRQ line go high, therefore we are going to use
715 * 0x04 instead: lower it to inhibit interrupts to PC.
717 if (_INB(port) & 0x01) {
718 _OUTB(port, hw->regs[0] & ~0x04);
719 hw->regs[0] &= ~0x04;
725 tmp = hw->regs[0] & ~0x04;
727 hw->regs[0] = tmp; /* update mirror */
728 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
729 if (_INB(port) & 0x02) /* verify */
734 tmp = hw->regs[0] & ~0x10;
736 hw->regs[0] = tmp; /* update mirror */
737 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
738 if (_INB(port) & 0x10) /* verify */
752 /*============================================================================
753 * Acknowledge SDLA hardware interrupt.
756 EXPORT_SYMBOL(sdla_intack);
758 int sdla_intack (sdlahw_t* hw)
760 unsigned port = hw->port;
765 /* To acknoledge hardware interrupt we have to toggle bit 3 of
766 * control register: \_/
767 * Note that interrupt control operations on S502E are allowed
768 * only if CPU is enabled (bit 1 of status register is set).
770 if (_INB(port) & 0x01) {
771 tmp = hw->regs[0] & ~0x04;
781 if (_INB(port) & 0x04) {
782 tmp = hw->regs[0] & ~0x08;
802 /*============================================================================
803 * Acknowledge S514 hardware interrupt.
806 EXPORT_SYMBOL(S514_intack);
808 void S514_intack (sdlahw_t* hw, u32 int_status)
810 pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
814 /*============================================================================
815 * Read the S514 hardware interrupt status.
818 EXPORT_SYMBOL(read_S514_int_stat);
820 void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
822 pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
826 /*============================================================================
827 * Generate an interrupt to adapter's CPU.
830 EXPORT_SYMBOL(sdla_intr);
832 int sdla_intr (sdlahw_t* hw)
834 unsigned port = hw->port;
838 if (!(_INB(port) & 0x40)) {
839 _OUTB(port, 0x10); /* issue NMI to CPU */
846 if ((_INB(port) & 0x06) == 0x06) {
853 if (_INB(port + 1) & 0x02) {
867 /*============================================================================
868 * Execute Adapter Command.
870 * o Busy-wait until flag is reset.
871 * o Return number of loops made, or 0 if command timed out.
874 EXPORT_SYMBOL(sdla_exec);
876 int sdla_exec (void* opflag)
878 volatile unsigned char* flag = opflag;
882 if(readb(flag) != 0x00) {
884 "WANPIPE: opp flag set on entry to sdla_exec\n");
890 tstop = SYSTEM_TICK + EXEC_TIMEOUT;
892 for (nloops = 1; (readb(flag) == 0x01); ++ nloops) {
893 unsigned delay = exec_idle;
894 while (-- delay); /* delay */
895 if (SYSTEM_TICK > tstop) return 0; /* time is up! */
900 /*============================================================================
901 * Read absolute adapter memory.
902 * Transfer data from adapter's memory to data buffer.
905 * Care should be taken when crossing dual-port memory window boundary.
906 * This function is not atomic, so caller must disable interrupt if
907 * interrupt routines are accessing adapter shared memory.
910 EXPORT_SYMBOL(sdla_peek);
912 int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
915 if (addr + len > hw->memory) /* verify arguments */
918 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
919 peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
923 else { /* copy data for the S508 adapter */
924 unsigned long oldvec = hw->vector;
925 unsigned winsize = hw->dpmsize;
926 unsigned curpos, curlen; /* current offset and block size */
927 unsigned long curvec; /* current DPM window vector */
930 while (len && !err) {
931 curpos = addr % winsize; /* current window offset */
932 curvec = addr - curpos; /* current window vector */
933 curlen = (len > (winsize - curpos)) ?
934 (winsize - curpos) : len;
935 /* Relocate window and copy block of data */
936 err = sdla_mapmem(hw, curvec);
937 peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
940 buf = (char*)buf + curlen;
944 /* Restore DPM window position */
945 sdla_mapmem(hw, oldvec);
951 /*============================================================================
952 * Read data from adapter's memory to a data buffer in 4-byte chunks.
953 * Note that we ensure that the SDLA memory address is on a 4-byte boundary
954 * before we begin moving the data in 4-byte chunks.
957 static void peek_by_4 (unsigned long src, void* buf, unsigned len)
960 /* byte copy data until we get to a 4-byte boundary */
961 while (len && (src & 0x03)) {
962 *(char *)buf ++ = readb(src ++);
966 /* copy data in 4-byte chunks */
968 *(unsigned long *)buf = readl(src);
974 /* byte copy any remaining data */
976 *(char *)buf ++ = readb(src ++);
982 /*============================================================================
983 * Write Absolute Adapter Memory.
984 * Transfer data from data buffer to adapter's memory.
987 * Care should be taken when crossing dual-port memory window boundary.
988 * This function is not atomic, so caller must disable interrupt if
989 * interrupt routines are accessing adapter shared memory.
992 EXPORT_SYMBOL(sdla_poke);
994 int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
997 if (addr + len > hw->memory) /* verify arguments */
1000 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
1001 poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
1005 else { /* copy data for the S508 adapter */
1006 unsigned long oldvec = hw->vector;
1007 unsigned winsize = hw->dpmsize;
1008 unsigned curpos, curlen; /* current offset and block size */
1009 unsigned long curvec; /* current DPM window vector */
1012 while (len && !err) {
1013 curpos = addr % winsize; /* current window offset */
1014 curvec = addr - curpos; /* current window vector */
1015 curlen = (len > (winsize - curpos)) ?
1016 (winsize - curpos) : len;
1017 /* Relocate window and copy block of data */
1018 sdla_mapmem(hw, curvec);
1019 poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
1022 buf = (char*)buf + curlen;
1026 /* Restore DPM window position */
1027 sdla_mapmem(hw, oldvec);
1033 /*============================================================================
1034 * Write from a data buffer to adapter's memory in 4-byte chunks.
1035 * Note that we ensure that the SDLA memory address is on a 4-byte boundary
1036 * before we begin moving the data in 4-byte chunks.
1039 static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
1042 /* byte copy data until we get to a 4-byte boundary */
1043 while (len && (dest & 0x03)) {
1044 writeb (*(char *)buf ++, dest ++);
1048 /* copy data in 4-byte chunks */
1050 writel (*(unsigned long *)buf, dest);
1056 /* byte copy any remaining data */
1058 writeb (*(char *)buf ++ , dest ++);
1064 #ifdef DONT_COMPIPLE_THIS
1065 #endif /* DONT_COMPIPLE_THIS */
1067 /****** Hardware-Specific Functions *****************************************/
1069 /*============================================================================
1070 * Detect adapter type.
1071 * o if adapter type is specified then call detection routine for that adapter
1072 * type. Otherwise call detection routines for every adapter types until
1073 * adapter is detected.
1076 * 1) Detection tests are destructive! Adapter will be left in shutdown state
1079 static int sdla_detect (sdlahw_t* hw)
1081 unsigned port = hw->port;
1084 if (!port && (hw->type != SDLA_S514))
1089 if (!detect_s502a(port)) err = -ENODEV;
1093 if (!detect_s502e(port)) err = -ENODEV;
1097 if (!detect_s503(port)) err = -ENODEV;
1101 if (!detect_s507(port)) err = -ENODEV;
1105 if (!detect_s508(port)) err = -ENODEV;
1109 if (!detect_s514(hw)) err = -ENODEV;
1113 if (detect_s502a(port))
1114 hw->type = SDLA_S502A;
1115 else if (detect_s502e(port))
1116 hw->type = SDLA_S502E;
1117 else if (detect_s503(port))
1118 hw->type = SDLA_S503;
1119 else if (detect_s507(port))
1120 hw->type = SDLA_S507;
1121 else if (detect_s508(port))
1122 hw->type = SDLA_S508;
1128 /*============================================================================
1129 * Autoselect memory region.
1130 * o try all available DMP address options from the top down until success.
1132 static int sdla_autodpm (sdlahw_t* hw)
1134 int i, err = -EINVAL;
1139 opt = s502a_dpmbase_options;
1145 opt = s508_dpmbase_options;
1149 opt = s507_dpmbase_options;
1156 /* Start testing from 8th position, address
1157 * 0xC8000 from the 508 address table.
1158 * We don't want to test A**** addresses, since
1159 * they are usually used for Video */
1160 for (i = 8; i <= opt[0] && err; i++) {
1161 hw->dpmbase = phys_to_virt(opt[i]);
1162 err = sdla_setdpm(hw);
1167 /*============================================================================
1168 * Set up adapter dual-port memory window.
1169 * o shut down adapter
1170 * o make sure that no physical memory exists in this region, i.e entire
1171 * region reads 0xFF and is not writable when adapter is shut down.
1172 * o initialize adapter hardware
1173 * o make sure that region is usable with SDLA card, i.e. we can write to it
1174 * when adapter is configured.
1176 static int sdla_setdpm (sdlahw_t* hw)
1180 /* Shut down card and verify memory region */
1182 if (check_memregion(hw->dpmbase, hw->dpmsize))
1185 /* Initialize adapter and test on-board memory segment by segment.
1186 * If memory size appears to be less than shared memory window size,
1187 * assume that memory region is unusable.
1189 err = sdla_init(hw);
1190 if (err) return err;
1192 if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */
1196 sdla_mapmem(hw, 0L); /* set window vector at bottom */
1200 /*============================================================================
1201 * Load adapter from the memory image of the SDLA firmware module.
1202 * o verify firmware integrity and compatibility
1203 * o start adapter up
1205 static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1210 /* Verify firmware signature */
1211 if (strcmp(sfm->signature, SFM_SIGNATURE)) {
1212 printk(KERN_INFO "%s: not SDLA firmware!\n",
1217 /* Verify firmware module format version */
1218 if (sfm->version != SFM_VERSION) {
1220 "%s: firmware format %u rejected! Expecting %u.\n",
1221 modname, sfm->version, SFM_VERSION);
1225 /* Verify firmware module length and checksum */
1226 if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
1227 (checksum((void*)&sfm->info,
1228 sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) {
1229 printk(KERN_INFO "%s: firmware corrupted!\n", modname);
1234 printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1235 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1238 if(hw->type == SDLA_S514)
1239 printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
1240 modname, hw->S514_cpu_no[0]);
1242 /* Scan through the list of compatible adapters and make sure our
1243 * adapter type is listed.
1246 (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1249 if (i == SFM_MAX_SDLA) {
1250 printk(KERN_INFO "%s: firmware is not compatible with S%u!\n",
1256 /* Make sure there is enough on-board memory */
1257 if (hw->memory < sfm->info.memsize) {
1259 "%s: firmware needs %lu bytes of on-board memory!\n",
1260 modname, sfm->info.memsize);
1264 /* Move code onto adapter */
1265 if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) {
1266 printk(KERN_INFO "%s: failed to load code segment!\n",
1271 /* Prepare boot-time configuration data and kick-off CPU */
1272 sdla_bootcfg(hw, &sfm->info);
1273 if (sdla_start(hw, sfm->info.startoffs)) {
1274 printk(KERN_INFO "%s: Damn... Adapter won't start!\n",
1279 /* position DPM window over the mailbox and enable interrupts */
1280 if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) {
1281 printk(KERN_INFO "%s: adapter hardware failure!\n",
1285 hw->fwid = sfm->info.codeid; /* set firmware ID */
1289 /*============================================================================
1290 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1292 static int sdla_init (sdlahw_t* hw)
1296 for (i = 0; i < SDLA_MAXIORANGE; ++i)
1300 case SDLA_S502A: return init_s502a(hw);
1301 case SDLA_S502E: return init_s502e(hw);
1302 case SDLA_S503: return init_s503(hw);
1303 case SDLA_S507: return init_s507(hw);
1304 case SDLA_S508: return init_s508(hw);
1309 /*============================================================================
1310 * Test adapter on-board memory.
1311 * o slide DPM window from the bottom up and test adapter memory segment by
1313 * Return adapter memory size.
1315 static unsigned long sdla_memtest (sdlahw_t* hw)
1317 unsigned long memsize;
1320 for (memsize = 0, winsize = hw->dpmsize;
1321 !sdla_mapmem(hw, memsize) &&
1322 (test_memregion(hw->dpmbase, winsize) == winsize)
1326 hw->memory = memsize;
1330 /*============================================================================
1331 * Prepare boot-time firmware configuration data.
1332 * o position DPM window
1333 * o initialize configuration data area
1335 static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1337 unsigned char* data;
1339 if (!sfminfo->datasize) return 0; /* nothing to do */
1341 if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1344 if(hw->type == SDLA_S514)
1345 data = (void*)(hw->dpmbase + sfminfo->dataoffs);
1347 data = (void*)((u8 *)hw->dpmbase +
1348 (sfminfo->dataoffs - hw->vector));
1350 memset_io (data, 0, sfminfo->datasize);
1352 writeb (make_config_byte(hw), &data[0x00]);
1354 switch (sfminfo->codeid) {
1357 writeb (3, &data[0x01]); /* T1 timer */
1358 writeb (10, &data[0x03]); /* N2 */
1359 writeb (7, &data[0x06]); /* HDLC window size */
1360 writeb (1, &data[0x0B]); /* DTE */
1361 writeb (2, &data[0x0C]); /* X.25 packet window size */
1362 writew (128, &data[0x0D]); /* default X.25 data size */
1363 writew (128, &data[0x0F]); /* maximum X.25 data size */
1369 /*============================================================================
1370 * Prepare configuration byte identifying adapter type and CPU clock rate.
1372 static unsigned char make_config_byte (sdlahw_t* hw)
1374 unsigned char byte = 0;
1377 case 5000: byte = 0x01; break;
1378 case 7200: byte = 0x02; break;
1379 case 8000: byte = 0x03; break;
1380 case 10000: byte = 0x04; break;
1381 case 16000: byte = 0x05; break;
1385 case SDLA_S502E: byte |= 0x80; break;
1386 case SDLA_S503: byte |= 0x40; break;
1391 /*============================================================================
1392 * Start adapter's CPU.
1393 * o calculate a pointer to adapter's cold boot entry point
1394 * o position DPM window
1395 * o place boot instruction (jp addr) at cold boot entry point
1398 static int sdla_start (sdlahw_t* hw, unsigned addr)
1400 unsigned port = hw->port;
1401 unsigned char *bootp;
1404 if (!port && (hw->type != SDLA_S514)) return -EFAULT;
1408 bootp = hw->dpmbase;
1417 bootp = hw->dpmbase;
1424 err = sdla_mapmem(hw, 0);
1425 if (err) return err;
1427 writeb (0xC3, bootp); /* Z80: 'jp' opcode */
1429 writew (addr, bootp);
1433 _OUTB(port, 0x10); /* issue NMI to CPU */
1438 _OUTB(port + 3, 0x01); /* start CPU */
1440 for (i = 0; i < SDLA_IODELAY; ++i);
1441 if (_INB(port) & 0x01) { /* verify */
1443 * Enabling CPU changes functionality of the
1444 * control register, so we have to reset its
1447 _OUTB(port, 0); /* disable interrupts */
1454 tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */
1456 hw->regs[0] = tmp; /* update mirror */
1457 for (i = 0; i < SDLA_IODELAY; ++i);
1458 if (!(_INB(port) & 0x01)) /* verify */
1463 tmp = hw->regs[0] | 0x02;
1465 hw->regs[0] = tmp; /* update mirror */
1466 for (i = 0; i < SDLA_IODELAY; ++i);
1467 if (!(_INB(port) & 0x04)) /* verify */
1472 tmp = hw->regs[0] | 0x02;
1474 hw->regs[0] = tmp; /* update mirror */
1475 for (i = 0; i < SDLA_IODELAY; ++i);
1476 if (!(_INB(port + 1) & 0x02)) /* verify */
1481 writeb (S514_CPU_START, hw->vector);
1490 /*============================================================================
1491 * Initialize S502A adapter.
1493 static int init_s502a (sdlahw_t* hw)
1495 unsigned port = hw->port;
1498 if (!detect_s502a(port))
1504 /* Verify configuration options */
1505 i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1509 tmp = s502a_hmcr[i - 1];
1510 switch (hw->dpmsize) {
1522 /* Setup dual-port memory window (this also enables memory access) */
1523 _OUTB(port + 1, tmp);
1529 /*============================================================================
1530 * Initialize S502E adapter.
1532 static int init_s502e (sdlahw_t* hw)
1534 unsigned port = hw->port;
1537 if (!detect_s502e(port))
1540 /* Verify configuration options */
1541 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1545 tmp = s502e_hmcr[i - 1];
1546 switch (hw->dpmsize) {
1558 /* Setup dual-port memory window */
1559 _OUTB(port + 1, tmp);
1562 /* Enable memory access */
1565 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1566 return (_INB(port) & 0x02) ? 0 : -EIO;
1569 /*============================================================================
1570 * Initialize S503 adapter.
1571 * ---------------------------------------------------------------------------
1573 static int init_s503 (sdlahw_t* hw)
1575 unsigned port = hw->port;
1578 if (!detect_s503(port))
1581 /* Verify configuration options */
1582 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1586 tmp = s502e_hmcr[i - 1];
1587 switch (hw->dpmsize) {
1599 /* Setup dual-port memory window */
1600 _OUTB(port + 1, tmp);
1603 /* Enable memory access */
1605 hw->regs[0] = 0x02; /* update mirror */
1609 /*============================================================================
1610 * Initialize S507 adapter.
1612 static int init_s507 (sdlahw_t* hw)
1614 unsigned port = hw->port;
1617 if (!detect_s507(port))
1620 /* Verify configuration options */
1621 i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1625 tmp = s507_hmcr[i - 1];
1626 switch (hw->dpmsize) {
1638 /* Enable adapter's logic */
1641 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1642 if (!(_INB(port) & 0x20))
1645 /* Setup dual-port memory window */
1646 _OUTB(port + 1, tmp);
1649 /* Enable memory access */
1650 tmp = hw->regs[0] | 0x04;
1652 i = get_option_index(s508_irq_options, hw->irq);
1653 if (i) tmp |= s507_irqmask[i - 1];
1656 hw->regs[0] = tmp; /* update mirror */
1657 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1658 return (_INB(port) & 0x08) ? 0 : -EIO;
1661 /*============================================================================
1662 * Initialize S508 adapter.
1664 static int init_s508 (sdlahw_t* hw)
1666 unsigned port = hw->port;
1669 if (!detect_s508(port))
1672 /* Verify configuration options */
1673 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1677 /* Setup memory configuration */
1678 tmp = s508_hmcr[i - 1];
1679 _OUTB(port + 1, tmp);
1682 /* Enable memory access */
1684 hw->regs[0] = 0x04; /* update mirror */
1685 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1686 return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1689 /*============================================================================
1690 * Detect S502A adapter.
1691 * Following tests are used to detect S502A adapter:
1692 * 1. All registers other than status (BASE) should read 0xFF
1693 * 2. After writing 00001000b to control register, status register should
1695 * 3. After writing 0 to control register, status register should still
1697 * 4. After writing 00000100b to control register, status register should
1699 * Return 1 if detected o.k. or 0 if failed.
1700 * Note: This test is destructive! Adapter will be left in shutdown
1701 * state after the test.
1703 static int detect_s502a (int port)
1707 if (!get_option_index(s502_port_options, port))
1710 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1711 if (_INB(port + j) != 0xFF)
1713 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1716 _OUTB(port, 0x08); /* halt CPU */
1719 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1720 if (_INB(port) != 0x40)
1723 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1724 if (_INB(port) != 0x40)
1727 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1728 if (_INB(port) != 0x44)
1735 _OUTB(port + 1, 0xFF);
1739 /*============================================================================
1740 * Detect S502E 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 CPU control register (BASE+3), status register
1744 * (BASE) should read 11111000b.
1745 * 3. After writing 00000100b to port BASE (set bit 2), status register
1746 * (BASE) should read 11111100b.
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_s502e (int port)
1755 if (!get_option_index(s502_port_options, port))
1757 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1758 if (_INB(port + j) != 0xFF)
1760 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1763 _OUTB(port + 3, 0); /* CPU control reg. */
1764 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1765 if (_INB(port) != 0xF8) /* read status */
1767 _OUTB(port, 0x04); /* set bit 2 */
1768 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1769 if (_INB(port) != 0xFC) /* verify */
1777 /*============================================================================
1778 * Detect s503 adapter.
1779 * Following tests are used to verify adapter presence:
1780 * 1. All registers other than status (BASE) should read 0xFF.
1781 * 2. After writing 0 to control register (BASE), status register (BASE)
1782 * should read 11110000b.
1783 * 3. After writing 00000100b (set bit 2) to control register (BASE),
1784 * status register should read 11110010b.
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_s503 (int port)
1793 if (!get_option_index(s503_port_options, port))
1795 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1796 if (_INB(port + j) != 0xFF)
1798 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1801 _OUTB(port, 0); /* reset control reg.*/
1802 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1803 if (_INB(port) != 0xF0) /* read status */
1805 _OUTB(port, 0x04); /* set bit 2 */
1806 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1807 if (_INB(port) != 0xF2) /* verify */
1815 /*============================================================================
1816 * Detect s507 adapter.
1817 * Following tests are used to detect s507 adapter:
1818 * 1. All ports should read the same value.
1819 * 2. After writing 0x00 to control register, status register should read
1821 * 3. After writing 0x01 to control register, status register should read
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_s507 (int port)
1831 if (!get_option_index(s508_port_options, port))
1834 for (j = 1; j < S507_IORANGE; ++j) {
1835 if (_INB(port + j) != tmp)
1837 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1841 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1842 if ((_INB(port) & 0x7E) != 0x30)
1845 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1846 if ((_INB(port) & 0x7E) != 0x32)
1854 /*============================================================================
1855 * Detect s508 adapter.
1856 * Following tests are used to detect s508 adapter:
1857 * 1. After writing 0x00 to control register, status register should read
1859 * 2. After writing 0x10 to control register, status register should read
1861 * Return 1 if detected o.k. or 0 if failed.
1862 * Note: This test is destructive! Adapter will be left in shutdown
1863 * state after the test.
1865 static int detect_s508 (int port)
1869 if (!get_option_index(s508_port_options, port))
1872 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1873 if ((_INB(port + 1) & 0x3F) != 0x00)
1876 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1877 if ((_INB(port + 1) & 0x3F) != 0x10)
1885 /*============================================================================
1886 * Detect s514 PCI adapter.
1887 * Return 1 if detected o.k. or 0 if failed.
1888 * Note: This test is destructive! Adapter will be left in shutdown
1889 * state after the test.
1891 static int detect_s514 (sdlahw_t* hw)
1893 unsigned char CPU_no, slot_no, auto_slot_cfg;
1894 int number_S514_cards = 0;
1895 u32 S514_mem_base_addr = 0;
1897 struct pci_dev *pci_dev;
1901 printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname);
1906 The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
1907 slot number defined in 'router.conf' via the 'port' definition.
1909 CPU_no = hw->S514_cpu_no[0];
1910 slot_no = hw->S514_slot_no;
1911 auto_slot_cfg = hw->auto_pci_cfg;
1914 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot=Auto\n",
1918 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot #%d\n",
1919 modname, CPU_no, slot_no);
1922 /* check to see that CPU A or B has been selected in 'router.conf' */
1929 printk(KERN_INFO "%s: S514 CPU definition invalid.\n",
1931 printk(KERN_INFO "Must be 'A' or 'B'\n");
1935 number_S514_cards = find_s514_adapter(hw, 0);
1936 if(!number_S514_cards)
1939 /* we are using a single S514 adapter with a slot of 0 so re-read the */
1940 /* location of this adapter */
1941 if((number_S514_cards == 1) && auto_slot_cfg) {
1942 number_S514_cards = find_s514_adapter(hw, 1);
1943 if(!number_S514_cards) {
1944 printk(KERN_INFO "%s: Error finding PCI card\n",
1950 pci_dev = hw->pci_dev;
1951 /* read the physical memory base address */
1952 S514_mem_base_addr = (CPU_no == S514_CPU_A) ?
1953 (pci_dev->resource[1].start) :
1954 (pci_dev->resource[2].start);
1956 printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n",
1957 modname, S514_mem_base_addr);
1958 if(!S514_mem_base_addr) {
1959 if(CPU_no == S514_CPU_B)
1960 printk(KERN_INFO "%s: CPU #B not present on the card\n", modname);
1962 printk(KERN_INFO "%s: No PCI memory allocated to card\n", modname);
1966 /* enable the PCI memory */
1967 pci_read_config_dword(pci_dev,
1968 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1970 pci_write_config_dword(pci_dev,
1971 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1972 (ut_u32 | PCI_MEMORY_ENABLE));
1974 /* check the IRQ allocated and enable IRQ usage */
1975 if(!(hw->irq = pci_dev->irq)) {
1976 printk(KERN_INFO "%s: IRQ not allocated to S514 adapter\n",
1981 /* BUG FIX : Mar 6 2000
1982 * On a initial loading of the card, we must check
1983 * and clear PCI interrupt bits, due to a reset
1984 * problem on some other boards. i.e. An interrupt
1985 * might be pending, even after system bootup,
1986 * in which case, when starting wanrouter the machine
1989 if (init_pci_slot(hw))
1992 pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32);
1993 ut_u32 |= (CPU_no == S514_CPU_A) ?
1994 PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B;
1995 pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32);
1997 printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
2000 /* map the physical PCI memory to virtual memory */
2001 (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
2002 (unsigned long)MAX_SIZEOF_S514_MEMORY);
2003 /* map the physical control register memory to virtual memory */
2004 hw->vector = (unsigned long)ioremap(
2005 (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE),
2008 if(!hw->dpmbase || !hw->vector) {
2009 printk(KERN_INFO "%s: PCI virtual memory allocation failed\n",
2014 /* halt the adapter */
2015 writeb (S514_CPU_HALT, hw->vector);
2020 /*============================================================================
2021 * Find the S514 PCI adapter in the PCI bus.
2022 * Return the number of S514 adapters found (0 if no adapter found).
2024 static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
2026 unsigned char slot_no;
2027 int number_S514_cards = 0;
2028 char S514_found_in_slot = 0;
2029 u16 PCI_subsys_vendor;
2031 struct pci_dev *pci_dev = NULL;
2033 slot_no = hw->S514_slot_no;
2035 while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2038 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2039 &PCI_subsys_vendor);
2041 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2044 hw->pci_dev = pci_dev;
2046 if(find_first_S514_card)
2049 number_S514_cards ++;
2052 "%s: S514 card found, slot #%d (devfn 0x%X)\n",
2053 modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2056 if (hw->auto_pci_cfg){
2057 hw->S514_slot_no = ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK);
2058 slot_no = hw->S514_slot_no;
2060 }else if (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == slot_no){
2061 S514_found_in_slot = 1;
2066 /* if no S514 adapter has been found, then exit */
2067 if (!number_S514_cards) {
2068 printk(KERN_INFO "%s: Error, no S514 adapters found\n", modname);
2071 /* 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 */
2072 else if ((number_S514_cards > 1) && hw->auto_pci_cfg) {
2073 printk(KERN_INFO "%s: Error, PCI Slot autodetect Failed! \n"
2074 "%s: More than one S514 adapter found.\n"
2075 "%s: Disable the Autodetect feature and supply\n"
2076 "%s: the PCISLOT numbers for each card.\n",
2077 modname,modname,modname,modname);
2080 /* if the user has specified a slot number and the S514 adapter has */
2081 /* not been found in that slot, then exit */
2082 else if (!hw->auto_pci_cfg && !S514_found_in_slot) {
2084 "%s: Error, S514 card not found in specified slot #%d\n",
2089 return (number_S514_cards);
2094 /******* Miscellaneous ******************************************************/
2096 /*============================================================================
2097 * Calibrate SDLA memory access delay.
2098 * Count number of idle loops made within 1 second and then calculate the
2099 * number of loops that should be made to achive desired delay.
2101 static int calibrate_delay (int mks)
2106 for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
2107 return (delay/(1000000L/mks) + 1);
2110 /*============================================================================
2111 * Get option's index into the options list.
2112 * Return option's index (1 .. N) or zero if option is invalid.
2114 static int get_option_index (unsigned* optlist, unsigned optval)
2118 for (i = 1; i <= optlist[0]; ++i)
2119 if ( optlist[i] == optval)
2124 /*============================================================================
2125 * Check memory region to see if it's available.
2128 static unsigned check_memregion (void* ptr, unsigned len)
2130 volatile unsigned char* p = ptr;
2132 for (; len && (readb (p) == 0xFF); --len, ++p) {
2133 writeb (0, p); /* attempt to write 0 */
2134 if (readb(p) != 0xFF) { /* still has to read 0xFF */
2135 writeb (0xFF, p);/* restore original value */
2136 break; /* not good */
2143 /*============================================================================
2144 * Test memory region.
2145 * Return: size of the region that passed the test.
2146 * Note: Region size must be multiple of 2 !
2148 static unsigned test_memregion (void* ptr, unsigned len)
2150 volatile unsigned short* w_ptr;
2151 unsigned len_w = len >> 1; /* region len in words */
2154 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2155 writew (0xAA55, w_ptr);
2157 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2158 if (readw (w_ptr) != 0xAA55) {
2163 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2164 writew (0x55AA, w_ptr);
2166 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2167 if (readw(w_ptr) != 0x55AA) {
2172 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2178 /*============================================================================
2179 * Calculate 16-bit CRC using CCITT polynomial.
2181 static unsigned short checksum (unsigned char* buf, unsigned len)
2183 unsigned short crc = 0;
2184 unsigned mask, flag;
2186 for (; len; --len, ++buf) {
2187 for (mask = 0x80; mask; mask >>= 1) {
2188 flag = (crc & 0x8000);
2190 crc |= ((*buf & mask) ? 1 : 0);
2191 if (flag) crc ^= 0x1021;
2197 static int init_pci_slot(sdlahw_t *hw)
2201 int volatile found=0;
2204 /* Check if this is a very first load for a specific
2205 * pci card. If it is, clear the interrput bits, and
2206 * set the flag indicating that this card was initialized.
2209 for (i=0; (i<MAX_S514_CARDS) && !found; i++){
2210 if (pci_slot_ar[i] == hw->S514_slot_no){
2214 if (pci_slot_ar[i] == 0xFF){
2220 read_S514_int_stat(hw,&int_status);
2221 S514_intack(hw,int_status);
2222 if (i == MAX_S514_CARDS){
2223 printk(KERN_INFO "%s: Critical Error !!!\n",modname);
2225 "%s: Number of Sangoma PCI cards exceeded maximum limit.\n",
2227 printk(KERN_INFO "Please contact Sangoma Technologies\n");
2230 pci_slot_ar[i] = hw->S514_slot_no;
2235 static int pci_probe(sdlahw_t *hw)
2238 unsigned char slot_no;
2239 int number_S514_cards = 0;
2240 u16 PCI_subsys_vendor;
2243 struct pci_dev *pci_dev = NULL;
2244 struct pci_bus *bus = NULL;
2248 while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2251 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2252 &PCI_subsys_vendor);
2254 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2257 pci_read_config_word(pci_dev, PCI_CARD_TYPE,
2262 /* A dual cpu card can support up to 4 physical connections,
2263 * where a single cpu card can support up to 2 physical
2264 * connections. The FT1 card can only support a single
2265 * connection, however we cannot distinguish between a Single
2266 * CPU card and an FT1 card. */
2267 if (PCI_card_type == S514_DUAL_CPU){
2268 number_S514_cards += 4;
2270 "wanpipe: S514-PCI card found, cpu(s) 2, bus #%d, slot #%d, irq #%d\n",
2271 bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2274 number_S514_cards += 2;
2276 "wanpipe: S514-PCI card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n",
2277 bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2282 return number_S514_cards;
2288 EXPORT_SYMBOL(wanpipe_hw_probe);
2290 unsigned wanpipe_hw_probe(void)
2293 unsigned* opt = s508_port_options;
2297 memset(&hw, 0, sizeof(hw));
2299 for (i = 1; i <= opt[0]; i++) {
2300 if (detect_s508(opt[i])){
2301 /* S508 card can support up to two physical links */
2303 printk(KERN_INFO "wanpipe: S508-ISA card found, port 0x%x\n",opt[i]);
2308 hw.S514_slot_no = 0;
2309 cardno += pci_probe(&hw);
2311 printk(KERN_INFO "wanpipe: Warning, Kernel not compiled for PCI support!\n");
2312 printk(KERN_INFO "wanpipe: PCI Hardware Probe Failed!\n");
2318 /****** End *****************************************************************/