1 /* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
14 #include "xdi_adapter.h"
21 static void *diva_xdiLoadFileFile
= NULL
;
22 static dword diva_xdiLoadFileLength
= 0;
27 extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter
);
28 extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter
);
29 extern void diva_xdi_display_adapter_features(int card
);
30 extern void diva_add_slave_adapter(diva_os_xdi_adapter_t
* a
);
32 extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter
);
33 extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter
);
35 extern int diva_card_read_xlog(diva_os_xdi_adapter_t
* a
);
40 static unsigned long _4bri_bar_length
[4] = {
46 static unsigned long _4bri_v2_bar_length
[4] = {
52 static unsigned long _4bri_v2_bri_bar_length
[4] = {
60 static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t
* a
);
61 static int _4bri_get_serial_number(diva_os_xdi_adapter_t
* a
);
62 static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter
*a
,
63 diva_xdi_um_cfg_cmd_t
* cmd
,
65 static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t
* a
);
66 static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t
* a
,
67 byte
* data
, dword length
);
68 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter
);
69 static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter
,
72 dword length
, dword limit
);
73 static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter
,
74 dword start_address
, dword features
);
75 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter
);
76 static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t
* a
);
78 static int _4bri_is_rev_2_card(int card_ordinal
)
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
:
91 static int _4bri_is_rev_2_bri_card(int card_ordinal
)
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
:
102 static void diva_4bri_set_addresses(diva_os_xdi_adapter_t
*a
)
104 dword offset
= a
->resources
.pci
.qoffset
;
105 dword c_offset
= offset
* a
->xdi_adapter
.ControllerNumber
;
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;
115 Set up hardware related pointers
117 a
->xdi_adapter
.Address
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
118 a
->xdi_adapter
.Address
+= c_offset
;
120 a
->xdi_adapter
.Control
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
122 a
->xdi_adapter
.ram
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
123 a
->xdi_adapter
.ram
+= c_offset
+ (offset
- MQ_SHARED_RAM_SIZE
);
125 a
->xdi_adapter
.reset
= a
->resources
.pci
.addr
[0]; /* BAR0 CONFIG */
127 ctlReg contains the register address for the MIPS CPU reset control
129 a
->xdi_adapter
.ctlReg
= a
->resources
.pci
.addr
[3]; /* BAR3 CNTRL */
131 prom contains the register address for FPGA and EEPROM programming
133 a
->xdi_adapter
.prom
= &a
->xdi_adapter
.reset
[0x6E];
137 ** BAR0 - MEM - 0x100 - CONFIG MEM
138 ** BAR1 - I/O - 0x100 - UNUSED
139 ** BAR2 - MEM - MQ_MEMORY_SIZE (MQ2_MEMORY_SIZE on Rev.2) - SDRAM
140 ** BAR3 - MEM - 0x2000 (0x10000 on Rev.2) - CNTRL
142 ** Called by master adapter, that will initialize and add slave adapters
144 int diva_4bri_init_card(diva_os_xdi_adapter_t
* a
)
148 PADAPTER_LIST_ENTRY quadro_list
;
149 diva_os_xdi_adapter_t
*diva_current
;
150 diva_os_xdi_adapter_t
*adapter_list
[4];
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;
158 if (_4bri_is_rev_2_bri_card(a
->CardOrdinal
)) {
159 memcpy(bar_length
, _4bri_v2_bri_bar_length
,
162 memcpy(bar_length
, _4bri_v2_bar_length
,
166 memcpy(bar_length
, _4bri_bar_length
, sizeof(bar_length
));
168 DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
169 bar_length
[2], tasks
, factor
))
173 The serial number of 4BRI is accessible in accordance with PCI spec
174 via command register located in configuration space, also we do not
175 have to map any BAR before we can access it
177 if (!_4bri_get_serial_number(a
)) {
178 DBG_ERR(("A: 4BRI can't get Serial Number"))
179 diva_4bri_cleanup_adapter(a
);
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
))
193 First initialization step: get and check hardware resoures.
194 Do not map resources and do not access card at this step
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)) {
204 ("A: invalid bar[%d]=%08x", bar
,
205 a
->resources
.pci
.bar
[bar
]))
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"));
218 a
->xdi_adapter
.sdram_bar
= a
->resources
.pci
.bar
[2];
223 for (bar
= 0; bar
< 4; bar
++) {
224 if (bar
!= 1) { /* ignore I/O */
225 a
->resources
.pci
.addr
[bar
] =
226 divasa_remap_pci_bar(a
, bar
, a
->resources
.pci
.bar
[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
);
239 sprintf(&a
->port_name
[0], "DIVA 4BRI %ld", (long) a
->xdi_adapter
.serialNo
);
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
);
248 a
->resources
.pci
.addr
[1] =
249 (void *) (unsigned long) a
->resources
.pci
.bar
[1];
252 Set cleanup pointer for base adapter only, so slave adapter
253 will be unable to get cleanup
255 a
->interface
.cleanup_adapter_proc
= diva_4bri_cleanup_adapter
;
258 Create slave adapters
261 if (!(a
->slave_adapters
[0] =
262 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
264 diva_4bri_cleanup_adapter(a
);
267 if (!(a
->slave_adapters
[1] =
268 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
270 diva_os_free(0, a
->slave_adapters
[0]);
271 a
->slave_adapters
[0] = NULL
;
272 diva_4bri_cleanup_adapter(a
);
275 if (!(a
->slave_adapters
[2] =
276 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
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
);
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
));
291 adapter_list
[1] = a
->slave_adapters
[0];
292 adapter_list
[2] = a
->slave_adapters
[1];
293 adapter_list
[3] = a
->slave_adapters
[2];
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
;
305 diva_4bri_cleanup_adapter(a
);
308 memset(quadro_list
, 0x00, sizeof(*quadro_list
));
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
;
321 for (i
= 0; i
< tasks
; i
++) {
322 diva_current
= adapter_list
[i
];
324 diva_current
->dsp_mask
= 0x00000003;
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
;
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
=
340 diva_current
->xdi_adapter
.e_max
*
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
]);
351 memset(diva_current
->xdi_adapter
.e_tbl
, 0x00,
352 diva_current
->xdi_adapter
.e_max
* sizeof(E_INFO
));
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
]);
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
]);
371 strcpy(diva_current
->xdi_adapter
.req_soft_isr
. dpc_thread_name
, "kdivas4brid");
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
]);
384 Do not initialize second DPC - only one thread will be created
386 diva_current
->xdi_adapter
.isr_soft_isr
.object
=
387 diva_current
->xdi_adapter
.req_soft_isr
.object
;
391 prepare_qBri2_functions(&a
->xdi_adapter
);
393 prepare_qBri_functions(&a
->xdi_adapter
);
396 for (i
= 0; i
< tasks
; i
++) {
397 diva_current
= adapter_list
[i
];
399 memcpy(&diva_current
->resources
, &a
->resources
, sizeof(divas_card_resources_t
));
400 diva_current
->resources
.pci
.qoffset
= (a
->xdi_adapter
.MemorySize
>> factor
);
404 Set up hardware related pointers
406 a
->xdi_adapter
.cfg
= (void *) (unsigned long) a
->resources
.pci
.bar
[0]; /* BAR0 CONFIG */
407 a
->xdi_adapter
.port
= (void *) (unsigned long) a
->resources
.pci
.bar
[1]; /* BAR1 */
408 a
->xdi_adapter
.ctlReg
= (void *) (unsigned long) a
->resources
.pci
.bar
[3]; /* BAR3 CNTRL */
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
;
417 Slave
->serialNo
= ((dword
) (Slave
->ControllerNumber
<< 24)) |
418 a
->xdi_adapter
.serialNo
;
419 Slave
->cardType
= a
->xdi_adapter
.cardType
;
424 reset contains the base address for the PLX 9054 register set
426 p
= DIVA_OS_MEM_ATTACH_RESET(&a
->xdi_adapter
);
427 WRITE_BYTE(&p
[PLX9054_INTCSR
], 0x00); /* disable PCI interrupts */
428 DIVA_OS_MEM_DETACH_RESET(&a
->xdi_adapter
, p
);
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
);
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
]);
447 a
->xdi_adapter
.irq_info
.registered
= 1;
450 Add three slave adapters
453 diva_add_slave_adapter(adapter_list
[1]);
454 diva_add_slave_adapter(adapter_list
[2]);
455 diva_add_slave_adapter(adapter_list
[3]);
458 diva_log_info("%s IRQ:%d SerNo:%d", a
->xdi_adapter
.Properties
.Name
,
459 a
->resources
.pci
.irq
, a
->xdi_adapter
.serialNo
);
465 ** Cleanup function will be called for master adapter only
466 ** this is guaranteed by design: cleanup callback is set
467 ** by master adapter only
469 static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t
* a
)
474 Stop adapter if running
476 if (a
->xdi_adapter
.Initialized
) {
477 diva_4bri_stop_adapter(a
);
483 if (a
->xdi_adapter
.irq_info
.registered
) {
484 diva_os_remove_irq(a
, a
->xdi_adapter
.irq_info
.irq_nr
);
486 a
->xdi_adapter
.irq_info
.registered
= 0;
489 Free DPC's and spin locks on all adapters
491 diva_4bri_cleanup_slave_adapters(a
);
496 for (bar
= 0; bar
< 4; bar
++) {
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
;
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
->
514 _4bri_v2_bar_length
[1] :
516 &a
->port_name
[0], 1);
517 a
->resources
.pci
.bar
[1] = 0;
518 a
->resources
.pci
.addr
[1] = NULL
;
522 diva_os_free(0, a
->slave_list
);
523 a
->slave_list
= NULL
;
529 static int _4bri_get_serial_number(diva_os_xdi_adapter_t
* a
)
533 word addr
, status
, i
, j
;
537 Bus
= a
->resources
.pci
.bus
;
538 Slot
= a
->resources
.pci
.func
;
539 hdev
= a
->resources
.pci
.hdev
;
541 for (i
= 0; i
< 64; ++i
) {
543 for (j
= 0; j
< 5; ++j
) {
544 PCIwrite(Bus
, Slot
, 0x4E, &addr
, sizeof(addr
),
547 PCIread(Bus
, Slot
, 0x4E, &status
, sizeof(status
),
553 DBG_ERR(("EEPROM[%d] read failed (0x%x)", i
* 4, addr
))
556 PCIread(Bus
, Slot
, 0x50, &data
[i
], sizeof(data
[i
]), hdev
);
558 DBG_BLK(((char *) &data
[0], sizeof(data
)))
561 if (serNo
== 0 || serNo
== 0xffffffff)
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
;
571 a
->xdi_adapter
.serialNo
= serNo
;
573 DBG_REG(("Serial No. : %ld", a
->xdi_adapter
.serialNo
))
579 ** Release resources of slave adapters
581 static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t
* a
)
583 diva_os_xdi_adapter_t
*adapter_list
[4];
584 diva_os_xdi_adapter_t
*diva_current
;
588 adapter_list
[1] = a
->slave_adapters
[0];
589 adapter_list
[2] = a
->slave_adapters
[1];
590 adapter_list
[3] = a
->slave_adapters
[2];
592 for (i
= 0; i
< a
->xdi_adapter
.tasks
; i
++) {
593 diva_current
= adapter_list
[i
];
595 diva_os_destroy_spin_lock(&diva_current
->
597 isr_spin_lock
, "unload");
598 diva_os_destroy_spin_lock(&diva_current
->
603 diva_os_cancel_soft_isr(&diva_current
->xdi_adapter
.
605 diva_os_cancel_soft_isr(&diva_current
->xdi_adapter
.
608 diva_os_remove_soft_isr(&diva_current
->xdi_adapter
.
610 diva_current
->xdi_adapter
.isr_soft_isr
.object
= NULL
;
612 if (diva_current
->xdi_adapter
.e_tbl
) {
614 diva_current
->xdi_adapter
.
617 diva_current
->xdi_adapter
.e_tbl
= NULL
;
618 diva_current
->xdi_adapter
.e_max
= 0;
619 diva_current
->xdi_adapter
.e_count
= 0;
627 diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter
*a
,
628 diva_xdi_um_cfg_cmd_t
* cmd
, int length
)
632 if (cmd
->adapter
!= a
->controller
) {
633 DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
634 cmd
->adapter
, a
->controller
))
638 switch (cmd
->command
) {
639 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL
:
640 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
;
651 case DIVA_XDI_UM_CMD_GET_SERIAL_NR
:
652 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
;
663 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG
:
664 if (!a
->xdi_adapter
.ControllerNumber
) {
666 Only master adapter can access hardware config
668 a
->xdi_mbox
.data_length
= sizeof(dword
) * 9;
670 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
671 if (a
->xdi_mbox
.data
) {
673 dword
*data
= (dword
*) a
->xdi_mbox
.data
;
675 for (i
= 0; i
< 8; i
++) {
676 *data
++ = a
->resources
.pci
.bar
[i
];
678 *data
++ = (dword
) a
->resources
.pci
.irq
;
679 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
685 case DIVA_XDI_UM_CMD_GET_CARD_STATE
:
686 if (!a
->xdi_adapter
.ControllerNumber
) {
687 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
) {
696 } else if (a
->xdi_adapter
.trapped
) {
698 } else if (a
->xdi_adapter
.Initialized
) {
703 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
709 case DIVA_XDI_UM_CMD_WRITE_FPGA
:
710 if (!a
->xdi_adapter
.ControllerNumber
) {
712 diva_4bri_write_fpga_image(a
,
720 case DIVA_XDI_UM_CMD_RESET_ADAPTER
:
721 if (!a
->xdi_adapter
.ControllerNumber
) {
722 ret
= diva_4bri_reset_adapter(&a
->xdi_adapter
);
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
,
744 case DIVA_XDI_UM_CMD_START_ADAPTER
:
745 if (!a
->xdi_adapter
.ControllerNumber
) {
746 ret
= diva_4bri_start_adapter(&a
->xdi_adapter
,
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
))
766 case DIVA_XDI_UM_CMD_STOP_ADAPTER
:
767 if (!a
->xdi_adapter
.ControllerNumber
) {
768 ret
= diva_4bri_stop_adapter(a
);
772 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY
:
773 ret
= diva_card_read_xlog(a
);
776 case DIVA_XDI_UM_CMD_READ_SDRAM
:
777 if (!a
->xdi_adapter
.ControllerNumber
778 && a
->xdi_adapter
.Address
) {
780 (a
->xdi_mbox
.data_length
=
781 cmd
->command_data
.read_sdram
.length
)) {
783 (a
->xdi_mbox
.data_length
+
784 cmd
->command_data
.read_sdram
.offset
) <
785 a
->xdi_adapter
.MemorySize
) {
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
;
796 src
+= cmd
->command_data
.read_sdram
.offset
;
799 *dst
++ = READ_BYTE(src
++);
801 DIVA_OS_MEM_DETACH_ADDRESS(&a
->xdi_adapter
, p
);
802 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
811 DBG_ERR(("A: A(%d) invalid cmd=%d", a
->controller
,
818 void *xdiLoadFile(char *FileName
, dword
*FileLength
,
821 void *ret
= diva_xdiLoadFileFile
;
824 *FileLength
= diva_xdiLoadFileLength
;
826 diva_xdiLoadFileFile
= NULL
;
827 diva_xdiLoadFileLength
= 0;
832 void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter
)
836 void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter
)
841 diva_4bri_write_fpga_image(diva_os_xdi_adapter_t
* a
, byte
* data
,
846 diva_xdiLoadFileFile
= data
;
847 diva_xdiLoadFileLength
= length
;
849 ret
= qBri_FPGA_download(&a
->xdi_adapter
);
851 diva_xdiLoadFileFile
= NULL
;
852 diva_xdiLoadFileLength
= 0;
854 return (ret
? 0 : -1);
857 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter
)
862 if (!IoAdapter
->Address
|| !IoAdapter
->reset
) {
865 if (IoAdapter
->Initialized
) {
866 DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
872 Forget all entities on all adapters
874 for (i
= 0; ((i
< IoAdapter
->tasks
) && IoAdapter
->QuadroList
); i
++) {
875 Slave
= IoAdapter
->QuadroList
->QuadroAdapter
[i
];
878 memset(Slave
->e_tbl
, 0x00,
879 Slave
->e_max
* sizeof(E_INFO
));
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
));
909 diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter
,
911 const byte
* data
, dword length
, dword limit
)
913 byte __iomem
*p
= DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter
);
914 byte __iomem
*mem
= p
;
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
))
925 WRITE_BYTE(mem
++, *data
++);
928 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter
, p
);
933 diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter
,
934 dword start_address
, dword features
)
936 volatile word __iomem
*signature
;
944 start_qBri_hardware(IoAdapter
);
946 p
= DIVA_OS_MEM_ATTACH_RAM(IoAdapter
);
948 wait for signature in shared memory (max. 3 seconds)
950 signature
= (volatile word __iomem
*) (&p
[0x1E]);
952 for (i
= 0; i
< 300; ++i
) {
954 if (READ_WORD(&signature
[0]) == 0x4447) {
955 DBG_TRC(("Protocol startup time %d.%02d seconds",
956 (i
/ 100), (i
% 100)))
962 for (i
= 1; i
< IoAdapter
->tasks
; i
++) {
963 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->features
=
965 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->a
.
966 protocol_capabilities
= IoAdapter
->features
;
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
);
978 DIVA_OS_MEM_DETACH_RAM(IoAdapter
, p
);
980 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
981 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 1;
982 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->IrqCount
= 0;
985 if (check_qBri_interrupt(IoAdapter
)) {
986 DBG_ERR(("A: A(%d) interrupt test failed",
988 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
989 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 0;
991 IoAdapter
->stop(IoAdapter
);
995 IoAdapter
->Properties
.Features
= (word
) features
;
996 diva_xdi_display_adapter_features(IoAdapter
->ANum
);
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
;
1009 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter
)
1011 #ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
1013 ADAPTER
*a
= &IoAdapter
->a
;
1016 IoAdapter
->IrqCount
= 0;
1018 if (IoAdapter
->ControllerNumber
> 0)
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
);
1028 a
->ram_out(a
, &PR_RAM
->ReadyInt
, 1);
1030 for (i
= 100; !IoAdapter
->IrqCount
&& (i
-- > 0); diva_os_wait(10));
1032 return ((IoAdapter
->IrqCount
> 0) ? 0 : -1);
1034 dword
volatile __iomem
*qBriIrq
;
1037 Reset on-board interrupt register
1039 IoAdapter
->IrqCount
= 0;
1040 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
1041 qBriIrq
= (dword
volatile __iomem
*) (&p
[_4bri_is_rev_2_card
1043 cardType
) ? (MQ2_BREG_IRQ_TEST
)
1044 : (MQ_BREG_IRQ_TEST
)]);
1046 WRITE_DWORD(qBriIrq
, MQ_IRQ_REQ_OFF
);
1047 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
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
);
1056 #endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
1059 static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t
* a
)
1061 PISDN_ADAPTER IoAdapter
= &a
->xdi_adapter
;
1064 clear any pending interrupt
1066 IoAdapter
->disIrq(IoAdapter
);
1068 IoAdapter
->tst_irq(&IoAdapter
->a
);
1069 IoAdapter
->clr_irq(&IoAdapter
->a
);
1070 IoAdapter
->tst_irq(&IoAdapter
->a
);
1075 diva_os_cancel_soft_isr(&IoAdapter
->req_soft_isr
);
1076 diva_os_cancel_soft_isr(&IoAdapter
->isr_soft_isr
);
1079 static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t
* a
)
1081 PISDN_ADAPTER IoAdapter
= &a
->xdi_adapter
;
1084 if (!IoAdapter
->ram
) {
1088 if (!IoAdapter
->Initialized
) {
1089 DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
1091 return (-1); /* nothing to stop */
1094 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
1095 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 0;
1099 Disconnect Adapters from DIDD
1101 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
1102 diva_xdi_didd_remove_adapter(IoAdapter
->QuadroList
->QuadroAdapter
[i
]->ANum
);
1110 a
->clear_interrupts_proc
= diva_4bri_clear_interrupts
;
1111 IoAdapter
->a
.ReadyInt
= 1;
1112 IoAdapter
->a
.ram_inc(&IoAdapter
->a
, &PR_RAM
->ReadyInt
);
1115 } while (i
-- && a
->clear_interrupts_proc
);
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",
1123 IoAdapter
->a
.ReadyInt
= 0;
1126 Stop and reset adapter
1128 IoAdapter
->stop(IoAdapter
);