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