xref: /illumos-gate/usr/src/uts/common/io/ntxn/unm_gem.c (revision 15c07adc)
19a5557fdSlucy wang - Sun Microsystems - Beijing China /*
29a5557fdSlucy wang - Sun Microsystems - Beijing China  * CDDL HEADER START
39a5557fdSlucy wang - Sun Microsystems - Beijing China  *
49a5557fdSlucy wang - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
59a5557fdSlucy wang - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
69a5557fdSlucy wang - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
79a5557fdSlucy wang - Sun Microsystems - Beijing China  *
89a5557fdSlucy wang - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99a5557fdSlucy wang - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
109a5557fdSlucy wang - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
119a5557fdSlucy wang - Sun Microsystems - Beijing China  * and limitations under the License.
129a5557fdSlucy wang - Sun Microsystems - Beijing China  *
139a5557fdSlucy wang - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
149a5557fdSlucy wang - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159a5557fdSlucy wang - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
169a5557fdSlucy wang - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
179a5557fdSlucy wang - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
189a5557fdSlucy wang - Sun Microsystems - Beijing China  *
199a5557fdSlucy wang - Sun Microsystems - Beijing China  * CDDL HEADER END
209a5557fdSlucy wang - Sun Microsystems - Beijing China  */
219a5557fdSlucy wang - Sun Microsystems - Beijing China /*
229a5557fdSlucy wang - Sun Microsystems - Beijing China  * Copyright 2008 NetXen, Inc.  All rights reserved.
239a5557fdSlucy wang - Sun Microsystems - Beijing China  * Use is subject to license terms.
249a5557fdSlucy wang - Sun Microsystems - Beijing China  */
259a5557fdSlucy wang - Sun Microsystems - Beijing China /*
2693833965Sjing xiong ERI-SUN  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
279a5557fdSlucy wang - Sun Microsystems - Beijing China  * Use is subject to license terms.
289a5557fdSlucy wang - Sun Microsystems - Beijing China  */
29*15c07adcSJohn Levon 
30*15c07adcSJohn Levon /*
31*15c07adcSJohn Levon  * Copyright (c) 2018, Joyent, Inc.
32*15c07adcSJohn Levon  */
33*15c07adcSJohn Levon 
349a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/types.h>
359a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/conf.h>
369a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/debug.h>
379a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stropts.h>
389a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stream.h>
399a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/strlog.h>
409a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/kmem.h>
419a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stat.h>
429a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/kstat.h>
439a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/vtrace.h>
449a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/dlpi.h>
459a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/strsun.h>
469a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ethernet.h>
479a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/modctl.h>
489a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/errno.h>
499a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/dditypes.h>
509a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ddi.h>
519a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/sunddi.h>
529a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/sysmacros.h>
539a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/pci.h>
549a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ddi_intr.h>
559a5557fdSlucy wang - Sun Microsystems - Beijing China 
569a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic.h"
579a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic_hw.h"
589a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_brdcfg.h"
599a5557fdSlucy wang - Sun Microsystems - Beijing China #include "nic_cmn.h"
609a5557fdSlucy wang - Sun Microsystems - Beijing China #include "nic_phan_reg.h"
619a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic_ioctl.h"
629a5557fdSlucy wang - Sun Microsystems - Beijing China #include "nx_hw_pci_regs.h"
639a5557fdSlucy wang - Sun Microsystems - Beijing China 
649a5557fdSlucy wang - Sun Microsystems - Beijing China char ident[] = "Netxen nic driver v" UNM_NIC_VERSIONID;
659a5557fdSlucy wang - Sun Microsystems - Beijing China char unm_nic_driver_name[] = "ntxn";
669a5557fdSlucy wang - Sun Microsystems - Beijing China int verbmsg = 0;
679a5557fdSlucy wang - Sun Microsystems - Beijing China 
689a5557fdSlucy wang - Sun Microsystems - Beijing China static char txbcopythreshold_propname[] = "tx_bcopy_threshold";
699a5557fdSlucy wang - Sun Microsystems - Beijing China static char rxbcopythreshold_propname[] = "rx_bcopy_threshold";
709a5557fdSlucy wang - Sun Microsystems - Beijing China static char rxringsize_propname[] = "rx_ring_size";
719a5557fdSlucy wang - Sun Microsystems - Beijing China static char jumborxringsize_propname[] = "jumbo_rx_ring_size";
729a5557fdSlucy wang - Sun Microsystems - Beijing China static char txringsize_propname[] = "tx_ring_size";
739a5557fdSlucy wang - Sun Microsystems - Beijing China static char defaultmtu_propname[] = "default_mtu";
749a5557fdSlucy wang - Sun Microsystems - Beijing China static char dmesg_propname[] = "verbose_driver";
759a5557fdSlucy wang - Sun Microsystems - Beijing China 
769a5557fdSlucy wang - Sun Microsystems - Beijing China #define	STRUCT_COPY(a, b)	bcopy(&(b), &(a), sizeof (a))
779a5557fdSlucy wang - Sun Microsystems - Beijing China 
789a5557fdSlucy wang - Sun Microsystems - Beijing China extern int unm_register_mac(unm_adapter *adapter);
799a5557fdSlucy wang - Sun Microsystems - Beijing China extern void unm_fini_kstats(unm_adapter* adapter);
809a5557fdSlucy wang - Sun Microsystems - Beijing China extern void unm_nic_remove(unm_adapter *adapter);
819a5557fdSlucy wang - Sun Microsystems - Beijing China extern int unm_nic_suspend(unm_adapter *);
829a5557fdSlucy wang - Sun Microsystems - Beijing China extern uint_t unm_intr(caddr_t, caddr_t);
839a5557fdSlucy wang - Sun Microsystems - Beijing China 
849a5557fdSlucy wang - Sun Microsystems - Beijing China /* Data access requirements. */
859a5557fdSlucy wang - Sun Microsystems - Beijing China static struct ddi_device_acc_attr unm_dev_attr = {
869a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
879a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_STRUCTURE_LE_ACC,
889a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC
899a5557fdSlucy wang - Sun Microsystems - Beijing China };
909a5557fdSlucy wang - Sun Microsystems - Beijing China 
919a5557fdSlucy wang - Sun Microsystems - Beijing China static struct ddi_device_acc_attr unm_buf_attr = {
929a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_DEVICE_ATTR_V0,
939a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_NEVERSWAP_ACC,
949a5557fdSlucy wang - Sun Microsystems - Beijing China 	DDI_STRICTORDER_ACC
959a5557fdSlucy wang - Sun Microsystems - Beijing China };
969a5557fdSlucy wang - Sun Microsystems - Beijing China 
979a5557fdSlucy wang - Sun Microsystems - Beijing China static ddi_dma_attr_t unm_dma_attr_desc = {
989a5557fdSlucy wang - Sun Microsystems - Beijing China 	DMA_ATTR_V0,		/* dma_attr_version */
999a5557fdSlucy wang - Sun Microsystems - Beijing China 	0,			/* dma_attr_addr_lo */
1009a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffffffull,		/* dma_attr_addr_hi */
1019a5557fdSlucy wang - Sun Microsystems - Beijing China 	0x000fffffull,		/* dma_attr_count_max */
1029a5557fdSlucy wang - Sun Microsystems - Beijing China 	4096,			/* dma_attr_align */
1039a5557fdSlucy wang - Sun Microsystems - Beijing China 	0x000fffffull,		/* dma_attr_burstsizes */
1049a5557fdSlucy wang - Sun Microsystems - Beijing China 	4,			/* dma_attr_minxfer */
1059a5557fdSlucy wang - Sun Microsystems - Beijing China 	0x003fffffull,		/* dma_attr_maxxfer */
1069a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffffffull,		/* dma_attr_seg */
1079a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_sgllen */
1089a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_granular */
1099a5557fdSlucy wang - Sun Microsystems - Beijing China 	0			/* dma_attr_flags */
1109a5557fdSlucy wang - Sun Microsystems - Beijing China };
1119a5557fdSlucy wang - Sun Microsystems - Beijing China 
1129a5557fdSlucy wang - Sun Microsystems - Beijing China static ddi_dma_attr_t unm_dma_attr_rxbuf = {
1139a5557fdSlucy wang - Sun Microsystems - Beijing China 	DMA_ATTR_V0,		/* dma_attr_version */
1149a5557fdSlucy wang - Sun Microsystems - Beijing China 	0,			/* dma_attr_addr_lo */
1159a5557fdSlucy wang - Sun Microsystems - Beijing China 	0x7ffffffffULL,		/* dma_attr_addr_hi */
1169a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffull,		/* dma_attr_count_max */
1179a5557fdSlucy wang - Sun Microsystems - Beijing China 	4096,			/* dma_attr_align */
1189a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xfff8ull,		/* dma_attr_burstsizes */
1199a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_minxfer */
1209a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffffffull,		/* dma_attr_maxxfer */
1219a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffull,		/* dma_attr_seg */
1229a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_sgllen */
1239a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_granular */
1249a5557fdSlucy wang - Sun Microsystems - Beijing China 	0			/* dma_attr_flags */
1259a5557fdSlucy wang - Sun Microsystems - Beijing China };
1269a5557fdSlucy wang - Sun Microsystems - Beijing China 
1279a5557fdSlucy wang - Sun Microsystems - Beijing China static ddi_dma_attr_t unm_dma_attr_cmddesc = {
1289a5557fdSlucy wang - Sun Microsystems - Beijing China 	DMA_ATTR_V0,		/* dma_attr_version */
1299a5557fdSlucy wang - Sun Microsystems - Beijing China 	0,			/* dma_attr_addr_lo */
1309a5557fdSlucy wang - Sun Microsystems - Beijing China 	0x7ffffffffULL,		/* dma_attr_addr_hi */
1319a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffull,		/* dma_attr_count_max */
1329a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_align */
1339a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xfff8ull,		/* dma_attr_burstsizes */
1349a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_minxfer */
1359a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffff0ull,		/* dma_attr_maxxfer */
1369a5557fdSlucy wang - Sun Microsystems - Beijing China 	0xffffull,		/* dma_attr_seg */
1379a5557fdSlucy wang - Sun Microsystems - Beijing China 	16,			/* dma_attr_sgllen */
1389a5557fdSlucy wang - Sun Microsystems - Beijing China 	1,			/* dma_attr_granular */
1399a5557fdSlucy wang - Sun Microsystems - Beijing China 	0			/* dma_attr_flags */
1409a5557fdSlucy wang - Sun Microsystems - Beijing China };
1419a5557fdSlucy wang - Sun Microsystems - Beijing China 
1429a5557fdSlucy wang - Sun Microsystems - Beijing China static struct nx_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
1439a5557fdSlucy wang - Sun Microsystems - Beijing China 
1449a5557fdSlucy wang - Sun Microsystems - Beijing China static int
check_hw_init(struct unm_adapter_s * adapter)1459a5557fdSlucy wang - Sun Microsystems - Beijing China check_hw_init(struct unm_adapter_s *adapter)
1469a5557fdSlucy wang - Sun Microsystems - Beijing China {
1479a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32	val;
1489a5557fdSlucy wang - Sun Microsystems - Beijing China 	int	ret = 0;
1499a5557fdSlucy wang - Sun Microsystems - Beijing China 
1509a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_read_wx(adapter, UNM_CAM_RAM(0x1fc), &val, 4);
1519a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (val == 0x55555555) {
1529a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* This is the first boot after power up */
1539a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_read_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
1549a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &val, 4);
1559a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (val != 0x80000f)
1569a5557fdSlucy wang - Sun Microsystems - Beijing China 			ret = -1;
1579a5557fdSlucy wang - Sun Microsystems - Beijing China 
1589a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1599a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* Start P2 boot loader */
1609a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_pci_write_normalize(adapter,
1619a5557fdSlucy wang - Sun Microsystems - Beijing China 			    UNM_CAM_RAM(0x1fc), UNM_BDINFO_MAGIC);
1629a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_pci_write_normalize(adapter,
1639a5557fdSlucy wang - Sun Microsystems - Beijing China 			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
1649a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1659a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1669a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ret);
1679a5557fdSlucy wang - Sun Microsystems - Beijing China }
1689a5557fdSlucy wang - Sun Microsystems - Beijing China 
1699a5557fdSlucy wang - Sun Microsystems - Beijing China 
1709a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_get_flash_block(unm_adapter * adapter,int base,int size,uint32_t * buf)1719a5557fdSlucy wang - Sun Microsystems - Beijing China unm_get_flash_block(unm_adapter *adapter, int base, int size, uint32_t *buf)
1729a5557fdSlucy wang - Sun Microsystems - Beijing China {
1739a5557fdSlucy wang - Sun Microsystems - Beijing China 	int i, addr;
1749a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t *ptr32;
1759a5557fdSlucy wang - Sun Microsystems - Beijing China 
1769a5557fdSlucy wang - Sun Microsystems - Beijing China 	addr  = base;
1779a5557fdSlucy wang - Sun Microsystems - Beijing China 	ptr32 = buf;
1789a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < size / sizeof (uint32_t); i++) {
1799a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1)
1809a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (-1);
1819a5557fdSlucy wang - Sun Microsystems - Beijing China 		ptr32++;
1829a5557fdSlucy wang - Sun Microsystems - Beijing China 		addr += sizeof (uint32_t);
1839a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1849a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((char *)buf + size > (char *)ptr32) {
1859a5557fdSlucy wang - Sun Microsystems - Beijing China 		int local;
1869a5557fdSlucy wang - Sun Microsystems - Beijing China 
1879a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rom_fast_read(adapter, addr, &local) == -1)
1889a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (-1);
1899a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) memcpy(ptr32, &local,
1909a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (uintptr_t)((char *)buf + size) - (uintptr_t)(char *)ptr32);
1919a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1929a5557fdSlucy wang - Sun Microsystems - Beijing China 
1939a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
1949a5557fdSlucy wang - Sun Microsystems - Beijing China }
1959a5557fdSlucy wang - Sun Microsystems - Beijing China 
1969a5557fdSlucy wang - Sun Microsystems - Beijing China 
1979a5557fdSlucy wang - Sun Microsystems - Beijing China static int
get_flash_mac_addr(struct unm_adapter_s * adapter,u64 mac[])1989a5557fdSlucy wang - Sun Microsystems - Beijing China get_flash_mac_addr(struct unm_adapter_s *adapter, u64 mac[])
1999a5557fdSlucy wang - Sun Microsystems - Beijing China {
2009a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t *pmac = (uint32_t *)&mac[0];
2019a5557fdSlucy wang - Sun Microsystems - Beijing China 
2029a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
2039a5557fdSlucy wang - Sun Microsystems - Beijing China 		uint32_t temp, crbaddr;
2049a5557fdSlucy wang - Sun Microsystems - Beijing China 		uint16_t *pmac16 = (uint16_t *)pmac;
2059a5557fdSlucy wang - Sun Microsystems - Beijing China 
2069a5557fdSlucy wang - Sun Microsystems - Beijing China 		// FOR P3, read from CAM RAM
2079a5557fdSlucy wang - Sun Microsystems - Beijing China 
2089a5557fdSlucy wang - Sun Microsystems - Beijing China 		int pci_func = adapter->ahw.pci_func;
20993833965Sjing xiong ERI-SUN 		pmac16 += (4 * pci_func);
2109a5557fdSlucy wang - Sun Microsystems - Beijing China 		crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) +
2119a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (4 * (pci_func & 1));
2129a5557fdSlucy wang - Sun Microsystems - Beijing China 
2139a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_read_wx(adapter, crbaddr, &temp, 4);
2149a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (pci_func & 1) {
2159a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp >> 16);
2169a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
2179a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &temp, 4);
2189a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp & 0xffff);
2199a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp >> 16);
2209a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16 = 0;
2219a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else {
2229a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp & 0xffff);
2239a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp >> 16);
2249a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
2259a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &temp, 4);
2269a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16++ = (temp & 0xffff);
2279a5557fdSlucy wang - Sun Microsystems - Beijing China 			*pmac16 = 0;
2289a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2299a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (0);
2309a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2319a5557fdSlucy wang - Sun Microsystems - Beijing China 
2329a5557fdSlucy wang - Sun Microsystems - Beijing China 
2339a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_get_flash_block(adapter, USER_START +
2349a5557fdSlucy wang - Sun Microsystems - Beijing China 	    offsetof(unm_user_info_t, mac_addr), FLASH_NUM_PORTS * sizeof (U64),
2359a5557fdSlucy wang - Sun Microsystems - Beijing China 	    pmac) == -1)
2369a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (-1);
2379a5557fdSlucy wang - Sun Microsystems - Beijing China 
2389a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (*mac == ~0ULL) {
2399a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_get_flash_block(adapter, USER_START_OLD +
2409a5557fdSlucy wang - Sun Microsystems - Beijing China 		    offsetof(unm_old_user_info_t, mac_addr),
2419a5557fdSlucy wang - Sun Microsystems - Beijing China 		    FLASH_NUM_PORTS * sizeof (U64), pmac) == -1)
2429a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (-1);
2439a5557fdSlucy wang - Sun Microsystems - Beijing China 
2449a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (*mac == ~0ULL)
2459a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (-1);
2469a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2479a5557fdSlucy wang - Sun Microsystems - Beijing China 
2489a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
2499a5557fdSlucy wang - Sun Microsystems - Beijing China }
2509a5557fdSlucy wang - Sun Microsystems - Beijing China 
2519a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_initialize_dummy_dma(unm_adapter * adapter)2529a5557fdSlucy wang - Sun Microsystems - Beijing China unm_initialize_dummy_dma(unm_adapter *adapter)
2539a5557fdSlucy wang - Sun Microsystems - Beijing China {
2549a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t		hi, lo, temp;
2559a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
2569a5557fdSlucy wang - Sun Microsystems - Beijing China 
2579a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_pci_alloc_consistent(adapter, UNM_HOST_DUMMY_DMA_SIZE,
2589a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (caddr_t *)&adapter->dummy_dma.addr, &cookie,
2599a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &adapter->dummy_dma.dma_handle,
2609a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &adapter->dummy_dma.acc_handle) != DDI_SUCCESS) {
2619a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Unable to alloc dummy dma buf\n",
2629a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2639a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_ENOMEM);
2649a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2659a5557fdSlucy wang - Sun Microsystems - Beijing China 
2669a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->dummy_dma.phys_addr = cookie.dmac_laddress;
2679a5557fdSlucy wang - Sun Microsystems - Beijing China 
2689a5557fdSlucy wang - Sun Microsystems - Beijing China 	hi = (adapter->dummy_dma.phys_addr >> 32) & 0xffffffff;
2699a5557fdSlucy wang - Sun Microsystems - Beijing China 	lo = adapter->dummy_dma.phys_addr & 0xffffffff;
2709a5557fdSlucy wang - Sun Microsystems - Beijing China 
2719a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
2729a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI,
2739a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &hi, 4);
2749a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO,
2759a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &lo, 4);
2769a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
2779a5557fdSlucy wang - Sun Microsystems - Beijing China 		temp = DUMMY_BUF_INIT;
2789a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF,
2799a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &temp, 4);
2809a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2819a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
2829a5557fdSlucy wang - Sun Microsystems - Beijing China 
2839a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
2849a5557fdSlucy wang - Sun Microsystems - Beijing China }
2859a5557fdSlucy wang - Sun Microsystems - Beijing China 
2869a5557fdSlucy wang - Sun Microsystems - Beijing China void
unm_free_dummy_dma(unm_adapter * adapter)2879a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_dummy_dma(unm_adapter *adapter)
2889a5557fdSlucy wang - Sun Microsystems - Beijing China {
2899a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->dummy_dma.addr) {
2909a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_pci_free_consistent(&adapter->dummy_dma.dma_handle,
2919a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &adapter->dummy_dma.acc_handle);
2929a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->dummy_dma.addr = NULL;
2939a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2949a5557fdSlucy wang - Sun Microsystems - Beijing China }
2959a5557fdSlucy wang - Sun Microsystems - Beijing China 
2969a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_pci_cfg_init(unm_adapter * adapter)2979a5557fdSlucy wang - Sun Microsystems - Beijing China unm_pci_cfg_init(unm_adapter *adapter)
2989a5557fdSlucy wang - Sun Microsystems - Beijing China {
2999a5557fdSlucy wang - Sun Microsystems - Beijing China 	hardware_context *hwcontext;
3009a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_acc_handle_t pci_cfg_hdl;
3019a5557fdSlucy wang - Sun Microsystems - Beijing China 	int *reg_options;
3029a5557fdSlucy wang - Sun Microsystems - Beijing China 	dev_info_t *dip;
3039a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint_t noptions;
3049a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
3059a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint16_t vendor_id, pci_cmd_word;
3069a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint8_t	base_class, sub_class, prog_class;
3079a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t pexsizes;
3089a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct nx_legacy_intr_set *legacy_intrp;
3099a5557fdSlucy wang - Sun Microsystems - Beijing China 
3109a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwcontext = &adapter->ahw;
3119a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_cfg_hdl = adapter->pci_cfg_handle;
3129a5557fdSlucy wang - Sun Microsystems - Beijing China 	dip = adapter->dip;
3139a5557fdSlucy wang - Sun Microsystems - Beijing China 
3149a5557fdSlucy wang - Sun Microsystems - Beijing China 	vendor_id = pci_config_get16(pci_cfg_hdl, PCI_CONF_VENID);
3159a5557fdSlucy wang - Sun Microsystems - Beijing China 
3169a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (vendor_id != 0x4040) {
3179a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: vendor id %x not 0x4040\n",
3189a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, vendor_id);
3199a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
3209a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
3219a5557fdSlucy wang - Sun Microsystems - Beijing China 
3229a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
3239a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dip, 0, "reg", &reg_options, &noptions);
3249a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_PROP_SUCCESS) {
3259a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Could not determine reg property\n",
3269a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
3279a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
3289a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
3299a5557fdSlucy wang - Sun Microsystems - Beijing China 
3309a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwcontext->pci_func = (reg_options[0] >> 8) & 0x7;
3319a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_prop_free(reg_options);
3329a5557fdSlucy wang - Sun Microsystems - Beijing China 
3339a5557fdSlucy wang - Sun Microsystems - Beijing China 	base_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_BASCLASS);
3349a5557fdSlucy wang - Sun Microsystems - Beijing China 	sub_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_SUBCLASS);
3359a5557fdSlucy wang - Sun Microsystems - Beijing China 	prog_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_PROGCLASS);
3369a5557fdSlucy wang - Sun Microsystems - Beijing China 
3379a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
3389a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Need this check so that MEZZ card mgmt interface ntxn0 could fail
3399a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * attach & return and proceed to next interfaces ntxn1 and ntxn2
3409a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
3419a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((base_class != 0x02) || (sub_class != 0) || (prog_class != 0)) {
3429a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Base/sub/prog class problem %d/%d/%d\n",
3439a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, base_class, sub_class,
3449a5557fdSlucy wang - Sun Microsystems - Beijing China 		    prog_class);
3459a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
3469a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
3479a5557fdSlucy wang - Sun Microsystems - Beijing China 
3489a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwcontext->revision_id = pci_config_get8(pci_cfg_hdl, PCI_CONF_REVID);
3499a5557fdSlucy wang - Sun Microsystems - Beijing China 
3509a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
3519a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Refuse to work with dubious P3 cards.
3529a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
3539a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((hwcontext->revision_id >= NX_P3_A0) &&
3549a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (hwcontext->revision_id < NX_P3_B1)) {
3559a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: NetXen chip revs between 0x%x-0x%x "
3569a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "is unsupported\n", adapter->name, adapter->instance,
3579a5557fdSlucy wang - Sun Microsystems - Beijing China 		    NX_P3_A0, NX_P3_B0);
3589a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
3599a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
3609a5557fdSlucy wang - Sun Microsystems - Beijing China 
3619a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
3629a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Save error reporting settings; clear [19:16] error status bits.
3639a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Set max read request [14:12] to 0 for 128 bytes. Set max payload
3649a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * size[7:5] to 0 for for 128 bytes.
3659a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
3669a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P2(hwcontext->revision_id)) {
3679a5557fdSlucy wang - Sun Microsystems - Beijing China 		pexsizes = pci_config_get32(pci_cfg_hdl, 0xd8);
3689a5557fdSlucy wang - Sun Microsystems - Beijing China 		pexsizes &= 7;
3699a5557fdSlucy wang - Sun Microsystems - Beijing China 		pexsizes |= 0xF0000;
3709a5557fdSlucy wang - Sun Microsystems - Beijing China 		pci_config_put32(pci_cfg_hdl, 0xd8, pexsizes);
3719a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
3729a5557fdSlucy wang - Sun Microsystems - Beijing China 
3739a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_cmd_word = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM);
3749a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_cmd_word |= (PCI_COMM_INTX_DISABLE | PCI_COMM_SERR_ENABLE);
3759a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, pci_cmd_word);
3769a5557fdSlucy wang - Sun Microsystems - Beijing China 
3779a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (hwcontext->revision_id >= NX_P3_B0)
3789a5557fdSlucy wang - Sun Microsystems - Beijing China 		legacy_intrp = &legacy_intr[hwcontext->pci_func];
3799a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
3809a5557fdSlucy wang - Sun Microsystems - Beijing China 		legacy_intrp = &legacy_intr[0];
3819a5557fdSlucy wang - Sun Microsystems - Beijing China 
3829a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
3839a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
3849a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
3859a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
3869a5557fdSlucy wang - Sun Microsystems - Beijing China 
3879a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
3889a5557fdSlucy wang - Sun Microsystems - Beijing China }
3899a5557fdSlucy wang - Sun Microsystems - Beijing China 
390dda0720aSjing xiong ERI-SUN static void
unm_free_tx_dmahdl(unm_adapter * adapter)3919a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_tx_dmahdl(unm_adapter *adapter)
3929a5557fdSlucy wang - Sun Microsystems - Beijing China {
3939a5557fdSlucy wang - Sun Microsystems - Beijing China 	int i;
3949a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t	 *nodep;
3959a5557fdSlucy wang - Sun Microsystems - Beijing China 
3969a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_enter(&adapter->tx_lock);
3979a5557fdSlucy wang - Sun Microsystems - Beijing China 	nodep = &adapter->tx_dma_hdls[0];
3989a5557fdSlucy wang - Sun Microsystems - Beijing China 
3999a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
4009a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (nodep->dmahdl != NULL) {
4019a5557fdSlucy wang - Sun Microsystems - Beijing China 			ddi_dma_free_handle(&nodep->dmahdl);
4029a5557fdSlucy wang - Sun Microsystems - Beijing China 			nodep->dmahdl = NULL;
4039a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
4049a5557fdSlucy wang - Sun Microsystems - Beijing China 		nodep->next = NULL;
4059a5557fdSlucy wang - Sun Microsystems - Beijing China 		nodep++;
4069a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4079a5557fdSlucy wang - Sun Microsystems - Beijing China 
4089a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->dmahdl_pool = NULL;
4099a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freehdls = 0;
4109a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_exit(&adapter->tx_lock);
4119a5557fdSlucy wang - Sun Microsystems - Beijing China }
4129a5557fdSlucy wang - Sun Microsystems - Beijing China 
4139a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_alloc_tx_dmahdl(unm_adapter * adapter)4149a5557fdSlucy wang - Sun Microsystems - Beijing China unm_alloc_tx_dmahdl(unm_adapter *adapter)
4159a5557fdSlucy wang - Sun Microsystems - Beijing China {
4169a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		i;
4179a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t	*nodep = &adapter->tx_dma_hdls[0];
4189a5557fdSlucy wang - Sun Microsystems - Beijing China 
4199a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_enter(&adapter->tx_lock);
4209a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
4219a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (ddi_dma_alloc_handle(adapter->dip, &unm_dma_attr_cmddesc,
4229a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_DONTWAIT, NULL, &nodep->dmahdl) != DDI_SUCCESS) {
4239a5557fdSlucy wang - Sun Microsystems - Beijing China 			mutex_exit(&adapter->tx_lock);
4249a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto alloc_hdl_fail;
4259a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
4269a5557fdSlucy wang - Sun Microsystems - Beijing China 
4279a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (i > 0)
4289a5557fdSlucy wang - Sun Microsystems - Beijing China 			nodep->next = nodep - 1;
4299a5557fdSlucy wang - Sun Microsystems - Beijing China 		nodep++;
4309a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4319a5557fdSlucy wang - Sun Microsystems - Beijing China 
4329a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->dmahdl_pool = nodep - 1;
4339a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freehdls = i;
4349a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_exit(&adapter->tx_lock);
4359a5557fdSlucy wang - Sun Microsystems - Beijing China 
4369a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
4379a5557fdSlucy wang - Sun Microsystems - Beijing China 
4389a5557fdSlucy wang - Sun Microsystems - Beijing China alloc_hdl_fail:
4399a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_tx_dmahdl(adapter);
4409a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmn_err(CE_WARN, "%s%d: Failed transmit ring dma handle allocation\n",
4419a5557fdSlucy wang - Sun Microsystems - Beijing China 	    adapter->name, adapter->instance);
4429a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_FAILURE);
4439a5557fdSlucy wang - Sun Microsystems - Beijing China }
4449a5557fdSlucy wang - Sun Microsystems - Beijing China 
4459a5557fdSlucy wang - Sun Microsystems - Beijing China static void
unm_free_dma_mem(dma_area_t * dma_p)4469a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_dma_mem(dma_area_t *dma_p)
4479a5557fdSlucy wang - Sun Microsystems - Beijing China {
4489a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (dma_p->dma_hdl != NULL) {
4499a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (dma_p->ncookies) {
4509a5557fdSlucy wang - Sun Microsystems - Beijing China 			(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
4519a5557fdSlucy wang - Sun Microsystems - Beijing China 			dma_p->ncookies = 0;
4529a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
4539a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4549a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (dma_p->acc_hdl != NULL) {
4559a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_mem_free(&dma_p->acc_hdl);
4569a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_p->acc_hdl = NULL;
4579a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4589a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (dma_p->dma_hdl != NULL) {
4599a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_free_handle(&dma_p->dma_hdl);
4609a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_p->dma_hdl = NULL;
4619a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4629a5557fdSlucy wang - Sun Microsystems - Beijing China }
4639a5557fdSlucy wang - Sun Microsystems - Beijing China 
4649a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_alloc_dma_mem(unm_adapter * adapter,int size,uint_t dma_flag,ddi_dma_attr_t * dma_attr_p,dma_area_t * dma_p)4659a5557fdSlucy wang - Sun Microsystems - Beijing China unm_alloc_dma_mem(unm_adapter *adapter, int size, uint_t dma_flag,
4669a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_attr_t *dma_attr_p, dma_area_t *dma_p)
4679a5557fdSlucy wang - Sun Microsystems - Beijing China {
4689a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
4699a5557fdSlucy wang - Sun Microsystems - Beijing China 	caddr_t vaddr;
4709a5557fdSlucy wang - Sun Microsystems - Beijing China 	size_t actual_size;
4719a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
4729a5557fdSlucy wang - Sun Microsystems - Beijing China 
4739a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_dma_alloc_handle(adapter->dip,
4749a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dma_attr_p, DDI_DMA_DONTWAIT,
4759a5557fdSlucy wang - Sun Microsystems - Beijing China 	    NULL, &dma_p->dma_hdl);
4769a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
4779a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Failed ddi_dma_alloc_handle\n",
4789a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
4799a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto dma_mem_fail;
4809a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4819a5557fdSlucy wang - Sun Microsystems - Beijing China 
4829a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_dma_mem_alloc(dma_p->dma_hdl,
4839a5557fdSlucy wang - Sun Microsystems - Beijing China 	    size, &adapter->gc_attr_desc,
4849a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dma_flag & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
4859a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_DONTWAIT, NULL, &vaddr, &actual_size,
4869a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &dma_p->acc_hdl);
4879a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
4889a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() failed\n",
4899a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
4909a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto dma_mem_fail;
4919a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4929a5557fdSlucy wang - Sun Microsystems - Beijing China 
4939a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (actual_size < size) {
4949a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() allocated small\n",
4959a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
4969a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto dma_mem_fail;
4979a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
4989a5557fdSlucy wang - Sun Microsystems - Beijing China 
4999a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_dma_addr_bind_handle(dma_p->dma_hdl,
5009a5557fdSlucy wang - Sun Microsystems - Beijing China 	    NULL, vaddr, size, dma_flag, DDI_DMA_DONTWAIT,
5019a5557fdSlucy wang - Sun Microsystems - Beijing China 	    NULL, &cookie, &dma_p->ncookies);
5029a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_DMA_MAPPED || dma_p->ncookies != 1) {
5039a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: ddi_dma_addr_bind_handle() failed, "
5049a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "%d, %d\n", adapter->name, adapter->instance, ret,
5059a5557fdSlucy wang - Sun Microsystems - Beijing China 		    dma_p->ncookies);
5069a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto dma_mem_fail;
5079a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
5089a5557fdSlucy wang - Sun Microsystems - Beijing China 
5099a5557fdSlucy wang - Sun Microsystems - Beijing China 	dma_p->dma_addr = cookie.dmac_laddress;
5109a5557fdSlucy wang - Sun Microsystems - Beijing China 	dma_p->vaddr = vaddr;
5119a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(vaddr, 0, size);
5129a5557fdSlucy wang - Sun Microsystems - Beijing China 
5139a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
5149a5557fdSlucy wang - Sun Microsystems - Beijing China 
5159a5557fdSlucy wang - Sun Microsystems - Beijing China dma_mem_fail:
5169a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_dma_mem(dma_p);
5179a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_FAILURE);
5189a5557fdSlucy wang - Sun Microsystems - Beijing China }
5199a5557fdSlucy wang - Sun Microsystems - Beijing China 
520dda0720aSjing xiong ERI-SUN static void
unm_free_tx_buffers(unm_adapter * adapter)5219a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_tx_buffers(unm_adapter *adapter)
5229a5557fdSlucy wang - Sun Microsystems - Beijing China {
5239a5557fdSlucy wang - Sun Microsystems - Beijing China 	int i;
5249a5557fdSlucy wang - Sun Microsystems - Beijing China 	dma_area_t *dma_p;
5259a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_cmd_buffer *cmd_buf;
5269a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t	 *nodep;
5279a5557fdSlucy wang - Sun Microsystems - Beijing China 
5289a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmd_buf = &adapter->cmd_buf_arr[0];
5299a5557fdSlucy wang - Sun Microsystems - Beijing China 
5309a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < adapter->MaxTxDescCount; i++) {
5319a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_p = &cmd_buf->dma_area;
5329a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dma_mem(dma_p);
5339a5557fdSlucy wang - Sun Microsystems - Beijing China 		nodep = cmd_buf->head;
5349a5557fdSlucy wang - Sun Microsystems - Beijing China 		while (nodep != NULL) {
5359a5557fdSlucy wang - Sun Microsystems - Beijing China 			(void) ddi_dma_unbind_handle(nodep->dmahdl);
5369a5557fdSlucy wang - Sun Microsystems - Beijing China 			nodep = nodep->next;
5379a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
5389a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (cmd_buf->msg != NULL)
5399a5557fdSlucy wang - Sun Microsystems - Beijing China 			freemsg(cmd_buf->msg);
5409a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmd_buf++;
5419a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
5429a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freecmds = 0;
5439a5557fdSlucy wang - Sun Microsystems - Beijing China }
5449a5557fdSlucy wang - Sun Microsystems - Beijing China 
5459a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_alloc_tx_buffers(unm_adapter * adapter)5469a5557fdSlucy wang - Sun Microsystems - Beijing China unm_alloc_tx_buffers(unm_adapter *adapter)
5479a5557fdSlucy wang - Sun Microsystems - Beijing China {
5489a5557fdSlucy wang - Sun Microsystems - Beijing China 	int i, ret, size, allocated = 0;
5499a5557fdSlucy wang - Sun Microsystems - Beijing China 	dma_area_t *dma_p;
5509a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_cmd_buffer *cmd_buf;
5519a5557fdSlucy wang - Sun Microsystems - Beijing China 
5529a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmd_buf = &adapter->cmd_buf_arr[0];
5539a5557fdSlucy wang - Sun Microsystems - Beijing China 	size = adapter->maxmtu;
5549a5557fdSlucy wang - Sun Microsystems - Beijing China 
5559a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < adapter->MaxTxDescCount; i++) {
5569a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_p = &cmd_buf->dma_area;
5579a5557fdSlucy wang - Sun Microsystems - Beijing China 		ret = unm_alloc_dma_mem(adapter, size,
5589a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
5599a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &unm_dma_attr_rxbuf, dma_p);
5609a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (ret != DDI_SUCCESS)
5619a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto alloc_tx_buffer_fail;
5629a5557fdSlucy wang - Sun Microsystems - Beijing China 
5639a5557fdSlucy wang - Sun Microsystems - Beijing China 		allocated++;
5649a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmd_buf++;
5659a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
5669a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freecmds = adapter->MaxTxDescCount;
5679a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
5689a5557fdSlucy wang - Sun Microsystems - Beijing China 
5699a5557fdSlucy wang - Sun Microsystems - Beijing China alloc_tx_buffer_fail:
5709a5557fdSlucy wang - Sun Microsystems - Beijing China 
5719a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmd_buf = &adapter->cmd_buf_arr[0];
5729a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < allocated; i++) {
5739a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_p = &cmd_buf->dma_area;
5749a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dma_mem(dma_p);
5759a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmd_buf++;
5769a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
5779a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmn_err(CE_WARN, "%s%d: Failed transmit ring memory allocation\n",
5789a5557fdSlucy wang - Sun Microsystems - Beijing China 	    adapter->name, adapter->instance);
5799a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_FAILURE);
5809a5557fdSlucy wang - Sun Microsystems - Beijing China }
5819a5557fdSlucy wang - Sun Microsystems - Beijing China 
5829a5557fdSlucy wang - Sun Microsystems - Beijing China /*
5839a5557fdSlucy wang - Sun Microsystems - Beijing China  * Called by freemsg() to "free" the resource.
5849a5557fdSlucy wang - Sun Microsystems - Beijing China  */
5859a5557fdSlucy wang - Sun Microsystems - Beijing China static void
unm_rx_buffer_recycle(char * arg)5869a5557fdSlucy wang - Sun Microsystems - Beijing China unm_rx_buffer_recycle(char *arg)
5879a5557fdSlucy wang - Sun Microsystems - Beijing China {
5889a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t *rx_buffer = (unm_rx_buffer_t *)(uintptr_t)arg;
5899a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter *adapter = rx_buffer->adapter;
5909a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t *rcv_desc = rx_buffer->rcv_desc;
5919a5557fdSlucy wang - Sun Microsystems - Beijing China 
5929a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer->mp = desballoc(rx_buffer->dma_info.vaddr,
5939a5557fdSlucy wang - Sun Microsystems - Beijing China 	    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
5949a5557fdSlucy wang - Sun Microsystems - Beijing China 
5959a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rx_buffer->mp == NULL)
5969a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.desballocfailed++;
5979a5557fdSlucy wang - Sun Microsystems - Beijing China 
5989a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_enter(rcv_desc->recycle_lock);
5999a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer->next = rcv_desc->recycle_list;
6009a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->recycle_list = rx_buffer;
6019a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_recycle++;
6029a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_exit(rcv_desc->recycle_lock);
6039a5557fdSlucy wang - Sun Microsystems - Beijing China }
6049a5557fdSlucy wang - Sun Microsystems - Beijing China 
605dda0720aSjing xiong ERI-SUN static void
unm_destroy_rx_ring(unm_rcv_desc_ctx_t * rcv_desc)6069a5557fdSlucy wang - Sun Microsystems - Beijing China unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc)
6079a5557fdSlucy wang - Sun Microsystems - Beijing China {
6089a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t i, total_buf;
6099a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t *buf_pool;
6109a5557fdSlucy wang - Sun Microsystems - Beijing China 
6119a5557fdSlucy wang - Sun Microsystems - Beijing China 	total_buf = rcv_desc->rx_buf_total;
6129a5557fdSlucy wang - Sun Microsystems - Beijing China 	buf_pool = rcv_desc->rx_buf_pool;
6139a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < total_buf; i++) {
6149a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (buf_pool->mp != NULL)
6159a5557fdSlucy wang - Sun Microsystems - Beijing China 			freemsg(buf_pool->mp);
6169a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dma_mem(&buf_pool->dma_info);
6179a5557fdSlucy wang - Sun Microsystems - Beijing China 		buf_pool++;
6189a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
6199a5557fdSlucy wang - Sun Microsystems - Beijing China 
6209a5557fdSlucy wang - Sun Microsystems - Beijing China 	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
6219a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_pool = NULL;
6229a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->pool_list = NULL;
6239a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->recycle_list = NULL;
6249a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_free = 0;
6259a5557fdSlucy wang - Sun Microsystems - Beijing China 
6269a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_destroy(rcv_desc->pool_lock);
6279a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_destroy(rcv_desc->recycle_lock);
6289a5557fdSlucy wang - Sun Microsystems - Beijing China }
6299a5557fdSlucy wang - Sun Microsystems - Beijing China 
6309a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_create_rx_ring(unm_adapter * adapter,unm_rcv_desc_ctx_t * rcv_desc)6319a5557fdSlucy wang - Sun Microsystems - Beijing China unm_create_rx_ring(unm_adapter *adapter, unm_rcv_desc_ctx_t *rcv_desc)
6329a5557fdSlucy wang - Sun Microsystems - Beijing China {
6339a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		i, ret, allocate = 0, sreoff;
6349a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t	total_buf;
6359a5557fdSlucy wang - Sun Microsystems - Beijing China 	dma_area_t	*dma_info;
6369a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t	*rx_buffer;
6379a5557fdSlucy wang - Sun Microsystems - Beijing China 
6389a5557fdSlucy wang - Sun Microsystems - Beijing China 	sreoff = adapter->ahw.cut_through ? 0 : IP_ALIGNMENT_BYTES;
6399a5557fdSlucy wang - Sun Microsystems - Beijing China 
6409a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* temporarily set the total rx buffers two times of MaxRxDescCount */
6419a5557fdSlucy wang - Sun Microsystems - Beijing China 	total_buf = rcv_desc->rx_buf_total = rcv_desc->MaxRxDescCount * 2;
6429a5557fdSlucy wang - Sun Microsystems - Beijing China 
6439a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_pool = kmem_zalloc(sizeof (unm_rx_buffer_t) *
6449a5557fdSlucy wang - Sun Microsystems - Beijing China 	    total_buf, KM_SLEEP);
6459a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer = rcv_desc->rx_buf_pool;
6469a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < total_buf; i++) {
6479a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_info = &rx_buffer->dma_info;
6489a5557fdSlucy wang - Sun Microsystems - Beijing China 		ret = unm_alloc_dma_mem(adapter, rcv_desc->buf_size,
6499a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_READ | DDI_DMA_STREAMING,
6509a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &unm_dma_attr_rxbuf, dma_info);
6519a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (ret != DDI_SUCCESS)
6529a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto alloc_mem_failed;
6539a5557fdSlucy wang - Sun Microsystems - Beijing China 		else {
6549a5557fdSlucy wang - Sun Microsystems - Beijing China 			allocate++;
6559a5557fdSlucy wang - Sun Microsystems - Beijing China 			dma_info->vaddr = (void *) ((char *)dma_info->vaddr +
6569a5557fdSlucy wang - Sun Microsystems - Beijing China 			    sreoff);
6579a5557fdSlucy wang - Sun Microsystems - Beijing China 			dma_info->dma_addr += sreoff;
6589a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->rx_recycle.free_func =
6599a5557fdSlucy wang - Sun Microsystems - Beijing China 			    unm_rx_buffer_recycle;
6609a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->rx_recycle.free_arg = (caddr_t)rx_buffer;
6619a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->next = NULL;
6629a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->mp = desballoc(dma_info->vaddr,
6639a5557fdSlucy wang - Sun Microsystems - Beijing China 			    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
6649a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (rx_buffer->mp == NULL)
6659a5557fdSlucy wang - Sun Microsystems - Beijing China 				adapter->stats.desballocfailed++;
6669a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->rcv_desc = rcv_desc;
6679a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->adapter = adapter;
6689a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer++;
6699a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
6709a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
6719a5557fdSlucy wang - Sun Microsystems - Beijing China 
6729a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < (total_buf - 1); i++) {
6739a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->rx_buf_pool[i].next = &rcv_desc->rx_buf_pool[i + 1];
6749a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
6759a5557fdSlucy wang - Sun Microsystems - Beijing China 
6769a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->pool_list = rcv_desc->rx_buf_pool;
6779a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->recycle_list = NULL;
6789a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_free = total_buf;
6799a5557fdSlucy wang - Sun Microsystems - Beijing China 
6809a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_init(rcv_desc->pool_lock, NULL,
6819a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
6829a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_init(rcv_desc->recycle_lock, NULL,
6839a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
6849a5557fdSlucy wang - Sun Microsystems - Beijing China 
6859a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
6869a5557fdSlucy wang - Sun Microsystems - Beijing China 
6879a5557fdSlucy wang - Sun Microsystems - Beijing China alloc_mem_failed:
6889a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer = rcv_desc->rx_buf_pool;
6899a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < allocate; i++, rx_buffer++) {
6909a5557fdSlucy wang - Sun Microsystems - Beijing China 		dma_info = &rx_buffer->dma_info;
6919a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rx_buffer->mp != NULL)
6929a5557fdSlucy wang - Sun Microsystems - Beijing China 			freemsg(rx_buffer->mp);
6939a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dma_mem(dma_info);
6949a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
6959a5557fdSlucy wang - Sun Microsystems - Beijing China 
6969a5557fdSlucy wang - Sun Microsystems - Beijing China 	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
6979a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_pool = NULL;
6989a5557fdSlucy wang - Sun Microsystems - Beijing China 
6999a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmn_err(CE_WARN, "%s%d: Failed receive ring resource allocation\n",
7009a5557fdSlucy wang - Sun Microsystems - Beijing China 	    adapter->name, adapter->instance);
7019a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_FAILURE);
7029a5557fdSlucy wang - Sun Microsystems - Beijing China }
7039a5557fdSlucy wang - Sun Microsystems - Beijing China 
7049a5557fdSlucy wang - Sun Microsystems - Beijing China static void
unm_check_options(unm_adapter * adapter)7059a5557fdSlucy wang - Sun Microsystems - Beijing China unm_check_options(unm_adapter *adapter)
7069a5557fdSlucy wang - Sun Microsystems - Beijing China {
707dda0720aSjing xiong ERI-SUN 	int			i, ring, tx_desc, rx_desc, rx_jdesc, maxrx;
7089a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx;
7099a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc;
7109a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint8_t			revid = adapter->ahw.revision_id;
7119a5557fdSlucy wang - Sun Microsystems - Beijing China 	dev_info_t		*dip = adapter->dip;
7129a5557fdSlucy wang - Sun Microsystems - Beijing China 
713dda0720aSjing xiong ERI-SUN 	/*
714dda0720aSjing xiong ERI-SUN 	 * Reduce number of regular rcv desc to half on x86.
715dda0720aSjing xiong ERI-SUN 	 */
716dda0720aSjing xiong ERI-SUN 	maxrx = MAX_RCV_DESCRIPTORS;
717dda0720aSjing xiong ERI-SUN #if !defined(_LP64)
718dda0720aSjing xiong ERI-SUN 	maxrx /= 2;
719dda0720aSjing xiong ERI-SUN #endif /* !_LP64 */
720dda0720aSjing xiong ERI-SUN 
7219a5557fdSlucy wang - Sun Microsystems - Beijing China 	verbmsg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
7229a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dmesg_propname, 0);
7239a5557fdSlucy wang - Sun Microsystems - Beijing China 
7249a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->tx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
7259a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dip, DDI_PROP_DONTPASS, txbcopythreshold_propname,
7269a5557fdSlucy wang - Sun Microsystems - Beijing China 	    UNM_TX_BCOPY_THRESHOLD);
7279a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->rx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
7289a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dip, DDI_PROP_DONTPASS, rxbcopythreshold_propname,
7299a5557fdSlucy wang - Sun Microsystems - Beijing China 	    UNM_RX_BCOPY_THRESHOLD);
7309a5557fdSlucy wang - Sun Microsystems - Beijing China 
7319a5557fdSlucy wang - Sun Microsystems - Beijing China 	tx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
7329a5557fdSlucy wang - Sun Microsystems - Beijing China 	    txringsize_propname, MAX_CMD_DESCRIPTORS_HOST);
733de710d24SJosef 'Jeff' Sipek 	if (tx_desc >= 256 && tx_desc <= MAX_CMD_DESCRIPTORS && ISP2(tx_desc)) {
7349a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxTxDescCount = tx_desc;
7359a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
7369a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: TxRingSize defaulting to %d, since "
7379a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ".conf value is not 2 power aligned in range 256 - %d\n",
7389a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, MAX_CMD_DESCRIPTORS_HOST,
7399a5557fdSlucy wang - Sun Microsystems - Beijing China 		    MAX_CMD_DESCRIPTORS);
7409a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxTxDescCount = MAX_CMD_DESCRIPTORS_HOST;
7419a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
7429a5557fdSlucy wang - Sun Microsystems - Beijing China 
7439a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
744dda0720aSjing xiong ERI-SUN 	    rxringsize_propname, maxrx);
7459a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rx_desc >= NX_MIN_DRIVER_RDS_SIZE &&
746de710d24SJosef 'Jeff' Sipek 	    rx_desc <= NX_MAX_SUPPORTED_RDS_SIZE && ISP2(rx_desc)) {
7479a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxRxDescCount = rx_desc;
7489a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
7499a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: RxRingSize defaulting to %d, since "
7509a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ".conf value is not 2 power aligned in range %d - %d\n",
7519a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, MAX_RCV_DESCRIPTORS,
7529a5557fdSlucy wang - Sun Microsystems - Beijing China 		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_RDS_SIZE);
7539a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxRxDescCount = MAX_RCV_DESCRIPTORS;
7549a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
7559a5557fdSlucy wang - Sun Microsystems - Beijing China 
7569a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_jdesc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
7579a5557fdSlucy wang - Sun Microsystems - Beijing China 	    jumborxringsize_propname, MAX_JUMBO_RCV_DESCRIPTORS);
7589a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rx_jdesc >= NX_MIN_DRIVER_RDS_SIZE &&
759de710d24SJosef 'Jeff' Sipek 	    rx_jdesc <= NX_MAX_SUPPORTED_JUMBO_RDS_SIZE && ISP2(rx_jdesc)) {
7609a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxJumboRxDescCount = rx_jdesc;
7619a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
7629a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: JumboRingSize defaulting to %d, since "
7639a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ".conf value is not 2 power aligned in range %d - %d\n",
7649a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, MAX_JUMBO_RCV_DESCRIPTORS,
7659a5557fdSlucy wang - Sun Microsystems - Beijing China 		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_JUMBO_RDS_SIZE);
7669a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS;
7679a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
7689a5557fdSlucy wang - Sun Microsystems - Beijing China 
769dda0720aSjing xiong ERI-SUN 	/*
770dda0720aSjing xiong ERI-SUN 	 * Solaris does not use LRO, but older firmware needs to have a
771dda0720aSjing xiong ERI-SUN 	 * couple of descriptors for initialization.
772dda0720aSjing xiong ERI-SUN 	 */
773dda0720aSjing xiong ERI-SUN 	adapter->MaxLroRxDescCount = (adapter->fw_major < 4) ? 2 : 0;
7749a5557fdSlucy wang - Sun Microsystems - Beijing China 
7759a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->mtu = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
7769a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_PROP_DONTPASS, defaultmtu_propname, MTU_SIZE);
7779a5557fdSlucy wang - Sun Microsystems - Beijing China 
7789a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->mtu < MTU_SIZE) {
7799a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Raising mtu to %d\n", MTU_SIZE);
7809a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->mtu = MTU_SIZE;
7819a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
7829a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->maxmtu = NX_IS_REVISION_P2(revid) ? P2_MAX_MTU : P3_MAX_MTU;
7839a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->mtu > adapter->maxmtu) {
7849a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Lowering mtu to %d\n", adapter->maxmtu);
7859a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->mtu = adapter->maxmtu;
7869a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
7879a5557fdSlucy wang - Sun Microsystems - Beijing China 
788dda0720aSjing xiong ERI-SUN 	adapter->maxmtu = adapter->mtu + NX_MAX_ETHERHDR;
789dda0720aSjing xiong ERI-SUN 
790dda0720aSjing xiong ERI-SUN 	/*
791dda0720aSjing xiong ERI-SUN 	 * If we are not expecting to receive jumbo frames, save memory and
792dda0720aSjing xiong ERI-SUN 	 * do not allocate.
793dda0720aSjing xiong ERI-SUN 	 */
794dda0720aSjing xiong ERI-SUN 	if (adapter->mtu <= MTU_SIZE)
795dda0720aSjing xiong ERI-SUN 		adapter->MaxJumboRxDescCount = NX_MIN_DRIVER_RDS_SIZE;
7969a5557fdSlucy wang - Sun Microsystems - Beijing China 
7979a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < MAX_RCV_CTX; ++i) {
7989a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx = &adapter->recv_ctx[i];
7999a5557fdSlucy wang - Sun Microsystems - Beijing China 
8009a5557fdSlucy wang - Sun Microsystems - Beijing China 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
8019a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc = &recv_ctx->rcv_desc[ring];
8029a5557fdSlucy wang - Sun Microsystems - Beijing China 
8039a5557fdSlucy wang - Sun Microsystems - Beijing China 			switch (RCV_DESC_TYPE(ring)) {
8049a5557fdSlucy wang - Sun Microsystems - Beijing China 			case RCV_DESC_NORMAL:
8059a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->MaxRxDescCount =
8069a5557fdSlucy wang - Sun Microsystems - Beijing China 				    adapter->MaxRxDescCount;
8079a5557fdSlucy wang - Sun Microsystems - Beijing China 				if (adapter->ahw.cut_through) {
8089a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->dma_size =
8099a5557fdSlucy wang - Sun Microsystems - Beijing China 					    NX_CT_DEFAULT_RX_BUF_LEN;
8109a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->buf_size = rcv_desc->dma_size;
8119a5557fdSlucy wang - Sun Microsystems - Beijing China 				} else {
8129a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->dma_size =
8139a5557fdSlucy wang - Sun Microsystems - Beijing China 					    NX_RX_NORMAL_BUF_MAX_LEN;
8149a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->buf_size =
8159a5557fdSlucy wang - Sun Microsystems - Beijing China 					    rcv_desc->dma_size +
8169a5557fdSlucy wang - Sun Microsystems - Beijing China 					    IP_ALIGNMENT_BYTES;
8179a5557fdSlucy wang - Sun Microsystems - Beijing China 				}
8189a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
8199a5557fdSlucy wang - Sun Microsystems - Beijing China 
8209a5557fdSlucy wang - Sun Microsystems - Beijing China 			case RCV_DESC_JUMBO:
8219a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->MaxRxDescCount =
8229a5557fdSlucy wang - Sun Microsystems - Beijing China 				    adapter->MaxJumboRxDescCount;
8239a5557fdSlucy wang - Sun Microsystems - Beijing China 				if (adapter->ahw.cut_through) {
8249a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->dma_size =
8259a5557fdSlucy wang - Sun Microsystems - Beijing China 					    rcv_desc->buf_size =
8269a5557fdSlucy wang - Sun Microsystems - Beijing China 					    NX_P3_RX_JUMBO_BUF_MAX_LEN;
8279a5557fdSlucy wang - Sun Microsystems - Beijing China 				} else {
8289a5557fdSlucy wang - Sun Microsystems - Beijing China 					if (NX_IS_REVISION_P2(revid))
8299a5557fdSlucy wang - Sun Microsystems - Beijing China 						rcv_desc->dma_size =
8309a5557fdSlucy wang - Sun Microsystems - Beijing China 						    NX_P2_RX_JUMBO_BUF_MAX_LEN;
8319a5557fdSlucy wang - Sun Microsystems - Beijing China 					else
8329a5557fdSlucy wang - Sun Microsystems - Beijing China 						rcv_desc->dma_size =
8339a5557fdSlucy wang - Sun Microsystems - Beijing China 						    NX_P3_RX_JUMBO_BUF_MAX_LEN;
8349a5557fdSlucy wang - Sun Microsystems - Beijing China 					rcv_desc->buf_size =
8359a5557fdSlucy wang - Sun Microsystems - Beijing China 					    rcv_desc->dma_size +
8369a5557fdSlucy wang - Sun Microsystems - Beijing China 					    IP_ALIGNMENT_BYTES;
8379a5557fdSlucy wang - Sun Microsystems - Beijing China 				}
8389a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
8399a5557fdSlucy wang - Sun Microsystems - Beijing China 
8409a5557fdSlucy wang - Sun Microsystems - Beijing China 			case RCV_RING_LRO:
8419a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->MaxRxDescCount =
8429a5557fdSlucy wang - Sun Microsystems - Beijing China 				    adapter->MaxLroRxDescCount;
8439a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->buf_size = MAX_RX_LRO_BUFFER_LENGTH;
8449a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
8459a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
8469a5557fdSlucy wang - Sun Microsystems - Beijing China 			default:
8479a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
8489a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
8499a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
8509a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
8519a5557fdSlucy wang - Sun Microsystems - Beijing China }
8529a5557fdSlucy wang - Sun Microsystems - Beijing China 
8539a5557fdSlucy wang - Sun Microsystems - Beijing China static void
vector128M(unm_adapter * aptr)8549a5557fdSlucy wang - Sun Microsystems - Beijing China vector128M(unm_adapter *aptr)
8559a5557fdSlucy wang - Sun Microsystems - Beijing China {
8569a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_128M;
8579a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_128M;
8589a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_128M;
8599a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_128M;
8609a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_ioctl_128M;
8619a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_ioctl_128M;
8629a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_128M;
8639a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_128M;
8649a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_128M;
8659a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_128M;
8669a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_128M;
8679a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_128M;
8689a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_128M;
8699a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_128M;
8709a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_128M;
8719a5557fdSlucy wang - Sun Microsystems - Beijing China }
8729a5557fdSlucy wang - Sun Microsystems - Beijing China 
8739a5557fdSlucy wang - Sun Microsystems - Beijing China static void
vector2M(unm_adapter * aptr)8749a5557fdSlucy wang - Sun Microsystems - Beijing China vector2M(unm_adapter *aptr)
8759a5557fdSlucy wang - Sun Microsystems - Beijing China {
8769a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_2M;
8779a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_2M;
8789a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_2M;
8799a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_2M;
8809a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_wx_2M;
8819a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_wx_2M;
8829a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_2M;
8839a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_2M;
8849a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_2M;
8859a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_2M;
8869a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_2M;
8879a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_2M;
8889a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_2M;
8899a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_2M;
8909a5557fdSlucy wang - Sun Microsystems - Beijing China 	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_2M;
8919a5557fdSlucy wang - Sun Microsystems - Beijing China }
8929a5557fdSlucy wang - Sun Microsystems - Beijing China 
8939a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_pci_map_setup(unm_adapter * adapter)8949a5557fdSlucy wang - Sun Microsystems - Beijing China unm_pci_map_setup(unm_adapter *adapter)
8959a5557fdSlucy wang - Sun Microsystems - Beijing China {
8969a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
8979a5557fdSlucy wang - Sun Microsystems - Beijing China 	caddr_t reg_base, db_base;
8989a5557fdSlucy wang - Sun Microsystems - Beijing China 	caddr_t mem_ptr0, mem_ptr1 = NULL, mem_ptr2 = NULL;
8999a5557fdSlucy wang - Sun Microsystems - Beijing China 	unsigned long pci_len0;
9009a5557fdSlucy wang - Sun Microsystems - Beijing China 	unsigned long first_page_group_start, first_page_group_end;
9019a5557fdSlucy wang - Sun Microsystems - Beijing China 
9029a5557fdSlucy wang - Sun Microsystems - Beijing China 	off_t regsize, dbsize = UNM_DB_MAPSIZE_BYTES;
9039a5557fdSlucy wang - Sun Microsystems - Beijing China 	dev_info_t *dip = adapter->dip;
9049a5557fdSlucy wang - Sun Microsystems - Beijing China 
9059a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.qdr_sn_window = adapter->ahw.ddr_mn_window = -1;
9069a5557fdSlucy wang - Sun Microsystems - Beijing China 
9079a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* map register space */
9089a5557fdSlucy wang - Sun Microsystems - Beijing China 
9099a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_dev_regsize(dip, 1, &regsize);
9109a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
9119a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: failed to read reg size for bar0\n",
9129a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
9139a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9149a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
9159a5557fdSlucy wang - Sun Microsystems - Beijing China 
9169a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_regs_map_setup(dip, 1, &reg_base, 0,
9179a5557fdSlucy wang - Sun Microsystems - Beijing China 	    regsize, &unm_dev_attr, &adapter->regs_handle);
9189a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
9199a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: failed to map registers\n",
9209a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
9219a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9229a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
9239a5557fdSlucy wang - Sun Microsystems - Beijing China 
9249a5557fdSlucy wang - Sun Microsystems - Beijing China 	mem_ptr0 = reg_base;
9259a5557fdSlucy wang - Sun Microsystems - Beijing China 
9269a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (regsize == UNM_PCI_128MB_SIZE) {
9279a5557fdSlucy wang - Sun Microsystems - Beijing China 		pci_len0 = FIRST_PAGE_GROUP_SIZE;
9289a5557fdSlucy wang - Sun Microsystems - Beijing China 		mem_ptr1 = mem_ptr0 + SECOND_PAGE_GROUP_START;
9299a5557fdSlucy wang - Sun Microsystems - Beijing China 		mem_ptr2 = mem_ptr0 + THIRD_PAGE_GROUP_START;
9309a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_start = FIRST_PAGE_GROUP_START;
9319a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_end   = FIRST_PAGE_GROUP_END;
9329a5557fdSlucy wang - Sun Microsystems - Beijing China 		vector128M(adapter);
9339a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (regsize == UNM_PCI_32MB_SIZE) {
9349a5557fdSlucy wang - Sun Microsystems - Beijing China 		pci_len0 = 0;
9359a5557fdSlucy wang - Sun Microsystems - Beijing China 		mem_ptr1 = mem_ptr0;
9369a5557fdSlucy wang - Sun Microsystems - Beijing China 		mem_ptr2 = mem_ptr0 +
9379a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START);
9389a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_start = 0;
9399a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_end   = 0;
9409a5557fdSlucy wang - Sun Microsystems - Beijing China 		vector128M(adapter);
9419a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (regsize == UNM_PCI_2MB_SIZE) {
9429a5557fdSlucy wang - Sun Microsystems - Beijing China 		pci_len0 = UNM_PCI_2MB_SIZE;
9439a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_start = 0;
9449a5557fdSlucy wang - Sun Microsystems - Beijing China 		first_page_group_end = 0;
9459a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ahw.ddr_mn_window = adapter->ahw.qdr_sn_window = 0;
9469a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
9479a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (adapter->ahw.pci_func * 0x20);
9489a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->ahw.pci_func < 4)
9499a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
9509a5557fdSlucy wang - Sun Microsystems - Beijing China 			    (adapter->ahw.pci_func * 0x20);
9519a5557fdSlucy wang - Sun Microsystems - Beijing China 		else
9529a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
9539a5557fdSlucy wang - Sun Microsystems - Beijing China 			    0xA0 + ((adapter->ahw.pci_func - 4) * 0x10);
9549a5557fdSlucy wang - Sun Microsystems - Beijing China 		vector2M(adapter);
9559a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
9569a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: invalid pci regs map size %ld\n",
9579a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, regsize);
9589a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_regs_map_free(&adapter->regs_handle);
9599a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9609a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
9619a5557fdSlucy wang - Sun Microsystems - Beijing China 
9629a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_base0  = (unsigned long)mem_ptr0;
9639a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_len0   = pci_len0;
9649a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_base1  = (unsigned long)mem_ptr1;
9659a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_len1   = SECOND_PAGE_GROUP_SIZE;
9669a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_base2  = (unsigned long)mem_ptr2;
9679a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.pci_len2   = THIRD_PAGE_GROUP_SIZE;
9689a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.crb_base   =
9699a5557fdSlucy wang - Sun Microsystems - Beijing China 	    PCI_OFFSET_SECOND_RANGE(adapter, UNM_PCI_CRBSPACE);
9709a5557fdSlucy wang - Sun Microsystems - Beijing China 
9719a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.first_page_group_start = first_page_group_start;
9729a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.first_page_group_end   = first_page_group_end;
9739a5557fdSlucy wang - Sun Microsystems - Beijing China 
9749a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* map doorbell */
9759a5557fdSlucy wang - Sun Microsystems - Beijing China 
9769a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_regs_map_setup(dip, 2, &db_base, 0,
9779a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dbsize, &unm_dev_attr, &adapter->db_handle);
9789a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
9799a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: failed to map doorbell\n",
9809a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
9819a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_regs_map_free(&adapter->regs_handle);
9829a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
9839a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
9849a5557fdSlucy wang - Sun Microsystems - Beijing China 
9859a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.db_base   = (unsigned long)db_base;
9869a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.db_len    = dbsize;
9879a5557fdSlucy wang - Sun Microsystems - Beijing China 
9889a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
9899a5557fdSlucy wang - Sun Microsystems - Beijing China }
9909a5557fdSlucy wang - Sun Microsystems - Beijing China 
9919a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unm_initialize_intr(unm_adapter * adapter)9929a5557fdSlucy wang - Sun Microsystems - Beijing China unm_initialize_intr(unm_adapter *adapter)
9939a5557fdSlucy wang - Sun Microsystems - Beijing China {
9949a5557fdSlucy wang - Sun Microsystems - Beijing China 
9959a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		ret;
9969a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		type, count, avail, actual;
9979a5557fdSlucy wang - Sun Microsystems - Beijing China 
9989a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_get_supported_types(adapter->dip, &type);
9999a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
10009a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: ddi_intr_get_supported_types() "
10019a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "failed\n", adapter->name, adapter->instance);
10029a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10039a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10049a5557fdSlucy wang - Sun Microsystems - Beijing China 
10059a5557fdSlucy wang - Sun Microsystems - Beijing China 	type = DDI_INTR_TYPE_MSI;
10069a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
10079a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((ret == DDI_SUCCESS) && (count > 0))
10089a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto found_msi;
10099a5557fdSlucy wang - Sun Microsystems - Beijing China 
10109a5557fdSlucy wang - Sun Microsystems - Beijing China 	type = DDI_INTR_TYPE_FIXED;
10119a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
10129a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((ret != DDI_SUCCESS) || (count == 0)) {
10139a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN,
10149a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "ddi_intr_get_nintrs() failure ret=%d\n", ret);
10159a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10169a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10179a5557fdSlucy wang - Sun Microsystems - Beijing China 
10189a5557fdSlucy wang - Sun Microsystems - Beijing China found_msi:
10199a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->intr_type = type;
10209a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->flags &= ~(UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED);
10219a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (type == DDI_INTR_TYPE_MSI)
10229a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->flags |= UNM_NIC_MSI_ENABLED;
10239a5557fdSlucy wang - Sun Microsystems - Beijing China 
10249a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Get number of available interrupts */
10259a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_get_navail(adapter->dip, type, &avail);
10269a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
10279a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "ddi_intr_get_navail() failure, ret=%d\n",
10289a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ret);
10299a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10309a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10319a5557fdSlucy wang - Sun Microsystems - Beijing China 
10329a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_alloc(adapter->dip, &adapter->intr_handle,
10339a5557fdSlucy wang - Sun Microsystems - Beijing China 	    type, 0, 1, &actual, DDI_INTR_ALLOC_NORMAL);
10349a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
10359a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "ddi_intr_alloc() failure: %d\n", ret);
10369a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10379a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10389a5557fdSlucy wang - Sun Microsystems - Beijing China 
10399a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_get_pri(adapter->intr_handle, &adapter->intr_pri);
10409a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
10419a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "ddi_intr_get_pri() failure: %d\n", ret);
10429a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10439a5557fdSlucy wang - Sun Microsystems - Beijing China 
10449a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Call ddi_intr_add_handler() */
10459a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = ddi_intr_add_handler(adapter->intr_handle, unm_intr,
10469a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (caddr_t)adapter, NULL);
10479a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
10489a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: ddi_intr_add_handler() failure\n",
10499a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
10509a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_free(adapter->intr_handle);
10519a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
10529a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
10539a5557fdSlucy wang - Sun Microsystems - Beijing China 
10549a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Add softintr if required */
10559a5557fdSlucy wang - Sun Microsystems - Beijing China 
10569a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
10579a5557fdSlucy wang - Sun Microsystems - Beijing China 
10589a5557fdSlucy wang - Sun Microsystems - Beijing China }
10599a5557fdSlucy wang - Sun Microsystems - Beijing China 
10609a5557fdSlucy wang - Sun Microsystems - Beijing China void
unm_destroy_intr(unm_adapter * adapter)10619a5557fdSlucy wang - Sun Microsystems - Beijing China unm_destroy_intr(unm_adapter *adapter)
10629a5557fdSlucy wang - Sun Microsystems - Beijing China {
10639a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* disable interrupt */
10649a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
10659a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_block_disable(&adapter->intr_handle, 1);
10669a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
10679a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_disable(adapter->intr_handle);
10689a5557fdSlucy wang - Sun Microsystems - Beijing China 
10699a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_intr_remove_handler(adapter->intr_handle);
10709a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_intr_free(adapter->intr_handle);
10719a5557fdSlucy wang - Sun Microsystems - Beijing China 
10729a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Remove the software intr handler */
10739a5557fdSlucy wang - Sun Microsystems - Beijing China }
10749a5557fdSlucy wang - Sun Microsystems - Beijing China 
10759a5557fdSlucy wang - Sun Microsystems - Beijing China static void
netxen_set_port_mode(unm_adapter * adapter)10769a5557fdSlucy wang - Sun Microsystems - Beijing China netxen_set_port_mode(unm_adapter *adapter)
10779a5557fdSlucy wang - Sun Microsystems - Beijing China {
10789a5557fdSlucy wang - Sun Microsystems - Beijing China 	static int	wol_port_mode = UNM_PORT_MODE_AUTO_NEG_1G;
10799a5557fdSlucy wang - Sun Microsystems - Beijing China 	static int	port_mode = UNM_PORT_MODE_AUTO_NEG;
10809a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		btype = adapter->ahw.boardcfg.board_type, data = 0;
10819a5557fdSlucy wang - Sun Microsystems - Beijing China 
10829a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (btype == UNM_BRDTYPE_P3_HMEZ || btype == UNM_BRDTYPE_P3_XG_LOM) {
10839a5557fdSlucy wang - Sun Microsystems - Beijing China 		data = port_mode;	/* set to port_mode normally */
10849a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((port_mode != UNM_PORT_MODE_802_3_AP) &&
10859a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (port_mode != UNM_PORT_MODE_XG) &&
10869a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
10879a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
10889a5557fdSlucy wang - Sun Microsystems - Beijing China 			data = UNM_PORT_MODE_AUTO_NEG;
10899a5557fdSlucy wang - Sun Microsystems - Beijing China 
10909a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter, UNM_PORT_MODE_ADDR,
10919a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &data, 4);
10929a5557fdSlucy wang - Sun Microsystems - Beijing China 
10939a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((wol_port_mode != UNM_PORT_MODE_802_3_AP) &&
10949a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (wol_port_mode != UNM_PORT_MODE_XG) &&
10959a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
10969a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
10979a5557fdSlucy wang - Sun Microsystems - Beijing China 			wol_port_mode = UNM_PORT_MODE_AUTO_NEG;
10989a5557fdSlucy wang - Sun Microsystems - Beijing China 
10999a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter, UNM_WOL_PORT_MODE,
11009a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &wol_port_mode, 4);
11019a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
11029a5557fdSlucy wang - Sun Microsystems - Beijing China }
11039a5557fdSlucy wang - Sun Microsystems - Beijing China 
11049a5557fdSlucy wang - Sun Microsystems - Beijing China static void
netxen_pcie_strap_init(unm_adapter * adapter)11059a5557fdSlucy wang - Sun Microsystems - Beijing China netxen_pcie_strap_init(unm_adapter *adapter)
11069a5557fdSlucy wang - Sun Microsystems - Beijing China {
11079a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_acc_handle_t	pcihdl = adapter->pci_cfg_handle;
11089a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32			chicken, control, c8c9value = 0xF1000;
11099a5557fdSlucy wang - Sun Microsystems - Beijing China 
11109a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
11119a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &chicken, 4);
11129a5557fdSlucy wang - Sun Microsystems - Beijing China 
11139a5557fdSlucy wang - Sun Microsystems - Beijing China 	chicken &= 0xFCFFFFFF;		/* clear chicken3 25:24 */
11149a5557fdSlucy wang - Sun Microsystems - Beijing China 	control = pci_config_get32(pcihdl, 0xD0);
11159a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((control & 0x000F0000) != 0x00020000)	/* is it gen1? */
11169a5557fdSlucy wang - Sun Microsystems - Beijing China 		chicken |= 0x01000000;
11179a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
11189a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &chicken, 4);
11199a5557fdSlucy wang - Sun Microsystems - Beijing China 	control = pci_config_get32(pcihdl, 0xC8);
11209a5557fdSlucy wang - Sun Microsystems - Beijing China 	control = pci_config_get32(pcihdl, 0xC8);
11219a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_config_put32(pcihdl, 0xC8, c8c9value);
11229a5557fdSlucy wang - Sun Microsystems - Beijing China }
11239a5557fdSlucy wang - Sun Microsystems - Beijing China 
11249a5557fdSlucy wang - Sun Microsystems - Beijing China static int
netxen_read_mac_addr(unm_adapter * adapter)11259a5557fdSlucy wang - Sun Microsystems - Beijing China netxen_read_mac_addr(unm_adapter *adapter)
11269a5557fdSlucy wang - Sun Microsystems - Beijing China {
1127dda0720aSjing xiong ERI-SUN 	u64		mac_addr[8 + 1];
11289a5557fdSlucy wang - Sun Microsystems - Beijing China 	unsigned char	*p;
11299a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		i;
11309a5557fdSlucy wang - Sun Microsystems - Beijing China 
11319a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (get_flash_mac_addr(adapter, mac_addr) != 0)
11329a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (-1);
11339a5557fdSlucy wang - Sun Microsystems - Beijing China 
11349a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
11359a5557fdSlucy wang - Sun Microsystems - Beijing China 		p = (unsigned char *)&mac_addr[adapter->ahw.pci_func];
11369a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
11379a5557fdSlucy wang - Sun Microsystems - Beijing China 		p = (unsigned char *)&mac_addr[adapter->portnum];
11389a5557fdSlucy wang - Sun Microsystems - Beijing China 
11399a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = 0; i < 6; i++)
11409a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->mac_addr[i] = p[5 - i];
11419a5557fdSlucy wang - Sun Microsystems - Beijing China 
11429a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0)
11439a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (-1);
11449a5557fdSlucy wang - Sun Microsystems - Beijing China 
11459a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
11469a5557fdSlucy wang - Sun Microsystems - Beijing China }
11479a5557fdSlucy wang - Sun Microsystems - Beijing China 
11489a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unmattach(dev_info_t * dip,ddi_attach_cmd_t cmd)11499a5557fdSlucy wang - Sun Microsystems - Beijing China unmattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
11509a5557fdSlucy wang - Sun Microsystems - Beijing China {
11519a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter			*adapter;
11529a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				i, first_driver = 0;
1153dda0720aSjing xiong ERI-SUN 	int				ret, temp;
11549a5557fdSlucy wang - Sun Microsystems - Beijing China 
11559a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (cmd) {
11569a5557fdSlucy wang - Sun Microsystems - Beijing China 	case DDI_ATTACH:
11579a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
11589a5557fdSlucy wang - Sun Microsystems - Beijing China 	case DDI_RESUME:
11599a5557fdSlucy wang - Sun Microsystems - Beijing China 	case DDI_PM_RESUME:
11609a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
11619a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
11629a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
11639a5557fdSlucy wang - Sun Microsystems - Beijing China 
11649a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter = kmem_zalloc(sizeof (unm_adapter), KM_SLEEP);
11659a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->dip = dip;
11669a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_set_driver_private(dip, adapter);
11679a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->instance = ddi_get_instance(dip);
11689a5557fdSlucy wang - Sun Microsystems - Beijing China 
11699a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->name = ddi_driver_name(dip);
11709a5557fdSlucy wang - Sun Microsystems - Beijing China 
11719a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = pci_config_setup(dip, &adapter->pci_cfg_handle);
11729a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
11739a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: pci_config_setup failed\n",
11749a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
11759a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto attach_setup_err;
11769a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
11779a5557fdSlucy wang - Sun Microsystems - Beijing China 
11789a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = unm_pci_cfg_init(adapter);
11799a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS)
11809a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto attach_err;
11819a5557fdSlucy wang - Sun Microsystems - Beijing China 
11829a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = unm_pci_map_setup(adapter);
11839a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS)
11849a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto attach_err;
11859a5557fdSlucy wang - Sun Microsystems - Beijing China 
11869a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_initialize_intr(adapter) != DDI_SUCCESS)
11879a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto attach_unmap_regs;
11889a5557fdSlucy wang - Sun Microsystems - Beijing China 
11899a5557fdSlucy wang - Sun Microsystems - Beijing China 	rw_init(&adapter->adapter_lock, NULL,
11909a5557fdSlucy wang - Sun Microsystems - Beijing China 	    RW_DRIVER, DDI_INTR_PRI(adapter->intr_pri));
11919a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_init(&adapter->tx_lock, NULL,
11929a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
11939a5557fdSlucy wang - Sun Microsystems - Beijing China 	mutex_init(&adapter->lock, NULL,
11949a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
11959a5557fdSlucy wang - Sun Microsystems - Beijing China 
11969a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->portnum = (int8_t)adapter->ahw.pci_func;
11979a5557fdSlucy wang - Sun Microsystems - Beijing China 
11989a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
11999a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Set the CRB window to invalid. If any register in window 0 is
12009a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * accessed it should set window to 0 and then reset it to 1.
12019a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
12029a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->curr_window = 255;
12039a5557fdSlucy wang - Sun Microsystems - Beijing China 
12049a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->fw_major = adapter->unm_nic_pci_read_normalize(adapter,
12059a5557fdSlucy wang - Sun Microsystems - Beijing China 	    UNM_FW_VERSION_MAJOR);
12069a5557fdSlucy wang - Sun Microsystems - Beijing China 
12079a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->fw_major < 4)
12089a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->max_rds_rings = 3;
12099a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
12109a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->max_rds_rings = 2;
12119a5557fdSlucy wang - Sun Microsystems - Beijing China 
12129a5557fdSlucy wang - Sun Microsystems - Beijing China 	STRUCT_COPY(adapter->gc_dma_attr_desc, unm_dma_attr_desc);
12139a5557fdSlucy wang - Sun Microsystems - Beijing China 	STRUCT_COPY(adapter->gc_attr_desc, unm_buf_attr);
12149a5557fdSlucy wang - Sun Microsystems - Beijing China 
12159a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = unm_nic_get_board_info(adapter);
12169a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
12179a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: error reading board config\n",
12189a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
12199a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto attach_destroy_intr;
12209a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
12219a5557fdSlucy wang - Sun Microsystems - Beijing China 
12229a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Mezz cards have PCI function 0, 2, 3 enabled */
12239a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (adapter->ahw.boardcfg.board_type) {
12249a5557fdSlucy wang - Sun Microsystems - Beijing China 	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
12259a5557fdSlucy wang - Sun Microsystems - Beijing China 	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
12269a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->ahw.pci_func >= 2) {
12279a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->portnum = adapter->ahw.pci_func - 2;
12289a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
12299a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
12309a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
12319a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
12329a5557fdSlucy wang - Sun Microsystems - Beijing China 
12339a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
12349a5557fdSlucy wang - Sun Microsystems - Beijing China 		temp = UNM_CRB_READ_VAL_ADAPTER(UNM_MIU_MN_CONTROL, adapter);
12359a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ahw.cut_through = NX_IS_SYSTEM_CUT_THROUGH(temp);
12369a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->ahw.pci_func == 0)
12379a5557fdSlucy wang - Sun Microsystems - Beijing China 			first_driver = 1;
12389a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
12399a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->portnum == 0)
12409a5557fdSlucy wang - Sun Microsystems - Beijing China 			first_driver = 1;
12419a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
12429a5557fdSlucy wang - Sun Microsystems - Beijing China 
12439a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_check_options(adapter);
12449a5557fdSlucy wang - Sun Microsystems - Beijing China 
12459a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (first_driver) {
12469a5557fdSlucy wang - Sun Microsystems - Beijing China 		int first_boot = adapter->unm_nic_pci_read_normalize(adapter,
12479a5557fdSlucy wang - Sun Microsystems - Beijing China 		    UNM_CAM_RAM(0x1fc));
12489a5557fdSlucy wang - Sun Microsystems - Beijing China 
12499a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (check_hw_init(adapter) != 0) {
12509a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_WARN, "%s%d: Error in HW init sequence\n",
12519a5557fdSlucy wang - Sun Microsystems - Beijing China 			    adapter->name, adapter->instance);
12529a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto attach_destroy_intr;
12539a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
12549a5557fdSlucy wang - Sun Microsystems - Beijing China 
12559a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
12569a5557fdSlucy wang - Sun Microsystems - Beijing China 			netxen_set_port_mode(adapter);
12579a5557fdSlucy wang - Sun Microsystems - Beijing China 
12589a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (first_boot != 0x55555555) {
12599a5557fdSlucy wang - Sun Microsystems - Beijing China 			temp = 0;
12609a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE,
12619a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &temp, 4);
12629a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (pinit_from_rom(adapter, 0) != 0)
12639a5557fdSlucy wang - Sun Microsystems - Beijing China 				goto attach_destroy_intr;
12649a5557fdSlucy wang - Sun Microsystems - Beijing China 
12659a5557fdSlucy wang - Sun Microsystems - Beijing China 			drv_usecwait(500);
12669a5557fdSlucy wang - Sun Microsystems - Beijing China 
12679a5557fdSlucy wang - Sun Microsystems - Beijing China 			ret = load_from_flash(adapter);
12689a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (ret != DDI_SUCCESS)
12699a5557fdSlucy wang - Sun Microsystems - Beijing China 				goto attach_destroy_intr;
12709a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
12719a5557fdSlucy wang - Sun Microsystems - Beijing China 
12729a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (ret = unm_initialize_dummy_dma(adapter))
12739a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto attach_destroy_intr;
12749a5557fdSlucy wang - Sun Microsystems - Beijing China 
12759a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
12769a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * Tell the hardware our version number.
12779a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
12789a5557fdSlucy wang - Sun Microsystems - Beijing China 		i = (_UNM_NIC_MAJOR << 16) |
12799a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ((_UNM_NIC_MINOR << 8)) | (_UNM_NIC_SUBVERSION);
12809a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter, CRB_DRIVER_VERSION,
12819a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &i, 4);
12829a5557fdSlucy wang - Sun Microsystems - Beijing China 
12839a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Unlock the HW, prompting the boot sequence */
12849a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((first_boot == 0x55555555) &&
12859a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (NX_IS_REVISION_P2(adapter->ahw.revision_id)))
12869a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_pci_write_normalize(adapter,
12879a5557fdSlucy wang - Sun Microsystems - Beijing China 			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
12889a5557fdSlucy wang - Sun Microsystems - Beijing China 
12899a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Handshake with the card before we register the devices. */
12909a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (phantom_init(adapter, 0) != DDI_SUCCESS)
12919a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto attach_destroy_intr;
12929a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
12939a5557fdSlucy wang - Sun Microsystems - Beijing China 
12949a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
12959a5557fdSlucy wang - Sun Microsystems - Beijing China 		netxen_pcie_strap_init(adapter);
12969a5557fdSlucy wang - Sun Microsystems - Beijing China 
12979a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
12989a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * See if the firmware gave us a virtual-physical port mapping.
12999a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
13009a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->physical_port = adapter->portnum;
13019a5557fdSlucy wang - Sun Microsystems - Beijing China 	i = adapter->unm_nic_pci_read_normalize(adapter,
13029a5557fdSlucy wang - Sun Microsystems - Beijing China 	    CRB_V2P(adapter->portnum));
13039a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (i != 0x55555555)
13049a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->physical_port = (uint16_t)i;
13059a5557fdSlucy wang - Sun Microsystems - Beijing China 
13069a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ahw.linkup = 0;
13079a5557fdSlucy wang - Sun Microsystems - Beijing China 
13089a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (receive_peg_ready(adapter)) {
13099a5557fdSlucy wang - Sun Microsystems - Beijing China 		ret = -EIO;
1310dda0720aSjing xiong ERI-SUN 		goto free_dummy_dma;
13119a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
13129a5557fdSlucy wang - Sun Microsystems - Beijing China 
13139a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (netxen_read_mac_addr(adapter))
13149a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Failed to read MAC addr\n",
13159a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
13169a5557fdSlucy wang - Sun Microsystems - Beijing China 
13179a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_flash_print(adapter);
13189a5557fdSlucy wang - Sun Microsystems - Beijing China 
13199a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (verbmsg != 0) {
13209a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (adapter->ahw.board_type) {
13219a5557fdSlucy wang - Sun Microsystems - Beijing China 		case UNM_NIC_GBE:
13229a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_NOTE, "%s: QUAD GbE port %d initialized\n",
13239a5557fdSlucy wang - Sun Microsystems - Beijing China 			    unm_nic_driver_name, adapter->portnum);
13249a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
13259a5557fdSlucy wang - Sun Microsystems - Beijing China 
13269a5557fdSlucy wang - Sun Microsystems - Beijing China 		case UNM_NIC_XGBE:
13279a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_NOTE, "%s: XGbE port %d initialized\n",
13289a5557fdSlucy wang - Sun Microsystems - Beijing China 			    unm_nic_driver_name, adapter->portnum);
13299a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
13309a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
13319a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
13329a5557fdSlucy wang - Sun Microsystems - Beijing China 
13339a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = unm_register_mac(adapter);
13349a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
13359a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_NOTE, "%s%d: Mac registration error\n",
13369a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
1337dda0720aSjing xiong ERI-SUN 		goto free_dummy_dma;
13389a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
13399a5557fdSlucy wang - Sun Microsystems - Beijing China 
13409a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
13419a5557fdSlucy wang - Sun Microsystems - Beijing China 
1342dda0720aSjing xiong ERI-SUN free_dummy_dma:
1343dda0720aSjing xiong ERI-SUN 	if (first_driver)
13449a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dummy_dma(adapter);
13459a5557fdSlucy wang - Sun Microsystems - Beijing China attach_destroy_intr:
13469a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_destroy_intr(adapter);
13479a5557fdSlucy wang - Sun Microsystems - Beijing China attach_unmap_regs:
13489a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_regs_map_free(&(adapter->regs_handle));
13499a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_regs_map_free(&(adapter->db_handle));
13509a5557fdSlucy wang - Sun Microsystems - Beijing China attach_err:
13519a5557fdSlucy wang - Sun Microsystems - Beijing China 	pci_config_teardown(&adapter->pci_cfg_handle);
13529a5557fdSlucy wang - Sun Microsystems - Beijing China attach_setup_err:
13539a5557fdSlucy wang - Sun Microsystems - Beijing China 	kmem_free(adapter, sizeof (unm_adapter));
13549a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ret);
13559a5557fdSlucy wang - Sun Microsystems - Beijing China }
13569a5557fdSlucy wang - Sun Microsystems - Beijing China 
13579a5557fdSlucy wang - Sun Microsystems - Beijing China static int
unmdetach(dev_info_t * dip,ddi_detach_cmd_t cmd)13589a5557fdSlucy wang - Sun Microsystems - Beijing China unmdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
13599a5557fdSlucy wang - Sun Microsystems - Beijing China {
13609a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter  *adapter = (unm_adapter *)ddi_get_driver_private(dip);
13619a5557fdSlucy wang - Sun Microsystems - Beijing China 
13629a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter == NULL)
1363*15c07adcSJohn Levon 		return (DDI_FAILURE);
13649a5557fdSlucy wang - Sun Microsystems - Beijing China 
13659a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (cmd) {
13669a5557fdSlucy wang - Sun Microsystems - Beijing China 	case DDI_DETACH:
13679a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_fini_kstats(adapter);
13689a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->kstats[0] = NULL;
13699a5557fdSlucy wang - Sun Microsystems - Beijing China 
13709a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->pci_cfg_handle != NULL)
1371dda0720aSjing xiong ERI-SUN 			pci_config_teardown(&adapter->pci_cfg_handle);
13729a5557fdSlucy wang - Sun Microsystems - Beijing China 
13739a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nd_cleanup(adapter);
13749a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_remove(adapter);
13759a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_SUCCESS);
13769a5557fdSlucy wang - Sun Microsystems - Beijing China 
13779a5557fdSlucy wang - Sun Microsystems - Beijing China 	case DDI_SUSPEND:
13789a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (unm_nic_suspend(adapter));
13799a5557fdSlucy wang - Sun Microsystems - Beijing China 
13809a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
13819a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
13829a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
13839a5557fdSlucy wang - Sun Microsystems - Beijing China 
13849a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_FAILURE);
13859a5557fdSlucy wang - Sun Microsystems - Beijing China }
13869a5557fdSlucy wang - Sun Microsystems - Beijing China 
1387dda0720aSjing xiong ERI-SUN int
create_rxtx_rings(unm_adapter * adapter)1388dda0720aSjing xiong ERI-SUN create_rxtx_rings(unm_adapter *adapter)
1389dda0720aSjing xiong ERI-SUN {
1390dda0720aSjing xiong ERI-SUN 	unm_recv_context_t	*recv_ctx;
1391dda0720aSjing xiong ERI-SUN 	unm_rcv_desc_ctx_t	*rcv_desc;
1392dda0720aSjing xiong ERI-SUN 	int			i, ring;
1393dda0720aSjing xiong ERI-SUN 
1394dda0720aSjing xiong ERI-SUN 	adapter->cmd_buf_arr = (struct unm_cmd_buffer *)kmem_zalloc(
1395dda0720aSjing xiong ERI-SUN 	    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount,
1396dda0720aSjing xiong ERI-SUN 	    KM_SLEEP);
1397dda0720aSjing xiong ERI-SUN 
1398dda0720aSjing xiong ERI-SUN 	for (i = 0; i < MAX_RCV_CTX; ++i) {
1399dda0720aSjing xiong ERI-SUN 		recv_ctx = &adapter->recv_ctx[i];
1400dda0720aSjing xiong ERI-SUN 
1401dda0720aSjing xiong ERI-SUN 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1402dda0720aSjing xiong ERI-SUN 			rcv_desc = &recv_ctx->rcv_desc[ring];
1403dda0720aSjing xiong ERI-SUN 			if (unm_create_rx_ring(adapter, rcv_desc) !=
1404dda0720aSjing xiong ERI-SUN 			    DDI_SUCCESS)
1405dda0720aSjing xiong ERI-SUN 				goto attach_free_cmdbufs;
1406dda0720aSjing xiong ERI-SUN 		}
1407dda0720aSjing xiong ERI-SUN 	}
1408dda0720aSjing xiong ERI-SUN 
1409dda0720aSjing xiong ERI-SUN 	if (unm_alloc_tx_dmahdl(adapter) != DDI_SUCCESS)
1410dda0720aSjing xiong ERI-SUN 		goto attach_free_cmdbufs;
1411dda0720aSjing xiong ERI-SUN 
1412dda0720aSjing xiong ERI-SUN 	if (unm_alloc_tx_buffers(adapter) != DDI_SUCCESS)
1413dda0720aSjing xiong ERI-SUN 		goto attach_free_tx_dmahdl;
1414dda0720aSjing xiong ERI-SUN 
1415dda0720aSjing xiong ERI-SUN 	return (DDI_SUCCESS);
1416dda0720aSjing xiong ERI-SUN 
1417dda0720aSjing xiong ERI-SUN attach_free_tx_buffers:
1418dda0720aSjing xiong ERI-SUN 	unm_free_tx_buffers(adapter);
1419dda0720aSjing xiong ERI-SUN attach_free_tx_dmahdl:
1420dda0720aSjing xiong ERI-SUN 	unm_free_tx_dmahdl(adapter);
1421dda0720aSjing xiong ERI-SUN attach_free_cmdbufs:
1422dda0720aSjing xiong ERI-SUN 	kmem_free(adapter->cmd_buf_arr, sizeof (struct unm_cmd_buffer) *
1423dda0720aSjing xiong ERI-SUN 	    adapter->MaxTxDescCount);
1424dda0720aSjing xiong ERI-SUN 	for (i = 0; i < MAX_RCV_CTX; ++i) {
1425dda0720aSjing xiong ERI-SUN 		recv_ctx = &adapter->recv_ctx[i];
1426dda0720aSjing xiong ERI-SUN 
1427dda0720aSjing xiong ERI-SUN 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1428dda0720aSjing xiong ERI-SUN 			rcv_desc = &recv_ctx->rcv_desc[ring];
1429dda0720aSjing xiong ERI-SUN 			if (rcv_desc->rx_buf_pool != NULL)
1430dda0720aSjing xiong ERI-SUN 				unm_destroy_rx_ring(rcv_desc);
1431dda0720aSjing xiong ERI-SUN 		}
1432dda0720aSjing xiong ERI-SUN 	}
1433dda0720aSjing xiong ERI-SUN 	return (DDI_FAILURE);
1434dda0720aSjing xiong ERI-SUN }
1435dda0720aSjing xiong ERI-SUN 
1436dda0720aSjing xiong ERI-SUN void
destroy_rxtx_rings(unm_adapter * adapter)1437dda0720aSjing xiong ERI-SUN destroy_rxtx_rings(unm_adapter *adapter)
1438dda0720aSjing xiong ERI-SUN {
1439dda0720aSjing xiong ERI-SUN 	unm_recv_context_t	*recv_ctx;
1440dda0720aSjing xiong ERI-SUN 	unm_rcv_desc_ctx_t	*rcv_desc;
1441dda0720aSjing xiong ERI-SUN 	int			ctx, ring;
1442dda0720aSjing xiong ERI-SUN 
1443dda0720aSjing xiong ERI-SUN 	unm_free_tx_buffers(adapter);
1444dda0720aSjing xiong ERI-SUN 	unm_free_tx_dmahdl(adapter);
1445dda0720aSjing xiong ERI-SUN 
1446dda0720aSjing xiong ERI-SUN 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
1447dda0720aSjing xiong ERI-SUN 		recv_ctx = &adapter->recv_ctx[ctx];
1448dda0720aSjing xiong ERI-SUN 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1449dda0720aSjing xiong ERI-SUN 			rcv_desc = &recv_ctx->rcv_desc[ring];
1450dda0720aSjing xiong ERI-SUN 			if (rcv_desc->rx_buf_pool != NULL)
1451dda0720aSjing xiong ERI-SUN 				unm_destroy_rx_ring(rcv_desc);
1452dda0720aSjing xiong ERI-SUN 		}
1453dda0720aSjing xiong ERI-SUN 	}
1454dda0720aSjing xiong ERI-SUN 
1455dda0720aSjing xiong ERI-SUN 	if (adapter->cmd_buf_arr != NULL)
1456dda0720aSjing xiong ERI-SUN 		kmem_free(adapter->cmd_buf_arr,
1457dda0720aSjing xiong ERI-SUN 		    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount);
1458dda0720aSjing xiong ERI-SUN }
1459dda0720aSjing xiong ERI-SUN 
14609a5557fdSlucy wang - Sun Microsystems - Beijing China #ifdef SOLARIS11
14619a5557fdSlucy wang - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
14629a5557fdSlucy wang - Sun Microsystems - Beijing China 	nodev, NULL, D_MP, NULL, NULL);
14639a5557fdSlucy wang - Sun Microsystems - Beijing China #else
14649a5557fdSlucy wang - Sun Microsystems - Beijing China DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
14659a5557fdSlucy wang - Sun Microsystems - Beijing China 	nodev, NULL, D_MP, NULL);
14669a5557fdSlucy wang - Sun Microsystems - Beijing China #endif
14679a5557fdSlucy wang - Sun Microsystems - Beijing China 
14689a5557fdSlucy wang - Sun Microsystems - Beijing China static struct modldrv modldrv = {
14699a5557fdSlucy wang - Sun Microsystems - Beijing China 	&mod_driverops,	/* Type of module.  This one is a driver */
14709a5557fdSlucy wang - Sun Microsystems - Beijing China 	ident,
14719a5557fdSlucy wang - Sun Microsystems - Beijing China 	&unm_ops,	/* driver ops */
14729a5557fdSlucy wang - Sun Microsystems - Beijing China };
14739a5557fdSlucy wang - Sun Microsystems - Beijing China 
14749a5557fdSlucy wang - Sun Microsystems - Beijing China static struct modlinkage modlinkage = {
14759a5557fdSlucy wang - Sun Microsystems - Beijing China 	MODREV_1,
14769a5557fdSlucy wang - Sun Microsystems - Beijing China 	(&modldrv),
14779a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL
14789a5557fdSlucy wang - Sun Microsystems - Beijing China };
14799a5557fdSlucy wang - Sun Microsystems - Beijing China 
14809a5557fdSlucy wang - Sun Microsystems - Beijing China 
14819a5557fdSlucy wang - Sun Microsystems - Beijing China int
_init(void)14829a5557fdSlucy wang - Sun Microsystems - Beijing China _init(void)
14839a5557fdSlucy wang - Sun Microsystems - Beijing China {
14849a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
14859a5557fdSlucy wang - Sun Microsystems - Beijing China 
14869a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_ops.devo_cb_ops->cb_str = NULL;
14879a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_init_ops(&unm_ops, "ntxn");
14889a5557fdSlucy wang - Sun Microsystems - Beijing China 
14899a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = mod_install(&modlinkage);
14909a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != DDI_SUCCESS) {
14919a5557fdSlucy wang - Sun Microsystems - Beijing China 		mac_fini_ops(&unm_ops);
14929a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "ntxn: mod_install failed\n");
14939a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
14949a5557fdSlucy wang - Sun Microsystems - Beijing China 
14959a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ret);
14969a5557fdSlucy wang - Sun Microsystems - Beijing China }
14979a5557fdSlucy wang - Sun Microsystems - Beijing China 
14989a5557fdSlucy wang - Sun Microsystems - Beijing China 
14999a5557fdSlucy wang - Sun Microsystems - Beijing China int
_fini(void)15009a5557fdSlucy wang - Sun Microsystems - Beijing China _fini(void)
15019a5557fdSlucy wang - Sun Microsystems - Beijing China {
15029a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
15039a5557fdSlucy wang - Sun Microsystems - Beijing China 
15049a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = mod_remove(&modlinkage);
15059a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret == DDI_SUCCESS)
15069a5557fdSlucy wang - Sun Microsystems - Beijing China 		mac_fini_ops(&unm_ops);
15079a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ret);
15089a5557fdSlucy wang - Sun Microsystems - Beijing China }
15099a5557fdSlucy wang - Sun Microsystems - Beijing China 
15109a5557fdSlucy wang - Sun Microsystems - Beijing China int
_info(struct modinfo * modinfop)15119a5557fdSlucy wang - Sun Microsystems - Beijing China _info(struct modinfo *modinfop)
15129a5557fdSlucy wang - Sun Microsystems - Beijing China {
15139a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (mod_info(&modlinkage, modinfop));
15149a5557fdSlucy wang - Sun Microsystems - Beijing China }
1515