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