xref: /illumos-gate/usr/src/uts/common/io/ntxn/unm_nic_init.c (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 NetXen, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 2018, Joyent, Inc.
29  */
30 
31 #include <sys/types.h>
32 #include <sys/conf.h>
33 #include <sys/debug.h>
34 #include <sys/stropts.h>
35 #include <sys/stream.h>
36 #include <sys/strlog.h>
37 #include <sys/kmem.h>
38 #include <sys/stat.h>
39 #include <sys/kstat.h>
40 #include <sys/vtrace.h>
41 #include <sys/dlpi.h>
42 #include <sys/strsun.h>
43 #include <sys/ethernet.h>
44 #include <sys/modctl.h>
45 #include <sys/errno.h>
46 #include <sys/dditypes.h>
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
49 #include <sys/sysmacros.h>
50 #include <sys/pci.h>
51 
52 #include "unm_nic.h"
53 #include "unm_nic_hw.h"
54 #include "nic_cmn.h"
55 #include "unm_nic_ioctl.h"
56 #include "nic_phan_reg.h"
57 
58 struct crb_addr_pair {
59 	long	addr, data;
60 };
61 
62 #define	MAX_CRB_XFORM	60
63 #define	ADDR_ERROR	((unsigned long)0xffffffff)
64 
65 #define	crb_addr_transform(name)				\
66 		crb_addr_xform[UNM_HW_PX_MAP_CRB_##name] =		\
67 		UNM_HW_CRB_HUB_AGT_ADR_##name << 20
68 
69 static unsigned int crb_addr_xform[MAX_CRB_XFORM];
70 
71 static void
72 crb_addr_transform_setup(void)
73 {
74 	crb_addr_transform(XDMA);
75 	crb_addr_transform(TIMR);
76 	crb_addr_transform(SRE);
77 	crb_addr_transform(SQN3);
78 	crb_addr_transform(SQN2);
79 	crb_addr_transform(SQN1);
80 	crb_addr_transform(SQN0);
81 	crb_addr_transform(SQS3);
82 	crb_addr_transform(SQS2);
83 	crb_addr_transform(SQS1);
84 	crb_addr_transform(SQS0);
85 	crb_addr_transform(RPMX7);
86 	crb_addr_transform(RPMX6);
87 	crb_addr_transform(RPMX5);
88 	crb_addr_transform(RPMX4);
89 	crb_addr_transform(RPMX3);
90 	crb_addr_transform(RPMX2);
91 	crb_addr_transform(RPMX1);
92 	crb_addr_transform(RPMX0);
93 	crb_addr_transform(ROMUSB);
94 	crb_addr_transform(SN);
95 	crb_addr_transform(QMN);
96 	crb_addr_transform(QMS);
97 	crb_addr_transform(PGNI);
98 	crb_addr_transform(PGND);
99 	crb_addr_transform(PGN3);
100 	crb_addr_transform(PGN2);
101 	crb_addr_transform(PGN1);
102 	crb_addr_transform(PGN0);
103 	crb_addr_transform(PGSI);
104 	crb_addr_transform(PGSD);
105 	crb_addr_transform(PGS3);
106 	crb_addr_transform(PGS2);
107 	crb_addr_transform(PGS1);
108 	crb_addr_transform(PGS0);
109 	crb_addr_transform(PS);
110 	crb_addr_transform(PH);
111 	crb_addr_transform(NIU);
112 	crb_addr_transform(I2Q);
113 	crb_addr_transform(EG);
114 	crb_addr_transform(MN);
115 	crb_addr_transform(MS);
116 	crb_addr_transform(CAS2);
117 	crb_addr_transform(CAS1);
118 	crb_addr_transform(CAS0);
119 	crb_addr_transform(CAM);
120 	crb_addr_transform(C2C1);
121 	crb_addr_transform(C2C0);
122 	crb_addr_transform(SMB);
123 	crb_addr_transform(OCM0);
124 
125 	/*
126 	 * Used only in P3 just define it for P2 also.
127 	 */
128 	crb_addr_transform(I2C0);
129 }
130 
131 /*
132  * decode_crb_addr(0 - utility to translate from internal Phantom CRB address
133  * to external PCI CRB address.
134  */
135 static unsigned long
136 decode_crb_addr(unsigned long addr)
137 {
138 	int i;
139 	unsigned long base_addr, offset, pci_base;
140 
141 	crb_addr_transform_setup();
142 
143 	pci_base = ADDR_ERROR;
144 	base_addr = addr & 0xfff00000;
145 	offset = addr & 0x000fffff;
146 
147 	for (i = 0; i < MAX_CRB_XFORM; i++) {
148 		if (crb_addr_xform[i] == base_addr) {
149 			pci_base = i << 20;
150 			break;
151 		}
152 	}
153 
154 	if (pci_base == ADDR_ERROR) {
155 		return (pci_base);
156 	} else {
157 		return (pci_base + offset);
158 	}
159 }
160 
161 static long rom_max_timeout = 100;
162 static long rom_lock_timeout = 10000;
163 
164 static int
165 rom_lock(unm_adapter *adapter)
166 {
167 	uint32_t done = 0;
168 	long timeout = 0;
169 
170 	while (!done) {
171 		/* acquire semaphore2 from PCI HW block */
172 		unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
173 		if (done == 1)
174 			break;
175 		if (timeout >= rom_lock_timeout) {
176 			cmn_err(CE_WARN, "%s%d rom_lock timed out %d %ld\n",
177 			    adapter->name, adapter->instance, done, timeout);
178 			return (-1);
179 		}
180 		timeout++;
181 	}
182 	unm_nic_reg_write(adapter, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
183 	return (0);
184 }
185 
186 static void
187 rom_unlock(unm_adapter *adapter)
188 {
189 	uint32_t val;
190 
191 	/* release semaphore2 */
192 	unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
193 }
194 
195 static int
196 wait_rom_done(unm_adapter *adapter)
197 {
198 	long timeout = 0;
199 	long done = 0;
200 
201 	while (done == 0) {
202 		unm_nic_reg_read(adapter, UNM_ROMUSB_GLB_STATUS, &done);
203 		done &= 2;
204 		timeout++;
205 		if (timeout >= rom_max_timeout) {
206 			cmn_err(CE_WARN,
207 			    "Timeout reached waiting for rom done");
208 			return (-1);
209 		}
210 	}
211 	return (0);
212 }
213 
214 static int
215 do_rom_fast_read(unm_adapter *adapter, int addr, int *valp)
216 {
217 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ADDRESS, addr);
218 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
219 	drv_usecwait(100);   /* prevent bursting on CRB */
220 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
221 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_INSTR_OPCODE, 0xb);
222 	if (wait_rom_done(adapter) != DDI_SUCCESS) {
223 		cmn_err(CE_WARN, "Error waiting for rom done\n");
224 		return (-1);
225 	}
226 
227 	// reset abyte_cnt and dummy_byte_cnt
228 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
229 	drv_usecwait(100);   /* prevent bursting on CRB */
230 	unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
231 
232 	unm_nic_reg_read(adapter, UNM_ROMUSB_ROM_RDATA, valp);
233 	return (0);
234 }
235 
236 int
237 rom_fast_read(struct unm_adapter_s *adapter, int addr, int *valp)
238 {
239 	int ret;
240 
241 	if (rom_lock(adapter) != 0) {
242 		cmn_err(CE_WARN, "%s(%d)rom_lock failed\n",
243 		    __FUNCTION__, __LINE__);
244 		return (-1);
245 	}
246 
247 	ret = do_rom_fast_read(adapter, addr, valp);
248 	if (ret != 0) {
249 		cmn_err(CE_WARN, "%s do_rom_fast_read returned: %d\n",
250 		    __FUNCTION__, __LINE__);
251 		return (-1);
252 	}
253 	rom_unlock(adapter);
254 	return (ret);
255 }
256 
257 int
258 pinit_from_rom(struct unm_adapter_s *adapter, int verbose)
259 {
260 	int	addr, val, status, i, init_delay = 0, n;
261 	struct crb_addr_pair	*buf;
262 	unsigned long	off;
263 	unsigned int	offset;
264 
265 	status = unm_nic_get_board_info(adapter);
266 	if (status)
267 		cmn_err(CE_WARN, "%s: pinit_from_rom: Error getting brdinfo\n",
268 		    unm_nic_driver_name);
269 
270 	UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET, 0xffffffff, adapter);
271 
272 	if (verbose) {
273 		int	val;
274 		if (rom_fast_read(adapter, 0x4008, &val) == 0)
275 			cmn_err(CE_WARN, "P2 ROM board type: 0x%08x\n", val);
276 		else
277 			cmn_err(CE_WARN, "Could not read board type\n");
278 		if (rom_fast_read(adapter, 0x400c, &val) == 0)
279 			cmn_err(CE_WARN, "ROM board  num: 0x%08x\n", val);
280 		else
281 			cmn_err(CE_WARN, "Could not read board number\n");
282 		if (rom_fast_read(adapter, 0x4010, &val) == 0)
283 			cmn_err(CE_WARN, "ROM chip   num: 0x%08x\n", val);
284 		else
285 			cmn_err(CE_WARN, "Could not read chip number\n");
286 	}
287 
288 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
289 		if (rom_fast_read(adapter, 0, &n) != 0 ||
290 		    (unsigned int)n != 0xcafecafe ||
291 		    rom_fast_read(adapter, 4, &n) != 0) {
292 			cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
293 			    "n: %08x\n", unm_nic_driver_name, n);
294 			return (-1);
295 		}
296 
297 		offset = n & 0xffffU;
298 		n = (n >> 16) & 0xffffU;
299 	} else {
300 		if (rom_fast_read(adapter, 0, &n) != 0 ||
301 		    !(n & 0x80000000)) {
302 			cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
303 			    "n: %08x\n", unm_nic_driver_name, n);
304 			return (-1);
305 		}
306 		offset = 1;
307 		n &= ~0x80000000;
308 	}
309 
310 	if (n  >= 1024) {
311 		cmn_err(CE_WARN, "%s: %s:n=0x%x Card flash not initialized\n",
312 		    unm_nic_driver_name, __FUNCTION__, n);
313 		return (-1);
314 	}
315 
316 	if (verbose)
317 		cmn_err(CE_WARN, "%s: %d CRB init values found in ROM.\n",
318 		    unm_nic_driver_name, n);
319 
320 	buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
321 	if (buf == NULL) {
322 		cmn_err(CE_WARN, "%s: pinit_from_rom: Unable to get memory\n",
323 		    unm_nic_driver_name);
324 		return (-1);
325 	}
326 
327 	for (i = 0; i < n; i++) {
328 		if (rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
329 		    rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
330 			kmem_free(buf, n * sizeof (struct crb_addr_pair));
331 			return (-1);
332 		}
333 
334 		buf[i].addr = addr;
335 		buf[i].data = val;
336 
337 		if (verbose)
338 			cmn_err(CE_WARN, "%s: PCI:     0x%08x == 0x%08x\n",
339 			    unm_nic_driver_name,
340 			    (unsigned int)decode_crb_addr(
341 			    (unsigned long)addr), val);
342 	}
343 
344 	for (i = 0; i < n; i++) {
345 		off = decode_crb_addr((unsigned long)buf[i].addr) +
346 		    UNM_PCI_CRBSPACE;
347 		/* skipping cold reboot MAGIC */
348 		if (off == UNM_CAM_RAM(0x1fc)) {
349 			continue;
350 		}
351 
352 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
353 			/* do not reset PCI */
354 			if (off == (ROMUSB_GLB + 0xbc)) {
355 				continue;
356 			}
357 			if (off == (ROMUSB_GLB + 0xc8))	/* core clock */
358 				continue;
359 			if (off == (ROMUSB_GLB + 0x24))	/* MN clock */
360 				continue;
361 			if (off == (ROMUSB_GLB + 0x1c))	/* MS clock */
362 				continue;
363 			if (off == (UNM_CRB_PEG_NET_1 + 0x18)) {
364 				buf[i].data = 0x1020;
365 			}
366 			/* skip the function enable register */
367 			if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
368 				continue;
369 			}
370 			if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
371 				continue;
372 			}
373 
374 			if ((off & 0x0ff00000) == UNM_CRB_SMB) {
375 				continue;
376 			}
377 
378 		}
379 
380 		if (off == ADDR_ERROR) {
381 			cmn_err(CE_WARN, "%s: Err: Unknown addr: 0x%08lx\n",
382 			    unm_nic_driver_name, buf[i].addr);
383 			continue;
384 		}
385 
386 		/* After writing this register, HW needs time for CRB */
387 		/* to quiet down (else crb_window returns 0xffffffff) */
388 		if (off == UNM_ROMUSB_GLB_SW_RESET) {
389 			init_delay = 1;
390 
391 			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
392 				/* hold xdma in reset also */
393 				buf[i].data = 0x8000ff;
394 			}
395 		}
396 
397 		adapter->unm_nic_hw_write_wx(adapter, off, &buf[i].data, 4);
398 
399 		if (init_delay == 1) {
400 			nx_msleep(1000);	/* Sleep 1000 msecs */
401 			init_delay = 0;
402 		}
403 
404 		nx_msleep(1);			/* Sleep 1 msec */
405 	}
406 
407 	kmem_free(buf, n * sizeof (struct crb_addr_pair));
408 
409 	// disable_peg_cache_all
410 	// unreset_net_cache
411 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
412 		val = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
413 		    adapter);
414 		UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
415 		    (val & 0xffffff0f), adapter);
416 	}
417 
418 	// p2dn replyCount
419 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0xec, 0x1e, adapter);
420 	// disable_peg_cache 0
421 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0x4c, 8, adapter);
422 	// disable_peg_cache 1
423 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_I+0x4c, 8, adapter);
424 
425 	// peg_clr_all
426 	// peg_clr 0
427 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0x8, 0, adapter);
428 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0xc, 0, adapter);
429 	// peg_clr 1
430 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0x8, 0, adapter);
431 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0xc, 0, adapter);
432 	// peg_clr 2
433 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0x8, 0, adapter);
434 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0xc, 0, adapter);
435 	// peg_clr 3
436 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0x8, 0, adapter);
437 	UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0xc, 0, adapter);
438 
439 	return (0);
440 }
441 
442 int
443 phantom_init(struct unm_adapter_s *adapter, int pegtune_val)
444 {
445 	u32	val = 0;
446 	int	retries = 120;
447 
448 	if (!pegtune_val) {
449 		do {
450 			val = adapter->unm_nic_pci_read_normalize(adapter,
451 			    CRB_CMDPEG_STATE);
452 
453 			if ((val == PHAN_INITIALIZE_COMPLETE) ||
454 			    (val == PHAN_INITIALIZE_ACK))
455 				return (DDI_SUCCESS);
456 
457 			/* 500 msec wait */
458 			drv_usecwait(500000);
459 		} while (--retries > 0);
460 
461 		if (!retries) {
462 			val = adapter->unm_nic_pci_read_normalize(adapter,
463 			    UNM_ROMUSB_GLB_PEGTUNE_DONE);
464 			cmn_err(CE_WARN, "WARNING: Initial boot wait loop"
465 			    "failed...state:%d\n", val);
466 			return (DDI_FAILURE);
467 		}
468 	}
469 
470 	return (DDI_SUCCESS);
471 }
472 
473 int
474 load_from_flash(struct unm_adapter_s *adapter)
475 {
476 	int  i;
477 	long data, size = 0;
478 	long flashaddr = BOOTLD_START, memaddr = BOOTLD_START;
479 
480 	size = (IMAGE_START - BOOTLD_START)/4;
481 
482 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
483 		data = 1;
484 		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
485 		    &data, 4);
486 	}
487 
488 	for (i = 0; i < size; i++) {
489 		if (rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
490 			cmn_err(CE_WARN, "Error in rom_fast_read: "
491 			    "Will skip loading flash image\n");
492 			return (DDI_FAILURE);
493 		}
494 
495 		adapter->unm_nic_pci_mem_write(adapter, memaddr, &data, 4);
496 		flashaddr += 4;
497 		memaddr += 4;
498 	}
499 
500 	drv_usecwait(100);
501 	UNM_READ_LOCK(&adapter->adapter_lock);
502 
503 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
504 		data = 0x80001d;
505 		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
506 		    &data, 4);
507 	} else {
508 		data = 0x3fff;
509 		adapter->unm_nic_hw_write_wx(adapter,
510 		    UNM_ROMUSB_GLB_CHIP_CLK_CTRL, &data, 4);
511 		data = 0;
512 		adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
513 		    &data, 4);
514 	}
515 
516 	UNM_READ_UNLOCK(&adapter->adapter_lock);
517 	return (DDI_SUCCESS);
518 }
519