OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [hardware/] [eicon/] [os_4bri.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
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
 
21
static void *diva_xdiLoadFileFile = NULL;
22
static dword diva_xdiLoadFileLength = 0;
23
 
24
/*
25
**  IMPORTS
26
*/
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);
31
 
32
extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
33
extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
34
 
35
extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
36
 
37
/*
38
**  LOCALS
39
*/
40
static unsigned long _4bri_bar_length[4] = {
41
        0x100,
42
        0x100,                  /* I/O */
43
        MQ_MEMORY_SIZE,
44
        0x2000
45
};
46
static unsigned long _4bri_v2_bar_length[4] = {
47
        0x100,
48
        0x100,                  /* I/O */
49
        MQ2_MEMORY_SIZE,
50
        0x10000
51
};
52
static unsigned long _4bri_v2_bri_bar_length[4] = {
53
        0x100,
54
        0x100,                  /* I/O */
55
        BRI2_MEMORY_SIZE,
56
        0x10000
57
};
58
 
59
 
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,
64
                                   int length);
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,
70
                                       dword address,
71
                                       const byte * data,
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);
77
 
78
static 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
 
91
static 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
 
102
static 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
           Set up hardware related pointers
116
         */
117
        a->xdi_adapter.Address = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
118
        a->xdi_adapter.Address += c_offset;
119
 
120
        a->xdi_adapter.Control = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
121
 
122
        a->xdi_adapter.ram = a->resources.pci.addr[2];  /* BAR2 SDRAM  */
123
        a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
124
 
125
        a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */
126
        /*
127
           ctlReg contains the register address for the MIPS CPU reset control
128
         */
129
        a->xdi_adapter.ctlReg = a->resources.pci.addr[3];       /* BAR3 CNTRL  */
130
        /*
131
           prom contains the register address for FPGA and EEPROM programming
132
         */
133
        a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
134
}
135
 
136
/*
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
141
**
142
**  Called by master adapter, that will initialize and add slave adapters
143
*/
144
int 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[sizeof(_4bri_bar_length) /
153
                                 sizeof(_4bri_bar_length[0])];
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
           Get Serial Number
174
           The serial number of 4BRI is accessible in accordance with PCI spec
175
           via command register located in configuration space, also we do not
176
           have to map any BAR before we can access it
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
           Set properties
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
           First initialization step: get and check hardware resoures.
195
           Do not map resources and do not access card at this step
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
           Map all MEMORY BAR's
223
         */
224
        for (bar = 0; bar < 4; bar++) {
225
                if (bar != 1) { /* ignore I/O */
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
           Register I/O port
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
           Set cleanup pointer for base adapter only, so slave adapter
254
           will be unable to get cleanup
255
         */
256
        a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
257
 
258
        /*
259
           Create slave adapters
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
           Allocate slave list
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
           Set interfaces
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
                   Do not initialize second DPC - only one thread will be created
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
           Set up hardware related pointers
406
         */
407
        a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0];   /* BAR0 CONFIG */
408
        a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1        */
409
        a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3];       /* BAR3 CNTRL  */
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
           reset contains the base address for the PLX 9054 register set
426
         */
427
        p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
428
        WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);   /* disable PCI interrupts */
429
        DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
430
 
431
        /*
432
           Set IRQ handler
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
           Add three slave adapters
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
**  Cleanup function will be called for master adapter only
467
**  this is guaranteed by design: cleanup callback is set
468
**  by master adapter only
469
*/
470
static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
471
{
472
        int bar;
473
 
474
        /*
475
           Stop adapter if running
476
         */
477
        if (a->xdi_adapter.Initialized) {
478
                diva_4bri_stop_adapter(a);
479
        }
480
 
481
        /*
482
           Remove IRQ handler
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
           Free DPC's and spin locks on all adapters
491
         */
492
        diva_4bri_cleanup_slave_adapters(a);
493
 
494
        /*
495
           Unmap all BARS
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
           Unregister I/O
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
 
530
static 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
**  Release resources of slave adapters
581
*/
582
static 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
 
627
static int
628
diva_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
                           Only master adapter can access hardware config
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
 
819
void *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
 
833
void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
834
{
835
}
836
 
837
void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
838
{
839
}
840
 
841
static int
842
diva_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
 
858
static 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
           Forget all entities on all adapters
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
 
909
static int
910
diva_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
 
933
static int
934
diva_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
           start adapter
944
         */
945
        start_qBri_hardware(IoAdapter);
946
 
947
        p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
948
        /*
949
           wait for signature in shared memory (max. 3 seconds)
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 successfull 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
 
1010
static 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
           interrupt test
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
           Reset on-board interrupt register
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                          /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
1058
}
1059
 
1060
static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
1061
{
1062
        PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1063
 
1064
        /*
1065
           clear any pending interrupt
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
           kill pending dpcs
1075
         */
1076
        diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
1077
        diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
1078
}
1079
 
1080
static 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);    /* nothing to stop */
1093
        }
1094
 
1095
        for (i = 0; i < IoAdapter->tasks; i++) {
1096
                IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
1097
        }
1098
 
1099
        /*
1100
           Disconnect Adapters from DIDD
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
           Stop interrupts
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
           Stop and reset adapter
1128
         */
1129
        IoAdapter->stop(IoAdapter);
1130
 
1131
        return (0);
1132
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.