aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wan/sdladrv.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/wan/sdladrv.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/wan/sdladrv.c')
-rw-r--r--drivers/net/wan/sdladrv.c2318
1 files changed, 2318 insertions, 0 deletions
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
new file mode 100644
index 000000000000..c8bc6da57a41
--- /dev/null
+++ b/drivers/net/wan/sdladrv.c
@@ -0,0 +1,2318 @@
1/*****************************************************************************
2* sdladrv.c SDLA Support Module. Main module.
3*
4* This module is a library of common hardware-specific functions
5* used by all Sangoma drivers.
6*
7* Author: Gideon Hack
8*
9* Copyright: (c) 1995-2000 Sangoma Technologies Inc.
10*
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
17* the PCISLOT #0.
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*****************************************************************************/
35
36/*****************************************************************************
37 * Notes:
38 * ------
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:
42 *
43 * Platform Define
44 * -------- ------
45 * Linux _LINUX_
46 * SCO Unix _SCO_UNIX_
47 *
48 * 2. Supported adapter types:
49 *
50 * S502A
51 * ES502A (S502E)
52 * S503
53 * S507
54 * S508 (S509)
55 *
56 * 3. S502A Notes:
57 *
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).
62 *
63 * S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
64 *
65 * There should be a delay of ??? before reading back S502A status
66 * register.
67 *
68 * 4. S502E Notes:
69 *
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.
76 *
77 * S502E CPU and DPM control is limited:
78 *
79 * o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
80 * control register (BASE+3) shuts the board down entirely, including
81 * DPM;
82 *
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
86 * running.
87 ****************************************************************************/
88
89#define _LINUX_
90
91#if defined(_LINUX_) /****** Linux *******************************/
92
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. */
105
106#define _INB(port) (inb(port))
107#define _OUTB(port, byte) (outb((byte),(port)))
108#define SYSTEM_TICK jiffies
109
110#include <linux/init.h>
111
112
113#elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
114
115#if !defined(INKERNEL)
116#error This code MUST be compiled in kernel mode!
117#endif
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
124
125#else
126#error Unknown system type!
127#endif
128
129#define MOD_VERSION 3
130#define MOD_RELEASE 0
131
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 */
135
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
142
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
148
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
154#define NO_PORT -1
155
156
157
158
159
160/****** Function Prototypes *************************************************/
161
162/* Hardware-specific functions */
163static int sdla_detect (sdlahw_t* hw);
164static int sdla_autodpm (sdlahw_t* hw);
165static int sdla_setdpm (sdlahw_t* hw);
166static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);
167static int sdla_init (sdlahw_t* hw);
168static unsigned long sdla_memtest (sdlahw_t* hw);
169static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo);
170static unsigned char make_config_byte (sdlahw_t* hw);
171static int sdla_start (sdlahw_t* hw, unsigned addr);
172
173static int init_s502a (sdlahw_t* hw);
174static int init_s502e (sdlahw_t* hw);
175static int init_s503 (sdlahw_t* hw);
176static int init_s507 (sdlahw_t* hw);
177static int init_s508 (sdlahw_t* hw);
178
179static int detect_s502a (int port);
180static int detect_s502e (int port);
181static int detect_s503 (int port);
182static int detect_s507 (int port);
183static int detect_s508 (int port);
184static int detect_s514 (sdlahw_t* hw);
185static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
186
187/* Miscellaneous functions */
188static void peek_by_4 (unsigned long src, void* buf, unsigned len);
189static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
190static int calibrate_delay (int mks);
191static int get_option_index (unsigned* optlist, unsigned optval);
192static unsigned check_memregion (void* ptr, unsigned len);
193static unsigned test_memregion (void* ptr, unsigned len);
194static unsigned short checksum (unsigned char* buf, unsigned len);
195static int init_pci_slot(sdlahw_t *);
196
197static int pci_probe(sdlahw_t *hw);
198
199/****** Global Data **********************************************************
200 * Note: All data must be explicitly initialized!!!
201 */
202
203static struct pci_device_id sdladrv_pci_tbl[] = {
204 { V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
205 { } /* Terminating entry */
206};
207MODULE_DEVICE_TABLE(pci, sdladrv_pci_tbl);
208
209MODULE_LICENSE("GPL");
210
211/* private data */
212static char modname[] = "sdladrv";
213static char fullname[] = "SDLA Support Module";
214static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
215static unsigned exec_idle;
216
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).
220 */
221static unsigned s502_port_options[] =
222 { 4, 0x250, 0x300, 0x350, 0x360 }
223;
224static unsigned s503_port_options[] =
225 { 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
226;
227static unsigned s508_port_options[] =
228 { 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
229;
230
231static unsigned s502a_irq_options[] = { 0 };
232static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
233static unsigned s503_irq_options[] = { 5, 2, 3, 4, 5, 7 };
234static unsigned s508_irq_options[] = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
235
236static unsigned s502a_dpmbase_options[] =
237{
238 28,
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,
243};
244static unsigned s507_dpmbase_options[] =
245{
246 32,
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,
251};
252static unsigned s508_dpmbase_options[] = /* incl. S502E and S503 */
253{
254 32,
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,
259};
260
261/*
262static unsigned s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
263static unsigned s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
264static unsigned s508_dpmsize_options[] = { 1, 0x2000 };
265*/
266
267static unsigned s502a_pclk_options[] = { 2, 3600, 7200 };
268static unsigned s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
269static unsigned s503_pclk_options[] = { 3, 7200, 8000, 10000 };
270static unsigned s507_pclk_options[] = { 1, 12288 };
271static unsigned s508_pclk_options[] = { 1, 16000 };
272
273/* Host memory control register masks */
274static unsigned char s502a_hmcr[] =
275{
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 */
280};
281static unsigned char s502e_hmcr[] =
282{
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 */
287};
288static unsigned char s507_hmcr[] =
289{
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 */
294};
295static unsigned char s508_hmcr[] =
296{
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 */
301};
302
303static unsigned char s507_irqmask[] =
304{
305 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
306};
307
308static int pci_slot_ar[MAX_S514_CARDS];
309
310/******* Kernel Loadable Module Entry Points ********************************/
311
312/*============================================================================
313 * Module 'insert' entry point.
314 * o print announcement
315 * o initialize static data
316 * o calibrate SDLA shared memory access delay.
317 *
318 * Return: 0 Ok
319 * < 0 error.
320 * Context: process
321 */
322
323static int __init sdladrv_init(void)
324{
325 int i=0;
326
327 printk(KERN_INFO "%s v%u.%u %s\n",
328 fullname, MOD_VERSION, MOD_RELEASE, copyright);
329 exec_idle = calibrate_delay(EXEC_DELAY);
330#ifdef WANDEBUG
331 printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
332#endif
333
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;
339
340 return 0;
341}
342
343/*============================================================================
344 * Module 'remove' entry point.
345 * o release all remaining system resources
346 */
347static void __exit sdladrv_cleanup(void)
348{
349}
350
351module_init(sdladrv_init);
352module_exit(sdladrv_cleanup);
353
354/******* Kernel APIs ********************************************************/
355
356/*============================================================================
357 * Set up adapter.
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
363 * o load firmware
364 * Return: 0 ok.
365 * < 0 error
366 */
367
368EXPORT_SYMBOL(sdla_setup);
369
370int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
371{
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 */
375 int err=0;
376
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",
380 modname, hw->port);
381 return -EINVAL;
382 }
383
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);
387
388 hw->dpmsize = SDLA_WINDOWSIZE;
389 switch (hw->type) {
390 case SDLA_S502A:
391 hw->io_range = S502A_IORANGE;
392 irq_opt = s502a_irq_options;
393 dpmbase_opt = s502a_dpmbase_options;
394 pclk_opt = s502a_pclk_options;
395 break;
396
397 case SDLA_S502E:
398 hw->io_range = S502E_IORANGE;
399 irq_opt = s502e_irq_options;
400 dpmbase_opt = s508_dpmbase_options;
401 pclk_opt = s502e_pclk_options;
402 break;
403
404 case SDLA_S503:
405 hw->io_range = S503_IORANGE;
406 irq_opt = s503_irq_options;
407 dpmbase_opt = s508_dpmbase_options;
408 pclk_opt = s503_pclk_options;
409 break;
410
411 case SDLA_S507:
412 hw->io_range = S507_IORANGE;
413 irq_opt = s508_irq_options;
414 dpmbase_opt = s507_dpmbase_options;
415 pclk_opt = s507_pclk_options;
416 break;
417
418 case SDLA_S508:
419 hw->io_range = S508_IORANGE;
420 irq_opt = s508_irq_options;
421 dpmbase_opt = s508_dpmbase_options;
422 pclk_opt = s508_pclk_options;
423 break;
424 }
425
426 /* Verify IRQ configuration options */
427 if (!get_option_index(irq_opt, hw->irq)) {
428 printk(KERN_INFO "%s: IRQ %d is invalid!\n",
429 modname, hw->irq);
430 return -EINVAL;
431 }
432
433 /* Verify CPU clock rate configuration options */
434 if (hw->pclk == 0)
435 hw->pclk = pclk_opt[1]; /* use default */
436
437 else if (!get_option_index(pclk_opt, hw->pclk)) {
438 printk(KERN_INFO "%s: CPU clock %u is invalid!\n",
439 modname, hw->pclk);
440 return -EINVAL;
441 }
442 printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
443 modname, hw->pclk);
444
445 /* Setup adapter dual-port memory window and test memory */
446 if (hw->dpmbase == 0) {
447 err = sdla_autodpm(hw);
448 if (err) {
449 printk(KERN_INFO
450 "%s: can't find available memory region!\n",
451 modname);
452 return err;
453 }
454 }
455 else if (!get_option_index(dpmbase_opt,
456 virt_to_phys(hw->dpmbase))) {
457 printk(KERN_INFO
458 "%s: memory address 0x%lX is invalid!\n",
459 modname, virt_to_phys(hw->dpmbase));
460 return -EINVAL;
461 }
462 else if (sdla_setdpm(hw)) {
463 printk(KERN_INFO
464 "%s: 8K memory region at 0x%lX is not available!\n",
465 modname, virt_to_phys(hw->dpmbase));
466 return -EINVAL;
467 }
468 printk(KERN_INFO
469 "%s: dual-port memory window is set at 0x%lX.\n",
470 modname, virt_to_phys(hw->dpmbase));
471
472
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);
484 }
485 }
486
487 else {
488 hw->memory = test_memregion((void*)hw->dpmbase,
489 MAX_SIZEOF_S514_MEMORY);
490 if(hw->memory < (256 * 1024)) {
491 printk(KERN_INFO
492 "%s: error in testing S514 memory (0x%lX)\n",
493 modname, hw->memory);
494 sdla_down(hw);
495 return -EINVAL;
496 }
497 }
498
499 printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
500 modname, hw->memory / 1024);
501
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 */
505
506 return err;
507}
508
509/*============================================================================
510 * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
511 */
512
513EXPORT_SYMBOL(sdla_down);
514
515int sdla_down (sdlahw_t* hw)
516{
517 unsigned port = hw->port;
518 int i;
519 unsigned char CPU_no;
520 u32 int_config, int_status;
521
522 if(!port && (hw->type != SDLA_S514))
523 return -EFAULT;
524
525 switch (hw->type) {
526 case SDLA_S502A:
527 _OUTB(port, 0x08); /* halt CPU */
528 _OUTB(port, 0x08);
529 _OUTB(port, 0x08);
530 hw->regs[0] = 0x08;
531 _OUTB(port + 1, 0xFF); /* close memory window */
532 hw->regs[1] = 0xFF;
533 break;
534
535 case SDLA_S502E:
536 _OUTB(port + 3, 0); /* stop CPU */
537 _OUTB(port, 0); /* reset board */
538 for (i = 0; i < S502E_IORANGE; ++i)
539 hw->regs[i] = 0
540 ;
541 break;
542
543 case SDLA_S503:
544 case SDLA_S507:
545 case SDLA_S508:
546 _OUTB(port, 0); /* reset board logic */
547 hw->regs[0] = 0;
548 break;
549
550 case SDLA_S514:
551 /* halt the adapter */
552 *(char *)hw->vector = S514_CPU_HALT;
553 CPU_no = hw->S514_cpu_no[0];
554
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);
564 else
565 pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
566 PCI_CPU_B_MEM_DISABLE);
567
568 /* free up the allocated virtual memory */
569 iounmap((void *)hw->dpmbase);
570 iounmap((void *)hw->vector);
571 break;
572
573
574 default:
575 return -EINVAL;
576 }
577 return 0;
578}
579
580/*============================================================================
581 * Map shared memory window into SDLA address space.
582 */
583
584EXPORT_SYMBOL(sdla_mapmem);
585
586int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
587{
588 unsigned port = hw->port;
589 register int tmp;
590
591 switch (hw->type) {
592 case SDLA_S502A:
593 case SDLA_S502E:
594 if (addr < S502_MAXMEM) { /* verify parameter */
595 tmp = addr >> 13; /* convert to register mask */
596 _OUTB(port + 2, tmp);
597 hw->regs[2] = tmp;
598 }
599 else return -EINVAL;
600 break;
601
602 case SDLA_S503:
603 if (addr < S503_MAXMEM) { /* verify parameter */
604 tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
605 _OUTB(port, tmp);
606 hw->regs[0] = tmp;
607 }
608 else return -EINVAL;
609 break;
610
611 case SDLA_S507:
612 if (addr < S507_MAXMEM) {
613 if (!(_INB(port) & 0x02))
614 return -EIO;
615 tmp = addr >> 13; /* convert to register mask */
616 _OUTB(port + 2, tmp);
617 hw->regs[2] = tmp;
618 }
619 else return -EINVAL;
620 break;
621
622 case SDLA_S508:
623 if (addr < S508_MAXMEM) {
624 tmp = addr >> 13; /* convert to register mask */
625 _OUTB(port + 2, tmp);
626 hw->regs[2] = tmp;
627 }
628 else return -EINVAL;
629 break;
630
631 case SDLA_S514:
632 return 0;
633
634 default:
635 return -EINVAL;
636 }
637 hw->vector = addr & 0xFFFFE000L;
638 return 0;
639}
640
641/*============================================================================
642 * Enable interrupt generation.
643 */
644
645EXPORT_SYMBOL(sdla_inten);
646
647int sdla_inten (sdlahw_t* hw)
648{
649 unsigned port = hw->port;
650 int tmp, i;
651
652 switch (hw->type) {
653 case SDLA_S502E:
654 /* Note thar interrupt control operations on S502E are allowed
655 * only if CPU is enabled (bit 0 of status register is set).
656 */
657 if (_INB(port) & 0x01) {
658 _OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
659 _OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
660 hw->regs[0] = 0x06;
661 }
662 else return -EIO;
663 break;
664
665 case SDLA_S503:
666 tmp = hw->regs[0] | 0x04;
667 _OUTB(port, tmp);
668 hw->regs[0] = tmp; /* update mirror */
669 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
670 if (!(_INB(port) & 0x02)) /* verify */
671 return -EIO;
672 break;
673
674 case SDLA_S508:
675 tmp = hw->regs[0] | 0x10;
676 _OUTB(port, tmp);
677 hw->regs[0] = tmp; /* update mirror */
678 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
679 if (!(_INB(port + 1) & 0x10)) /* verify */
680 return -EIO;
681 break;
682
683 case SDLA_S502A:
684 case SDLA_S507:
685 break;
686
687 case SDLA_S514:
688 break;
689
690 default:
691 return -EINVAL;
692
693 }
694 return 0;
695}
696
697/*============================================================================
698 * Disable interrupt generation.
699 */
700
701EXPORT_SYMBOL(sdla_intde);
702
703int sdla_intde (sdlahw_t* hw)
704{
705 unsigned port = hw->port;
706 int tmp, i;
707
708 switch (hw->type) {
709 case SDLA_S502E:
710 /* Notes:
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.
716 */
717 if (_INB(port) & 0x01) {
718 _OUTB(port, hw->regs[0] & ~0x04);
719 hw->regs[0] &= ~0x04;
720 }
721 else return -EIO;
722 break;
723
724 case SDLA_S503:
725 tmp = hw->regs[0] & ~0x04;
726 _OUTB(port, tmp);
727 hw->regs[0] = tmp; /* update mirror */
728 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
729 if (_INB(port) & 0x02) /* verify */
730 return -EIO;
731 break;
732
733 case SDLA_S508:
734 tmp = hw->regs[0] & ~0x10;
735 _OUTB(port, tmp);
736 hw->regs[0] = tmp; /* update mirror */
737 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
738 if (_INB(port) & 0x10) /* verify */
739 return -EIO;
740 break;
741
742 case SDLA_S502A:
743 case SDLA_S507:
744 break;
745
746 default:
747 return -EINVAL;
748 }
749 return 0;
750}
751
752/*============================================================================
753 * Acknowledge SDLA hardware interrupt.
754 */
755
756EXPORT_SYMBOL(sdla_intack);
757
758int sdla_intack (sdlahw_t* hw)
759{
760 unsigned port = hw->port;
761 int tmp;
762
763 switch (hw->type) {
764 case SDLA_S502E:
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).
769 */
770 if (_INB(port) & 0x01) {
771 tmp = hw->regs[0] & ~0x04;
772 _OUTB(port, tmp);
773 tmp |= 0x04;
774 _OUTB(port, tmp);
775 hw->regs[0] = tmp;
776 }
777 else return -EIO;
778 break;
779
780 case SDLA_S503:
781 if (_INB(port) & 0x04) {
782 tmp = hw->regs[0] & ~0x08;
783 _OUTB(port, tmp);
784 tmp |= 0x08;
785 _OUTB(port, tmp);
786 hw->regs[0] = tmp;
787 }
788 break;
789
790 case SDLA_S502A:
791 case SDLA_S507:
792 case SDLA_S508:
793 break;
794
795 default:
796 return -EINVAL;
797 }
798 return 0;
799}
800
801
802/*============================================================================
803 * Acknowledge S514 hardware interrupt.
804 */
805
806EXPORT_SYMBOL(S514_intack);
807
808void S514_intack (sdlahw_t* hw, u32 int_status)
809{
810 pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
811}
812
813
814/*============================================================================
815 * Read the S514 hardware interrupt status.
816 */
817
818EXPORT_SYMBOL(read_S514_int_stat);
819
820void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
821{
822 pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
823}
824
825
826/*============================================================================
827 * Generate an interrupt to adapter's CPU.
828 */
829
830EXPORT_SYMBOL(sdla_intr);
831
832int sdla_intr (sdlahw_t* hw)
833{
834 unsigned port = hw->port;
835
836 switch (hw->type) {
837 case SDLA_S502A:
838 if (!(_INB(port) & 0x40)) {
839 _OUTB(port, 0x10); /* issue NMI to CPU */
840 hw->regs[0] = 0x10;
841 }
842 else return -EIO;
843 break;
844
845 case SDLA_S507:
846 if ((_INB(port) & 0x06) == 0x06) {
847 _OUTB(port + 3, 0);
848 }
849 else return -EIO;
850 break;
851
852 case SDLA_S508:
853 if (_INB(port + 1) & 0x02) {
854 _OUTB(port, 0x08);
855 }
856 else return -EIO;
857 break;
858
859 case SDLA_S502E:
860 case SDLA_S503:
861 default:
862 return -EINVAL;
863 }
864 return 0;
865}
866
867/*============================================================================
868 * Execute Adapter Command.
869 * o Set exec flag.
870 * o Busy-wait until flag is reset.
871 * o Return number of loops made, or 0 if command timed out.
872 */
873
874EXPORT_SYMBOL(sdla_exec);
875
876int sdla_exec (void* opflag)
877{
878 volatile unsigned char* flag = opflag;
879 unsigned long tstop;
880 int nloops;
881
882 if(readb(flag) != 0x00) {
883 printk(KERN_INFO
884 "WANPIPE: opp flag set on entry to sdla_exec\n");
885 return 0;
886 }
887
888 writeb(0x01, flag);
889
890 tstop = SYSTEM_TICK + EXEC_TIMEOUT;
891
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! */
896 }
897 return nloops;
898}
899
900/*============================================================================
901 * Read absolute adapter memory.
902 * Transfer data from adapter's memory to data buffer.
903 *
904 * Note:
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.
908 */
909
910EXPORT_SYMBOL(sdla_peek);
911
912int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
913{
914
915 if (addr + len > hw->memory) /* verify arguments */
916 return -EINVAL;
917
918 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
919 peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
920 return 0;
921 }
922
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 */
928 int err = 0;
929
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,
938 curlen);
939 addr += curlen;
940 buf = (char*)buf + curlen;
941 len -= curlen;
942 }
943
944 /* Restore DPM window position */
945 sdla_mapmem(hw, oldvec);
946 return err;
947 }
948}
949
950
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.
955*/
956
957static void peek_by_4 (unsigned long src, void* buf, unsigned len)
958{
959
960 /* byte copy data until we get to a 4-byte boundary */
961 while (len && (src & 0x03)) {
962 *(char *)buf ++ = readb(src ++);
963 len --;
964 }
965
966 /* copy data in 4-byte chunks */
967 while (len >= 4) {
968 *(unsigned long *)buf = readl(src);
969 buf += 4;
970 src += 4;
971 len -= 4;
972 }
973
974 /* byte copy any remaining data */
975 while (len) {
976 *(char *)buf ++ = readb(src ++);
977 len --;
978 }
979}
980
981
982/*============================================================================
983 * Write Absolute Adapter Memory.
984 * Transfer data from data buffer to adapter's memory.
985 *
986 * Note:
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.
990 */
991
992EXPORT_SYMBOL(sdla_poke);
993
994int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
995{
996
997 if (addr + len > hw->memory) /* verify arguments */
998 return -EINVAL;
999
1000 if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
1001 poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
1002 return 0;
1003 }
1004
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 */
1010 int err = 0;
1011
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,
1020 curlen);
1021 addr += curlen;
1022 buf = (char*)buf + curlen;
1023 len -= curlen;
1024 }
1025
1026 /* Restore DPM window position */
1027 sdla_mapmem(hw, oldvec);
1028 return err;
1029 }
1030}
1031
1032
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.
1037*/
1038
1039static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
1040{
1041
1042 /* byte copy data until we get to a 4-byte boundary */
1043 while (len && (dest & 0x03)) {
1044 writeb (*(char *)buf ++, dest ++);
1045 len --;
1046 }
1047
1048 /* copy data in 4-byte chunks */
1049 while (len >= 4) {
1050 writel (*(unsigned long *)buf, dest);
1051 dest += 4;
1052 buf += 4;
1053 len -= 4;
1054 }
1055
1056 /* byte copy any remaining data */
1057 while (len) {
1058 writeb (*(char *)buf ++ , dest ++);
1059 len --;
1060 }
1061}
1062
1063
1064#ifdef DONT_COMPIPLE_THIS
1065#endif /* DONT_COMPIPLE_THIS */
1066
1067/****** Hardware-Specific Functions *****************************************/
1068
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.
1074 *
1075 * Notes:
1076 * 1) Detection tests are destructive! Adapter will be left in shutdown state
1077 * after the test.
1078 */
1079static int sdla_detect (sdlahw_t* hw)
1080{
1081 unsigned port = hw->port;
1082 int err = 0;
1083
1084 if (!port && (hw->type != SDLA_S514))
1085 return -EFAULT;
1086
1087 switch (hw->type) {
1088 case SDLA_S502A:
1089 if (!detect_s502a(port)) err = -ENODEV;
1090 break;
1091
1092 case SDLA_S502E:
1093 if (!detect_s502e(port)) err = -ENODEV;
1094 break;
1095
1096 case SDLA_S503:
1097 if (!detect_s503(port)) err = -ENODEV;
1098 break;
1099
1100 case SDLA_S507:
1101 if (!detect_s507(port)) err = -ENODEV;
1102 break;
1103
1104 case SDLA_S508:
1105 if (!detect_s508(port)) err = -ENODEV;
1106 break;
1107
1108 case SDLA_S514:
1109 if (!detect_s514(hw)) err = -ENODEV;
1110 break;
1111
1112 default:
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;
1123 else err = -ENODEV;
1124 }
1125 return err;
1126}
1127
1128/*============================================================================
1129 * Autoselect memory region.
1130 * o try all available DMP address options from the top down until success.
1131 */
1132static int sdla_autodpm (sdlahw_t* hw)
1133{
1134 int i, err = -EINVAL;
1135 unsigned* opt;
1136
1137 switch (hw->type) {
1138 case SDLA_S502A:
1139 opt = s502a_dpmbase_options;
1140 break;
1141
1142 case SDLA_S502E:
1143 case SDLA_S503:
1144 case SDLA_S508:
1145 opt = s508_dpmbase_options;
1146 break;
1147
1148 case SDLA_S507:
1149 opt = s507_dpmbase_options;
1150 break;
1151
1152 default:
1153 return -EINVAL;
1154 }
1155
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);
1163 }
1164 return err;
1165}
1166
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.
1175 */
1176static int sdla_setdpm (sdlahw_t* hw)
1177{
1178 int err;
1179
1180 /* Shut down card and verify memory region */
1181 sdla_down(hw);
1182 if (check_memregion(hw->dpmbase, hw->dpmsize))
1183 return -EINVAL;
1184
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.
1188 */
1189 err = sdla_init(hw);
1190 if (err) return err;
1191
1192 if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */
1193 sdla_down(hw);
1194 return -EIO;
1195 }
1196 sdla_mapmem(hw, 0L); /* set window vector at bottom */
1197 return 0;
1198}
1199
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
1204 */
1205static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
1206{
1207
1208 int i;
1209
1210 /* Verify firmware signature */
1211 if (strcmp(sfm->signature, SFM_SIGNATURE)) {
1212 printk(KERN_INFO "%s: not SDLA firmware!\n",
1213 modname);
1214 return -EINVAL;
1215 }
1216
1217 /* Verify firmware module format version */
1218 if (sfm->version != SFM_VERSION) {
1219 printk(KERN_INFO
1220 "%s: firmware format %u rejected! Expecting %u.\n",
1221 modname, sfm->version, SFM_VERSION);
1222 return -EINVAL;
1223 }
1224
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);
1230 return -EINVAL;
1231 }
1232
1233 /* Announce */
1234 printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
1235 (sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
1236 sfm->info.codeid);
1237
1238 if(hw->type == SDLA_S514)
1239 printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
1240 modname, hw->S514_cpu_no[0]);
1241
1242 /* Scan through the list of compatible adapters and make sure our
1243 * adapter type is listed.
1244 */
1245 for (i = 0;
1246 (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
1247 ++i);
1248
1249 if (i == SFM_MAX_SDLA) {
1250 printk(KERN_INFO "%s: firmware is not compatible with S%u!\n",
1251 modname, hw->type);
1252 return -EINVAL;
1253 }
1254
1255
1256 /* Make sure there is enough on-board memory */
1257 if (hw->memory < sfm->info.memsize) {
1258 printk(KERN_INFO
1259 "%s: firmware needs %lu bytes of on-board memory!\n",
1260 modname, sfm->info.memsize);
1261 return -EINVAL;
1262 }
1263
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",
1267 modname);
1268 return -EIO;
1269 }
1270
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",
1275 modname);
1276 return -EIO;
1277 }
1278
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",
1282 modname);
1283 return -EIO;
1284 }
1285 hw->fwid = sfm->info.codeid; /* set firmware ID */
1286 return 0;
1287}
1288
1289/*============================================================================
1290 * Initialize SDLA hardware: setup memory window, IRQ, etc.
1291 */
1292static int sdla_init (sdlahw_t* hw)
1293{
1294 int i;
1295
1296 for (i = 0; i < SDLA_MAXIORANGE; ++i)
1297 hw->regs[i] = 0;
1298
1299 switch (hw->type) {
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);
1305 }
1306 return -EINVAL;
1307}
1308
1309/*============================================================================
1310 * Test adapter on-board memory.
1311 * o slide DPM window from the bottom up and test adapter memory segment by
1312 * segment.
1313 * Return adapter memory size.
1314 */
1315static unsigned long sdla_memtest (sdlahw_t* hw)
1316{
1317 unsigned long memsize;
1318 unsigned winsize;
1319
1320 for (memsize = 0, winsize = hw->dpmsize;
1321 !sdla_mapmem(hw, memsize) &&
1322 (test_memregion(hw->dpmbase, winsize) == winsize)
1323 ;
1324 memsize += winsize)
1325 ;
1326 hw->memory = memsize;
1327 return memsize;
1328}
1329
1330/*============================================================================
1331 * Prepare boot-time firmware configuration data.
1332 * o position DPM window
1333 * o initialize configuration data area
1334 */
1335static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
1336{
1337 unsigned char* data;
1338
1339 if (!sfminfo->datasize) return 0; /* nothing to do */
1340
1341 if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
1342 return -EIO;
1343
1344 if(hw->type == SDLA_S514)
1345 data = (void*)(hw->dpmbase + sfminfo->dataoffs);
1346 else
1347 data = (void*)((u8 *)hw->dpmbase +
1348 (sfminfo->dataoffs - hw->vector));
1349
1350 memset_io (data, 0, sfminfo->datasize);
1351
1352 writeb (make_config_byte(hw), &data[0x00]);
1353
1354 switch (sfminfo->codeid) {
1355 case SFID_X25_502:
1356 case SFID_X25_508:
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 */
1364 break;
1365 }
1366 return 0;
1367}
1368
1369/*============================================================================
1370 * Prepare configuration byte identifying adapter type and CPU clock rate.
1371 */
1372static unsigned char make_config_byte (sdlahw_t* hw)
1373{
1374 unsigned char byte = 0;
1375
1376 switch (hw->pclk) {
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;
1382 }
1383
1384 switch (hw->type) {
1385 case SDLA_S502E: byte |= 0x80; break;
1386 case SDLA_S503: byte |= 0x40; break;
1387 }
1388 return byte;
1389}
1390
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
1396 * o start CPU
1397 */
1398static int sdla_start (sdlahw_t* hw, unsigned addr)
1399{
1400 unsigned port = hw->port;
1401 unsigned char *bootp;
1402 int err, tmp, i;
1403
1404 if (!port && (hw->type != SDLA_S514)) return -EFAULT;
1405
1406 switch (hw->type) {
1407 case SDLA_S502A:
1408 bootp = hw->dpmbase;
1409 bootp += 0x66;
1410 break;
1411
1412 case SDLA_S502E:
1413 case SDLA_S503:
1414 case SDLA_S507:
1415 case SDLA_S508:
1416 case SDLA_S514:
1417 bootp = hw->dpmbase;
1418 break;
1419
1420 default:
1421 return -EINVAL;
1422 }
1423
1424 err = sdla_mapmem(hw, 0);
1425 if (err) return err;
1426
1427 writeb (0xC3, bootp); /* Z80: 'jp' opcode */
1428 bootp ++;
1429 writew (addr, bootp);
1430
1431 switch (hw->type) {
1432 case SDLA_S502A:
1433 _OUTB(port, 0x10); /* issue NMI to CPU */
1434 hw->regs[0] = 0x10;
1435 break;
1436
1437 case SDLA_S502E:
1438 _OUTB(port + 3, 0x01); /* start CPU */
1439 hw->regs[3] = 0x01;
1440 for (i = 0; i < SDLA_IODELAY; ++i);
1441 if (_INB(port) & 0x01) { /* verify */
1442 /*
1443 * Enabling CPU changes functionality of the
1444 * control register, so we have to reset its
1445 * mirror.
1446 */
1447 _OUTB(port, 0); /* disable interrupts */
1448 hw->regs[0] = 0;
1449 }
1450 else return -EIO;
1451 break;
1452
1453 case SDLA_S503:
1454 tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */
1455 _OUTB(port, tmp);
1456 hw->regs[0] = tmp; /* update mirror */
1457 for (i = 0; i < SDLA_IODELAY; ++i);
1458 if (!(_INB(port) & 0x01)) /* verify */
1459 return -EIO;
1460 break;
1461
1462 case SDLA_S507:
1463 tmp = hw->regs[0] | 0x02;
1464 _OUTB(port, tmp);
1465 hw->regs[0] = tmp; /* update mirror */
1466 for (i = 0; i < SDLA_IODELAY; ++i);
1467 if (!(_INB(port) & 0x04)) /* verify */
1468 return -EIO;
1469 break;
1470
1471 case SDLA_S508:
1472 tmp = hw->regs[0] | 0x02;
1473 _OUTB(port, tmp);
1474 hw->regs[0] = tmp; /* update mirror */
1475 for (i = 0; i < SDLA_IODELAY; ++i);
1476 if (!(_INB(port + 1) & 0x02)) /* verify */
1477 return -EIO;
1478 break;
1479
1480 case SDLA_S514:
1481 writeb (S514_CPU_START, hw->vector);
1482 break;
1483
1484 default:
1485 return -EINVAL;
1486 }
1487 return 0;
1488}
1489
1490/*============================================================================
1491 * Initialize S502A adapter.
1492 */
1493static int init_s502a (sdlahw_t* hw)
1494{
1495 unsigned port = hw->port;
1496 int tmp, i;
1497
1498 if (!detect_s502a(port))
1499 return -ENODEV;
1500
1501 hw->regs[0] = 0x08;
1502 hw->regs[1] = 0xFF;
1503
1504 /* Verify configuration options */
1505 i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
1506 if (i == 0)
1507 return -EINVAL;
1508
1509 tmp = s502a_hmcr[i - 1];
1510 switch (hw->dpmsize) {
1511 case 0x2000:
1512 tmp |= 0x01;
1513 break;
1514
1515 case 0x10000L:
1516 break;
1517
1518 default:
1519 return -EINVAL;
1520 }
1521
1522 /* Setup dual-port memory window (this also enables memory access) */
1523 _OUTB(port + 1, tmp);
1524 hw->regs[1] = tmp;
1525 hw->regs[0] = 0x08;
1526 return 0;
1527}
1528
1529/*============================================================================
1530 * Initialize S502E adapter.
1531 */
1532static int init_s502e (sdlahw_t* hw)
1533{
1534 unsigned port = hw->port;
1535 int tmp, i;
1536
1537 if (!detect_s502e(port))
1538 return -ENODEV;
1539
1540 /* Verify configuration options */
1541 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1542 if (i == 0)
1543 return -EINVAL;
1544
1545 tmp = s502e_hmcr[i - 1];
1546 switch (hw->dpmsize) {
1547 case 0x2000:
1548 tmp |= 0x01;
1549 break;
1550
1551 case 0x10000L:
1552 break;
1553
1554 default:
1555 return -EINVAL;
1556 }
1557
1558 /* Setup dual-port memory window */
1559 _OUTB(port + 1, tmp);
1560 hw->regs[1] = tmp;
1561
1562 /* Enable memory access */
1563 _OUTB(port, 0x02);
1564 hw->regs[0] = 0x02;
1565 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1566 return (_INB(port) & 0x02) ? 0 : -EIO;
1567}
1568
1569/*============================================================================
1570 * Initialize S503 adapter.
1571 * ---------------------------------------------------------------------------
1572 */
1573static int init_s503 (sdlahw_t* hw)
1574{
1575 unsigned port = hw->port;
1576 int tmp, i;
1577
1578 if (!detect_s503(port))
1579 return -ENODEV;
1580
1581 /* Verify configuration options */
1582 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1583 if (i == 0)
1584 return -EINVAL;
1585
1586 tmp = s502e_hmcr[i - 1];
1587 switch (hw->dpmsize) {
1588 case 0x2000:
1589 tmp |= 0x01;
1590 break;
1591
1592 case 0x10000L:
1593 break;
1594
1595 default:
1596 return -EINVAL;
1597 }
1598
1599 /* Setup dual-port memory window */
1600 _OUTB(port + 1, tmp);
1601 hw->regs[1] = tmp;
1602
1603 /* Enable memory access */
1604 _OUTB(port, 0x02);
1605 hw->regs[0] = 0x02; /* update mirror */
1606 return 0;
1607}
1608
1609/*============================================================================
1610 * Initialize S507 adapter.
1611 */
1612static int init_s507 (sdlahw_t* hw)
1613{
1614 unsigned port = hw->port;
1615 int tmp, i;
1616
1617 if (!detect_s507(port))
1618 return -ENODEV;
1619
1620 /* Verify configuration options */
1621 i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
1622 if (i == 0)
1623 return -EINVAL;
1624
1625 tmp = s507_hmcr[i - 1];
1626 switch (hw->dpmsize) {
1627 case 0x2000:
1628 tmp |= 0x01;
1629 break;
1630
1631 case 0x10000L:
1632 break;
1633
1634 default:
1635 return -EINVAL;
1636 }
1637
1638 /* Enable adapter's logic */
1639 _OUTB(port, 0x01);
1640 hw->regs[0] = 0x01;
1641 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1642 if (!(_INB(port) & 0x20))
1643 return -EIO;
1644
1645 /* Setup dual-port memory window */
1646 _OUTB(port + 1, tmp);
1647 hw->regs[1] = tmp;
1648
1649 /* Enable memory access */
1650 tmp = hw->regs[0] | 0x04;
1651 if (hw->irq) {
1652 i = get_option_index(s508_irq_options, hw->irq);
1653 if (i) tmp |= s507_irqmask[i - 1];
1654 }
1655 _OUTB(port, tmp);
1656 hw->regs[0] = tmp; /* update mirror */
1657 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1658 return (_INB(port) & 0x08) ? 0 : -EIO;
1659}
1660
1661/*============================================================================
1662 * Initialize S508 adapter.
1663 */
1664static int init_s508 (sdlahw_t* hw)
1665{
1666 unsigned port = hw->port;
1667 int tmp, i;
1668
1669 if (!detect_s508(port))
1670 return -ENODEV;
1671
1672 /* Verify configuration options */
1673 i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
1674 if (i == 0)
1675 return -EINVAL;
1676
1677 /* Setup memory configuration */
1678 tmp = s508_hmcr[i - 1];
1679 _OUTB(port + 1, tmp);
1680 hw->regs[1] = tmp;
1681
1682 /* Enable memory access */
1683 _OUTB(port, 0x04);
1684 hw->regs[0] = 0x04; /* update mirror */
1685 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1686 return (_INB(port + 1) & 0x04) ? 0 : -EIO;
1687}
1688
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
1694 * read 01000000b.
1695 * 3. After writing 0 to control register, status register should still
1696 * read 01000000b.
1697 * 4. After writing 00000100b to control register, status register should
1698 * read 01000100b.
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.
1702 */
1703static int detect_s502a (int port)
1704{
1705 int i, j;
1706
1707 if (!get_option_index(s502_port_options, port))
1708 return 0;
1709
1710 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1711 if (_INB(port + j) != 0xFF)
1712 return 0;
1713 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1714 }
1715
1716 _OUTB(port, 0x08); /* halt CPU */
1717 _OUTB(port, 0x08);
1718 _OUTB(port, 0x08);
1719 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1720 if (_INB(port) != 0x40)
1721 return 0;
1722 _OUTB(port, 0x00);
1723 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1724 if (_INB(port) != 0x40)
1725 return 0;
1726 _OUTB(port, 0x04);
1727 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1728 if (_INB(port) != 0x44)
1729 return 0;
1730
1731 /* Reset adapter */
1732 _OUTB(port, 0x08);
1733 _OUTB(port, 0x08);
1734 _OUTB(port, 0x08);
1735 _OUTB(port + 1, 0xFF);
1736 return 1;
1737}
1738
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.
1750 */
1751static int detect_s502e (int port)
1752{
1753 int i, j;
1754
1755 if (!get_option_index(s502_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 */
1761 }
1762
1763 _OUTB(port + 3, 0); /* CPU control reg. */
1764 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1765 if (_INB(port) != 0xF8) /* 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) != 0xFC) /* verify */
1770 return 0;
1771
1772 /* Reset adapter */
1773 _OUTB(port, 0);
1774 return 1;
1775}
1776
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.
1788 */
1789static int detect_s503 (int port)
1790{
1791 int i, j;
1792
1793 if (!get_option_index(s503_port_options, port))
1794 return 0;
1795 for (j = 1; j < SDLA_MAXIORANGE; ++j) {
1796 if (_INB(port + j) != 0xFF)
1797 return 0;
1798 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1799 }
1800
1801 _OUTB(port, 0); /* reset control reg.*/
1802 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1803 if (_INB(port) != 0xF0) /* read status */
1804 return 0;
1805 _OUTB(port, 0x04); /* set bit 2 */
1806 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1807 if (_INB(port) != 0xF2) /* verify */
1808 return 0;
1809
1810 /* Reset adapter */
1811 _OUTB(port, 0);
1812 return 1;
1813}
1814
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
1820 * ?011000?b.
1821 * 3. After writing 0x01 to control register, status register should read
1822 * ?011001?b.
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.
1826 */
1827static int detect_s507 (int port)
1828{
1829 int tmp, i, j;
1830
1831 if (!get_option_index(s508_port_options, port))
1832 return 0;
1833 tmp = _INB(port);
1834 for (j = 1; j < S507_IORANGE; ++j) {
1835 if (_INB(port + j) != tmp)
1836 return 0;
1837 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1838 }
1839
1840 _OUTB(port, 0x00);
1841 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1842 if ((_INB(port) & 0x7E) != 0x30)
1843 return 0;
1844 _OUTB(port, 0x01);
1845 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1846 if ((_INB(port) & 0x7E) != 0x32)
1847 return 0;
1848
1849 /* Reset adapter */
1850 _OUTB(port, 0x00);
1851 return 1;
1852}
1853
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
1858 * ??000000b.
1859 * 2. After writing 0x10 to control register, status register should read
1860 * ??010000b
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.
1864 */
1865static int detect_s508 (int port)
1866{
1867 int i;
1868
1869 if (!get_option_index(s508_port_options, port))
1870 return 0;
1871 _OUTB(port, 0x00);
1872 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1873 if ((_INB(port + 1) & 0x3F) != 0x00)
1874 return 0;
1875 _OUTB(port, 0x10);
1876 for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
1877 if ((_INB(port + 1) & 0x3F) != 0x10)
1878 return 0;
1879
1880 /* Reset adapter */
1881 _OUTB(port, 0x00);
1882 return 1;
1883}
1884
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.
1890 */
1891static int detect_s514 (sdlahw_t* hw)
1892{
1893 unsigned char CPU_no, slot_no, auto_slot_cfg;
1894 int number_S514_cards = 0;
1895 u32 S514_mem_base_addr = 0;
1896 u32 ut_u32;
1897 struct pci_dev *pci_dev;
1898
1899
1900#ifndef CONFIG_PCI
1901 printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname);
1902 return 0;
1903#endif
1904
1905 /*
1906 The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
1907 slot number defined in 'router.conf' via the 'port' definition.
1908 */
1909 CPU_no = hw->S514_cpu_no[0];
1910 slot_no = hw->S514_slot_no;
1911 auto_slot_cfg = hw->auto_pci_cfg;
1912
1913 if (auto_slot_cfg){
1914 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot=Auto\n",
1915 modname, CPU_no);
1916
1917 }else{
1918 printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot #%d\n",
1919 modname, CPU_no, slot_no);
1920 }
1921
1922 /* check to see that CPU A or B has been selected in 'router.conf' */
1923 switch(CPU_no) {
1924 case S514_CPU_A:
1925 case S514_CPU_B:
1926 break;
1927
1928 default:
1929 printk(KERN_INFO "%s: S514 CPU definition invalid.\n",
1930 modname);
1931 printk(KERN_INFO "Must be 'A' or 'B'\n");
1932 return 0;
1933 }
1934
1935 number_S514_cards = find_s514_adapter(hw, 0);
1936 if(!number_S514_cards)
1937 return 0;
1938
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",
1945 modname);
1946 return 0;
1947 }
1948 }
1949
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);
1955
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);
1961 else
1962 printk(KERN_INFO "%s: No PCI memory allocated to card\n", modname);
1963 return 0;
1964 }
1965
1966 /* enable the PCI memory */
1967 pci_read_config_dword(pci_dev,
1968 (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
1969 &ut_u32);
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));
1973
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",
1977 modname);
1978 return 0;
1979 }
1980
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
1987 * would crash.
1988 */
1989 if (init_pci_slot(hw))
1990 return 0;
1991
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);
1996
1997 printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
1998 modname, hw->irq);
1999
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),
2006 (unsigned long)16);
2007
2008 if(!hw->dpmbase || !hw->vector) {
2009 printk(KERN_INFO "%s: PCI virtual memory allocation failed\n",
2010 modname);
2011 return 0;
2012 }
2013
2014 /* halt the adapter */
2015 writeb (S514_CPU_HALT, hw->vector);
2016
2017 return 1;
2018}
2019
2020/*============================================================================
2021 * Find the S514 PCI adapter in the PCI bus.
2022 * Return the number of S514 adapters found (0 if no adapter found).
2023 */
2024static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
2025{
2026 unsigned char slot_no;
2027 int number_S514_cards = 0;
2028 char S514_found_in_slot = 0;
2029 u16 PCI_subsys_vendor;
2030
2031 struct pci_dev *pci_dev = NULL;
2032
2033 slot_no = hw->S514_slot_no;
2034
2035 while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2036 != NULL) {
2037
2038 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2039 &PCI_subsys_vendor);
2040
2041 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2042 continue;
2043
2044 hw->pci_dev = pci_dev;
2045
2046 if(find_first_S514_card)
2047 return(1);
2048
2049 number_S514_cards ++;
2050
2051 printk(KERN_INFO
2052 "%s: S514 card found, slot #%d (devfn 0x%X)\n",
2053 modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
2054 pci_dev->devfn);
2055
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;
2059
2060 }else if (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == slot_no){
2061 S514_found_in_slot = 1;
2062 break;
2063 }
2064 }
2065
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);
2069 return 0;
2070 }
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);
2078 return 0;
2079 }
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) {
2083 printk(KERN_INFO
2084 "%s: Error, S514 card not found in specified slot #%d\n",
2085 modname, slot_no);
2086 return 0;
2087 }
2088
2089 return (number_S514_cards);
2090}
2091
2092
2093
2094/******* Miscellaneous ******************************************************/
2095
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.
2100 */
2101static int calibrate_delay (int mks)
2102{
2103 unsigned int delay;
2104 unsigned long stop;
2105
2106 for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
2107 return (delay/(1000000L/mks) + 1);
2108}
2109
2110/*============================================================================
2111 * Get option's index into the options list.
2112 * Return option's index (1 .. N) or zero if option is invalid.
2113 */
2114static int get_option_index (unsigned* optlist, unsigned optval)
2115{
2116 int i;
2117
2118 for (i = 1; i <= optlist[0]; ++i)
2119 if ( optlist[i] == optval)
2120 return i;
2121 return 0;
2122}
2123
2124/*============================================================================
2125 * Check memory region to see if it's available.
2126 * Return: 0 ok.
2127 */
2128static unsigned check_memregion (void* ptr, unsigned len)
2129{
2130 volatile unsigned char* p = ptr;
2131
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 */
2137 }
2138 }
2139
2140 return len;
2141}
2142
2143/*============================================================================
2144 * Test memory region.
2145 * Return: size of the region that passed the test.
2146 * Note: Region size must be multiple of 2 !
2147 */
2148static unsigned test_memregion (void* ptr, unsigned len)
2149{
2150 volatile unsigned short* w_ptr;
2151 unsigned len_w = len >> 1; /* region len in words */
2152 unsigned i;
2153
2154 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2155 writew (0xAA55, w_ptr);
2156
2157 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2158 if (readw (w_ptr) != 0xAA55) {
2159 len_w = i;
2160 break;
2161 }
2162
2163 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2164 writew (0x55AA, w_ptr);
2165
2166 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2167 if (readw(w_ptr) != 0x55AA) {
2168 len_w = i;
2169 break;
2170 }
2171
2172 for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
2173 writew (0, w_ptr);
2174
2175 return len_w << 1;
2176}
2177
2178/*============================================================================
2179 * Calculate 16-bit CRC using CCITT polynomial.
2180 */
2181static unsigned short checksum (unsigned char* buf, unsigned len)
2182{
2183 unsigned short crc = 0;
2184 unsigned mask, flag;
2185
2186 for (; len; --len, ++buf) {
2187 for (mask = 0x80; mask; mask >>= 1) {
2188 flag = (crc & 0x8000);
2189 crc <<= 1;
2190 crc |= ((*buf & mask) ? 1 : 0);
2191 if (flag) crc ^= 0x1021;
2192 }
2193 }
2194 return crc;
2195}
2196
2197static int init_pci_slot(sdlahw_t *hw)
2198{
2199
2200 u32 int_status;
2201 int volatile found=0;
2202 int i=0;
2203
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.
2207 */
2208
2209 for (i=0; (i<MAX_S514_CARDS) && !found; i++){
2210 if (pci_slot_ar[i] == hw->S514_slot_no){
2211 found=1;
2212 break;
2213 }
2214 if (pci_slot_ar[i] == 0xFF){
2215 break;
2216 }
2217 }
2218
2219 if (!found){
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);
2224 printk(KERN_INFO
2225 "%s: Number of Sangoma PCI cards exceeded maximum limit.\n",
2226 modname);
2227 printk(KERN_INFO "Please contact Sangoma Technologies\n");
2228 return 1;
2229 }
2230 pci_slot_ar[i] = hw->S514_slot_no;
2231 }
2232 return 0;
2233}
2234
2235static int pci_probe(sdlahw_t *hw)
2236{
2237
2238 unsigned char slot_no;
2239 int number_S514_cards = 0;
2240 u16 PCI_subsys_vendor;
2241 u16 PCI_card_type;
2242
2243 struct pci_dev *pci_dev = NULL;
2244 struct pci_bus *bus = NULL;
2245
2246 slot_no = 0;
2247
2248 while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
2249 != NULL) {
2250
2251 pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
2252 &PCI_subsys_vendor);
2253
2254 if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
2255 continue;
2256
2257 pci_read_config_word(pci_dev, PCI_CARD_TYPE,
2258 &PCI_card_type);
2259
2260 bus = pci_dev->bus;
2261
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;
2269 printk(KERN_INFO
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),
2272 pci_dev->irq);
2273 }else{
2274 number_S514_cards += 2;
2275 printk(KERN_INFO
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),
2278 pci_dev->irq);
2279 }
2280 }
2281
2282 return number_S514_cards;
2283
2284}
2285
2286
2287
2288EXPORT_SYMBOL(wanpipe_hw_probe);
2289
2290unsigned wanpipe_hw_probe(void)
2291{
2292 sdlahw_t hw;
2293 unsigned* opt = s508_port_options;
2294 unsigned cardno=0;
2295 int i;
2296
2297 memset(&hw, 0, sizeof(hw));
2298
2299 for (i = 1; i <= opt[0]; i++) {
2300 if (detect_s508(opt[i])){
2301 /* S508 card can support up to two physical links */
2302 cardno+=2;
2303 printk(KERN_INFO "wanpipe: S508-ISA card found, port 0x%x\n",opt[i]);
2304 }
2305 }
2306
2307 #ifdef CONFIG_PCI
2308 hw.S514_slot_no = 0;
2309 cardno += pci_probe(&hw);
2310 #else
2311 printk(KERN_INFO "wanpipe: Warning, Kernel not compiled for PCI support!\n");
2312 printk(KERN_INFO "wanpipe: PCI Hardware Probe Failed!\n");
2313 #endif
2314
2315 return cardno;
2316}
2317
2318/****** End *****************************************************************/