1 // SPDX-License-Identifier: GPL-2.0
2 /* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 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_4bri.h"
17 #include "diva_pci.h"
18 #include "mi_pc.h"
19 #include "dsrv4bri.h"
20 #include "helpers.h"
21 
22 static void *diva_xdiLoadFileFile = NULL;
23 static dword diva_xdiLoadFileLength = 0;
24 
25 /*
26 **  IMPORTS
27 */
28 extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter);
29 extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter);
30 extern void diva_xdi_display_adapter_features(int card);
31 extern void diva_add_slave_adapter(diva_os_xdi_adapter_t *a);
32 
33 extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
34 extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
35 
36 extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
37 
38 /*
39 **  LOCALS
40 */
41 static unsigned long _4bri_bar_length[4] = {
42 	0x100,
43 	0x100,			/* I/O */
44 	MQ_MEMORY_SIZE,
45 	0x2000
46 };
47 static unsigned long _4bri_v2_bar_length[4] = {
48 	0x100,
49 	0x100,			/* I/O */
50 	MQ2_MEMORY_SIZE,
51 	0x10000
52 };
53 static unsigned long _4bri_v2_bri_bar_length[4] = {
54 	0x100,
55 	0x100,			/* I/O */
56 	BRI2_MEMORY_SIZE,
57 	0x10000
58 };
59 
60 
61 static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
62 static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a);
63 static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
64 				   diva_xdi_um_cfg_cmd_t *cmd,
65 				   int length);
66 static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a);
67 static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a,
68 				      byte *data, dword length);
69 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter);
70 static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
71 				       dword address,
72 				       const byte *data,
73 				       dword length, dword limit);
74 static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
75 				   dword start_address, dword features);
76 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter);
77 static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a);
78 
_4bri_is_rev_2_card(int card_ordinal)79 static int _4bri_is_rev_2_card(int card_ordinal)
80 {
81 	switch (card_ordinal) {
82 	case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
83 	case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
84 	case CARDTYPE_DIVASRV_B_2M_V2_PCI:
85 	case CARDTYPE_DIVASRV_B_2F_PCI:
86 	case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
87 		return (1);
88 	}
89 	return (0);
90 }
91 
_4bri_is_rev_2_bri_card(int card_ordinal)92 static int _4bri_is_rev_2_bri_card(int card_ordinal)
93 {
94 	switch (card_ordinal) {
95 	case CARDTYPE_DIVASRV_B_2M_V2_PCI:
96 	case CARDTYPE_DIVASRV_B_2F_PCI:
97 	case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
98 		return (1);
99 	}
100 	return (0);
101 }
102 
diva_4bri_set_addresses(diva_os_xdi_adapter_t * a)103 static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
104 {
105 	dword offset = a->resources.pci.qoffset;
106 	dword c_offset = offset * a->xdi_adapter.ControllerNumber;
107 
108 	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
109 	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
110 	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
111 	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
112 	a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
113 	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
114 
115 	/*
116 	  Set up hardware related pointers
117 	*/
118 	a->xdi_adapter.Address = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
119 	a->xdi_adapter.Address += c_offset;
120 
121 	a->xdi_adapter.Control = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
122 
123 	a->xdi_adapter.ram = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
124 	a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
125 
126 	a->xdi_adapter.reset = a->resources.pci.addr[0];	/* BAR0 CONFIG */
127 	/*
128 	  ctlReg contains the register address for the MIPS CPU reset control
129 	*/
130 	a->xdi_adapter.ctlReg = a->resources.pci.addr[3];	/* BAR3 CNTRL  */
131 	/*
132 	  prom contains the register address for FPGA and EEPROM programming
133 	*/
134 	a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
135 }
136 
137 /*
138 **  BAR0 - MEM - 0x100    - CONFIG MEM
139 **  BAR1 - I/O - 0x100    - UNUSED
140 **  BAR2 - MEM - MQ_MEMORY_SIZE (MQ2_MEMORY_SIZE on Rev.2) - SDRAM
141 **  BAR3 - MEM - 0x2000 (0x10000 on Rev.2)   - CNTRL
142 **
143 **  Called by master adapter, that will initialize and add slave adapters
144 */
diva_4bri_init_card(diva_os_xdi_adapter_t * a)145 int diva_4bri_init_card(diva_os_xdi_adapter_t *a)
146 {
147 	int bar, i;
148 	byte __iomem *p;
149 	PADAPTER_LIST_ENTRY quadro_list;
150 	diva_os_xdi_adapter_t *diva_current;
151 	diva_os_xdi_adapter_t *adapter_list[4];
152 	PISDN_ADAPTER Slave;
153 	unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
154 	int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
155 	int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
156 	int factor = (tasks == 1) ? 1 : 2;
157 
158 	if (v2) {
159 		if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
160 			memcpy(bar_length, _4bri_v2_bri_bar_length,
161 			       sizeof(bar_length));
162 		} else {
163 			memcpy(bar_length, _4bri_v2_bar_length,
164 			       sizeof(bar_length));
165 		}
166 	} else {
167 		memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
168 	}
169 	DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
170 		 bar_length[2], tasks, factor))
171 
172 		/*
173 		  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 */
diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)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 
_4bri_get_serial_number(diva_os_xdi_adapter_t * a)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 */
diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)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
diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter * a,diva_xdi_um_cfg_cmd_t * cmd,int length)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 
xdiLoadFile(char * FileName,dword * FileLength,unsigned long lim)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 
diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)833 void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
834 {
835 }
836 
diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)837 void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
838 {
839 }
840 
841 static int
diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a,byte * data,dword length)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 
diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)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
diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,dword address,const byte * data,dword length,dword limit)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
diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,dword start_address,dword features)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 successfully started",
1001 			 IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
1002 			 (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
1003 			diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1004 		IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
1005 	}
1006 
1007 	return (0);
1008 }
1009 
check_qBri_interrupt(PISDN_ADAPTER IoAdapter)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 
diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)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 
diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)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 }
1133