1 // SPDX-License-Identifier: GPL-2.0
2 /* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 armin Exp $ */
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_pri.h"
17 #include "diva_pci.h"
18 #include "mi_pc.h"
19 #include "pc_maint.h"
20 #include "dsp_tst.h"
21 #include "diva_dma.h"
22 #include "dsrv_pri.h"
23 
24 /* --------------------------------------------------------------------------
25    OS Dependent part of XDI driver for DIVA PRI Adapter
26 
27    DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
28    -------------------------------------------------------------------------- */
29 
30 #define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
31 
32 extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
33 
34 /*
35 **  IMPORTS
36 */
37 extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
38 extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
39 extern void diva_xdi_display_adapter_features(int card);
40 
41 static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
42 static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
43 				  diva_xdi_um_cfg_cmd_t *cmd, int length);
44 static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
45 static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
46 static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
47 
48 /*
49 **  Check card revision
50 */
pri_is_rev_2_card(int card_ordinal)51 static int pri_is_rev_2_card(int card_ordinal)
52 {
53 	switch (card_ordinal) {
54 	case CARDTYPE_DIVASRV_P_30M_V2_PCI:
55 	case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
56 		return (1);
57 	}
58 	return (0);
59 }
60 
diva_pri_set_addresses(diva_os_xdi_adapter_t * a)61 static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
62 {
63 	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
64 	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
65 	a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
66 	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
67 	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
68 	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
69 	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
70 
71 	a->xdi_adapter.Address = a->resources.pci.addr[0];
72 	a->xdi_adapter.Control = a->resources.pci.addr[2];
73 	a->xdi_adapter.Config = a->resources.pci.addr[4];
74 
75 	a->xdi_adapter.ram = a->resources.pci.addr[0];
76 	a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
77 
78 	a->xdi_adapter.reset = a->resources.pci.addr[2];
79 	a->xdi_adapter.reset += MP_RESET;
80 
81 	a->xdi_adapter.cfg = a->resources.pci.addr[4];
82 	a->xdi_adapter.cfg += MP_IRQ_RESET;
83 
84 	a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
85 
86 	a->xdi_adapter.prom = a->resources.pci.addr[3];
87 }
88 
89 /*
90 **  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
91 **  BAR1 - DEVICES,				0x1000
92 **  BAR2 - CONTROL (REG), 0x2000
93 **  BAR3 - FLASH (REG),		0x8000
94 **  BAR4 - CONFIG (CFG),	0x1000
95 */
diva_pri_init_card(diva_os_xdi_adapter_t * a)96 int diva_pri_init_card(diva_os_xdi_adapter_t *a)
97 {
98 	int bar = 0;
99 	int pri_rev_2;
100 	unsigned long bar_length[5] = {
101 		MP_MEMORY_SIZE,
102 		0x1000,
103 		0x2000,
104 		0x8000,
105 		0x1000
106 	};
107 
108 	pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
109 
110 	if (pri_rev_2) {
111 		bar_length[0] = MP2_MEMORY_SIZE;
112 	}
113 	/*
114 	  Set properties
115 	*/
116 	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
117 	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
118 
119 		/*
120 		  First initialization step: get and check hardware resoures.
121 		  Do not map resources and do not acecess card at this step
122 		*/
123 		for (bar = 0; bar < 5; bar++) {
124 			a->resources.pci.bar[bar] =
125 				divasa_get_pci_bar(a->resources.pci.bus,
126 						   a->resources.pci.func, bar,
127 						   a->resources.pci.hdev);
128 			if (!a->resources.pci.bar[bar]
129 			    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
130 				DBG_ERR(("A: invalid bar[%d]=%08x", bar,
131 					 a->resources.pci.bar[bar]))
132 					return (-1);
133 			}
134 		}
135 	a->resources.pci.irq =
136 		(byte) divasa_get_pci_irq(a->resources.pci.bus,
137 					  a->resources.pci.func,
138 					  a->resources.pci.hdev);
139 	if (!a->resources.pci.irq) {
140 		DBG_ERR(("A: invalid irq"));
141 		return (-1);
142 	}
143 
144 	/*
145 	  Map all BAR's
146 	*/
147 	for (bar = 0; bar < 5; bar++) {
148 		a->resources.pci.addr[bar] =
149 			divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
150 					     bar_length[bar]);
151 		if (!a->resources.pci.addr[bar]) {
152 			DBG_ERR(("A: A(%d), can't map bar[%d]",
153 				 a->controller, bar))
154 				diva_pri_cleanup_adapter(a);
155 			return (-1);
156 		}
157 	}
158 
159 	/*
160 	  Set all memory areas
161 	*/
162 	diva_pri_set_addresses(a);
163 
164 	/*
165 	  Get Serial Number of this adapter
166 	*/
167 	if (pri_get_serial_number(a)) {
168 		dword serNo;
169 		serNo = a->resources.pci.bar[1] & 0xffff0000;
170 		serNo |= ((dword) a->resources.pci.bus) << 8;
171 		serNo += (a->resources.pci.func + a->controller + 1);
172 		a->xdi_adapter.serialNo = serNo & ~0xFF000000;
173 		DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
174 			 a->controller, a->xdi_adapter.serialNo))
175 			}
176 
177 
178 	/*
179 	  Initialize os objects
180 	*/
181 	if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
182 		diva_pri_cleanup_adapter(a);
183 		return (-1);
184 	}
185 	if (diva_os_initialize_spin_lock
186 	    (&a->xdi_adapter.data_spin_lock, "data")) {
187 		diva_pri_cleanup_adapter(a);
188 		return (-1);
189 	}
190 
191 	strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
192 
193 	if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
194 					DIDpcRoutine, &a->xdi_adapter)) {
195 		diva_pri_cleanup_adapter(a);
196 		return (-1);
197 	}
198 
199 	/*
200 	  Do not initialize second DPC - only one thread will be created
201 	*/
202 	a->xdi_adapter.isr_soft_isr.object =
203 		a->xdi_adapter.req_soft_isr.object;
204 
205 	/*
206 	  Next step of card initialization:
207 	  set up all interface pointers
208 	*/
209 	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
210 	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
211 
212 	a->xdi_adapter.e_tbl =
213 		diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
214 	if (!a->xdi_adapter.e_tbl) {
215 		diva_pri_cleanup_adapter(a);
216 		return (-1);
217 	}
218 	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
219 
220 	a->xdi_adapter.a.io = &a->xdi_adapter;
221 	a->xdi_adapter.DIRequest = request;
222 	a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
223 	a->interface.cmd_proc = diva_pri_cmd_card_proc;
224 
225 	if (pri_rev_2) {
226 		prepare_pri2_functions(&a->xdi_adapter);
227 	} else {
228 		prepare_pri_functions(&a->xdi_adapter);
229 	}
230 
231 	a->dsp_mask = diva_pri_detect_dsps(a);
232 
233 	/*
234 	  Allocate DMA map
235 	*/
236 	if (pri_rev_2) {
237 		diva_init_dma_map(a->resources.pci.hdev,
238 				  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
239 	}
240 
241 	/*
242 	  Set IRQ handler
243 	*/
244 	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
245 	sprintf(a->xdi_adapter.irq_info.irq_name,
246 		"DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
247 
248 	if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
249 				 a->xdi_adapter.irq_info.irq_name)) {
250 		diva_pri_cleanup_adapter(a);
251 		return (-1);
252 	}
253 	a->xdi_adapter.irq_info.registered = 1;
254 
255 	diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
256 		      a->resources.pci.irq, a->xdi_adapter.serialNo);
257 
258 	return (0);
259 }
260 
diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)261 static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
262 {
263 	int bar = 0;
264 
265 	/*
266 	  Stop Adapter if adapter is running
267 	*/
268 	if (a->xdi_adapter.Initialized) {
269 		diva_pri_stop_adapter(a);
270 	}
271 
272 	/*
273 	  Remove ISR Handler
274 	*/
275 	if (a->xdi_adapter.irq_info.registered) {
276 		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
277 	}
278 	a->xdi_adapter.irq_info.registered = 0;
279 
280 	/*
281 	  Step 1: unmap all BAR's, if any was mapped
282 	*/
283 	for (bar = 0; bar < 5; bar++) {
284 		if (a->resources.pci.bar[bar]
285 		    && a->resources.pci.addr[bar]) {
286 			divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
287 			a->resources.pci.bar[bar] = 0;
288 			a->resources.pci.addr[bar] = NULL;
289 		}
290 	}
291 
292 	/*
293 	  Free OS objects
294 	*/
295 	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
296 	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
297 
298 	diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
299 	a->xdi_adapter.isr_soft_isr.object = NULL;
300 
301 	diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
302 	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
303 
304 	/*
305 	  Free memory accupied by XDI adapter
306 	*/
307 	if (a->xdi_adapter.e_tbl) {
308 		diva_os_free(0, a->xdi_adapter.e_tbl);
309 		a->xdi_adapter.e_tbl = NULL;
310 	}
311 	a->xdi_adapter.Channels = 0;
312 	a->xdi_adapter.e_max = 0;
313 
314 
315 	/*
316 	  Free adapter DMA map
317 	*/
318 	diva_free_dma_map(a->resources.pci.hdev,
319 			  (struct _diva_dma_map_entry *) a->xdi_adapter.
320 			  dma_map);
321 	a->xdi_adapter.dma_map = NULL;
322 
323 
324 	/*
325 	  Detach this adapter from debug driver
326 	*/
327 
328 	return (0);
329 }
330 
331 /*
332 **  Activate On Board Boot Loader
333 */
diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)334 static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
335 {
336 	dword i;
337 	struct mp_load __iomem *boot;
338 
339 	if (!IoAdapter->Address || !IoAdapter->reset) {
340 		return (-1);
341 	}
342 	if (IoAdapter->Initialized) {
343 		DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
344 			 IoAdapter->ANum))
345 			return (-1);
346 	}
347 
348 	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
349 	WRITE_DWORD(&boot->err, 0);
350 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
351 
352 	IoAdapter->rstFnc(IoAdapter);
353 
354 	diva_os_wait(10);
355 
356 	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
357 	i = READ_DWORD(&boot->live);
358 
359 	diva_os_wait(10);
360 	if (i == READ_DWORD(&boot->live)) {
361 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
362 		DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
363 			 IoAdapter->ANum, IoAdapter->serialNo))
364 			return (-1);
365 	}
366 	if (READ_DWORD(&boot->err)) {
367 		DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
368 			 IoAdapter->ANum, IoAdapter->serialNo,
369 			 READ_DWORD(&boot->err)))
370 			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
371 		return (-1);
372 	}
373 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
374 
375 	/*
376 	  Forget all outstanding entities
377 	*/
378 	IoAdapter->e_count = 0;
379 	if (IoAdapter->e_tbl) {
380 		memset(IoAdapter->e_tbl, 0x00,
381 		       IoAdapter->e_max * sizeof(E_INFO));
382 	}
383 	IoAdapter->head = 0;
384 	IoAdapter->tail = 0;
385 	IoAdapter->assign = 0;
386 	IoAdapter->trapped = 0;
387 
388 	memset(&IoAdapter->a.IdTable[0], 0x00,
389 	       sizeof(IoAdapter->a.IdTable));
390 	memset(&IoAdapter->a.IdTypeTable[0], 0x00,
391 	       sizeof(IoAdapter->a.IdTypeTable));
392 	memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
393 	       sizeof(IoAdapter->a.FlowControlIdTable));
394 	memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
395 	       sizeof(IoAdapter->a.FlowControlSkipTable));
396 	memset(&IoAdapter->a.misc_flags_table[0], 0x00,
397 	       sizeof(IoAdapter->a.misc_flags_table));
398 	memset(&IoAdapter->a.rx_stream[0], 0x00,
399 	       sizeof(IoAdapter->a.rx_stream));
400 	memset(&IoAdapter->a.tx_stream[0], 0x00,
401 	       sizeof(IoAdapter->a.tx_stream));
402 	memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
403 	memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
404 
405 	return (0);
406 }
407 
408 static int
diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,dword address,const byte * data,dword length,dword limit)409 diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
410 			   dword address,
411 			   const byte *data, dword length, dword limit)
412 {
413 	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
414 	byte __iomem *mem = p;
415 
416 	if (((address + length) >= limit) || !mem) {
417 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
418 		DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
419 			 IoAdapter->ANum, address + length))
420 			return (-1);
421 	}
422 	mem += address;
423 
424 	/* memcpy_toio(), maybe? */
425 	while (length--) {
426 		WRITE_BYTE(mem++, *data++);
427 	}
428 
429 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
430 	return (0);
431 }
432 
433 static int
diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,dword start_address,dword features)434 diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
435 		       dword start_address, dword features)
436 {
437 	dword i;
438 	int started = 0;
439 	byte __iomem *p;
440 	struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
441 	ADAPTER *a = &IoAdapter->a;
442 
443 	if (IoAdapter->Initialized) {
444 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
445 		DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
446 			 IoAdapter->ANum))
447 			return (-1);
448 	}
449 	if (!boot) {
450 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
451 		DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
452 			 IoAdapter->serialNo))
453 			return (-1);
454 	}
455 
456 	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
457 	DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
458 		 start_address))
459 
460 		WRITE_DWORD(&boot->addr, start_address);
461 	WRITE_DWORD(&boot->cmd, 3);
462 
463 	for (i = 0; i < 300; ++i) {
464 		diva_os_wait(10);
465 		if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
466 			DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
467 				 IoAdapter->ANum, (i / 100), (i % 100)))
468 				started = 1;
469 			break;
470 		}
471 	}
472 
473 	if (!started) {
474 		byte __iomem *p = (byte __iomem *)boot;
475 		dword TrapId;
476 		dword debug;
477 		TrapId = READ_DWORD(&p[0x80]);
478 		debug = READ_DWORD(&p[0x1c]);
479 		DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
480 			 IoAdapter->ANum, READ_DWORD(&boot->signature),
481 			 TrapId, debug))
482 			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
483 		if (IoAdapter->trapFnc) {
484 			(*(IoAdapter->trapFnc)) (IoAdapter);
485 		}
486 		IoAdapter->stop(IoAdapter);
487 		return (-1);
488 	}
489 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
490 
491 	IoAdapter->Initialized = true;
492 
493 	/*
494 	  Check Interrupt
495 	*/
496 	IoAdapter->IrqCount = 0;
497 	p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
498 	WRITE_DWORD(p, (dword)~0x03E00000);
499 	DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
500 	a->ReadyInt = 1;
501 	a->ram_out(a, &PR_RAM->ReadyInt, 1);
502 
503 	for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
504 
505 	if (!IoAdapter->IrqCount) {
506 		DBG_ERR(("A: A(%d) interrupt test failed",
507 			 IoAdapter->ANum))
508 			IoAdapter->Initialized = false;
509 		IoAdapter->stop(IoAdapter);
510 		return (-1);
511 	}
512 
513 	IoAdapter->Properties.Features = (word) features;
514 
515 	diva_xdi_display_adapter_features(IoAdapter->ANum);
516 
517 	DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
518 		/*
519 		  Register with DIDD
520 		*/
521 		diva_xdi_didd_register_adapter(IoAdapter->ANum);
522 
523 	return (0);
524 }
525 
diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)526 static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
527 {
528 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
529 
530 	/*
531 	  clear any pending interrupt
532 	*/
533 	IoAdapter->disIrq(IoAdapter);
534 
535 	IoAdapter->tst_irq(&IoAdapter->a);
536 	IoAdapter->clr_irq(&IoAdapter->a);
537 	IoAdapter->tst_irq(&IoAdapter->a);
538 
539 	/*
540 	  kill pending dpcs
541 	*/
542 	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
543 	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
544 }
545 
546 /*
547 **  Stop Adapter, but do not unmap/unregister - adapter
548 **  will be restarted later
549 */
diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)550 static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
551 {
552 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
553 	int i = 100;
554 
555 	if (!IoAdapter->ram) {
556 		return (-1);
557 	}
558 	if (!IoAdapter->Initialized) {
559 		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
560 			 IoAdapter->ANum))
561 			return (-1);	/* nothing to stop */
562 	}
563 	IoAdapter->Initialized = 0;
564 
565 	/*
566 	  Disconnect Adapter from DIDD
567 	*/
568 	diva_xdi_didd_remove_adapter(IoAdapter->ANum);
569 
570 	/*
571 	  Stop interrupts
572 	*/
573 	a->clear_interrupts_proc = diva_pri_clear_interrupts;
574 	IoAdapter->a.ReadyInt = 1;
575 	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
576 	do {
577 		diva_os_sleep(10);
578 	} while (i-- && a->clear_interrupts_proc);
579 
580 	if (a->clear_interrupts_proc) {
581 		diva_pri_clear_interrupts(a);
582 		a->clear_interrupts_proc = NULL;
583 		DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
584 			 IoAdapter->ANum))
585 			}
586 	IoAdapter->a.ReadyInt = 0;
587 
588 	/*
589 	  Stop and reset adapter
590 	*/
591 	IoAdapter->stop(IoAdapter);
592 
593 	return (0);
594 }
595 
596 /*
597 **  Process commands form configuration/download framework and from
598 **  user mode
599 **
600 **  return 0 on success
601 */
602 static int
diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter * a,diva_xdi_um_cfg_cmd_t * cmd,int length)603 diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
604 		       diva_xdi_um_cfg_cmd_t *cmd, int length)
605 {
606 	int ret = -1;
607 
608 	if (cmd->adapter != a->controller) {
609 		DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
610 			 cmd->adapter, a->controller))
611 			return (-1);
612 	}
613 
614 	switch (cmd->command) {
615 	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
616 		a->xdi_mbox.data_length = sizeof(dword);
617 		a->xdi_mbox.data =
618 			diva_os_malloc(0, a->xdi_mbox.data_length);
619 		if (a->xdi_mbox.data) {
620 			*(dword *) a->xdi_mbox.data =
621 				(dword) a->CardOrdinal;
622 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
623 			ret = 0;
624 		}
625 		break;
626 
627 	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
628 		a->xdi_mbox.data_length = sizeof(dword);
629 		a->xdi_mbox.data =
630 			diva_os_malloc(0, a->xdi_mbox.data_length);
631 		if (a->xdi_mbox.data) {
632 			*(dword *) a->xdi_mbox.data =
633 				(dword) a->xdi_adapter.serialNo;
634 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
635 			ret = 0;
636 		}
637 		break;
638 
639 	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
640 		a->xdi_mbox.data_length = sizeof(dword) * 9;
641 		a->xdi_mbox.data =
642 			diva_os_malloc(0, a->xdi_mbox.data_length);
643 		if (a->xdi_mbox.data) {
644 			int i;
645 			dword *data = (dword *) a->xdi_mbox.data;
646 
647 			for (i = 0; i < 8; i++) {
648 				*data++ = a->resources.pci.bar[i];
649 			}
650 			*data++ = (dword) a->resources.pci.irq;
651 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
652 			ret = 0;
653 		}
654 		break;
655 
656 	case DIVA_XDI_UM_CMD_RESET_ADAPTER:
657 		ret = diva_pri_reset_adapter(&a->xdi_adapter);
658 		break;
659 
660 	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
661 		ret = diva_pri_write_sdram_block(&a->xdi_adapter,
662 						 cmd->command_data.
663 						 write_sdram.offset,
664 						 (byte *)&cmd[1],
665 						 cmd->command_data.
666 						 write_sdram.length,
667 						 pri_is_rev_2_card(a->
668 								   CardOrdinal)
669 						 ? MP2_MEMORY_SIZE :
670 						 MP_MEMORY_SIZE);
671 		break;
672 
673 	case DIVA_XDI_UM_CMD_STOP_ADAPTER:
674 		ret = diva_pri_stop_adapter(a);
675 		break;
676 
677 	case DIVA_XDI_UM_CMD_START_ADAPTER:
678 		ret = diva_pri_start_adapter(&a->xdi_adapter,
679 					     cmd->command_data.start.
680 					     offset,
681 					     cmd->command_data.start.
682 					     features);
683 		break;
684 
685 	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
686 		a->xdi_adapter.features =
687 			cmd->command_data.features.features;
688 		a->xdi_adapter.a.protocol_capabilities =
689 			a->xdi_adapter.features;
690 		DBG_TRC(("Set raw protocol features (%08x)",
691 			 a->xdi_adapter.features))
692 			ret = 0;
693 		break;
694 
695 	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
696 		a->xdi_mbox.data_length = sizeof(dword);
697 		a->xdi_mbox.data =
698 			diva_os_malloc(0, a->xdi_mbox.data_length);
699 		if (a->xdi_mbox.data) {
700 			dword *data = (dword *) a->xdi_mbox.data;
701 			if (!a->xdi_adapter.ram ||
702 			    !a->xdi_adapter.reset ||
703 			    !a->xdi_adapter.cfg) {
704 				*data = 3;
705 			} else if (a->xdi_adapter.trapped) {
706 				*data = 2;
707 			} else if (a->xdi_adapter.Initialized) {
708 				*data = 1;
709 			} else {
710 				*data = 0;
711 			}
712 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
713 			ret = 0;
714 		}
715 		break;
716 
717 	case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
718 		ret = diva_card_read_xlog(a);
719 		break;
720 
721 	case DIVA_XDI_UM_CMD_READ_SDRAM:
722 		if (a->xdi_adapter.Address) {
723 			if (
724 				(a->xdi_mbox.data_length =
725 				 cmd->command_data.read_sdram.length)) {
726 				if (
727 					(a->xdi_mbox.data_length +
728 					 cmd->command_data.read_sdram.offset) <
729 					a->xdi_adapter.MemorySize) {
730 					a->xdi_mbox.data =
731 						diva_os_malloc(0,
732 							       a->xdi_mbox.
733 							       data_length);
734 					if (a->xdi_mbox.data) {
735 						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
736 						byte __iomem *src = p;
737 						byte *dst = a->xdi_mbox.data;
738 						dword len = a->xdi_mbox.data_length;
739 
740 						src += cmd->command_data.read_sdram.offset;
741 
742 						while (len--) {
743 							*dst++ = READ_BYTE(src++);
744 						}
745 						a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
746 						DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
747 						ret = 0;
748 					}
749 				}
750 			}
751 		}
752 		break;
753 
754 	default:
755 		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
756 			 cmd->command))
757 			}
758 
759 	return (ret);
760 }
761 
762 /*
763 **  Get Serial Number
764 */
pri_get_serial_number(diva_os_xdi_adapter_t * a)765 static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
766 {
767 	byte data[64];
768 	int i;
769 	dword len = sizeof(data);
770 	volatile byte __iomem *config;
771 	volatile byte __iomem *flash;
772 	byte c;
773 
774 /*
775  *  First set some GT6401x config registers before accessing the BOOT-ROM
776  */
777 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
778 	c = READ_BYTE(&config[0xc3c]);
779 	if (!(c & 0x08)) {
780 		WRITE_BYTE(&config[0xc3c], c);	/* Base Address enable register */
781 	}
782 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
783 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
784 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
785 /*
786  *  Read only the last 64 bytes of manufacturing data
787  */
788 	memset(data, '\0', len);
789 	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
790 	for (i = 0; i < len; i++) {
791 		data[i] = READ_BYTE(&flash[0x8000 - len + i]);
792 	}
793 	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
794 
795 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
796 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);	/* Disable FLASH EPROM access */
797 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
798 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
799 
800 	if (memcmp(&data[48], "DIVAserverPR", 12)) {
801 #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)	/* { */
802 		word cmd = 0, cmd_org;
803 		void *addr;
804 		dword addr1, addr3, addr4;
805 		byte Bus, Slot;
806 		void *hdev;
807 		addr4 = a->resources.pci.bar[4];
808 		addr3 = a->resources.pci.bar[3];	/* flash  */
809 		addr1 = a->resources.pci.bar[1];	/* unused */
810 
811 		DBG_ERR(("A: apply Compaq BIOS workaround"))
812 			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
813 				 data[0], data[1], data[2], data[3],
814 				 data[4], data[5], data[6], data[7]))
815 
816 			Bus = a->resources.pci.bus;
817 		Slot = a->resources.pci.func;
818 		hdev = a->resources.pci.hdev;
819 		PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
820 		PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
821 
822 		PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
823 		PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
824 
825 		PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
826 
827 		addr = a->resources.pci.addr[1];
828 		a->resources.pci.addr[1] = a->resources.pci.addr[4];
829 		a->resources.pci.addr[4] = addr;
830 
831 		addr1 = a->resources.pci.bar[1];
832 		a->resources.pci.bar[1] = a->resources.pci.bar[4];
833 		a->resources.pci.bar[4] = addr1;
834 
835 		/*
836 		  Try to read Flash again
837 		*/
838 		len = sizeof(data);
839 
840 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
841 		if (!(config[0xc3c] & 0x08)) {
842 			config[0xc3c] |= 0x08;	/* Base Address enable register */
843 		}
844 		config[LOW_BOOTCS_DREG] = 0x00;
845 		config[HI_BOOTCS_DREG] = 0xFF;
846 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
847 
848 		memset(data, '\0', len);
849 		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
850 		for (i = 0; i < len; i++) {
851 			data[i] = flash[0x8000 - len + i];
852 		}
853 		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
854 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
855 		config[LOW_BOOTCS_DREG] = 0xFC;
856 		config[HI_BOOTCS_DREG] = 0xFF;
857 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
858 
859 		if (memcmp(&data[48], "DIVAserverPR", 12)) {
860 			DBG_ERR(("A: failed to read serial number"))
861 				DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
862 					 data[0], data[1], data[2], data[3],
863 					 data[4], data[5], data[6], data[7]))
864 				return (-1);
865 		}
866 #else				/* } { */
867 		DBG_ERR(("A: failed to read DIVA signature word"))
868 			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
869 				 data[0], data[1], data[2], data[3],
870 				 data[4], data[5], data[6], data[7]))
871 			DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
872 				 data[45], data[44]))
873 #endif				/* } */
874 			}
875 
876 	a->xdi_adapter.serialNo =
877 		(data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
878 		data[44];
879 	if (!a->xdi_adapter.serialNo
880 	    || (a->xdi_adapter.serialNo == 0xffffffff)) {
881 		a->xdi_adapter.serialNo = 0;
882 		DBG_ERR(("A: failed to read serial number"))
883 			return (-1);
884 	}
885 
886 	DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
887 		DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
888 			 (int) data[40]))
889 		DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
890 			 (int) data[32]))
891 		DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
892 			 (int) data[36]))
893 
894 		DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
895 			 (int) ((data[28] > 90) ? 1900 : 2000) +
896 			 (int) data[28], (int) data[29], (int) data[30]))
897 
898 		return (0);
899 }
900 
diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)901 void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
902 {
903 }
904 
diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)905 void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
906 {
907 }
908 
909 /*
910 **  Checks presence of DSP on board
911 */
912 static int
dsp_check_presence(volatile byte __iomem * addr,volatile byte __iomem * data,int dsp)913 dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
914 {
915 	word pattern;
916 
917 	WRITE_WORD(addr, 0x4000);
918 	WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
919 
920 	WRITE_WORD(addr, 0x4000);
921 	pattern = READ_WORD(data);
922 
923 	if (pattern != DSP_SIGNATURE_PROBE_WORD) {
924 		DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
925 			 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
926 			return (-1);
927 	}
928 
929 	WRITE_WORD(addr, 0x4000);
930 	WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
931 
932 	WRITE_WORD(addr, 0x4000);
933 	pattern = READ_WORD(data);
934 
935 	if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
936 		DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
937 			 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
938 			return (-2);
939 	}
940 
941 	DBG_TRC(("DSP[%d] present", dsp))
942 
943 		return (0);
944 }
945 
946 
947 /*
948 **  Check if DSP's are present and operating
949 **  Information about detected DSP's is returned as bit mask
950 **  Bit 0  - DSP1
951 **  ...
952 **  ...
953 **  ...
954 **  Bit 29 - DSP30
955 */
diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)956 static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
957 {
958 	byte __iomem *base;
959 	byte __iomem *p;
960 	dword ret = 0;
961 	dword row_offset[7] = {
962 		0x00000000,
963 		0x00000800,	/* 1 - ROW 1 */
964 		0x00000840,	/* 2 - ROW 2 */
965 		0x00001000,	/* 3 - ROW 3 */
966 		0x00001040,	/* 4 - ROW 4 */
967 		0x00000000	/* 5 - ROW 0 */
968 	};
969 
970 	byte __iomem *dsp_addr_port;
971 	byte __iomem *dsp_data_port;
972 	byte row_state;
973 	int dsp_row = 0, dsp_index, dsp_num;
974 
975 	if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
976 		return (0);
977 	}
978 
979 	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
980 	WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
981 	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
982 	diva_os_wait(5);
983 
984 	base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
985 
986 	for (dsp_num = 0; dsp_num < 30; dsp_num++) {
987 		dsp_row = dsp_num / 7 + 1;
988 		dsp_index = dsp_num % 7;
989 
990 		dsp_data_port = base;
991 		dsp_addr_port = base;
992 
993 		dsp_data_port += row_offset[dsp_row];
994 		dsp_addr_port += row_offset[dsp_row];
995 
996 		dsp_data_port += (dsp_index * 8);
997 		dsp_addr_port += (dsp_index * 8) + 0x80;
998 
999 		if (!dsp_check_presence
1000 		    (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
1001 			ret |= (1 << dsp_num);
1002 		}
1003 	}
1004 	DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
1005 
1006 	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
1007 	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
1008 	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
1009 	diva_os_wait(5);
1010 
1011 	/*
1012 	  Verify modules
1013 	*/
1014 	for (dsp_row = 0; dsp_row < 4; dsp_row++) {
1015 		row_state = ((ret >> (dsp_row * 7)) & 0x7F);
1016 		if (row_state && (row_state != 0x7F)) {
1017 			for (dsp_index = 0; dsp_index < 7; dsp_index++) {
1018 				if (!(row_state & (1 << dsp_index))) {
1019 					DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
1020 						 dsp_row + 1,
1021 						 dsp_index + 1))
1022 						}
1023 			}
1024 		}
1025 	}
1026 
1027 	if (!(ret & 0x10000000)) {
1028 		DBG_ERR(("A: ON BOARD-DSP[1] failed"))
1029 			}
1030 	if (!(ret & 0x20000000)) {
1031 		DBG_ERR(("A: ON BOARD-DSP[2] failed"))
1032 			}
1033 
1034 	/*
1035 	  Print module population now
1036 	*/
1037 	DBG_LOG(("+-----------------------+"))
1038 		DBG_LOG(("| DSP MODULE POPULATION |"))
1039 		DBG_LOG(("+-----------------------+"))
1040 		DBG_LOG(("|  1  |  2  |  3  |  4  |"))
1041 		DBG_LOG(("+-----------------------+"))
1042 		DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
1043 			 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
1044 			 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
1045 			 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
1046 			 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
1047 		DBG_LOG(("+-----------------------+"))
1048 
1049 		DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
1050 			 ~ret & 0x3fffffff))
1051 
1052 		return (ret);
1053 }
1054