1 /*
2 * Diva Server 4BRI specific part of initialisation
3 *
4 * Copyright (C) Eicon Technology Corporation, 2000.
5 *
6 * Eicon File Revision : 1.7
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 *
11 */
12
13 #include "sys.h"
14 #include "idi.h"
15 #include "divas.h"
16 #include "pc.h"
17 #include "pr_pc.h"
18 #include "dsp_defs.h"
19 #include "constant.h"
20 #include "adapter.h"
21 #include "uxio.h"
22
23 #define TEST_INT_DIVAS_Q 0x13
24
25 #define DIVAS_MAINT_OFFSET 0xff00 /* value for 4BRI card */
26 #define MQ_BOARD_DSP_OFFSET 0x00a00000
27 #define MQ_DSP1_ADDR_OFFSET 0x00000008
28 #define MQ_DSP_JUNK_OFFSET 0x00000400
29 #define MQ_DSP1_DATA_OFFSET 0x00000000
30 #define MQ_BOARD_ISAC_DSP_RESET 0x00800028
31 #define MQ_BREG_RISC 0x1200 /* RISC Reset */
32 #define MQ_ISAC_DSP_RESET 0x0028 /* ISAC and DSP reset address offset */
33 #define MQ_RISC_COLD_RESET_MASK 0x0001 /* RISC Cold reset */
34 #define MQ_RISC_WARM_RESET_MASK 0x0002 /* RISC Warm reset */
35 #define MQ_IRQ_REQ_ON 0x1
36 #define MQ_IRQ_REQ_OFF 0x0
37 #define MQ_BREG_IRQ_TEST 0x0608
38 #define PLX9054_INTCSR 0x69
39 #define PLX9054_INT_ENA 0x09
40
41 #define DIVAS_IOBASE 0x01
42 #define M_PCI_RESET 0x10
43
44 byte mem_in(ADAPTER *a, void *adr);
45 word mem_inw(ADAPTER *a, void *adr);
46 void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
47 void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
48 void mem_out(ADAPTER *a, void *adr, byte data);
49 void mem_outw(ADAPTER *a, void *adr, word data);
50 void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
51 void mem_inc(ADAPTER *a, void *adr);
52
53 int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg);
54 static int fourbri_ISR (card_t* card);
55
56 int FPGA_Download(word, dword, byte *, byte *, int);
57 extern byte FPGA_Bytes[];
58 extern void *get_card(int);
59
60 byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
61 void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
62 word GetProtFeatureValue(char *sw_id);
63
64 void memcp(byte *dst, byte *src, dword dwLen);
65 int memcm(byte *dst, byte *src, dword dwLen);
66
diva_server_4bri_reset(card_t * card)67 static int diva_server_4bri_reset(card_t *card)
68 {
69 byte *ctl;
70
71 DPRINTF(("divas: reset Diva Server 4BRI"));
72
73 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
74
75 /* stop RISC, DSP's and ISAC */
76 UxCardMemOut(card->hw, &ctl[MQ_BREG_RISC], 0);
77 UxCardMemOut(card->hw, &ctl[MQ_ISAC_DSP_RESET], 0);
78
79 UxCardMemDetach(card->hw, ctl);
80
81 return 0;
82 }
83
diva_server_4bri_config(card_t * card,dia_config_t * config)84 static int diva_server_4bri_config(card_t *card, dia_config_t *config)
85 {
86 byte *shared;
87 int i, j;
88
89 DPRINTF(("divas: configure Diva Server 4BRI"));
90
91 shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
92
93 for (i=0; i<256; i++)
94 {
95 UxCardMemOut(card->hw, &shared[i], 0);
96 }
97
98 UxCardMemOut(card->hw, &shared[ 8], config->tei);
99 UxCardMemOut(card->hw, &shared[ 9], config->nt2);
100 UxCardMemOut(card->hw, &shared[10], config->sig_flags);
101 UxCardMemOut(card->hw, &shared[11], config->watchdog);
102 UxCardMemOut(card->hw, &shared[12], config->permanent);
103 UxCardMemOut(card->hw, &shared[13], config->x_interface);
104 UxCardMemOut(card->hw, &shared[14], config->stable_l2);
105 UxCardMemOut(card->hw, &shared[15], config->no_order_check);
106 UxCardMemOut(card->hw, &shared[16], config->handset_type);
107 UxCardMemOut(card->hw, &shared[17], 0);
108 UxCardMemOut(card->hw, &shared[18], config->low_channel);
109 UxCardMemOut(card->hw, &shared[19], config->prot_version);
110 UxCardMemOut(card->hw, &shared[20], config->crc4);
111
112 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
113 {
114 DPRINTF(("divas: Signifying V.90"));
115 UxCardMemOut(card->hw, &shared[22], 4);
116 }
117 else
118 {
119 UxCardMemOut(card->hw, &shared[22], 0);
120 }
121
122 for (i=0; i<2; i++)
123 {
124 for (j=0; j<32; j++)
125 {
126 UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
127 }
128
129 for (j=0; j<32; j++)
130 {
131 UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
132 }
133
134 for (j=0; j<32; j++)
135 {
136 UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
137 }
138 }
139
140 UxCardMemDetach(card->hw, shared);
141
142 return 0;
143 }
144
145 static
diva_server_4bri_reset_int(card_t * card)146 void diva_server_4bri_reset_int(card_t *card)
147 {
148 byte *ctl;
149
150 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
151
152 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
153
154 UxCardMemDetach(card->hw, ctl);
155
156 return;
157 }
158
159
diva_server_4bri_test_int(card_t * card)160 static int diva_server_4bri_test_int(card_t *card)
161 {
162 byte *ctl, i;
163 byte *reg;
164
165 DPRINTF(("divas: test interrupt for Diva Server 4BRI"));
166
167 /* We get the last (dummy) adapter in so we need to go back to the first */
168
169 card = get_card(card->cfg.card_id - 3);
170
171 /* Enable interrupts on PLX chip */
172
173 reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
174
175 UxCardPortIoOut(card->hw, reg, PLX9054_INTCSR, PLX9054_INT_ENA);
176
177 UxCardMemDetach(card->hw, reg);
178
179 /* Set the test interrupt flag */
180 card->test_int_pend = TEST_INT_DIVAS_Q;
181
182 /* Now to trigger the interrupt */
183
184 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
185
186 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_ON);
187
188 UxCardMemDetach(card->hw, ctl);
189
190 for (i = 0; i < 50; i++)
191 {
192 if (!card->test_int_pend)
193 {
194 break;
195 }
196 UxPause(10);
197 }
198
199 if (card->test_int_pend)
200 {
201 DPRINTF(("active: timeout waiting for card to interrupt"));
202 return (-1);
203 }
204
205 return 0;
206 }
207
208
print_hdr(unsigned char * code,int offset)209 static void print_hdr(unsigned char *code, int offset)
210 {
211 unsigned char hdr[80];
212 int i;
213
214 i = 0;
215
216 while ((i < (DIM(hdr) -1)) &&
217 (code[offset + i] != '\0') &&
218 (code[offset + i] != '\r') &&
219 (code[offset + i] != '\n'))
220 {
221 hdr[i] = code[offset + i];
222 i++;
223 }
224
225 hdr[i] = '\0';
226
227 DPRINTF(("divas: loading %s", hdr));
228 }
229
diva_server_4bri_load(card_t * card,dia_load_t * load)230 static int diva_server_4bri_load(card_t *card, dia_load_t *load)
231 {
232 byte *pRAM=NULL;
233 int download_offset=0;
234 card_t *FirstCard;
235 byte sw_id[80];
236
237 DPRINTF(("divas: loading Diva Server 4BRI[%d]", load->card_id));
238
239 switch(load->code_type)
240 {
241 case DIA_CPU_CODE:
242 DPRINTF(("divas: RISC code"));
243 print_hdr(load->code, 0x80);
244 card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
245 download_offset = 0; // Protocol code written to offset 0
246 pRAM = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
247 break;
248
249 case DIA_DSP_CODE:
250 DPRINTF(("divas: DSP code"));
251 print_hdr(load->code, 0x0);
252 FirstCard = get_card(load->card_id - 3);
253 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
254 {
255 download_offset = MQ_V90D_DSP_CODE_BASE;
256 }
257 else
258 {
259 download_offset = MQ_ORG_DSP_CODE_BASE;
260 }
261 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
262 download_offset += (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC);
263
264 break;
265
266 case DIA_TABLE_CODE:
267 DPRINTF(("divas: TABLE code"));
268 FirstCard = get_card(load->card_id - 3);
269 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
270 {
271 download_offset = MQ_V90D_DSP_CODE_BASE + sizeof(dword);
272 }
273 else
274 {
275 download_offset = MQ_ORG_DSP_CODE_BASE + sizeof(dword);
276 }
277 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
278 break;
279
280 case DIA_CONT_CODE:
281 DPRINTF(("divas: continuation code"));
282 break;
283
284 case DIA_DLOAD_CNT:
285 DPRINTF(("divas: COUNT code"));
286 FirstCard = get_card(load->card_id - 3);
287 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
288 {
289 download_offset = MQ_V90D_DSP_CODE_BASE;
290 }
291 else
292 {
293 download_offset = MQ_ORG_DSP_CODE_BASE;
294 }
295 pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);
296 break;
297
298 case DIA_FPGA_CODE:
299 DPRINTF(("divas: 4BRI FPGA download - %d bytes", load->length));
300 if (FPGA_Download(IDI_ADAPTER_MAESTRAQ,
301 card->hw->io_base,
302 sw_id,
303 load->code,
304 load->length
305 ) == -1)
306 {
307 DPRINTF(("divas: FPGA download failed"));
308 return -1;
309 }
310
311 /* NOW reset the 4BRI */
312 diva_server_4bri_reset(card);
313 return 0; // No need for anything further loading
314
315 default:
316 DPRINTF(("divas: unknown code type"));
317 return -1;
318 }
319
320 memcp(pRAM + (download_offset & 0x3FFFFF), load->code, load->length);
321
322 {
323 int mism_off;
324 if ((mism_off = memcm(pRAM + (download_offset & 0x3FFFFF), load->code, load->length)))
325 {
326 DPRINTF(("divas: memory mismatch at offset %d", mism_off));
327 UxCardMemDetach(card->hw, pRAM);
328 return -1;
329 }
330 }
331
332 UxCardMemDetach(card->hw, pRAM);
333
334 return 0;
335 }
336
diva_server_4bri_start(card_t * card,byte * channels)337 static int diva_server_4bri_start(card_t *card, byte *channels)
338 {
339 byte *ctl;
340 byte *shared;
341 int i;
342 int adapter_num;
343
344 DPRINTF(("divas: start Diva Server 4BRI"));
345 *channels = 0;
346 card->is_live = FALSE;
347
348 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
349
350 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK);
351
352 UxPause(2);
353
354 UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
355
356 UxPause(10);
357
358 UxCardMemDetach(card->hw, ctl);
359
360 shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
361
362 for ( i = 0 ; i < 300 ; ++i )
363 {
364 UxPause (10) ;
365
366 if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 )
367 {
368 DPRINTF(("divas: Protocol startup time %d.%02d seconds",
369 (i / 100), (i % 100) ));
370
371 break;
372 }
373 }
374
375 if (i==300)
376 {
377 DPRINTF(("divas: Timeout starting card"));
378 DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E])));
379
380 UxCardMemDetach(card->hw, shared);
381 return -1;
382 }
383
384 UxCardMemDetach(card->hw, shared);
385
386 for (adapter_num=3; adapter_num >= 0; adapter_num--)
387 {
388 card_t *qbri_card;
389
390 qbri_card = get_card(card->cfg.card_id - adapter_num);
391
392 if (qbri_card)
393 {
394 qbri_card->is_live = TRUE;
395 shared = UxCardMemAttach(qbri_card->hw, DIVAS_SHARED_MEMORY);
396 *channels += UxCardMemIn(qbri_card->hw, &shared[0x3F6]);
397 UxCardMemDetach(qbri_card->hw, shared);
398 }
399 else
400 {
401 DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id));
402 }
403 }
404
405 diva_server_4bri_test_int(card);
406
407 return 0;
408 }
409
410 static
diva_server_4bri_mem_get(card_t * card,mem_block_t * mem_block)411 int diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block)
412
413 {
414 byte *a;
415 byte *card_addr;
416 word length = 0;
417 int i;
418
419 a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
420
421 card_addr = a;
422 card_addr += mem_block->addr;
423
424 for (i=0; i < sizeof(mem_block->data); i++)
425 {
426 mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
427 card_addr++;
428 length++;
429 }
430
431 UxCardMemDetach(card->hw, a);
432
433 return length;
434 }
435
436 /*
437 * Initialise 4BRI specific entry points
438 */
439
Divas4BriInit(card_t * card,dia_card_t * cfg)440 int Divas4BriInit(card_t *card, dia_card_t *cfg)
441 {
442 // byte sw_id[80];
443 // extern int FPGA_Done;
444
445 DPRINTF(("divas: initialise Diva Server 4BRI"));
446
447 if (Divas4BRIInitPCI(card, cfg) == -1)
448 {
449 return -1;
450 }
451
452 /* Need to download the FPGA */
453 /* if (!FPGA_Done)
454 {
455 int retVal;
456
457 retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ,
458 cfg->io_base,
459 sw_id,
460 FPGA_Bytes
461 );
462 if(retVal==-1)
463 {
464
465 DPRINTF(("divas: FPGA Download Failed"));
466 return -1;
467
468 }
469 FPGA_Done = 1;
470 } */
471
472 card->card_reset = diva_server_4bri_reset;
473 card->card_load = diva_server_4bri_load;
474 card->card_config = diva_server_4bri_config;
475 card->card_start = diva_server_4bri_start;
476 card->reset_int = diva_server_4bri_reset_int;
477 card->card_mem_get = diva_server_4bri_mem_get;
478
479 card->xlog_offset = DIVAS_MAINT_OFFSET;
480
481 card->out = DivasOut;
482 card->test_int = DivasTestInt;
483 card->dpc = DivasDpc;
484 card->clear_int = DivasClearInt;
485 card->card_isr = fourbri_ISR;
486
487 card->a.ram_out = mem_out;
488 card->a.ram_outw = mem_outw;
489 card->a.ram_out_buffer = mem_out_buffer;
490 card->a.ram_inc = mem_inc;
491
492 card->a.ram_in = mem_in;
493 card->a.ram_inw = mem_inw;
494 card->a.ram_in_buffer = mem_in_buffer;
495 card->a.ram_look_ahead = mem_look_ahead;
496
497 return 0;
498 }
499
memcp(byte * dst,byte * src,dword dwLen)500 void memcp(byte *dst, byte *src, dword dwLen)
501 {
502 while (dwLen)
503 {
504 *dst = *src;
505 dst++; src++;
506 dwLen--;
507 }
508 }
509
memcm(byte * dst,byte * src,dword dwLen)510 int memcm(byte *dst, byte *src, dword dwLen)
511 {
512 int offset = 0;
513
514 while (offset < dwLen)
515 {
516 if(*dst != *src)
517 return (offset+1);
518
519 offset++;
520 src++;
521 dst++;
522 }
523
524 return 0;
525 }
526
527
528
529 /*int fourbri_ISR (card_t* card)
530 {
531 int served = 0;
532 byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
533
534
535 if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
536 {
537 served = 1;
538 card->int_pend += 1;
539 DivasDpcSchedule();
540 UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
541 }
542
543 UxCardMemDetach(card->hw, DivasIOBase);
544
545 return (served != 0);
546 }*/
547
548
fourbri_ISR(card_t * card)549 static int fourbri_ISR (card_t* card)
550 {
551 byte *ctl;
552
553 card->int_pend += 1;
554 DivasDpcSchedule(); /* ISR DPC */
555
556 ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);
557 UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);
558 UxCardMemDetach(card->hw, ctl);
559
560 return (1);
561 }
562