1
2
3#include "platform.h"
4#include "debuglib.h"
5#include "cardtype.h"
6#include "pc.h"
7#include "pr_pc.h"
8#include "di_defs.h"
9#include "dsp_defs.h"
10#include "di.h"
11#include "io.h"
12
13#include "xdi_msg.h"
14#include "xdi_adapter.h"
15#include "os_4bri.h"
16#include "diva_pci.h"
17#include "mi_pc.h"
18#include "dsrv4bri.h"
19#include "helpers.h"
20
21static void *diva_xdiLoadFileFile = NULL;
22static dword diva_xdiLoadFileLength = 0;
23
24
25
26
27extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter);
28extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter);
29extern void diva_xdi_display_adapter_features(int card);
30extern void diva_add_slave_adapter(diva_os_xdi_adapter_t *a);
31
32extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
33extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
34
35extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
36
37
38
39
40static unsigned long _4bri_bar_length[4] = {
41 0x100,
42 0x100,
43 MQ_MEMORY_SIZE,
44 0x2000
45};
46static unsigned long _4bri_v2_bar_length[4] = {
47 0x100,
48 0x100,
49 MQ2_MEMORY_SIZE,
50 0x10000
51};
52static unsigned long _4bri_v2_bri_bar_length[4] = {
53 0x100,
54 0x100,
55 BRI2_MEMORY_SIZE,
56 0x10000
57};
58
59
60static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
61static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a);
62static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
63 diva_xdi_um_cfg_cmd_t *cmd,
64 int length);
65static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a);
66static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a,
67 byte *data, dword length);
68static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter);
69static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
70 dword address,
71 const byte *data,
72 dword length, dword limit);
73static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
74 dword start_address, dword features);
75static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter);
76static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a);
77
78static int _4bri_is_rev_2_card(int card_ordinal)
79{
80 switch (card_ordinal) {
81 case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
82 case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
83 case CARDTYPE_DIVASRV_B_2M_V2_PCI:
84 case CARDTYPE_DIVASRV_B_2F_PCI:
85 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
86 return (1);
87 }
88 return (0);
89}
90
91static int _4bri_is_rev_2_bri_card(int card_ordinal)
92{
93 switch (card_ordinal) {
94 case CARDTYPE_DIVASRV_B_2M_V2_PCI:
95 case CARDTYPE_DIVASRV_B_2F_PCI:
96 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
97 return (1);
98 }
99 return (0);
100}
101
102static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
103{
104 dword offset = a->resources.pci.qoffset;
105 dword c_offset = offset * a->xdi_adapter.ControllerNumber;
106
107 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
108 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
109 a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
110 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
111 a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
112 a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
113
114
115
116
117 a->xdi_adapter.Address = a->resources.pci.addr[2];
118 a->xdi_adapter.Address += c_offset;
119
120 a->xdi_adapter.Control = a->resources.pci.addr[2];
121
122 a->xdi_adapter.ram = a->resources.pci.addr[2];
123 a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
124
125 a->xdi_adapter.reset = a->resources.pci.addr[0];
126
127
128
129 a->xdi_adapter.ctlReg = a->resources.pci.addr[3];
130
131
132
133 a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
134}
135
136
137
138
139
140
141
142
143
144int diva_4bri_init_card(diva_os_xdi_adapter_t *a)
145{
146 int bar, i;
147 byte __iomem *p;
148 PADAPTER_LIST_ENTRY quadro_list;
149 diva_os_xdi_adapter_t *diva_current;
150 diva_os_xdi_adapter_t *adapter_list[4];
151 PISDN_ADAPTER Slave;
152 unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
153 int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
154 int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
155 int factor = (tasks == 1) ? 1 : 2;
156
157 if (v2) {
158 if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
159 memcpy(bar_length, _4bri_v2_bri_bar_length,
160 sizeof(bar_length));
161 } else {
162 memcpy(bar_length, _4bri_v2_bar_length,
163 sizeof(bar_length));
164 }
165 } else {
166 memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
167 }
168 DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
169 bar_length[2], tasks, factor))
170
171
172
173
174
175
176
177 if (!_4bri_get_serial_number(a)) {
178 DBG_ERR(("A: 4BRI can't get Serial Number"))
179 diva_4bri_cleanup_adapter(a);
180 return (-1);
181 }
182
183
184
185
186 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
187 DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
188 a->xdi_adapter.Properties.Name,
189 a->xdi_adapter.serialNo,
190 a->resources.pci.bus, a->resources.pci.func))
191
192
193
194
195
196 for (bar = 0; bar < 4; bar++) {
197 a->resources.pci.bar[bar] =
198 divasa_get_pci_bar(a->resources.pci.bus,
199 a->resources.pci.func, bar,
200 a->resources.pci.hdev);
201 if (!a->resources.pci.bar[bar]
202 || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
203 DBG_ERR(
204 ("A: invalid bar[%d]=%08x", bar,
205 a->resources.pci.bar[bar]))
206 return (-1);
207 }
208 }
209 a->resources.pci.irq =
210 (byte) divasa_get_pci_irq(a->resources.pci.bus,
211 a->resources.pci.func,
212 a->resources.pci.hdev);
213 if (!a->resources.pci.irq) {
214 DBG_ERR(("A: invalid irq"));
215 return (-1);
216 }
217
218 a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];
219
220
221
222
223 for (bar = 0; bar < 4; bar++) {
224 if (bar != 1) {
225 a->resources.pci.addr[bar] =
226 divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
227 bar_length[bar]);
228 if (!a->resources.pci.addr[bar]) {
229 DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
230 diva_4bri_cleanup_adapter(a);
231 return (-1);
232 }
233 }
234 }
235
236
237
238
239 sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
240
241 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
242 bar_length[1], &a->port_name[0], 1)) {
243 DBG_ERR(("A: 4BRI: can't register bar[1]"))
244 diva_4bri_cleanup_adapter(a);
245 return (-1);
246 }
247
248 a->resources.pci.addr[1] =
249 (void *) (unsigned long) a->resources.pci.bar[1];
250
251
252
253
254
255 a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
256
257
258
259
260 if (tasks > 1) {
261 if (!(a->slave_adapters[0] =
262 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
263 {
264 diva_4bri_cleanup_adapter(a);
265 return (-1);
266 }
267 if (!(a->slave_adapters[1] =
268 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
269 {
270 diva_os_free(0, a->slave_adapters[0]);
271 a->slave_adapters[0] = NULL;
272 diva_4bri_cleanup_adapter(a);
273 return (-1);
274 }
275 if (!(a->slave_adapters[2] =
276 (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
277 {
278 diva_os_free(0, a->slave_adapters[0]);
279 diva_os_free(0, a->slave_adapters[1]);
280 a->slave_adapters[0] = NULL;
281 a->slave_adapters[1] = NULL;
282 diva_4bri_cleanup_adapter(a);
283 return (-1);
284 }
285 memset(a->slave_adapters[0], 0x00, sizeof(*a));
286 memset(a->slave_adapters[1], 0x00, sizeof(*a));
287 memset(a->slave_adapters[2], 0x00, sizeof(*a));
288 }
289
290 adapter_list[0] = a;
291 adapter_list[1] = a->slave_adapters[0];
292 adapter_list[2] = a->slave_adapters[1];
293 adapter_list[3] = a->slave_adapters[2];
294
295
296
297
298 quadro_list =
299 (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
300 if (!(a->slave_list = quadro_list)) {
301 for (i = 0; i < (tasks - 1); i++) {
302 diva_os_free(0, a->slave_adapters[i]);
303 a->slave_adapters[i] = NULL;
304 }
305 diva_4bri_cleanup_adapter(a);
306 return (-1);
307 }
308 memset(quadro_list, 0x00, sizeof(*quadro_list));
309
310
311
312
313 a->xdi_adapter.QuadroList = quadro_list;
314 for (i = 0; i < tasks; i++) {
315 adapter_list[i]->xdi_adapter.ControllerNumber = i;
316 adapter_list[i]->xdi_adapter.tasks = tasks;
317 quadro_list->QuadroAdapter[i] =
318 &adapter_list[i]->xdi_adapter;
319 }
320
321 for (i = 0; i < tasks; i++) {
322 diva_current = adapter_list[i];
323
324 diva_current->dsp_mask = 0x00000003;
325
326 diva_current->xdi_adapter.a.io =
327 &diva_current->xdi_adapter;
328 diva_current->xdi_adapter.DIRequest = request;
329 diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc;
330 diva_current->xdi_adapter.Properties =
331 CardProperties[a->CardOrdinal];
332 diva_current->CardOrdinal = a->CardOrdinal;
333
334 diva_current->xdi_adapter.Channels =
335 CardProperties[a->CardOrdinal].Channels;
336 diva_current->xdi_adapter.e_max =
337 CardProperties[a->CardOrdinal].E_info;
338 diva_current->xdi_adapter.e_tbl =
339 diva_os_malloc(0,
340 diva_current->xdi_adapter.e_max *
341 sizeof(E_INFO));
342
343 if (!diva_current->xdi_adapter.e_tbl) {
344 diva_4bri_cleanup_slave_adapters(a);
345 diva_4bri_cleanup_adapter(a);
346 for (i = 1; i < (tasks - 1); i++) {
347 diva_os_free(0, adapter_list[i]);
348 }
349 return (-1);
350 }
351 memset(diva_current->xdi_adapter.e_tbl, 0x00,
352 diva_current->xdi_adapter.e_max * sizeof(E_INFO));
353
354 if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.isr_spin_lock, "isr")) {
355 diva_4bri_cleanup_slave_adapters(a);
356 diva_4bri_cleanup_adapter(a);
357 for (i = 1; i < (tasks - 1); i++) {
358 diva_os_free(0, adapter_list[i]);
359 }
360 return (-1);
361 }
362 if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.data_spin_lock, "data")) {
363 diva_4bri_cleanup_slave_adapters(a);
364 diva_4bri_cleanup_adapter(a);
365 for (i = 1; i < (tasks - 1); i++) {
366 diva_os_free(0, adapter_list[i]);
367 }
368 return (-1);
369 }
370
371 strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");
372
373 if (diva_os_initialize_soft_isr(&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
374 &diva_current->xdi_adapter)) {
375 diva_4bri_cleanup_slave_adapters(a);
376 diva_4bri_cleanup_adapter(a);
377 for (i = 1; i < (tasks - 1); i++) {
378 diva_os_free(0, adapter_list[i]);
379 }
380 return (-1);
381 }
382
383
384
385
386 diva_current->xdi_adapter.isr_soft_isr.object =
387 diva_current->xdi_adapter.req_soft_isr.object;
388 }
389
390 if (v2) {
391 prepare_qBri2_functions(&a->xdi_adapter);
392 } else {
393 prepare_qBri_functions(&a->xdi_adapter);
394 }
395
396 for (i = 0; i < tasks; i++) {
397 diva_current = adapter_list[i];
398 if (i)
399 memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
400 diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
401 }
402
403
404
405
406 a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0];
407 a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1];
408 a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3];
409
410 for (i = 0; i < tasks; i++) {
411 diva_current = adapter_list[i];
412 diva_4bri_set_addresses(diva_current);
413 Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
414 Slave->MultiMaster = &a->xdi_adapter;
415 Slave->sdram_bar = a->xdi_adapter.sdram_bar;
416 if (i) {
417 Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
418 a->xdi_adapter.serialNo;
419 Slave->cardType = a->xdi_adapter.cardType;
420 }
421 }
422
423
424
425
426 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
427 WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);
428 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
429
430
431
432
433 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
434 sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld",
435 (long) a->xdi_adapter.serialNo);
436
437 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
438 a->xdi_adapter.irq_info.irq_name)) {
439 diva_4bri_cleanup_slave_adapters(a);
440 diva_4bri_cleanup_adapter(a);
441 for (i = 1; i < (tasks - 1); i++) {
442 diva_os_free(0, adapter_list[i]);
443 }
444 return (-1);
445 }
446
447 a->xdi_adapter.irq_info.registered = 1;
448
449
450
451
452 if (tasks > 1) {
453 diva_add_slave_adapter(adapter_list[1]);
454 diva_add_slave_adapter(adapter_list[2]);
455 diva_add_slave_adapter(adapter_list[3]);
456 }
457
458 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
459 a->resources.pci.irq, a->xdi_adapter.serialNo);
460
461 return (0);
462}
463
464
465
466
467
468
469static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
470{
471 int bar;
472
473
474
475
476 if (a->xdi_adapter.Initialized) {
477 diva_4bri_stop_adapter(a);
478 }
479
480
481
482
483 if (a->xdi_adapter.irq_info.registered) {
484 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
485 }
486 a->xdi_adapter.irq_info.registered = 0;
487
488
489
490
491 diva_4bri_cleanup_slave_adapters(a);
492
493
494
495
496 for (bar = 0; bar < 4; bar++) {
497 if (bar != 1) {
498 if (a->resources.pci.bar[bar]
499 && a->resources.pci.addr[bar]) {
500 divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
501 a->resources.pci.bar[bar] = 0;
502 a->resources.pci.addr[bar] = NULL;
503 }
504 }
505 }
506
507
508
509
510 if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
511 diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
512 _4bri_is_rev_2_card(a->
513 CardOrdinal) ?
514 _4bri_v2_bar_length[1] :
515 _4bri_bar_length[1],
516 &a->port_name[0], 1);
517 a->resources.pci.bar[1] = 0;
518 a->resources.pci.addr[1] = NULL;
519 }
520
521 if (a->slave_list) {
522 diva_os_free(0, a->slave_list);
523 a->slave_list = NULL;
524 }
525
526 return (0);
527}
528
529static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a)
530{
531 dword data[64];
532 dword serNo;
533 word addr, status, i, j;
534 byte Bus, Slot;
535 void *hdev;
536
537 Bus = a->resources.pci.bus;
538 Slot = a->resources.pci.func;
539 hdev = a->resources.pci.hdev;
540
541 for (i = 0; i < 64; ++i) {
542 addr = i * 4;
543 for (j = 0; j < 5; ++j) {
544 PCIwrite(Bus, Slot, 0x4E, &addr, sizeof(addr),
545 hdev);
546 diva_os_wait(1);
547 PCIread(Bus, Slot, 0x4E, &status, sizeof(status),
548 hdev);
549 if (status & 0x8000)
550 break;
551 }
552 if (j >= 5) {
553 DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
554 return (0);
555 }
556 PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
557 }
558 DBG_BLK(((char *) &data[0], sizeof(data)))
559
560 serNo = data[32];
561 if (serNo == 0 || serNo == 0xffffffff)
562 serNo = data[63];
563
564 if (!serNo) {
565 DBG_LOG(("W: Serial Number == 0, create one serial number"));
566 serNo = a->resources.pci.bar[1] & 0xffff0000;
567 serNo |= a->resources.pci.bus << 8;
568 serNo |= a->resources.pci.func;
569 }
570
571 a->xdi_adapter.serialNo = serNo;
572
573 DBG_REG(("Serial No. : %ld", a->xdi_adapter.serialNo))
574
575 return (serNo);
576}
577
578
579
580
581static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a)
582{
583 diva_os_xdi_adapter_t *adapter_list[4];
584 diva_os_xdi_adapter_t *diva_current;
585 int i;
586
587 adapter_list[0] = a;
588 adapter_list[1] = a->slave_adapters[0];
589 adapter_list[2] = a->slave_adapters[1];
590 adapter_list[3] = a->slave_adapters[2];
591
592 for (i = 0; i < a->xdi_adapter.tasks; i++) {
593 diva_current = adapter_list[i];
594 if (diva_current) {
595 diva_os_destroy_spin_lock(&diva_current->
596 xdi_adapter.
597 isr_spin_lock, "unload");
598 diva_os_destroy_spin_lock(&diva_current->
599 xdi_adapter.
600 data_spin_lock,
601 "unload");
602
603 diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
604 req_soft_isr);
605 diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
606 isr_soft_isr);
607
608 diva_os_remove_soft_isr(&diva_current->xdi_adapter.
609 req_soft_isr);
610 diva_current->xdi_adapter.isr_soft_isr.object = NULL;
611
612 if (diva_current->xdi_adapter.e_tbl) {
613 diva_os_free(0,
614 diva_current->xdi_adapter.
615 e_tbl);
616 }
617 diva_current->xdi_adapter.e_tbl = NULL;
618 diva_current->xdi_adapter.e_max = 0;
619 diva_current->xdi_adapter.e_count = 0;
620 }
621 }
622
623 return (0);
624}
625
626static int
627diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
628 diva_xdi_um_cfg_cmd_t *cmd, int length)
629{
630 int ret = -1;
631
632 if (cmd->adapter != a->controller) {
633 DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
634 cmd->adapter, a->controller))
635 return (-1);
636 }
637
638 switch (cmd->command) {
639 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
640 a->xdi_mbox.data_length = sizeof(dword);
641 a->xdi_mbox.data =
642 diva_os_malloc(0, a->xdi_mbox.data_length);
643 if (a->xdi_mbox.data) {
644 *(dword *) a->xdi_mbox.data =
645 (dword) a->CardOrdinal;
646 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
647 ret = 0;
648 }
649 break;
650
651 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
652 a->xdi_mbox.data_length = sizeof(dword);
653 a->xdi_mbox.data =
654 diva_os_malloc(0, a->xdi_mbox.data_length);
655 if (a->xdi_mbox.data) {
656 *(dword *) a->xdi_mbox.data =
657 (dword) a->xdi_adapter.serialNo;
658 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
659 ret = 0;
660 }
661 break;
662
663 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
664 if (!a->xdi_adapter.ControllerNumber) {
665
666
667
668 a->xdi_mbox.data_length = sizeof(dword) * 9;
669 a->xdi_mbox.data =
670 diva_os_malloc(0, a->xdi_mbox.data_length);
671 if (a->xdi_mbox.data) {
672 int i;
673 dword *data = (dword *) a->xdi_mbox.data;
674
675 for (i = 0; i < 8; i++) {
676 *data++ = a->resources.pci.bar[i];
677 }
678 *data++ = (dword) a->resources.pci.irq;
679 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
680 ret = 0;
681 }
682 }
683 break;
684
685 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
686 if (!a->xdi_adapter.ControllerNumber) {
687 a->xdi_mbox.data_length = sizeof(dword);
688 a->xdi_mbox.data =
689 diva_os_malloc(0, a->xdi_mbox.data_length);
690 if (a->xdi_mbox.data) {
691 dword *data = (dword *) a->xdi_mbox.data;
692 if (!a->xdi_adapter.ram
693 || !a->xdi_adapter.reset
694 || !a->xdi_adapter.cfg) {
695 *data = 3;
696 } else if (a->xdi_adapter.trapped) {
697 *data = 2;
698 } else if (a->xdi_adapter.Initialized) {
699 *data = 1;
700 } else {
701 *data = 0;
702 }
703 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
704 ret = 0;
705 }
706 }
707 break;
708
709 case DIVA_XDI_UM_CMD_WRITE_FPGA:
710 if (!a->xdi_adapter.ControllerNumber) {
711 ret =
712 diva_4bri_write_fpga_image(a,
713 (byte *)&cmd[1],
714 cmd->command_data.
715 write_fpga.
716 image_length);
717 }
718 break;
719
720 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
721 if (!a->xdi_adapter.ControllerNumber) {
722 ret = diva_4bri_reset_adapter(&a->xdi_adapter);
723 }
724 break;
725
726 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
727 if (!a->xdi_adapter.ControllerNumber) {
728 ret = diva_4bri_write_sdram_block(&a->xdi_adapter,
729 cmd->
730 command_data.
731 write_sdram.
732 offset,
733 (byte *) &
734 cmd[1],
735 cmd->
736 command_data.
737 write_sdram.
738 length,
739 a->xdi_adapter.
740 MemorySize);
741 }
742 break;
743
744 case DIVA_XDI_UM_CMD_START_ADAPTER:
745 if (!a->xdi_adapter.ControllerNumber) {
746 ret = diva_4bri_start_adapter(&a->xdi_adapter,
747 cmd->command_data.
748 start.offset,
749 cmd->command_data.
750 start.features);
751 }
752 break;
753
754 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
755 if (!a->xdi_adapter.ControllerNumber) {
756 a->xdi_adapter.features =
757 cmd->command_data.features.features;
758 a->xdi_adapter.a.protocol_capabilities =
759 a->xdi_adapter.features;
760 DBG_TRC(("Set raw protocol features (%08x)",
761 a->xdi_adapter.features))
762 ret = 0;
763 }
764 break;
765
766 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
767 if (!a->xdi_adapter.ControllerNumber) {
768 ret = diva_4bri_stop_adapter(a);
769 }
770 break;
771
772 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
773 ret = diva_card_read_xlog(a);
774 break;
775
776 case DIVA_XDI_UM_CMD_READ_SDRAM:
777 if (!a->xdi_adapter.ControllerNumber
778 && a->xdi_adapter.Address) {
779 if (
780 (a->xdi_mbox.data_length =
781 cmd->command_data.read_sdram.length)) {
782 if (
783 (a->xdi_mbox.data_length +
784 cmd->command_data.read_sdram.offset) <
785 a->xdi_adapter.MemorySize) {
786 a->xdi_mbox.data =
787 diva_os_malloc(0,
788 a->xdi_mbox.
789 data_length);
790 if (a->xdi_mbox.data) {
791 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
792 byte __iomem *src = p;
793 byte *dst = a->xdi_mbox.data;
794 dword len = a->xdi_mbox.data_length;
795
796 src += cmd->command_data.read_sdram.offset;
797
798 while (len--) {
799 *dst++ = READ_BYTE(src++);
800 }
801 DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
802 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
803 ret = 0;
804 }
805 }
806 }
807 }
808 break;
809
810 default:
811 DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
812 cmd->command))
813 }
814
815 return (ret);
816}
817
818void *xdiLoadFile(char *FileName, dword *FileLength,
819 unsigned long lim)
820{
821 void *ret = diva_xdiLoadFileFile;
822
823 if (FileLength) {
824 *FileLength = diva_xdiLoadFileLength;
825 }
826 diva_xdiLoadFileFile = NULL;
827 diva_xdiLoadFileLength = 0;
828
829 return (ret);
830}
831
832void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
833{
834}
835
836void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
837{
838}
839
840static int
841diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a, byte *data,
842 dword length)
843{
844 int ret;
845
846 diva_xdiLoadFileFile = data;
847 diva_xdiLoadFileLength = length;
848
849 ret = qBri_FPGA_download(&a->xdi_adapter);
850
851 diva_xdiLoadFileFile = NULL;
852 diva_xdiLoadFileLength = 0;
853
854 return (ret ? 0 : -1);
855}
856
857static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
858{
859 PISDN_ADAPTER Slave;
860 int i;
861
862 if (!IoAdapter->Address || !IoAdapter->reset) {
863 return (-1);
864 }
865 if (IoAdapter->Initialized) {
866 DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
867 IoAdapter->ANum))
868 return (-1);
869 }
870
871
872
873
874 for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
875 Slave = IoAdapter->QuadroList->QuadroAdapter[i];
876 Slave->e_count = 0;
877 if (Slave->e_tbl) {
878 memset(Slave->e_tbl, 0x00,
879 Slave->e_max * sizeof(E_INFO));
880 }
881 Slave->head = 0;
882 Slave->tail = 0;
883 Slave->assign = 0;
884 Slave->trapped = 0;
885
886 memset(&Slave->a.IdTable[0], 0x00,
887 sizeof(Slave->a.IdTable));
888 memset(&Slave->a.IdTypeTable[0], 0x00,
889 sizeof(Slave->a.IdTypeTable));
890 memset(&Slave->a.FlowControlIdTable[0], 0x00,
891 sizeof(Slave->a.FlowControlIdTable));
892 memset(&Slave->a.FlowControlSkipTable[0], 0x00,
893 sizeof(Slave->a.FlowControlSkipTable));
894 memset(&Slave->a.misc_flags_table[0], 0x00,
895 sizeof(Slave->a.misc_flags_table));
896 memset(&Slave->a.rx_stream[0], 0x00,
897 sizeof(Slave->a.rx_stream));
898 memset(&Slave->a.tx_stream[0], 0x00,
899 sizeof(Slave->a.tx_stream));
900 memset(&Slave->a.tx_pos[0], 0x00, sizeof(Slave->a.tx_pos));
901 memset(&Slave->a.rx_pos[0], 0x00, sizeof(Slave->a.rx_pos));
902 }
903
904 return (0);
905}
906
907
908static int
909diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
910 dword address,
911 const byte *data, dword length, dword limit)
912{
913 byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
914 byte __iomem *mem = p;
915
916 if (((address + length) >= limit) || !mem) {
917 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
918 DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
919 IoAdapter->ANum, address + length))
920 return (-1);
921 }
922 mem += address;
923
924 while (length--) {
925 WRITE_BYTE(mem++, *data++);
926 }
927
928 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
929 return (0);
930}
931
932static int
933diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
934 dword start_address, dword features)
935{
936 volatile word __iomem *signature;
937 int started = 0;
938 int i;
939 byte __iomem *p;
940
941
942
943
944 start_qBri_hardware(IoAdapter);
945
946 p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
947
948
949
950 signature = (volatile word __iomem *) (&p[0x1E]);
951
952 for (i = 0; i < 300; ++i) {
953 diva_os_wait(10);
954 if (READ_WORD(&signature[0]) == 0x4447) {
955 DBG_TRC(("Protocol startup time %d.%02d seconds",
956 (i / 100), (i % 100)))
957 started = 1;
958 break;
959 }
960 }
961
962 for (i = 1; i < IoAdapter->tasks; i++) {
963 IoAdapter->QuadroList->QuadroAdapter[i]->features =
964 IoAdapter->features;
965 IoAdapter->QuadroList->QuadroAdapter[i]->a.
966 protocol_capabilities = IoAdapter->features;
967 }
968
969 if (!started) {
970 DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
971 IoAdapter->Properties.Name,
972 READ_WORD(&signature[0])))
973 DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
974 (*(IoAdapter->trapFnc)) (IoAdapter);
975 IoAdapter->stop(IoAdapter);
976 return (-1);
977 }
978 DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
979
980 for (i = 0; i < IoAdapter->tasks; i++) {
981 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
982 IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0;
983 }
984
985 if (check_qBri_interrupt(IoAdapter)) {
986 DBG_ERR(("A: A(%d) interrupt test failed",
987 IoAdapter->ANum))
988 for (i = 0; i < IoAdapter->tasks; i++) {
989 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
990 }
991 IoAdapter->stop(IoAdapter);
992 return (-1);
993 }
994
995 IoAdapter->Properties.Features = (word) features;
996 diva_xdi_display_adapter_features(IoAdapter->ANum);
997
998 for (i = 0; i < IoAdapter->tasks; i++) {
999 DBG_LOG(("A(%d) %s adapter successfully started",
1000 IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
1001 (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
1002 diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1003 IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
1004 }
1005
1006 return (0);
1007}
1008
1009static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
1010{
1011#ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
1012 int i;
1013 ADAPTER *a = &IoAdapter->a;
1014 byte __iomem *p;
1015
1016 IoAdapter->IrqCount = 0;
1017
1018 if (IoAdapter->ControllerNumber > 0)
1019 return (-1);
1020
1021 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1022 WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1023 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1024
1025
1026
1027 a->ReadyInt = 1;
1028 a->ram_out(a, &PR_RAM->ReadyInt, 1);
1029
1030 for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
1031
1032 return ((IoAdapter->IrqCount > 0) ? 0 : -1);
1033#else
1034 dword volatile __iomem *qBriIrq;
1035 byte __iomem *p;
1036
1037
1038
1039 IoAdapter->IrqCount = 0;
1040 p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
1041 qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
1042 (IoAdapter->
1043 cardType) ? (MQ2_BREG_IRQ_TEST)
1044 : (MQ_BREG_IRQ_TEST)]);
1045
1046 WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
1047 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
1048
1049 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1050 WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1051 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1052
1053 diva_os_wait(100);
1054
1055 return (0);
1056#endif
1057}
1058
1059static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t *a)
1060{
1061 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1062
1063
1064
1065
1066 IoAdapter->disIrq(IoAdapter);
1067
1068 IoAdapter->tst_irq(&IoAdapter->a);
1069 IoAdapter->clr_irq(&IoAdapter->a);
1070 IoAdapter->tst_irq(&IoAdapter->a);
1071
1072
1073
1074
1075 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
1076 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
1077}
1078
1079static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a)
1080{
1081 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1082 int i;
1083
1084 if (!IoAdapter->ram) {
1085 return (-1);
1086 }
1087
1088 if (!IoAdapter->Initialized) {
1089 DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
1090 IoAdapter->ANum))
1091 return (-1);
1092 }
1093
1094 for (i = 0; i < IoAdapter->tasks; i++) {
1095 IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
1096 }
1097
1098
1099
1100
1101 for (i = 0; i < IoAdapter->tasks; i++) {
1102 diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1103 }
1104
1105 i = 100;
1106
1107
1108
1109
1110 a->clear_interrupts_proc = diva_4bri_clear_interrupts;
1111 IoAdapter->a.ReadyInt = 1;
1112 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
1113 do {
1114 diva_os_sleep(10);
1115 } while (i-- && a->clear_interrupts_proc);
1116
1117 if (a->clear_interrupts_proc) {
1118 diva_4bri_clear_interrupts(a);
1119 a->clear_interrupts_proc = NULL;
1120 DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
1121 IoAdapter->ANum))
1122 }
1123 IoAdapter->a.ReadyInt = 0;
1124
1125
1126
1127
1128 IoAdapter->stop(IoAdapter);
1129
1130 return (0);
1131}
1132