144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22a3c5bd6dSspeer * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish /* 2944961713Sgirish * SunOs MT STREAMS NIU/Neptune 10Gb Ethernet Device Driver. 3044961713Sgirish */ 3144961713Sgirish #include <sys/nxge/nxge_impl.h> 3214ea4bb7Ssd #include <sys/pcie.h> 3344961713Sgirish 3444961713Sgirish uint32_t nxge_use_partition = 0; /* debug partition flag */ 3544961713Sgirish uint32_t nxge_dma_obp_props_only = 1; /* use obp published props */ 3644961713Sgirish uint32_t nxge_use_rdc_intr = 1; /* debug to assign rdc intr */ 3744961713Sgirish /* 38ec090658Sml * PSARC/2007/453 MSI-X interrupt limit override 39ec090658Sml * (This PSARC case is limited to MSI-X vectors 40ec090658Sml * and SPARC platforms only). 4144961713Sgirish */ 42ec090658Sml #if defined(_BIG_ENDIAN) 43ec090658Sml uint32_t nxge_msi_enable = 2; 44ec090658Sml #else 45ec090658Sml uint32_t nxge_msi_enable = 1; 46ec090658Sml #endif 4744961713Sgirish 4844961713Sgirish /* 4944961713Sgirish * Globals: tunable parameters (/etc/system or adb) 5044961713Sgirish * 5144961713Sgirish */ 5244961713Sgirish uint32_t nxge_rbr_size = NXGE_RBR_RBB_DEFAULT; 5344961713Sgirish uint32_t nxge_rbr_spare_size = 0; 5444961713Sgirish uint32_t nxge_rcr_size = NXGE_RCR_DEFAULT; 5544961713Sgirish uint32_t nxge_tx_ring_size = NXGE_TX_RING_DEFAULT; 56b3a0105bSspeer boolean_t nxge_no_msg = B_TRUE; /* control message display */ 5744961713Sgirish uint32_t nxge_no_link_notify = 0; /* control DL_NOTIFY */ 5844961713Sgirish uint32_t nxge_bcopy_thresh = TX_BCOPY_MAX; 5944961713Sgirish uint32_t nxge_dvma_thresh = TX_FASTDVMA_MIN; 6044961713Sgirish uint32_t nxge_dma_stream_thresh = TX_STREAM_MIN; 6144961713Sgirish uint32_t nxge_jumbo_mtu = TX_JUMBO_MTU; 6244961713Sgirish boolean_t nxge_jumbo_enable = B_FALSE; 6344961713Sgirish uint16_t nxge_rcr_timeout = NXGE_RDC_RCR_TIMEOUT; 6444961713Sgirish uint16_t nxge_rcr_threshold = NXGE_RDC_RCR_THRESHOLD; 651f8914d5Sml nxge_tx_mode_t nxge_tx_scheme = NXGE_USE_SERIAL; 6644961713Sgirish 6744961713Sgirish /* 6844961713Sgirish * Debugging flags: 6944961713Sgirish * nxge_no_tx_lb : transmit load balancing 7044961713Sgirish * nxge_tx_lb_policy: 0 - TCP port (default) 7144961713Sgirish * 3 - DEST MAC 7244961713Sgirish */ 7344961713Sgirish uint32_t nxge_no_tx_lb = 0; 7444961713Sgirish uint32_t nxge_tx_lb_policy = NXGE_TX_LB_TCPUDP; 7544961713Sgirish 7644961713Sgirish /* 7744961713Sgirish * Add tunable to reduce the amount of time spent in the 7844961713Sgirish * ISR doing Rx Processing. 7944961713Sgirish */ 8044961713Sgirish uint32_t nxge_max_rx_pkts = 1024; 8144961713Sgirish 8244961713Sgirish /* 8344961713Sgirish * Tunables to manage the receive buffer blocks. 8444961713Sgirish * 8544961713Sgirish * nxge_rx_threshold_hi: copy all buffers. 8644961713Sgirish * nxge_rx_bcopy_size_type: receive buffer block size type. 8744961713Sgirish * nxge_rx_threshold_lo: copy only up to tunable block size type. 8844961713Sgirish */ 8944961713Sgirish nxge_rxbuf_threshold_t nxge_rx_threshold_hi = NXGE_RX_COPY_6; 9044961713Sgirish nxge_rxbuf_type_t nxge_rx_buf_size_type = RCR_PKTBUFSZ_0; 9144961713Sgirish nxge_rxbuf_threshold_t nxge_rx_threshold_lo = NXGE_RX_COPY_3; 9244961713Sgirish 9344961713Sgirish rtrace_t npi_rtracebuf; 9444961713Sgirish 9544961713Sgirish #if defined(sun4v) 9644961713Sgirish /* 9744961713Sgirish * Hypervisor N2/NIU services information. 9844961713Sgirish */ 9944961713Sgirish static hsvc_info_t niu_hsvc = { 10044961713Sgirish HSVC_REV_1, NULL, HSVC_GROUP_NIU, NIU_MAJOR_VER, 10144961713Sgirish NIU_MINOR_VER, "nxge" 10244961713Sgirish }; 10344961713Sgirish #endif 10444961713Sgirish 10544961713Sgirish /* 10644961713Sgirish * Function Prototypes 10744961713Sgirish */ 10844961713Sgirish static int nxge_attach(dev_info_t *, ddi_attach_cmd_t); 10944961713Sgirish static int nxge_detach(dev_info_t *, ddi_detach_cmd_t); 11044961713Sgirish static void nxge_unattach(p_nxge_t); 11144961713Sgirish 11244961713Sgirish #if NXGE_PROPERTY 11344961713Sgirish static void nxge_remove_hard_properties(p_nxge_t); 11444961713Sgirish #endif 11544961713Sgirish 11644961713Sgirish static nxge_status_t nxge_setup_system_dma_pages(p_nxge_t); 11744961713Sgirish 11844961713Sgirish static nxge_status_t nxge_setup_mutexes(p_nxge_t); 11944961713Sgirish static void nxge_destroy_mutexes(p_nxge_t); 12044961713Sgirish 12144961713Sgirish static nxge_status_t nxge_map_regs(p_nxge_t nxgep); 12244961713Sgirish static void nxge_unmap_regs(p_nxge_t nxgep); 12344961713Sgirish #ifdef NXGE_DEBUG 12444961713Sgirish static void nxge_test_map_regs(p_nxge_t nxgep); 12544961713Sgirish #endif 12644961713Sgirish 12744961713Sgirish static nxge_status_t nxge_add_intrs(p_nxge_t nxgep); 12844961713Sgirish static nxge_status_t nxge_add_soft_intrs(p_nxge_t nxgep); 12944961713Sgirish static void nxge_remove_intrs(p_nxge_t nxgep); 13044961713Sgirish static void nxge_remove_soft_intrs(p_nxge_t nxgep); 13144961713Sgirish 13244961713Sgirish static nxge_status_t nxge_add_intrs_adv(p_nxge_t nxgep); 13344961713Sgirish static nxge_status_t nxge_add_intrs_adv_type(p_nxge_t, uint32_t); 13444961713Sgirish static nxge_status_t nxge_add_intrs_adv_type_fix(p_nxge_t, uint32_t); 13544961713Sgirish static void nxge_intrs_enable(p_nxge_t nxgep); 13644961713Sgirish static void nxge_intrs_disable(p_nxge_t nxgep); 13744961713Sgirish 13844961713Sgirish static void nxge_suspend(p_nxge_t); 13944961713Sgirish static nxge_status_t nxge_resume(p_nxge_t); 14044961713Sgirish 14144961713Sgirish static nxge_status_t nxge_setup_dev(p_nxge_t); 14244961713Sgirish static void nxge_destroy_dev(p_nxge_t); 14344961713Sgirish 14444961713Sgirish static nxge_status_t nxge_alloc_mem_pool(p_nxge_t); 14544961713Sgirish static void nxge_free_mem_pool(p_nxge_t); 14644961713Sgirish 14744961713Sgirish static nxge_status_t nxge_alloc_rx_mem_pool(p_nxge_t); 14844961713Sgirish static void nxge_free_rx_mem_pool(p_nxge_t); 14944961713Sgirish 15044961713Sgirish static nxge_status_t nxge_alloc_tx_mem_pool(p_nxge_t); 15144961713Sgirish static void nxge_free_tx_mem_pool(p_nxge_t); 15244961713Sgirish 15344961713Sgirish static nxge_status_t nxge_dma_mem_alloc(p_nxge_t, dma_method_t, 15444961713Sgirish struct ddi_dma_attr *, 15544961713Sgirish size_t, ddi_device_acc_attr_t *, uint_t, 15644961713Sgirish p_nxge_dma_common_t); 15744961713Sgirish 15844961713Sgirish static void nxge_dma_mem_free(p_nxge_dma_common_t); 15944961713Sgirish 16044961713Sgirish static nxge_status_t nxge_alloc_rx_buf_dma(p_nxge_t, uint16_t, 16144961713Sgirish p_nxge_dma_common_t *, size_t, size_t, uint32_t *); 16244961713Sgirish static void nxge_free_rx_buf_dma(p_nxge_t, p_nxge_dma_common_t, uint32_t); 16344961713Sgirish 16444961713Sgirish static nxge_status_t nxge_alloc_rx_cntl_dma(p_nxge_t, uint16_t, 16544961713Sgirish p_nxge_dma_common_t *, size_t); 16644961713Sgirish static void nxge_free_rx_cntl_dma(p_nxge_t, p_nxge_dma_common_t); 16744961713Sgirish 16844961713Sgirish static nxge_status_t nxge_alloc_tx_buf_dma(p_nxge_t, uint16_t, 16944961713Sgirish p_nxge_dma_common_t *, size_t, size_t, uint32_t *); 17044961713Sgirish static void nxge_free_tx_buf_dma(p_nxge_t, p_nxge_dma_common_t, uint32_t); 17144961713Sgirish 17244961713Sgirish static nxge_status_t nxge_alloc_tx_cntl_dma(p_nxge_t, uint16_t, 17344961713Sgirish p_nxge_dma_common_t *, 17444961713Sgirish size_t); 17544961713Sgirish static void nxge_free_tx_cntl_dma(p_nxge_t, p_nxge_dma_common_t); 17644961713Sgirish 17744961713Sgirish static int nxge_init_common_dev(p_nxge_t); 17844961713Sgirish static void nxge_uninit_common_dev(p_nxge_t); 17944961713Sgirish 18044961713Sgirish /* 18144961713Sgirish * The next declarations are for the GLDv3 interface. 18244961713Sgirish */ 18344961713Sgirish static int nxge_m_start(void *); 18444961713Sgirish static void nxge_m_stop(void *); 18544961713Sgirish static int nxge_m_unicst(void *, const uint8_t *); 18644961713Sgirish static int nxge_m_multicst(void *, boolean_t, const uint8_t *); 18744961713Sgirish static int nxge_m_promisc(void *, boolean_t); 18844961713Sgirish static void nxge_m_ioctl(void *, queue_t *, mblk_t *); 18944961713Sgirish static void nxge_m_resources(void *); 19044961713Sgirish mblk_t *nxge_m_tx(void *arg, mblk_t *); 19144961713Sgirish static nxge_status_t nxge_mac_register(p_nxge_t); 19258324dfcSspeer static int nxge_altmac_set(p_nxge_t nxgep, uint8_t *mac_addr, 19358324dfcSspeer mac_addr_slot_t slot); 19458324dfcSspeer static void nxge_mmac_kstat_update(p_nxge_t nxgep, mac_addr_slot_t slot, 19558324dfcSspeer boolean_t factory); 19658324dfcSspeer static int nxge_m_mmac_add(void *arg, mac_multi_addr_t *maddr); 19758324dfcSspeer static int nxge_m_mmac_reserve(void *arg, mac_multi_addr_t *maddr); 19858324dfcSspeer static int nxge_m_mmac_remove(void *arg, mac_addr_slot_t slot); 19958324dfcSspeer static int nxge_m_mmac_modify(void *arg, mac_multi_addr_t *maddr); 20058324dfcSspeer static int nxge_m_mmac_get(void *arg, mac_multi_addr_t *maddr); 20144961713Sgirish 20244961713Sgirish #define NXGE_NEPTUNE_MAGIC 0x4E584745UL 20344961713Sgirish #define MAX_DUMP_SZ 256 20444961713Sgirish 20544961713Sgirish #define NXGE_M_CALLBACK_FLAGS (MC_RESOURCES | MC_IOCTL | MC_GETCAPAB) 20644961713Sgirish 20744961713Sgirish static boolean_t nxge_m_getcapab(void *, mac_capab_t, void *); 20844961713Sgirish static mac_callbacks_t nxge_m_callbacks = { 20944961713Sgirish NXGE_M_CALLBACK_FLAGS, 21044961713Sgirish nxge_m_stat, 21144961713Sgirish nxge_m_start, 21244961713Sgirish nxge_m_stop, 21344961713Sgirish nxge_m_promisc, 21444961713Sgirish nxge_m_multicst, 21544961713Sgirish nxge_m_unicst, 21644961713Sgirish nxge_m_tx, 21744961713Sgirish nxge_m_resources, 21844961713Sgirish nxge_m_ioctl, 21944961713Sgirish nxge_m_getcapab 22044961713Sgirish }; 22144961713Sgirish 22244961713Sgirish void 22344961713Sgirish nxge_err_inject(p_nxge_t, queue_t *, mblk_t *); 22444961713Sgirish 225ec090658Sml /* PSARC/2007/453 MSI-X interrupt limit override. */ 226ec090658Sml #define NXGE_MSIX_REQUEST_10G 8 227ec090658Sml #define NXGE_MSIX_REQUEST_1G 2 228ec090658Sml static int nxge_create_msi_property(p_nxge_t); 229ec090658Sml 23044961713Sgirish /* 23144961713Sgirish * These global variables control the message 23244961713Sgirish * output. 23344961713Sgirish */ 23444961713Sgirish out_dbgmsg_t nxge_dbgmsg_out = DBG_CONSOLE | STR_LOG; 23544961713Sgirish uint64_t nxge_debug_level = 0; 23644961713Sgirish 23744961713Sgirish /* 23844961713Sgirish * This list contains the instance structures for the Neptune 23944961713Sgirish * devices present in the system. The lock exists to guarantee 24044961713Sgirish * mutually exclusive access to the list. 24144961713Sgirish */ 24244961713Sgirish void *nxge_list = NULL; 24344961713Sgirish 24444961713Sgirish void *nxge_hw_list = NULL; 24544961713Sgirish nxge_os_mutex_t nxge_common_lock; 24644961713Sgirish 24744961713Sgirish nxge_os_mutex_t nxge_mii_lock; 24844961713Sgirish static uint32_t nxge_mii_lock_init = 0; 24944961713Sgirish nxge_os_mutex_t nxge_mdio_lock; 25044961713Sgirish static uint32_t nxge_mdio_lock_init = 0; 25144961713Sgirish 25244961713Sgirish extern uint64_t npi_debug_level; 25344961713Sgirish 25444961713Sgirish extern nxge_status_t nxge_ldgv_init(p_nxge_t, int *, int *); 25544961713Sgirish extern nxge_status_t nxge_ldgv_init_n2(p_nxge_t, int *, int *); 25644961713Sgirish extern nxge_status_t nxge_ldgv_uninit(p_nxge_t); 25744961713Sgirish extern nxge_status_t nxge_intr_ldgv_init(p_nxge_t); 25844961713Sgirish extern void nxge_fm_init(p_nxge_t, 25944961713Sgirish ddi_device_acc_attr_t *, 26044961713Sgirish ddi_device_acc_attr_t *, 26144961713Sgirish ddi_dma_attr_t *); 26244961713Sgirish extern void nxge_fm_fini(p_nxge_t); 26358324dfcSspeer extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t); 26444961713Sgirish 26544961713Sgirish /* 26644961713Sgirish * Count used to maintain the number of buffers being used 26744961713Sgirish * by Neptune instances and loaned up to the upper layers. 26844961713Sgirish */ 26944961713Sgirish uint32_t nxge_mblks_pending = 0; 27044961713Sgirish 27144961713Sgirish /* 27244961713Sgirish * Device register access attributes for PIO. 27344961713Sgirish */ 27444961713Sgirish static ddi_device_acc_attr_t nxge_dev_reg_acc_attr = { 27544961713Sgirish DDI_DEVICE_ATTR_V0, 27644961713Sgirish DDI_STRUCTURE_LE_ACC, 27744961713Sgirish DDI_STRICTORDER_ACC, 27844961713Sgirish }; 27944961713Sgirish 28044961713Sgirish /* 28144961713Sgirish * Device descriptor access attributes for DMA. 28244961713Sgirish */ 28344961713Sgirish static ddi_device_acc_attr_t nxge_dev_desc_dma_acc_attr = { 28444961713Sgirish DDI_DEVICE_ATTR_V0, 28544961713Sgirish DDI_STRUCTURE_LE_ACC, 28644961713Sgirish DDI_STRICTORDER_ACC 28744961713Sgirish }; 28844961713Sgirish 28944961713Sgirish /* 29044961713Sgirish * Device buffer access attributes for DMA. 29144961713Sgirish */ 29244961713Sgirish static ddi_device_acc_attr_t nxge_dev_buf_dma_acc_attr = { 29344961713Sgirish DDI_DEVICE_ATTR_V0, 29444961713Sgirish DDI_STRUCTURE_BE_ACC, 29544961713Sgirish DDI_STRICTORDER_ACC 29644961713Sgirish }; 29744961713Sgirish 29844961713Sgirish ddi_dma_attr_t nxge_desc_dma_attr = { 29944961713Sgirish DMA_ATTR_V0, /* version number. */ 30044961713Sgirish 0, /* low address */ 30144961713Sgirish 0xffffffffffffffff, /* high address */ 30244961713Sgirish 0xffffffffffffffff, /* address counter max */ 30344961713Sgirish #ifndef NIU_PA_WORKAROUND 30444961713Sgirish 0x100000, /* alignment */ 30544961713Sgirish #else 30644961713Sgirish 0x2000, 30744961713Sgirish #endif 30844961713Sgirish 0xfc00fc, /* dlim_burstsizes */ 30944961713Sgirish 0x1, /* minimum transfer size */ 31044961713Sgirish 0xffffffffffffffff, /* maximum transfer size */ 31144961713Sgirish 0xffffffffffffffff, /* maximum segment size */ 31244961713Sgirish 1, /* scatter/gather list length */ 31344961713Sgirish (unsigned int) 1, /* granularity */ 31444961713Sgirish 0 /* attribute flags */ 31544961713Sgirish }; 31644961713Sgirish 31744961713Sgirish ddi_dma_attr_t nxge_tx_dma_attr = { 31844961713Sgirish DMA_ATTR_V0, /* version number. */ 31944961713Sgirish 0, /* low address */ 32044961713Sgirish 0xffffffffffffffff, /* high address */ 32144961713Sgirish 0xffffffffffffffff, /* address counter max */ 32244961713Sgirish #if defined(_BIG_ENDIAN) 32344961713Sgirish 0x2000, /* alignment */ 32444961713Sgirish #else 32544961713Sgirish 0x1000, /* alignment */ 32644961713Sgirish #endif 32744961713Sgirish 0xfc00fc, /* dlim_burstsizes */ 32844961713Sgirish 0x1, /* minimum transfer size */ 32944961713Sgirish 0xffffffffffffffff, /* maximum transfer size */ 33044961713Sgirish 0xffffffffffffffff, /* maximum segment size */ 33144961713Sgirish 5, /* scatter/gather list length */ 33244961713Sgirish (unsigned int) 1, /* granularity */ 33344961713Sgirish 0 /* attribute flags */ 33444961713Sgirish }; 33544961713Sgirish 33644961713Sgirish ddi_dma_attr_t nxge_rx_dma_attr = { 33744961713Sgirish DMA_ATTR_V0, /* version number. */ 33844961713Sgirish 0, /* low address */ 33944961713Sgirish 0xffffffffffffffff, /* high address */ 34044961713Sgirish 0xffffffffffffffff, /* address counter max */ 34144961713Sgirish 0x2000, /* alignment */ 34244961713Sgirish 0xfc00fc, /* dlim_burstsizes */ 34344961713Sgirish 0x1, /* minimum transfer size */ 34444961713Sgirish 0xffffffffffffffff, /* maximum transfer size */ 34544961713Sgirish 0xffffffffffffffff, /* maximum segment size */ 34644961713Sgirish 1, /* scatter/gather list length */ 34744961713Sgirish (unsigned int) 1, /* granularity */ 3480e2bd521Ssbehera DDI_DMA_RELAXED_ORDERING /* attribute flags */ 34944961713Sgirish }; 35044961713Sgirish 35144961713Sgirish ddi_dma_lim_t nxge_dma_limits = { 35244961713Sgirish (uint_t)0, /* dlim_addr_lo */ 35344961713Sgirish (uint_t)0xffffffff, /* dlim_addr_hi */ 35444961713Sgirish (uint_t)0xffffffff, /* dlim_cntr_max */ 35544961713Sgirish (uint_t)0xfc00fc, /* dlim_burstsizes for 32 and 64 bit xfers */ 35644961713Sgirish 0x1, /* dlim_minxfer */ 35744961713Sgirish 1024 /* dlim_speed */ 35844961713Sgirish }; 35944961713Sgirish 36044961713Sgirish dma_method_t nxge_force_dma = DVMA; 36144961713Sgirish 36244961713Sgirish /* 36344961713Sgirish * dma chunk sizes. 36444961713Sgirish * 36544961713Sgirish * Try to allocate the largest possible size 36644961713Sgirish * so that fewer number of dma chunks would be managed 36744961713Sgirish */ 36844961713Sgirish #ifdef NIU_PA_WORKAROUND 36944961713Sgirish size_t alloc_sizes [] = {0x2000}; 37044961713Sgirish #else 37144961713Sgirish size_t alloc_sizes [] = {0x1000, 0x2000, 0x4000, 0x8000, 37244961713Sgirish 0x10000, 0x20000, 0x40000, 0x80000, 37344961713Sgirish 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000}; 37444961713Sgirish #endif 37544961713Sgirish 37644961713Sgirish /* 37744961713Sgirish * Translate "dev_t" to a pointer to the associated "dev_info_t". 37844961713Sgirish */ 37944961713Sgirish 38044961713Sgirish static int 38144961713Sgirish nxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 38244961713Sgirish { 38344961713Sgirish p_nxge_t nxgep = NULL; 38444961713Sgirish int instance; 38544961713Sgirish int status = DDI_SUCCESS; 38644961713Sgirish uint8_t portn; 38758324dfcSspeer nxge_mmac_t *mmac_info; 38844961713Sgirish 38944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_attach")); 39044961713Sgirish 39144961713Sgirish /* 39244961713Sgirish * Get the device instance since we'll need to setup 39344961713Sgirish * or retrieve a soft state for this instance. 39444961713Sgirish */ 39544961713Sgirish instance = ddi_get_instance(dip); 39644961713Sgirish 39744961713Sgirish switch (cmd) { 39844961713Sgirish case DDI_ATTACH: 39944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_ATTACH")); 40044961713Sgirish break; 40144961713Sgirish 40244961713Sgirish case DDI_RESUME: 40344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_RESUME")); 40444961713Sgirish nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 40544961713Sgirish if (nxgep == NULL) { 40644961713Sgirish status = DDI_FAILURE; 40744961713Sgirish break; 40844961713Sgirish } 40944961713Sgirish if (nxgep->dip != dip) { 41044961713Sgirish status = DDI_FAILURE; 41144961713Sgirish break; 41244961713Sgirish } 41344961713Sgirish if (nxgep->suspended == DDI_PM_SUSPEND) { 41444961713Sgirish status = ddi_dev_is_needed(nxgep->dip, 0, 1); 41544961713Sgirish } else { 41656d930aeSspeer status = nxge_resume(nxgep); 41744961713Sgirish } 41844961713Sgirish goto nxge_attach_exit; 41944961713Sgirish 42044961713Sgirish case DDI_PM_RESUME: 42144961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_PM_RESUME")); 42244961713Sgirish nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance); 42344961713Sgirish if (nxgep == NULL) { 42444961713Sgirish status = DDI_FAILURE; 42544961713Sgirish break; 42644961713Sgirish } 42744961713Sgirish if (nxgep->dip != dip) { 42844961713Sgirish status = DDI_FAILURE; 42944961713Sgirish break; 43044961713Sgirish } 43156d930aeSspeer status = nxge_resume(nxgep); 43244961713Sgirish goto nxge_attach_exit; 43344961713Sgirish 43444961713Sgirish default: 43544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing unknown")); 43644961713Sgirish status = DDI_FAILURE; 43744961713Sgirish goto nxge_attach_exit; 43844961713Sgirish } 43944961713Sgirish 44044961713Sgirish 44144961713Sgirish if (ddi_soft_state_zalloc(nxge_list, instance) == DDI_FAILURE) { 44244961713Sgirish status = DDI_FAILURE; 44344961713Sgirish goto nxge_attach_exit; 44444961713Sgirish } 44544961713Sgirish 44644961713Sgirish nxgep = ddi_get_soft_state(nxge_list, instance); 44744961713Sgirish if (nxgep == NULL) { 4482e59129aSraghus status = NXGE_ERROR; 4492e59129aSraghus goto nxge_attach_fail2; 45044961713Sgirish } 45144961713Sgirish 45298ecde52Stm nxgep->nxge_magic = NXGE_MAGIC; 45398ecde52Stm 45444961713Sgirish nxgep->drv_state = 0; 45544961713Sgirish nxgep->dip = dip; 45644961713Sgirish nxgep->instance = instance; 45744961713Sgirish nxgep->p_dip = ddi_get_parent(dip); 45844961713Sgirish nxgep->nxge_debug_level = nxge_debug_level; 45944961713Sgirish npi_debug_level = nxge_debug_level; 46044961713Sgirish 46144961713Sgirish nxge_fm_init(nxgep, &nxge_dev_reg_acc_attr, &nxge_dev_desc_dma_acc_attr, 46244961713Sgirish &nxge_rx_dma_attr); 46344961713Sgirish 46444961713Sgirish status = nxge_map_regs(nxgep); 46544961713Sgirish if (status != NXGE_OK) { 46644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_map_regs failed")); 4672e59129aSraghus goto nxge_attach_fail3; 46844961713Sgirish } 46944961713Sgirish 47044961713Sgirish status = nxge_init_common_dev(nxgep); 47144961713Sgirish if (status != NXGE_OK) { 47244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 47344961713Sgirish "nxge_init_common_dev failed")); 4742e59129aSraghus goto nxge_attach_fail4; 47544961713Sgirish } 47644961713Sgirish 47759ac0c16Sdavemq if (nxgep->niu_type == NEPTUNE_2_10GF) { 47859ac0c16Sdavemq if (nxgep->function_num > 1) { 47959ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Unsupported" 48059ac0c16Sdavemq " function %d. Only functions 0 and 1 are " 48159ac0c16Sdavemq "supported for this card.", nxgep->function_num)); 48259ac0c16Sdavemq status = NXGE_ERROR; 4832e59129aSraghus goto nxge_attach_fail4; 48459ac0c16Sdavemq } 48559ac0c16Sdavemq } 48659ac0c16Sdavemq 48744961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 48844961713Sgirish nxgep->mac.portnum = portn; 48944961713Sgirish if ((portn == 0) || (portn == 1)) 49044961713Sgirish nxgep->mac.porttype = PORT_TYPE_XMAC; 49144961713Sgirish else 49244961713Sgirish nxgep->mac.porttype = PORT_TYPE_BMAC; 49358324dfcSspeer /* 49458324dfcSspeer * Neptune has 4 ports, the first 2 ports use XMAC (10G MAC) 49558324dfcSspeer * internally, the rest 2 ports use BMAC (1G "Big" MAC). 49658324dfcSspeer * The two types of MACs have different characterizations. 49758324dfcSspeer */ 49858324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 49958324dfcSspeer if (nxgep->function_num < 2) { 50058324dfcSspeer mmac_info->num_mmac = XMAC_MAX_ALT_ADDR_ENTRY; 50158324dfcSspeer mmac_info->naddrfree = XMAC_MAX_ALT_ADDR_ENTRY; 50258324dfcSspeer } else { 50358324dfcSspeer mmac_info->num_mmac = BMAC_MAX_ALT_ADDR_ENTRY; 50458324dfcSspeer mmac_info->naddrfree = BMAC_MAX_ALT_ADDR_ENTRY; 50558324dfcSspeer } 50644961713Sgirish /* 50744961713Sgirish * Setup the Ndd parameters for the this instance. 50844961713Sgirish */ 50944961713Sgirish nxge_init_param(nxgep); 51044961713Sgirish 51144961713Sgirish /* 51244961713Sgirish * Setup Register Tracing Buffer. 51344961713Sgirish */ 51444961713Sgirish npi_rtrace_buf_init((rtrace_t *)&npi_rtracebuf); 51544961713Sgirish 51644961713Sgirish /* init stats ptr */ 51744961713Sgirish nxge_init_statsp(nxgep); 51856d930aeSspeer 5192e59129aSraghus /* 5202e59129aSraghus * read the vpd info from the eeprom into local data 5212e59129aSraghus * structure and check for the VPD info validity 5222e59129aSraghus */ 5232e59129aSraghus nxge_vpd_info_get(nxgep); 52456d930aeSspeer 5252e59129aSraghus status = nxge_xcvr_find(nxgep); 52644961713Sgirish 52744961713Sgirish if (status != NXGE_OK) { 52856d930aeSspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_attach: " 52944961713Sgirish " Couldn't determine card type" 53044961713Sgirish " .... exit ")); 5312e59129aSraghus goto nxge_attach_fail5; 53244961713Sgirish } 53344961713Sgirish 53444961713Sgirish status = nxge_get_config_properties(nxgep); 53544961713Sgirish 53644961713Sgirish if (status != NXGE_OK) { 53744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "get_hw create failed")); 53844961713Sgirish goto nxge_attach_fail; 53944961713Sgirish } 54044961713Sgirish 54144961713Sgirish /* 54244961713Sgirish * Setup the Kstats for the driver. 54344961713Sgirish */ 54444961713Sgirish nxge_setup_kstats(nxgep); 54544961713Sgirish 54644961713Sgirish nxge_setup_param(nxgep); 54744961713Sgirish 54844961713Sgirish status = nxge_setup_system_dma_pages(nxgep); 54944961713Sgirish if (status != NXGE_OK) { 55044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "set dma page failed")); 55144961713Sgirish goto nxge_attach_fail; 55244961713Sgirish } 55344961713Sgirish 55444961713Sgirish #if defined(sun4v) 55544961713Sgirish if (nxgep->niu_type == N2_NIU) { 55644961713Sgirish nxgep->niu_hsvc_available = B_FALSE; 55744961713Sgirish bcopy(&niu_hsvc, &nxgep->niu_hsvc, sizeof (hsvc_info_t)); 55844961713Sgirish if ((status = 55944961713Sgirish hsvc_register(&nxgep->niu_hsvc, 56044961713Sgirish &nxgep->niu_min_ver)) != 0) { 56144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 56244961713Sgirish "nxge_attach: " 56344961713Sgirish "%s: cannot negotiate " 56444961713Sgirish "hypervisor services " 56544961713Sgirish "revision %d " 56644961713Sgirish "group: 0x%lx " 56744961713Sgirish "major: 0x%lx minor: 0x%lx " 56844961713Sgirish "errno: %d", 56944961713Sgirish niu_hsvc.hsvc_modname, 57044961713Sgirish niu_hsvc.hsvc_rev, 57144961713Sgirish niu_hsvc.hsvc_group, 57244961713Sgirish niu_hsvc.hsvc_major, 57344961713Sgirish niu_hsvc.hsvc_minor, 57444961713Sgirish status)); 57544961713Sgirish status = DDI_FAILURE; 57644961713Sgirish goto nxge_attach_fail; 57744961713Sgirish } 57844961713Sgirish 57944961713Sgirish nxgep->niu_hsvc_available = B_TRUE; 58044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 58144961713Sgirish "NIU Hypervisor service enabled")); 58244961713Sgirish } 58344961713Sgirish #endif 58444961713Sgirish 58544961713Sgirish nxge_hw_id_init(nxgep); 58644961713Sgirish nxge_hw_init_niu_common(nxgep); 58744961713Sgirish 58844961713Sgirish status = nxge_setup_mutexes(nxgep); 58944961713Sgirish if (status != NXGE_OK) { 59044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "set mutex failed")); 59144961713Sgirish goto nxge_attach_fail; 59244961713Sgirish } 59344961713Sgirish 59444961713Sgirish status = nxge_setup_dev(nxgep); 59544961713Sgirish if (status != DDI_SUCCESS) { 59644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "set dev failed")); 59744961713Sgirish goto nxge_attach_fail; 59844961713Sgirish } 59944961713Sgirish 60044961713Sgirish status = nxge_add_intrs(nxgep); 60144961713Sgirish if (status != DDI_SUCCESS) { 60244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "add_intr failed")); 60344961713Sgirish goto nxge_attach_fail; 60444961713Sgirish } 60544961713Sgirish status = nxge_add_soft_intrs(nxgep); 60644961713Sgirish if (status != DDI_SUCCESS) { 60744961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL, "add_soft_intr failed")); 60844961713Sgirish goto nxge_attach_fail; 60944961713Sgirish } 61044961713Sgirish 61144961713Sgirish /* 61244961713Sgirish * Enable interrupts. 61344961713Sgirish */ 61444961713Sgirish nxge_intrs_enable(nxgep); 61544961713Sgirish 6162e59129aSraghus if ((status = nxge_mac_register(nxgep)) != NXGE_OK) { 61744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 61844961713Sgirish "unable to register to mac layer (%d)", status)); 61944961713Sgirish goto nxge_attach_fail; 62044961713Sgirish } 62144961713Sgirish 62244961713Sgirish mac_link_update(nxgep->mach, LINK_STATE_UNKNOWN); 62344961713Sgirish 62444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "registered to mac (instance %d)", 62544961713Sgirish instance)); 62644961713Sgirish 62744961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 62844961713Sgirish 62944961713Sgirish goto nxge_attach_exit; 63044961713Sgirish 63144961713Sgirish nxge_attach_fail: 63244961713Sgirish nxge_unattach(nxgep); 6332e59129aSraghus goto nxge_attach_fail1; 6342e59129aSraghus 6352e59129aSraghus nxge_attach_fail5: 6362e59129aSraghus /* 6372e59129aSraghus * Tear down the ndd parameters setup. 6382e59129aSraghus */ 6392e59129aSraghus nxge_destroy_param(nxgep); 6402e59129aSraghus 6412e59129aSraghus /* 6422e59129aSraghus * Tear down the kstat setup. 6432e59129aSraghus */ 6442e59129aSraghus nxge_destroy_kstats(nxgep); 6452e59129aSraghus 6462e59129aSraghus nxge_attach_fail4: 6472e59129aSraghus if (nxgep->nxge_hw_p) { 6482e59129aSraghus nxge_uninit_common_dev(nxgep); 6492e59129aSraghus nxgep->nxge_hw_p = NULL; 6502e59129aSraghus } 6512e59129aSraghus 6522e59129aSraghus nxge_attach_fail3: 6532e59129aSraghus /* 6542e59129aSraghus * Unmap the register setup. 6552e59129aSraghus */ 6562e59129aSraghus nxge_unmap_regs(nxgep); 6572e59129aSraghus 6582e59129aSraghus nxge_fm_fini(nxgep); 6592e59129aSraghus 6602e59129aSraghus nxge_attach_fail2: 6612e59129aSraghus ddi_soft_state_free(nxge_list, nxgep->instance); 6622e59129aSraghus 6632e59129aSraghus nxge_attach_fail1: 66456d930aeSspeer if (status != NXGE_OK) 66556d930aeSspeer status = (NXGE_ERROR | NXGE_DDI_FAILED); 66644961713Sgirish nxgep = NULL; 66744961713Sgirish 66844961713Sgirish nxge_attach_exit: 66944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_attach status = 0x%08x", 67044961713Sgirish status)); 67144961713Sgirish 67244961713Sgirish return (status); 67344961713Sgirish } 67444961713Sgirish 67544961713Sgirish static int 67644961713Sgirish nxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 67744961713Sgirish { 67844961713Sgirish int status = DDI_SUCCESS; 67944961713Sgirish int instance; 68044961713Sgirish p_nxge_t nxgep = NULL; 68144961713Sgirish 68244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_detach")); 68344961713Sgirish instance = ddi_get_instance(dip); 68444961713Sgirish nxgep = ddi_get_soft_state(nxge_list, instance); 68544961713Sgirish if (nxgep == NULL) { 68644961713Sgirish status = DDI_FAILURE; 68744961713Sgirish goto nxge_detach_exit; 68844961713Sgirish } 68944961713Sgirish 69044961713Sgirish switch (cmd) { 69144961713Sgirish case DDI_DETACH: 69244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_DETACH")); 69344961713Sgirish break; 69444961713Sgirish 69544961713Sgirish case DDI_PM_SUSPEND: 69644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_PM_SUSPEND")); 69744961713Sgirish nxgep->suspended = DDI_PM_SUSPEND; 69844961713Sgirish nxge_suspend(nxgep); 69944961713Sgirish break; 70044961713Sgirish 70144961713Sgirish case DDI_SUSPEND: 70244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "doing DDI_SUSPEND")); 70344961713Sgirish if (nxgep->suspended != DDI_PM_SUSPEND) { 70444961713Sgirish nxgep->suspended = DDI_SUSPEND; 70544961713Sgirish nxge_suspend(nxgep); 70644961713Sgirish } 70744961713Sgirish break; 70844961713Sgirish 70944961713Sgirish default: 71044961713Sgirish status = DDI_FAILURE; 71144961713Sgirish } 71244961713Sgirish 71344961713Sgirish if (cmd != DDI_DETACH) 71444961713Sgirish goto nxge_detach_exit; 71544961713Sgirish 71644961713Sgirish /* 71744961713Sgirish * Stop the xcvr polling. 71844961713Sgirish */ 71944961713Sgirish nxgep->suspended = cmd; 72044961713Sgirish 72144961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 72244961713Sgirish 72344961713Sgirish if (nxgep->mach && (status = mac_unregister(nxgep->mach)) != 0) { 72444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72544961713Sgirish "<== nxge_detach status = 0x%08X", status)); 72644961713Sgirish return (DDI_FAILURE); 72744961713Sgirish } 72844961713Sgirish 72944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 73044961713Sgirish "<== nxge_detach (mac_unregister) status = 0x%08X", status)); 73144961713Sgirish 73244961713Sgirish nxge_unattach(nxgep); 73344961713Sgirish nxgep = NULL; 73444961713Sgirish 73544961713Sgirish nxge_detach_exit: 73644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_detach status = 0x%08X", 73744961713Sgirish status)); 73844961713Sgirish 73944961713Sgirish return (status); 74044961713Sgirish } 74144961713Sgirish 74244961713Sgirish static void 74344961713Sgirish nxge_unattach(p_nxge_t nxgep) 74444961713Sgirish { 74544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_unattach")); 74644961713Sgirish 74744961713Sgirish if (nxgep == NULL || nxgep->dev_regs == NULL) { 74844961713Sgirish return; 74944961713Sgirish } 75044961713Sgirish 75198ecde52Stm nxgep->nxge_magic = 0; 75298ecde52Stm 75344961713Sgirish if (nxgep->nxge_hw_p) { 75444961713Sgirish nxge_uninit_common_dev(nxgep); 75544961713Sgirish nxgep->nxge_hw_p = NULL; 75644961713Sgirish } 75744961713Sgirish 75844961713Sgirish if (nxgep->nxge_timerid) { 75944961713Sgirish nxge_stop_timer(nxgep, nxgep->nxge_timerid); 76044961713Sgirish nxgep->nxge_timerid = 0; 76144961713Sgirish } 76244961713Sgirish 76344961713Sgirish #if defined(sun4v) 76444961713Sgirish if (nxgep->niu_type == N2_NIU && nxgep->niu_hsvc_available == B_TRUE) { 76544961713Sgirish (void) hsvc_unregister(&nxgep->niu_hsvc); 76644961713Sgirish nxgep->niu_hsvc_available = B_FALSE; 76744961713Sgirish } 76844961713Sgirish #endif 76944961713Sgirish /* 77044961713Sgirish * Stop any further interrupts. 77144961713Sgirish */ 77244961713Sgirish nxge_remove_intrs(nxgep); 77344961713Sgirish 77444961713Sgirish /* remove soft interrups */ 77544961713Sgirish nxge_remove_soft_intrs(nxgep); 77644961713Sgirish 77744961713Sgirish /* 77844961713Sgirish * Stop the device and free resources. 77944961713Sgirish */ 78044961713Sgirish nxge_destroy_dev(nxgep); 78144961713Sgirish 78244961713Sgirish /* 78344961713Sgirish * Tear down the ndd parameters setup. 78444961713Sgirish */ 78544961713Sgirish nxge_destroy_param(nxgep); 78644961713Sgirish 78744961713Sgirish /* 78844961713Sgirish * Tear down the kstat setup. 78944961713Sgirish */ 79044961713Sgirish nxge_destroy_kstats(nxgep); 79144961713Sgirish 79244961713Sgirish /* 79344961713Sgirish * Destroy all mutexes. 79444961713Sgirish */ 79544961713Sgirish nxge_destroy_mutexes(nxgep); 79644961713Sgirish 79744961713Sgirish /* 79844961713Sgirish * Remove the list of ndd parameters which 79944961713Sgirish * were setup during attach. 80044961713Sgirish */ 80144961713Sgirish if (nxgep->dip) { 80244961713Sgirish NXGE_DEBUG_MSG((nxgep, OBP_CTL, 80344961713Sgirish " nxge_unattach: remove all properties")); 80444961713Sgirish 80544961713Sgirish (void) ddi_prop_remove_all(nxgep->dip); 80644961713Sgirish } 80744961713Sgirish 80844961713Sgirish #if NXGE_PROPERTY 80944961713Sgirish nxge_remove_hard_properties(nxgep); 81044961713Sgirish #endif 81144961713Sgirish 81244961713Sgirish /* 81344961713Sgirish * Unmap the register setup. 81444961713Sgirish */ 81544961713Sgirish nxge_unmap_regs(nxgep); 81644961713Sgirish 81744961713Sgirish nxge_fm_fini(nxgep); 81844961713Sgirish 81944961713Sgirish ddi_soft_state_free(nxge_list, nxgep->instance); 82044961713Sgirish 82144961713Sgirish NXGE_DEBUG_MSG((NULL, DDI_CTL, "<== nxge_unattach")); 82244961713Sgirish } 82344961713Sgirish 82444961713Sgirish static char n2_siu_name[] = "niu"; 82544961713Sgirish 82644961713Sgirish static nxge_status_t 82744961713Sgirish nxge_map_regs(p_nxge_t nxgep) 82844961713Sgirish { 82944961713Sgirish int ddi_status = DDI_SUCCESS; 83044961713Sgirish p_dev_regs_t dev_regs; 83144961713Sgirish char buf[MAXPATHLEN + 1]; 83244961713Sgirish char *devname; 83344961713Sgirish #ifdef NXGE_DEBUG 83444961713Sgirish char *sysname; 83544961713Sgirish #endif 83644961713Sgirish off_t regsize; 83744961713Sgirish nxge_status_t status = NXGE_OK; 83814ea4bb7Ssd #if !defined(_BIG_ENDIAN) 83914ea4bb7Ssd off_t pci_offset; 84014ea4bb7Ssd uint16_t pcie_devctl; 84114ea4bb7Ssd #endif 84244961713Sgirish 84344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_map_regs")); 84444961713Sgirish nxgep->dev_regs = NULL; 84544961713Sgirish dev_regs = KMEM_ZALLOC(sizeof (dev_regs_t), KM_SLEEP); 84644961713Sgirish dev_regs->nxge_regh = NULL; 84744961713Sgirish dev_regs->nxge_pciregh = NULL; 84844961713Sgirish dev_regs->nxge_msix_regh = NULL; 84944961713Sgirish dev_regs->nxge_vir_regh = NULL; 85044961713Sgirish dev_regs->nxge_vir2_regh = NULL; 85159ac0c16Sdavemq nxgep->niu_type = NIU_TYPE_NONE; 85244961713Sgirish 85344961713Sgirish devname = ddi_pathname(nxgep->dip, buf); 85444961713Sgirish ASSERT(strlen(devname) > 0); 85544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 85644961713Sgirish "nxge_map_regs: pathname devname %s", devname)); 85744961713Sgirish 85844961713Sgirish if (strstr(devname, n2_siu_name)) { 85944961713Sgirish /* N2/NIU */ 86044961713Sgirish nxgep->niu_type = N2_NIU; 86144961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 86244961713Sgirish "nxge_map_regs: N2/NIU devname %s", devname)); 86344961713Sgirish /* get function number */ 86444961713Sgirish nxgep->function_num = 86544961713Sgirish (devname[strlen(devname) -1] == '1' ? 1 : 0); 86644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 86744961713Sgirish "nxge_map_regs: N2/NIU function number %d", 86844961713Sgirish nxgep->function_num)); 86944961713Sgirish } else { 87044961713Sgirish int *prop_val; 87144961713Sgirish uint_t prop_len; 87244961713Sgirish uint8_t func_num; 87344961713Sgirish 87444961713Sgirish if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 87544961713Sgirish 0, "reg", 87644961713Sgirish &prop_val, &prop_len) != DDI_PROP_SUCCESS) { 87744961713Sgirish NXGE_DEBUG_MSG((nxgep, VPD_CTL, 87844961713Sgirish "Reg property not found")); 87944961713Sgirish ddi_status = DDI_FAILURE; 88044961713Sgirish goto nxge_map_regs_fail0; 88144961713Sgirish 88244961713Sgirish } else { 88344961713Sgirish func_num = (prop_val[0] >> 8) & 0x7; 88444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 88544961713Sgirish "Reg property found: fun # %d", 88644961713Sgirish func_num)); 88744961713Sgirish nxgep->function_num = func_num; 88844961713Sgirish ddi_prop_free(prop_val); 88944961713Sgirish } 89044961713Sgirish } 89144961713Sgirish 89244961713Sgirish switch (nxgep->niu_type) { 89344961713Sgirish default: 89444961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 0, ®size); 89544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 89644961713Sgirish "nxge_map_regs: pci config size 0x%x", regsize)); 89744961713Sgirish 89844961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 0, 89944961713Sgirish (caddr_t *)&(dev_regs->nxge_pciregp), 0, 0, 90044961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_pciregh); 90144961713Sgirish if (ddi_status != DDI_SUCCESS) { 90244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 90344961713Sgirish "ddi_map_regs, nxge bus config regs failed")); 90444961713Sgirish goto nxge_map_regs_fail0; 90544961713Sgirish } 90644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 90744961713Sgirish "nxge_map_reg: PCI config addr 0x%0llx " 90844961713Sgirish " handle 0x%0llx", dev_regs->nxge_pciregp, 90944961713Sgirish dev_regs->nxge_pciregh)); 91044961713Sgirish /* 91144961713Sgirish * IMP IMP 91244961713Sgirish * workaround for bit swapping bug in HW 91344961713Sgirish * which ends up in no-snoop = yes 91444961713Sgirish * resulting, in DMA not synched properly 91544961713Sgirish */ 91644961713Sgirish #if !defined(_BIG_ENDIAN) 91714ea4bb7Ssd /* workarounds for x86 systems */ 91814ea4bb7Ssd pci_offset = 0x80 + PCIE_DEVCTL; 91914ea4bb7Ssd pcie_devctl = 0x0; 92014ea4bb7Ssd pcie_devctl &= PCIE_DEVCTL_ENABLE_NO_SNOOP; 92114ea4bb7Ssd pcie_devctl |= PCIE_DEVCTL_RO_EN; 92214ea4bb7Ssd pci_config_put16(dev_regs->nxge_pciregh, pci_offset, 92314ea4bb7Ssd pcie_devctl); 92444961713Sgirish #endif 92514ea4bb7Ssd 92644961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 1, ®size); 92744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 92844961713Sgirish "nxge_map_regs: pio size 0x%x", regsize)); 92944961713Sgirish /* set up the device mapped register */ 93044961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 1, 93144961713Sgirish (caddr_t *)&(dev_regs->nxge_regp), 0, 0, 93244961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_regh); 93344961713Sgirish if (ddi_status != DDI_SUCCESS) { 93444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 93544961713Sgirish "ddi_map_regs for Neptune global reg failed")); 93644961713Sgirish goto nxge_map_regs_fail1; 93744961713Sgirish } 93844961713Sgirish 93944961713Sgirish /* set up the msi/msi-x mapped register */ 94044961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 2, ®size); 94144961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 94244961713Sgirish "nxge_map_regs: msix size 0x%x", regsize)); 94344961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 2, 94444961713Sgirish (caddr_t *)&(dev_regs->nxge_msix_regp), 0, 0, 94544961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_msix_regh); 94644961713Sgirish if (ddi_status != DDI_SUCCESS) { 94744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 94844961713Sgirish "ddi_map_regs for msi reg failed")); 94944961713Sgirish goto nxge_map_regs_fail2; 95044961713Sgirish } 95144961713Sgirish 95244961713Sgirish /* set up the vio region mapped register */ 95344961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 3, ®size); 95444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 95544961713Sgirish "nxge_map_regs: vio size 0x%x", regsize)); 95644961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 3, 95744961713Sgirish (caddr_t *)&(dev_regs->nxge_vir_regp), 0, 0, 95844961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir_regh); 95944961713Sgirish 96044961713Sgirish if (ddi_status != DDI_SUCCESS) { 96144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 96244961713Sgirish "ddi_map_regs for nxge vio reg failed")); 96344961713Sgirish goto nxge_map_regs_fail3; 96444961713Sgirish } 96544961713Sgirish nxgep->dev_regs = dev_regs; 96644961713Sgirish 96744961713Sgirish NPI_PCI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_pciregh); 96844961713Sgirish NPI_PCI_ADD_HANDLE_SET(nxgep, 96944961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_pciregp); 97044961713Sgirish NPI_MSI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_msix_regh); 97144961713Sgirish NPI_MSI_ADD_HANDLE_SET(nxgep, 97244961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_msix_regp); 97344961713Sgirish 97444961713Sgirish NPI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 97544961713Sgirish NPI_ADD_HANDLE_SET(nxgep, (npi_reg_ptr_t)dev_regs->nxge_regp); 97644961713Sgirish 97744961713Sgirish NPI_REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 97844961713Sgirish NPI_REG_ADD_HANDLE_SET(nxgep, 97944961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_regp); 98044961713Sgirish 98144961713Sgirish NPI_VREG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir_regh); 98244961713Sgirish NPI_VREG_ADD_HANDLE_SET(nxgep, 98344961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_vir_regp); 98444961713Sgirish 98544961713Sgirish break; 98644961713Sgirish 98744961713Sgirish case N2_NIU: 98844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "ddi_map_regs, NIU")); 98944961713Sgirish /* 99044961713Sgirish * Set up the device mapped register (FWARC 2006/556) 99144961713Sgirish * (changed back to 1: reg starts at 1!) 99244961713Sgirish */ 99344961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 1, ®size); 99444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 99544961713Sgirish "nxge_map_regs: dev size 0x%x", regsize)); 99644961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 1, 99744961713Sgirish (caddr_t *)&(dev_regs->nxge_regp), 0, 0, 99844961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_regh); 99944961713Sgirish 100044961713Sgirish if (ddi_status != DDI_SUCCESS) { 100144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 100244961713Sgirish "ddi_map_regs for N2/NIU, global reg failed ")); 100344961713Sgirish goto nxge_map_regs_fail1; 100444961713Sgirish } 100544961713Sgirish 100644961713Sgirish /* set up the vio region mapped register */ 100744961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 2, ®size); 100844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 100944961713Sgirish "nxge_map_regs: vio (1) size 0x%x", regsize)); 101044961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 2, 101144961713Sgirish (caddr_t *)&(dev_regs->nxge_vir_regp), 0, 0, 101244961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir_regh); 101344961713Sgirish 101444961713Sgirish if (ddi_status != DDI_SUCCESS) { 101544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 101644961713Sgirish "ddi_map_regs for nxge vio reg failed")); 101744961713Sgirish goto nxge_map_regs_fail2; 101844961713Sgirish } 101944961713Sgirish /* set up the vio region mapped register */ 102044961713Sgirish (void) ddi_dev_regsize(nxgep->dip, 3, ®size); 102144961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 102244961713Sgirish "nxge_map_regs: vio (3) size 0x%x", regsize)); 102344961713Sgirish ddi_status = ddi_regs_map_setup(nxgep->dip, 3, 102444961713Sgirish (caddr_t *)&(dev_regs->nxge_vir2_regp), 0, 0, 102544961713Sgirish &nxge_dev_reg_acc_attr, &dev_regs->nxge_vir2_regh); 102644961713Sgirish 102744961713Sgirish if (ddi_status != DDI_SUCCESS) { 102844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 102944961713Sgirish "ddi_map_regs for nxge vio2 reg failed")); 103044961713Sgirish goto nxge_map_regs_fail3; 103144961713Sgirish } 103244961713Sgirish nxgep->dev_regs = dev_regs; 103344961713Sgirish 103444961713Sgirish NPI_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 103544961713Sgirish NPI_ADD_HANDLE_SET(nxgep, (npi_reg_ptr_t)dev_regs->nxge_regp); 103644961713Sgirish 103744961713Sgirish NPI_REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_regh); 103844961713Sgirish NPI_REG_ADD_HANDLE_SET(nxgep, 103944961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_regp); 104044961713Sgirish 104144961713Sgirish NPI_VREG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir_regh); 104244961713Sgirish NPI_VREG_ADD_HANDLE_SET(nxgep, 104344961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_vir_regp); 104444961713Sgirish 104544961713Sgirish NPI_V2REG_ACC_HANDLE_SET(nxgep, dev_regs->nxge_vir2_regh); 104644961713Sgirish NPI_V2REG_ADD_HANDLE_SET(nxgep, 104744961713Sgirish (npi_reg_ptr_t)dev_regs->nxge_vir2_regp); 104844961713Sgirish 104944961713Sgirish break; 105044961713Sgirish } 105144961713Sgirish 105244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_map_reg: hardware addr 0x%0llx " 105344961713Sgirish " handle 0x%0llx", dev_regs->nxge_regp, dev_regs->nxge_regh)); 105444961713Sgirish 105544961713Sgirish goto nxge_map_regs_exit; 105644961713Sgirish nxge_map_regs_fail3: 105744961713Sgirish if (dev_regs->nxge_msix_regh) { 105844961713Sgirish ddi_regs_map_free(&dev_regs->nxge_msix_regh); 105944961713Sgirish } 106044961713Sgirish if (dev_regs->nxge_vir_regh) { 106144961713Sgirish ddi_regs_map_free(&dev_regs->nxge_regh); 106244961713Sgirish } 106344961713Sgirish nxge_map_regs_fail2: 106444961713Sgirish if (dev_regs->nxge_regh) { 106544961713Sgirish ddi_regs_map_free(&dev_regs->nxge_regh); 106644961713Sgirish } 106744961713Sgirish nxge_map_regs_fail1: 106844961713Sgirish if (dev_regs->nxge_pciregh) { 106944961713Sgirish ddi_regs_map_free(&dev_regs->nxge_pciregh); 107044961713Sgirish } 107144961713Sgirish nxge_map_regs_fail0: 107244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Freeing register set memory")); 107344961713Sgirish kmem_free(dev_regs, sizeof (dev_regs_t)); 107444961713Sgirish 107544961713Sgirish nxge_map_regs_exit: 107644961713Sgirish if (ddi_status != DDI_SUCCESS) 107744961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 107844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_map_regs")); 107944961713Sgirish return (status); 108044961713Sgirish } 108144961713Sgirish 108244961713Sgirish static void 108344961713Sgirish nxge_unmap_regs(p_nxge_t nxgep) 108444961713Sgirish { 108544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_unmap_regs")); 108644961713Sgirish if (nxgep->dev_regs) { 108744961713Sgirish if (nxgep->dev_regs->nxge_pciregh) { 108844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 108944961713Sgirish "==> nxge_unmap_regs: bus")); 109044961713Sgirish ddi_regs_map_free(&nxgep->dev_regs->nxge_pciregh); 109144961713Sgirish nxgep->dev_regs->nxge_pciregh = NULL; 109244961713Sgirish } 109344961713Sgirish if (nxgep->dev_regs->nxge_regh) { 109444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 109544961713Sgirish "==> nxge_unmap_regs: device registers")); 109644961713Sgirish ddi_regs_map_free(&nxgep->dev_regs->nxge_regh); 109744961713Sgirish nxgep->dev_regs->nxge_regh = NULL; 109844961713Sgirish } 109944961713Sgirish if (nxgep->dev_regs->nxge_msix_regh) { 110044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 110144961713Sgirish "==> nxge_unmap_regs: device interrupts")); 110244961713Sgirish ddi_regs_map_free(&nxgep->dev_regs->nxge_msix_regh); 110344961713Sgirish nxgep->dev_regs->nxge_msix_regh = NULL; 110444961713Sgirish } 110544961713Sgirish if (nxgep->dev_regs->nxge_vir_regh) { 110644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 110744961713Sgirish "==> nxge_unmap_regs: vio region")); 110844961713Sgirish ddi_regs_map_free(&nxgep->dev_regs->nxge_vir_regh); 110944961713Sgirish nxgep->dev_regs->nxge_vir_regh = NULL; 111044961713Sgirish } 111144961713Sgirish if (nxgep->dev_regs->nxge_vir2_regh) { 111244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 111344961713Sgirish "==> nxge_unmap_regs: vio2 region")); 111444961713Sgirish ddi_regs_map_free(&nxgep->dev_regs->nxge_vir2_regh); 111544961713Sgirish nxgep->dev_regs->nxge_vir2_regh = NULL; 111644961713Sgirish } 111744961713Sgirish 111844961713Sgirish kmem_free(nxgep->dev_regs, sizeof (dev_regs_t)); 111944961713Sgirish nxgep->dev_regs = NULL; 112044961713Sgirish } 112144961713Sgirish 112244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_unmap_regs")); 112344961713Sgirish } 112444961713Sgirish 112544961713Sgirish static nxge_status_t 112644961713Sgirish nxge_setup_mutexes(p_nxge_t nxgep) 112744961713Sgirish { 112844961713Sgirish int ddi_status = DDI_SUCCESS; 112944961713Sgirish nxge_status_t status = NXGE_OK; 113044961713Sgirish nxge_classify_t *classify_ptr; 113144961713Sgirish int partition; 113244961713Sgirish 113344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_mutexes")); 113444961713Sgirish 113544961713Sgirish /* 113644961713Sgirish * Get the interrupt cookie so the mutexes can be 113758324dfcSspeer * Initialized. 113844961713Sgirish */ 113944961713Sgirish ddi_status = ddi_get_iblock_cookie(nxgep->dip, 0, 114044961713Sgirish &nxgep->interrupt_cookie); 114144961713Sgirish if (ddi_status != DDI_SUCCESS) { 114244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 114344961713Sgirish "<== nxge_setup_mutexes: failed 0x%x", ddi_status)); 114444961713Sgirish goto nxge_setup_mutexes_exit; 114544961713Sgirish } 114644961713Sgirish 114744961713Sgirish /* Initialize global mutex */ 114844961713Sgirish 114944961713Sgirish if (nxge_mdio_lock_init == 0) { 115044961713Sgirish MUTEX_INIT(&nxge_mdio_lock, NULL, MUTEX_DRIVER, NULL); 115144961713Sgirish } 115244961713Sgirish atomic_add_32(&nxge_mdio_lock_init, 1); 115344961713Sgirish 115444961713Sgirish if (nxge_mii_lock_init == 0) { 115544961713Sgirish MUTEX_INIT(&nxge_mii_lock, NULL, MUTEX_DRIVER, NULL); 115644961713Sgirish } 115744961713Sgirish atomic_add_32(&nxge_mii_lock_init, 1); 115844961713Sgirish 115944961713Sgirish nxgep->drv_state |= STATE_MDIO_LOCK_INIT; 116044961713Sgirish nxgep->drv_state |= STATE_MII_LOCK_INIT; 116144961713Sgirish 116298ecde52Stm cv_init(&nxgep->poll_cv, NULL, CV_DRIVER, NULL); 116398ecde52Stm MUTEX_INIT(&nxgep->poll_lock, NULL, 116498ecde52Stm MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 116598ecde52Stm 116644961713Sgirish /* 116798ecde52Stm * Initialize mutexes for this device. 116844961713Sgirish */ 116944961713Sgirish MUTEX_INIT(nxgep->genlock, NULL, 117044961713Sgirish MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 117144961713Sgirish MUTEX_INIT(&nxgep->ouraddr_lock, NULL, 117244961713Sgirish MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 117344961713Sgirish MUTEX_INIT(&nxgep->mif_lock, NULL, 117444961713Sgirish MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 117544961713Sgirish RW_INIT(&nxgep->filter_lock, NULL, 117644961713Sgirish RW_DRIVER, (void *)nxgep->interrupt_cookie); 117744961713Sgirish 117844961713Sgirish classify_ptr = &nxgep->classifier; 117944961713Sgirish /* 118044961713Sgirish * FFLP Mutexes are never used in interrupt context 118144961713Sgirish * as fflp operation can take very long time to 118244961713Sgirish * complete and hence not suitable to invoke from interrupt 118344961713Sgirish * handlers. 118444961713Sgirish */ 118544961713Sgirish MUTEX_INIT(&classify_ptr->tcam_lock, NULL, 118659ac0c16Sdavemq NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 11872e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 118844961713Sgirish MUTEX_INIT(&classify_ptr->fcram_lock, NULL, 118959ac0c16Sdavemq NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 119044961713Sgirish for (partition = 0; partition < MAX_PARTITION; partition++) { 119144961713Sgirish MUTEX_INIT(&classify_ptr->hash_lock[partition], NULL, 119244961713Sgirish NXGE_MUTEX_DRIVER, (void *)nxgep->interrupt_cookie); 119344961713Sgirish } 119444961713Sgirish } 119544961713Sgirish 119644961713Sgirish nxge_setup_mutexes_exit: 119744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 119859ac0c16Sdavemq "<== nxge_setup_mutexes status = %x", status)); 119944961713Sgirish 120044961713Sgirish if (ddi_status != DDI_SUCCESS) 120144961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 120244961713Sgirish 120344961713Sgirish return (status); 120444961713Sgirish } 120544961713Sgirish 120644961713Sgirish static void 120744961713Sgirish nxge_destroy_mutexes(p_nxge_t nxgep) 120844961713Sgirish { 120944961713Sgirish int partition; 121044961713Sgirish nxge_classify_t *classify_ptr; 121144961713Sgirish 121244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_mutexes")); 121344961713Sgirish RW_DESTROY(&nxgep->filter_lock); 121444961713Sgirish MUTEX_DESTROY(&nxgep->mif_lock); 121544961713Sgirish MUTEX_DESTROY(&nxgep->ouraddr_lock); 121644961713Sgirish MUTEX_DESTROY(nxgep->genlock); 121744961713Sgirish 121844961713Sgirish classify_ptr = &nxgep->classifier; 121944961713Sgirish MUTEX_DESTROY(&classify_ptr->tcam_lock); 122044961713Sgirish 122198ecde52Stm /* Destroy all polling resources. */ 122298ecde52Stm MUTEX_DESTROY(&nxgep->poll_lock); 122398ecde52Stm cv_destroy(&nxgep->poll_cv); 122498ecde52Stm 122598ecde52Stm /* free data structures, based on HW type */ 12262e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 122744961713Sgirish MUTEX_DESTROY(&classify_ptr->fcram_lock); 122844961713Sgirish for (partition = 0; partition < MAX_PARTITION; partition++) { 122944961713Sgirish MUTEX_DESTROY(&classify_ptr->hash_lock[partition]); 123044961713Sgirish } 123144961713Sgirish } 123244961713Sgirish if (nxgep->drv_state & STATE_MDIO_LOCK_INIT) { 123344961713Sgirish if (nxge_mdio_lock_init == 1) { 123444961713Sgirish MUTEX_DESTROY(&nxge_mdio_lock); 123544961713Sgirish } 123644961713Sgirish atomic_add_32(&nxge_mdio_lock_init, -1); 123744961713Sgirish } 123844961713Sgirish if (nxgep->drv_state & STATE_MII_LOCK_INIT) { 123944961713Sgirish if (nxge_mii_lock_init == 1) { 124044961713Sgirish MUTEX_DESTROY(&nxge_mii_lock); 124144961713Sgirish } 124244961713Sgirish atomic_add_32(&nxge_mii_lock_init, -1); 124344961713Sgirish } 124444961713Sgirish 124544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_destroy_mutexes")); 124644961713Sgirish } 124744961713Sgirish 124844961713Sgirish nxge_status_t 124944961713Sgirish nxge_init(p_nxge_t nxgep) 125044961713Sgirish { 125144961713Sgirish nxge_status_t status = NXGE_OK; 125244961713Sgirish 125344961713Sgirish NXGE_DEBUG_MSG((nxgep, STR_CTL, "==> nxge_init")); 125444961713Sgirish 125514ea4bb7Ssd if (nxgep->drv_state & STATE_HW_INITIALIZED) { 125614ea4bb7Ssd return (status); 125714ea4bb7Ssd } 125814ea4bb7Ssd 125944961713Sgirish /* 126044961713Sgirish * Allocate system memory for the receive/transmit buffer blocks 126144961713Sgirish * and receive/transmit descriptor rings. 126244961713Sgirish */ 126344961713Sgirish status = nxge_alloc_mem_pool(nxgep); 126444961713Sgirish if (status != NXGE_OK) { 126544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "alloc mem failed\n")); 126644961713Sgirish goto nxge_init_fail1; 126744961713Sgirish } 126844961713Sgirish 126944961713Sgirish /* 127044961713Sgirish * Initialize and enable TXC registers 127144961713Sgirish * (Globally enable TX controller, 127244961713Sgirish * enable a port, configure dma channel bitmap, 127344961713Sgirish * configure the max burst size). 127444961713Sgirish */ 127544961713Sgirish status = nxge_txc_init(nxgep); 127644961713Sgirish if (status != NXGE_OK) { 127744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init txc failed\n")); 127844961713Sgirish goto nxge_init_fail2; 127944961713Sgirish } 128044961713Sgirish 128144961713Sgirish /* 128244961713Sgirish * Initialize and enable TXDMA channels. 128344961713Sgirish */ 128444961713Sgirish status = nxge_init_txdma_channels(nxgep); 128544961713Sgirish if (status != NXGE_OK) { 128644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init txdma failed\n")); 128744961713Sgirish goto nxge_init_fail3; 128844961713Sgirish } 128944961713Sgirish 129044961713Sgirish /* 129144961713Sgirish * Initialize and enable RXDMA channels. 129244961713Sgirish */ 129344961713Sgirish status = nxge_init_rxdma_channels(nxgep); 129444961713Sgirish if (status != NXGE_OK) { 129544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init rxdma failed\n")); 129644961713Sgirish goto nxge_init_fail4; 129744961713Sgirish } 129844961713Sgirish 129944961713Sgirish /* 130044961713Sgirish * Initialize TCAM and FCRAM (Neptune). 130144961713Sgirish */ 130244961713Sgirish status = nxge_classify_init(nxgep); 130344961713Sgirish if (status != NXGE_OK) { 130444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init classify failed\n")); 130544961713Sgirish goto nxge_init_fail5; 130644961713Sgirish } 130744961713Sgirish 130844961713Sgirish /* 130944961713Sgirish * Initialize ZCP 131044961713Sgirish */ 131144961713Sgirish status = nxge_zcp_init(nxgep); 131244961713Sgirish if (status != NXGE_OK) { 131344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init ZCP failed\n")); 131444961713Sgirish goto nxge_init_fail5; 131544961713Sgirish } 131644961713Sgirish 131744961713Sgirish /* 131844961713Sgirish * Initialize IPP. 131944961713Sgirish */ 132044961713Sgirish status = nxge_ipp_init(nxgep); 132144961713Sgirish if (status != NXGE_OK) { 132244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init IPP failed\n")); 132344961713Sgirish goto nxge_init_fail5; 132444961713Sgirish } 132544961713Sgirish 132644961713Sgirish /* 132744961713Sgirish * Initialize the MAC block. 132844961713Sgirish */ 132944961713Sgirish status = nxge_mac_init(nxgep); 133044961713Sgirish if (status != NXGE_OK) { 133144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "init MAC failed\n")); 133244961713Sgirish goto nxge_init_fail5; 133344961713Sgirish } 133444961713Sgirish 133544961713Sgirish nxge_intrs_enable(nxgep); 133644961713Sgirish 133744961713Sgirish /* 133844961713Sgirish * Enable hardware interrupts. 133944961713Sgirish */ 134044961713Sgirish nxge_intr_hw_enable(nxgep); 134144961713Sgirish nxgep->drv_state |= STATE_HW_INITIALIZED; 134244961713Sgirish 134344961713Sgirish goto nxge_init_exit; 134444961713Sgirish 134544961713Sgirish nxge_init_fail5: 134644961713Sgirish nxge_uninit_rxdma_channels(nxgep); 134744961713Sgirish nxge_init_fail4: 134844961713Sgirish nxge_uninit_txdma_channels(nxgep); 134944961713Sgirish nxge_init_fail3: 135044961713Sgirish (void) nxge_txc_uninit(nxgep); 135144961713Sgirish nxge_init_fail2: 135244961713Sgirish nxge_free_mem_pool(nxgep); 135344961713Sgirish nxge_init_fail1: 135444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 135544961713Sgirish "<== nxge_init status (failed) = 0x%08x", status)); 135644961713Sgirish return (status); 135744961713Sgirish 135844961713Sgirish nxge_init_exit: 135944961713Sgirish 136044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_init status = 0x%08x", 136144961713Sgirish status)); 136244961713Sgirish return (status); 136344961713Sgirish } 136444961713Sgirish 136544961713Sgirish 136644961713Sgirish timeout_id_t 136744961713Sgirish nxge_start_timer(p_nxge_t nxgep, fptrv_t func, int msec) 136844961713Sgirish { 136944961713Sgirish if ((nxgep->suspended == 0) || 137044961713Sgirish (nxgep->suspended == DDI_RESUME)) { 137144961713Sgirish return (timeout(func, (caddr_t)nxgep, 137244961713Sgirish drv_usectohz(1000 * msec))); 137344961713Sgirish } 137444961713Sgirish return (NULL); 137544961713Sgirish } 137644961713Sgirish 137744961713Sgirish /*ARGSUSED*/ 137844961713Sgirish void 137944961713Sgirish nxge_stop_timer(p_nxge_t nxgep, timeout_id_t timerid) 138044961713Sgirish { 138144961713Sgirish if (timerid) { 138244961713Sgirish (void) untimeout(timerid); 138344961713Sgirish } 138444961713Sgirish } 138544961713Sgirish 138644961713Sgirish void 138744961713Sgirish nxge_uninit(p_nxge_t nxgep) 138844961713Sgirish { 138944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_uninit")); 139044961713Sgirish 139144961713Sgirish if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 139244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 139344961713Sgirish "==> nxge_uninit: not initialized")); 139444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 139544961713Sgirish "<== nxge_uninit")); 139644961713Sgirish return; 139744961713Sgirish } 139844961713Sgirish 139944961713Sgirish /* stop timer */ 140044961713Sgirish if (nxgep->nxge_timerid) { 140144961713Sgirish nxge_stop_timer(nxgep, nxgep->nxge_timerid); 140244961713Sgirish nxgep->nxge_timerid = 0; 140344961713Sgirish } 140444961713Sgirish 140544961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 140644961713Sgirish (void) nxge_intr_hw_disable(nxgep); 140744961713Sgirish 140844961713Sgirish /* 140944961713Sgirish * Reset the receive MAC side. 141044961713Sgirish */ 141144961713Sgirish (void) nxge_rx_mac_disable(nxgep); 141244961713Sgirish 141344961713Sgirish /* Disable and soft reset the IPP */ 141444961713Sgirish (void) nxge_ipp_disable(nxgep); 141544961713Sgirish 1416a3c5bd6dSspeer /* Free classification resources */ 1417a3c5bd6dSspeer (void) nxge_classify_uninit(nxgep); 1418a3c5bd6dSspeer 141944961713Sgirish /* 142044961713Sgirish * Reset the transmit/receive DMA side. 142144961713Sgirish */ 142244961713Sgirish (void) nxge_txdma_hw_mode(nxgep, NXGE_DMA_STOP); 142344961713Sgirish (void) nxge_rxdma_hw_mode(nxgep, NXGE_DMA_STOP); 142444961713Sgirish 142544961713Sgirish nxge_uninit_txdma_channels(nxgep); 142644961713Sgirish nxge_uninit_rxdma_channels(nxgep); 142744961713Sgirish 142844961713Sgirish /* 142944961713Sgirish * Reset the transmit MAC side. 143044961713Sgirish */ 143144961713Sgirish (void) nxge_tx_mac_disable(nxgep); 143244961713Sgirish 143344961713Sgirish nxge_free_mem_pool(nxgep); 143444961713Sgirish 143544961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 143644961713Sgirish 143744961713Sgirish nxgep->drv_state &= ~STATE_HW_INITIALIZED; 143844961713Sgirish 143944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_uninit: " 144044961713Sgirish "nxge_mblks_pending %d", nxge_mblks_pending)); 144144961713Sgirish } 144244961713Sgirish 144344961713Sgirish void 144444961713Sgirish nxge_get64(p_nxge_t nxgep, p_mblk_t mp) 144544961713Sgirish { 1446adfcba55Sjoycey #if defined(__i386) 1447adfcba55Sjoycey size_t reg; 1448adfcba55Sjoycey #else 144944961713Sgirish uint64_t reg; 1450adfcba55Sjoycey #endif 145144961713Sgirish uint64_t regdata; 145244961713Sgirish int i, retry; 145344961713Sgirish 145444961713Sgirish bcopy((char *)mp->b_rptr, (char *)®, sizeof (uint64_t)); 145544961713Sgirish regdata = 0; 145644961713Sgirish retry = 1; 145744961713Sgirish 145844961713Sgirish for (i = 0; i < retry; i++) { 145944961713Sgirish NXGE_REG_RD64(nxgep->npi_handle, reg, ®data); 146044961713Sgirish } 146144961713Sgirish bcopy((char *)®data, (char *)mp->b_rptr, sizeof (uint64_t)); 146244961713Sgirish } 146344961713Sgirish 146444961713Sgirish void 146544961713Sgirish nxge_put64(p_nxge_t nxgep, p_mblk_t mp) 146644961713Sgirish { 1467adfcba55Sjoycey #if defined(__i386) 1468adfcba55Sjoycey size_t reg; 1469adfcba55Sjoycey #else 147044961713Sgirish uint64_t reg; 1471adfcba55Sjoycey #endif 147244961713Sgirish uint64_t buf[2]; 147344961713Sgirish 147444961713Sgirish bcopy((char *)mp->b_rptr, (char *)&buf[0], 2 * sizeof (uint64_t)); 14757a8b1321Sjoycey #if defined(__i386) 14767a8b1321Sjoycey reg = (size_t)buf[0]; 14777a8b1321Sjoycey #else 147844961713Sgirish reg = buf[0]; 14797a8b1321Sjoycey #endif 148044961713Sgirish 148144961713Sgirish NXGE_NPI_PIO_WRITE64(nxgep->npi_handle, reg, buf[1]); 148244961713Sgirish } 148344961713Sgirish 148444961713Sgirish 148544961713Sgirish nxge_os_mutex_t nxgedebuglock; 148644961713Sgirish int nxge_debug_init = 0; 148744961713Sgirish 148844961713Sgirish /*ARGSUSED*/ 148944961713Sgirish /*VARARGS*/ 149044961713Sgirish void 149144961713Sgirish nxge_debug_msg(p_nxge_t nxgep, uint64_t level, char *fmt, ...) 149244961713Sgirish { 149344961713Sgirish char msg_buffer[1048]; 149444961713Sgirish char prefix_buffer[32]; 149544961713Sgirish int instance; 149644961713Sgirish uint64_t debug_level; 149744961713Sgirish int cmn_level = CE_CONT; 149844961713Sgirish va_list ap; 149944961713Sgirish 150044961713Sgirish debug_level = (nxgep == NULL) ? nxge_debug_level : 150144961713Sgirish nxgep->nxge_debug_level; 150244961713Sgirish 150344961713Sgirish if ((level & debug_level) || 150444961713Sgirish (level == NXGE_NOTE) || 150544961713Sgirish (level == NXGE_ERR_CTL)) { 150644961713Sgirish /* do the msg processing */ 150744961713Sgirish if (nxge_debug_init == 0) { 150844961713Sgirish MUTEX_INIT(&nxgedebuglock, NULL, MUTEX_DRIVER, NULL); 150944961713Sgirish nxge_debug_init = 1; 151044961713Sgirish } 151144961713Sgirish 151244961713Sgirish MUTEX_ENTER(&nxgedebuglock); 151344961713Sgirish 151444961713Sgirish if ((level & NXGE_NOTE)) { 151544961713Sgirish cmn_level = CE_NOTE; 151644961713Sgirish } 151744961713Sgirish 151844961713Sgirish if (level & NXGE_ERR_CTL) { 151944961713Sgirish cmn_level = CE_WARN; 152044961713Sgirish } 152144961713Sgirish 152244961713Sgirish va_start(ap, fmt); 152344961713Sgirish (void) vsprintf(msg_buffer, fmt, ap); 152444961713Sgirish va_end(ap); 152544961713Sgirish if (nxgep == NULL) { 152644961713Sgirish instance = -1; 152744961713Sgirish (void) sprintf(prefix_buffer, "%s :", "nxge"); 152844961713Sgirish } else { 152944961713Sgirish instance = nxgep->instance; 153044961713Sgirish (void) sprintf(prefix_buffer, 153144961713Sgirish "%s%d :", "nxge", instance); 153244961713Sgirish } 153344961713Sgirish 153444961713Sgirish MUTEX_EXIT(&nxgedebuglock); 153544961713Sgirish cmn_err(cmn_level, "!%s %s\n", 153644961713Sgirish prefix_buffer, msg_buffer); 153744961713Sgirish 153844961713Sgirish } 153944961713Sgirish } 154044961713Sgirish 154144961713Sgirish char * 154244961713Sgirish nxge_dump_packet(char *addr, int size) 154344961713Sgirish { 154444961713Sgirish uchar_t *ap = (uchar_t *)addr; 154544961713Sgirish int i; 154644961713Sgirish static char etherbuf[1024]; 154744961713Sgirish char *cp = etherbuf; 154844961713Sgirish char digits[] = "0123456789abcdef"; 154944961713Sgirish 155044961713Sgirish if (!size) 155144961713Sgirish size = 60; 155244961713Sgirish 155344961713Sgirish if (size > MAX_DUMP_SZ) { 155444961713Sgirish /* Dump the leading bytes */ 155544961713Sgirish for (i = 0; i < MAX_DUMP_SZ/2; i++) { 155644961713Sgirish if (*ap > 0x0f) 155744961713Sgirish *cp++ = digits[*ap >> 4]; 155844961713Sgirish *cp++ = digits[*ap++ & 0xf]; 155944961713Sgirish *cp++ = ':'; 156044961713Sgirish } 156144961713Sgirish for (i = 0; i < 20; i++) 156244961713Sgirish *cp++ = '.'; 156344961713Sgirish /* Dump the last MAX_DUMP_SZ/2 bytes */ 156444961713Sgirish ap = (uchar_t *)(addr + (size - MAX_DUMP_SZ/2)); 156544961713Sgirish for (i = 0; i < MAX_DUMP_SZ/2; i++) { 156644961713Sgirish if (*ap > 0x0f) 156744961713Sgirish *cp++ = digits[*ap >> 4]; 156844961713Sgirish *cp++ = digits[*ap++ & 0xf]; 156944961713Sgirish *cp++ = ':'; 157044961713Sgirish } 157144961713Sgirish } else { 157244961713Sgirish for (i = 0; i < size; i++) { 157344961713Sgirish if (*ap > 0x0f) 157444961713Sgirish *cp++ = digits[*ap >> 4]; 157544961713Sgirish *cp++ = digits[*ap++ & 0xf]; 157644961713Sgirish *cp++ = ':'; 157744961713Sgirish } 157844961713Sgirish } 157944961713Sgirish *--cp = 0; 158044961713Sgirish return (etherbuf); 158144961713Sgirish } 158244961713Sgirish 158344961713Sgirish #ifdef NXGE_DEBUG 158444961713Sgirish static void 158544961713Sgirish nxge_test_map_regs(p_nxge_t nxgep) 158644961713Sgirish { 158744961713Sgirish ddi_acc_handle_t cfg_handle; 158844961713Sgirish p_pci_cfg_t cfg_ptr; 158944961713Sgirish ddi_acc_handle_t dev_handle; 159044961713Sgirish char *dev_ptr; 159144961713Sgirish ddi_acc_handle_t pci_config_handle; 159244961713Sgirish uint32_t regval; 159344961713Sgirish int i; 159444961713Sgirish 159544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_test_map_regs")); 159644961713Sgirish 159744961713Sgirish dev_handle = nxgep->dev_regs->nxge_regh; 159844961713Sgirish dev_ptr = (char *)nxgep->dev_regs->nxge_regp; 159944961713Sgirish 16002e59129aSraghus if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 160144961713Sgirish cfg_handle = nxgep->dev_regs->nxge_pciregh; 160244961713Sgirish cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp; 160344961713Sgirish 160444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 160559ac0c16Sdavemq "Neptune PCI regp cfg_ptr 0x%llx", (char *)cfg_ptr)); 160644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 160759ac0c16Sdavemq "Neptune PCI cfg_ptr vendor id ptr 0x%llx", 160859ac0c16Sdavemq &cfg_ptr->vendorid)); 160944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 161059ac0c16Sdavemq "\tvendorid 0x%x devid 0x%x", 161159ac0c16Sdavemq NXGE_PIO_READ16(cfg_handle, &cfg_ptr->vendorid, 0), 161259ac0c16Sdavemq NXGE_PIO_READ16(cfg_handle, &cfg_ptr->devid, 0))); 161344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 161459ac0c16Sdavemq "PCI BAR: base 0x%x base14 0x%x base 18 0x%x " 161559ac0c16Sdavemq "bar1c 0x%x", 161659ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base, 0), 161759ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base14, 0), 161859ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base18, 0), 161959ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base1c, 0))); 162044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 162159ac0c16Sdavemq "\nNeptune PCI BAR: base20 0x%x base24 0x%x " 162259ac0c16Sdavemq "base 28 0x%x bar2c 0x%x\n", 162359ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base20, 0), 162459ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base24, 0), 162559ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base28, 0), 162659ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base2c, 0))); 162744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 162859ac0c16Sdavemq "\nNeptune PCI BAR: base30 0x%x\n", 162959ac0c16Sdavemq NXGE_PIO_READ32(cfg_handle, &cfg_ptr->base30, 0))); 163044961713Sgirish 163144961713Sgirish cfg_handle = nxgep->dev_regs->nxge_pciregh; 163244961713Sgirish cfg_ptr = (void *)nxgep->dev_regs->nxge_pciregp; 163344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 163459ac0c16Sdavemq "first 0x%llx second 0x%llx third 0x%llx " 163559ac0c16Sdavemq "last 0x%llx ", 163659ac0c16Sdavemq NXGE_PIO_READ64(dev_handle, 163759ac0c16Sdavemq (uint64_t *)(dev_ptr + 0), 0), 163859ac0c16Sdavemq NXGE_PIO_READ64(dev_handle, 163959ac0c16Sdavemq (uint64_t *)(dev_ptr + 8), 0), 164059ac0c16Sdavemq NXGE_PIO_READ64(dev_handle, 164159ac0c16Sdavemq (uint64_t *)(dev_ptr + 16), 0), 164259ac0c16Sdavemq NXGE_PIO_READ64(cfg_handle, 164359ac0c16Sdavemq (uint64_t *)(dev_ptr + 24), 0))); 164444961713Sgirish } 164544961713Sgirish } 164644961713Sgirish 164744961713Sgirish #endif 164844961713Sgirish 164944961713Sgirish static void 165044961713Sgirish nxge_suspend(p_nxge_t nxgep) 165144961713Sgirish { 165244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_suspend")); 165344961713Sgirish 165444961713Sgirish nxge_intrs_disable(nxgep); 165544961713Sgirish nxge_destroy_dev(nxgep); 165644961713Sgirish 165744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_suspend")); 165844961713Sgirish } 165944961713Sgirish 166044961713Sgirish static nxge_status_t 166144961713Sgirish nxge_resume(p_nxge_t nxgep) 166244961713Sgirish { 166344961713Sgirish nxge_status_t status = NXGE_OK; 166444961713Sgirish 166544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_resume")); 166644961713Sgirish 166791c98b31Sjoycey nxgep->suspended = DDI_RESUME; 166891c98b31Sjoycey (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 166991c98b31Sjoycey (void) nxge_rxdma_hw_mode(nxgep, NXGE_DMA_START); 167091c98b31Sjoycey (void) nxge_txdma_hw_mode(nxgep, NXGE_DMA_START); 167191c98b31Sjoycey (void) nxge_rx_mac_enable(nxgep); 167291c98b31Sjoycey (void) nxge_tx_mac_enable(nxgep); 167391c98b31Sjoycey nxge_intrs_enable(nxgep); 167444961713Sgirish nxgep->suspended = 0; 167544961713Sgirish 167644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 167744961713Sgirish "<== nxge_resume status = 0x%x", status)); 167844961713Sgirish return (status); 167944961713Sgirish } 168044961713Sgirish 168144961713Sgirish static nxge_status_t 168244961713Sgirish nxge_setup_dev(p_nxge_t nxgep) 168344961713Sgirish { 168444961713Sgirish nxge_status_t status = NXGE_OK; 168544961713Sgirish 168644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_dev port %d", 168759ac0c16Sdavemq nxgep->mac.portnum)); 168844961713Sgirish 168944961713Sgirish status = nxge_link_init(nxgep); 169014ea4bb7Ssd 169114ea4bb7Ssd if (fm_check_acc_handle(nxgep->dev_regs->nxge_regh) != DDI_FM_OK) { 169214ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 169314ea4bb7Ssd "port%d Bad register acc handle", nxgep->mac.portnum)); 169414ea4bb7Ssd status = NXGE_ERROR; 169514ea4bb7Ssd } 169614ea4bb7Ssd 169744961713Sgirish if (status != NXGE_OK) { 169844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 169944961713Sgirish " nxge_setup_dev status " 170044961713Sgirish "(xcvr init 0x%08x)", status)); 170144961713Sgirish goto nxge_setup_dev_exit; 170244961713Sgirish } 170344961713Sgirish 170444961713Sgirish nxge_setup_dev_exit: 170544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 170644961713Sgirish "<== nxge_setup_dev port %d status = 0x%08x", 170744961713Sgirish nxgep->mac.portnum, status)); 170844961713Sgirish 170944961713Sgirish return (status); 171044961713Sgirish } 171144961713Sgirish 171244961713Sgirish static void 171344961713Sgirish nxge_destroy_dev(p_nxge_t nxgep) 171444961713Sgirish { 171544961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_dev")); 171644961713Sgirish 171744961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP); 171844961713Sgirish 171944961713Sgirish (void) nxge_hw_stop(nxgep); 172044961713Sgirish 172144961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_destroy_dev")); 172244961713Sgirish } 172344961713Sgirish 172444961713Sgirish static nxge_status_t 172544961713Sgirish nxge_setup_system_dma_pages(p_nxge_t nxgep) 172644961713Sgirish { 172744961713Sgirish int ddi_status = DDI_SUCCESS; 172844961713Sgirish uint_t count; 172944961713Sgirish ddi_dma_cookie_t cookie; 173044961713Sgirish uint_t iommu_pagesize; 173144961713Sgirish nxge_status_t status = NXGE_OK; 173244961713Sgirish 173344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_setup_system_dma_pages")); 173444961713Sgirish nxgep->sys_page_sz = ddi_ptob(nxgep->dip, (ulong_t)1); 173544961713Sgirish if (nxgep->niu_type != N2_NIU) { 173644961713Sgirish iommu_pagesize = dvma_pagesize(nxgep->dip); 173744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 173844961713Sgirish " nxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 173944961713Sgirish " default_block_size %d iommu_pagesize %d", 174044961713Sgirish nxgep->sys_page_sz, 174144961713Sgirish ddi_ptob(nxgep->dip, (ulong_t)1), 174244961713Sgirish nxgep->rx_default_block_size, 174344961713Sgirish iommu_pagesize)); 174444961713Sgirish 174544961713Sgirish if (iommu_pagesize != 0) { 174644961713Sgirish if (nxgep->sys_page_sz == iommu_pagesize) { 174744961713Sgirish if (iommu_pagesize > 0x4000) 174844961713Sgirish nxgep->sys_page_sz = 0x4000; 174944961713Sgirish } else { 175044961713Sgirish if (nxgep->sys_page_sz > iommu_pagesize) 175144961713Sgirish nxgep->sys_page_sz = iommu_pagesize; 175244961713Sgirish } 175344961713Sgirish } 175444961713Sgirish } 175544961713Sgirish nxgep->sys_page_mask = ~(nxgep->sys_page_sz - 1); 175644961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 175744961713Sgirish "==> nxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 175844961713Sgirish "default_block_size %d page mask %d", 175944961713Sgirish nxgep->sys_page_sz, 176044961713Sgirish ddi_ptob(nxgep->dip, (ulong_t)1), 176144961713Sgirish nxgep->rx_default_block_size, 176244961713Sgirish nxgep->sys_page_mask)); 176344961713Sgirish 176444961713Sgirish 176544961713Sgirish switch (nxgep->sys_page_sz) { 176644961713Sgirish default: 176744961713Sgirish nxgep->sys_page_sz = 0x1000; 176844961713Sgirish nxgep->sys_page_mask = ~(nxgep->sys_page_sz - 1); 176944961713Sgirish nxgep->rx_default_block_size = 0x1000; 177044961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_4K; 177144961713Sgirish break; 177244961713Sgirish case 0x1000: 177344961713Sgirish nxgep->rx_default_block_size = 0x1000; 177444961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_4K; 177544961713Sgirish break; 177644961713Sgirish case 0x2000: 177744961713Sgirish nxgep->rx_default_block_size = 0x2000; 177844961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_8K; 177944961713Sgirish break; 178044961713Sgirish case 0x4000: 178144961713Sgirish nxgep->rx_default_block_size = 0x4000; 178244961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_16K; 178344961713Sgirish break; 178444961713Sgirish case 0x8000: 178544961713Sgirish nxgep->rx_default_block_size = 0x8000; 178644961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_32K; 178744961713Sgirish break; 178844961713Sgirish } 178944961713Sgirish 179044961713Sgirish #ifndef USE_RX_BIG_BUF 179144961713Sgirish nxge_rx_dma_attr.dma_attr_align = nxgep->sys_page_sz; 179244961713Sgirish #else 179344961713Sgirish nxgep->rx_default_block_size = 0x2000; 179444961713Sgirish nxgep->rx_bksize_code = RBR_BKSIZE_8K; 179544961713Sgirish #endif 179644961713Sgirish /* 179744961713Sgirish * Get the system DMA burst size. 179844961713Sgirish */ 179944961713Sgirish ddi_status = ddi_dma_alloc_handle(nxgep->dip, &nxge_tx_dma_attr, 180044961713Sgirish DDI_DMA_DONTWAIT, 0, 180144961713Sgirish &nxgep->dmasparehandle); 180244961713Sgirish if (ddi_status != DDI_SUCCESS) { 180344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 180444961713Sgirish "ddi_dma_alloc_handle: failed " 180544961713Sgirish " status 0x%x", ddi_status)); 180644961713Sgirish goto nxge_get_soft_properties_exit; 180744961713Sgirish } 180844961713Sgirish 180944961713Sgirish ddi_status = ddi_dma_addr_bind_handle(nxgep->dmasparehandle, NULL, 181044961713Sgirish (caddr_t)nxgep->dmasparehandle, 181144961713Sgirish sizeof (nxgep->dmasparehandle), 181244961713Sgirish DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 181344961713Sgirish DDI_DMA_DONTWAIT, 0, 181444961713Sgirish &cookie, &count); 181544961713Sgirish if (ddi_status != DDI_DMA_MAPPED) { 181644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 181744961713Sgirish "Binding spare handle to find system" 181844961713Sgirish " burstsize failed.")); 181944961713Sgirish ddi_status = DDI_FAILURE; 182044961713Sgirish goto nxge_get_soft_properties_fail1; 182144961713Sgirish } 182244961713Sgirish 182344961713Sgirish nxgep->sys_burst_sz = ddi_dma_burstsizes(nxgep->dmasparehandle); 182444961713Sgirish (void) ddi_dma_unbind_handle(nxgep->dmasparehandle); 182544961713Sgirish 182644961713Sgirish nxge_get_soft_properties_fail1: 182744961713Sgirish ddi_dma_free_handle(&nxgep->dmasparehandle); 182844961713Sgirish 182944961713Sgirish nxge_get_soft_properties_exit: 183044961713Sgirish 183144961713Sgirish if (ddi_status != DDI_SUCCESS) 183244961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 183344961713Sgirish 183444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 183544961713Sgirish "<== nxge_setup_system_dma_pages status = 0x%08x", status)); 183644961713Sgirish return (status); 183744961713Sgirish } 183844961713Sgirish 183944961713Sgirish static nxge_status_t 184044961713Sgirish nxge_alloc_mem_pool(p_nxge_t nxgep) 184144961713Sgirish { 184244961713Sgirish nxge_status_t status = NXGE_OK; 184344961713Sgirish 184444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_alloc_mem_pool")); 184544961713Sgirish 184644961713Sgirish status = nxge_alloc_rx_mem_pool(nxgep); 184744961713Sgirish if (status != NXGE_OK) { 184844961713Sgirish return (NXGE_ERROR); 184944961713Sgirish } 185044961713Sgirish 185144961713Sgirish status = nxge_alloc_tx_mem_pool(nxgep); 185244961713Sgirish if (status != NXGE_OK) { 185344961713Sgirish nxge_free_rx_mem_pool(nxgep); 185444961713Sgirish return (NXGE_ERROR); 185544961713Sgirish } 185644961713Sgirish 185744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_alloc_mem_pool")); 185844961713Sgirish return (NXGE_OK); 185944961713Sgirish } 186044961713Sgirish 186144961713Sgirish static void 186244961713Sgirish nxge_free_mem_pool(p_nxge_t nxgep) 186344961713Sgirish { 186444961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_free_mem_pool")); 186544961713Sgirish 186644961713Sgirish nxge_free_rx_mem_pool(nxgep); 186744961713Sgirish nxge_free_tx_mem_pool(nxgep); 186844961713Sgirish 186944961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "<== nxge_free_mem_pool")); 187044961713Sgirish } 187144961713Sgirish 187244961713Sgirish static nxge_status_t 187344961713Sgirish nxge_alloc_rx_mem_pool(p_nxge_t nxgep) 187444961713Sgirish { 187544961713Sgirish int i, j; 187644961713Sgirish uint32_t ndmas, st_rdc; 187744961713Sgirish p_nxge_dma_pt_cfg_t p_all_cfgp; 187844961713Sgirish p_nxge_hw_pt_cfg_t p_cfgp; 187944961713Sgirish p_nxge_dma_pool_t dma_poolp; 188044961713Sgirish p_nxge_dma_common_t *dma_buf_p; 188144961713Sgirish p_nxge_dma_pool_t dma_cntl_poolp; 188244961713Sgirish p_nxge_dma_common_t *dma_cntl_p; 188344961713Sgirish size_t rx_buf_alloc_size; 188444961713Sgirish size_t rx_cntl_alloc_size; 188544961713Sgirish uint32_t *num_chunks; /* per dma */ 188644961713Sgirish nxge_status_t status = NXGE_OK; 188744961713Sgirish 188844961713Sgirish uint32_t nxge_port_rbr_size; 188944961713Sgirish uint32_t nxge_port_rbr_spare_size; 189044961713Sgirish uint32_t nxge_port_rcr_size; 189144961713Sgirish 189244961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_mem_pool")); 189344961713Sgirish 189444961713Sgirish p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 189544961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 189644961713Sgirish st_rdc = p_cfgp->start_rdc; 189744961713Sgirish ndmas = p_cfgp->max_rdcs; 189844961713Sgirish 189944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 190044961713Sgirish " nxge_alloc_rx_mem_pool st_rdc %d ndmas %d", st_rdc, ndmas)); 190144961713Sgirish 190244961713Sgirish /* 190344961713Sgirish * Allocate memory for each receive DMA channel. 190444961713Sgirish */ 190544961713Sgirish dma_poolp = (p_nxge_dma_pool_t)KMEM_ZALLOC(sizeof (nxge_dma_pool_t), 190644961713Sgirish KM_SLEEP); 190744961713Sgirish dma_buf_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 190844961713Sgirish sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 190944961713Sgirish 191044961713Sgirish dma_cntl_poolp = (p_nxge_dma_pool_t) 191144961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_pool_t), KM_SLEEP); 191244961713Sgirish dma_cntl_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 191344961713Sgirish sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 191444961713Sgirish 191544961713Sgirish num_chunks = (uint32_t *)KMEM_ZALLOC( 191644961713Sgirish sizeof (uint32_t) * ndmas, KM_SLEEP); 191744961713Sgirish 191844961713Sgirish /* 191944961713Sgirish * Assume that each DMA channel will be configured with default 192044961713Sgirish * block size. 192144961713Sgirish * rbr block counts are mod of batch count (16). 192244961713Sgirish */ 192344961713Sgirish nxge_port_rbr_size = p_all_cfgp->rbr_size; 192444961713Sgirish nxge_port_rcr_size = p_all_cfgp->rcr_size; 192544961713Sgirish 192644961713Sgirish if (!nxge_port_rbr_size) { 192744961713Sgirish nxge_port_rbr_size = NXGE_RBR_RBB_DEFAULT; 192844961713Sgirish } 192944961713Sgirish if (nxge_port_rbr_size % NXGE_RXDMA_POST_BATCH) { 193044961713Sgirish nxge_port_rbr_size = (NXGE_RXDMA_POST_BATCH * 193144961713Sgirish (nxge_port_rbr_size / NXGE_RXDMA_POST_BATCH + 1)); 193244961713Sgirish } 193344961713Sgirish 193444961713Sgirish p_all_cfgp->rbr_size = nxge_port_rbr_size; 193544961713Sgirish nxge_port_rbr_spare_size = nxge_rbr_spare_size; 193644961713Sgirish 193744961713Sgirish if (nxge_port_rbr_spare_size % NXGE_RXDMA_POST_BATCH) { 193844961713Sgirish nxge_port_rbr_spare_size = (NXGE_RXDMA_POST_BATCH * 193944961713Sgirish (nxge_port_rbr_spare_size / NXGE_RXDMA_POST_BATCH + 1)); 194044961713Sgirish } 194144961713Sgirish 194244961713Sgirish /* 194344961713Sgirish * N2/NIU has limitation on the descriptor sizes (contiguous 194444961713Sgirish * memory allocation on data buffers to 4M (contig_mem_alloc) 194544961713Sgirish * and little endian for control buffers (must use the ddi/dki mem alloc 194644961713Sgirish * function). 194744961713Sgirish */ 194844961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 194944961713Sgirish if (nxgep->niu_type == N2_NIU) { 195044961713Sgirish nxge_port_rbr_spare_size = 0; 195144961713Sgirish if ((nxge_port_rbr_size > NXGE_NIU_CONTIG_RBR_MAX) || 195244961713Sgirish (!ISP2(nxge_port_rbr_size))) { 195344961713Sgirish nxge_port_rbr_size = NXGE_NIU_CONTIG_RBR_MAX; 195444961713Sgirish } 195544961713Sgirish if ((nxge_port_rcr_size > NXGE_NIU_CONTIG_RCR_MAX) || 195644961713Sgirish (!ISP2(nxge_port_rcr_size))) { 195744961713Sgirish nxge_port_rcr_size = NXGE_NIU_CONTIG_RCR_MAX; 195844961713Sgirish } 195944961713Sgirish } 196044961713Sgirish #endif 196144961713Sgirish 196244961713Sgirish rx_buf_alloc_size = (nxgep->rx_default_block_size * 196344961713Sgirish (nxge_port_rbr_size + nxge_port_rbr_spare_size)); 196444961713Sgirish 196544961713Sgirish /* 196644961713Sgirish * Addresses of receive block ring, receive completion ring and the 196744961713Sgirish * mailbox must be all cache-aligned (64 bytes). 196844961713Sgirish */ 196944961713Sgirish rx_cntl_alloc_size = nxge_port_rbr_size + nxge_port_rbr_spare_size; 197044961713Sgirish rx_cntl_alloc_size *= (sizeof (rx_desc_t)); 197144961713Sgirish rx_cntl_alloc_size += (sizeof (rcr_entry_t) * nxge_port_rcr_size); 197244961713Sgirish rx_cntl_alloc_size += sizeof (rxdma_mailbox_t); 197344961713Sgirish 197444961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_alloc_rx_mem_pool: " 197544961713Sgirish "nxge_port_rbr_size = %d nxge_port_rbr_spare_size = %d " 197644961713Sgirish "nxge_port_rcr_size = %d " 197744961713Sgirish "rx_cntl_alloc_size = %d", 197844961713Sgirish nxge_port_rbr_size, nxge_port_rbr_spare_size, 197944961713Sgirish nxge_port_rcr_size, 198044961713Sgirish rx_cntl_alloc_size)); 198144961713Sgirish 198244961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 198344961713Sgirish if (nxgep->niu_type == N2_NIU) { 198444961713Sgirish if (!ISP2(rx_buf_alloc_size)) { 198544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 198644961713Sgirish "==> nxge_alloc_rx_mem_pool: " 198744961713Sgirish " must be power of 2")); 198844961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 198944961713Sgirish goto nxge_alloc_rx_mem_pool_exit; 199044961713Sgirish } 199144961713Sgirish 199244961713Sgirish if (rx_buf_alloc_size > (1 << 22)) { 199344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 199444961713Sgirish "==> nxge_alloc_rx_mem_pool: " 199544961713Sgirish " limit size to 4M")); 199644961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 199744961713Sgirish goto nxge_alloc_rx_mem_pool_exit; 199844961713Sgirish } 199944961713Sgirish 200044961713Sgirish if (rx_cntl_alloc_size < 0x2000) { 200144961713Sgirish rx_cntl_alloc_size = 0x2000; 200244961713Sgirish } 200344961713Sgirish } 200444961713Sgirish #endif 200544961713Sgirish nxgep->nxge_port_rbr_size = nxge_port_rbr_size; 200644961713Sgirish nxgep->nxge_port_rcr_size = nxge_port_rcr_size; 200744961713Sgirish 200844961713Sgirish /* 200944961713Sgirish * Allocate memory for receive buffers and descriptor rings. 201044961713Sgirish * Replace allocation functions with interface functions provided 201144961713Sgirish * by the partition manager when it is available. 201244961713Sgirish */ 201344961713Sgirish /* 201444961713Sgirish * Allocate memory for the receive buffer blocks. 201544961713Sgirish */ 201644961713Sgirish for (i = 0; i < ndmas; i++) { 201744961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 201844961713Sgirish " nxge_alloc_rx_mem_pool to alloc mem: " 201944961713Sgirish " dma %d dma_buf_p %llx &dma_buf_p %llx", 202044961713Sgirish i, dma_buf_p[i], &dma_buf_p[i])); 202144961713Sgirish num_chunks[i] = 0; 202244961713Sgirish status = nxge_alloc_rx_buf_dma(nxgep, st_rdc, &dma_buf_p[i], 202344961713Sgirish rx_buf_alloc_size, 202444961713Sgirish nxgep->rx_default_block_size, &num_chunks[i]); 202544961713Sgirish if (status != NXGE_OK) { 202644961713Sgirish break; 202744961713Sgirish } 202844961713Sgirish st_rdc++; 202944961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 203044961713Sgirish " nxge_alloc_rx_mem_pool DONE alloc mem: " 203144961713Sgirish "dma %d dma_buf_p %llx &dma_buf_p %llx", i, 203244961713Sgirish dma_buf_p[i], &dma_buf_p[i])); 203344961713Sgirish } 203444961713Sgirish if (i < ndmas) { 203544961713Sgirish goto nxge_alloc_rx_mem_fail1; 203644961713Sgirish } 203744961713Sgirish /* 203844961713Sgirish * Allocate memory for descriptor rings and mailbox. 203944961713Sgirish */ 204044961713Sgirish st_rdc = p_cfgp->start_rdc; 204144961713Sgirish for (j = 0; j < ndmas; j++) { 204244961713Sgirish status = nxge_alloc_rx_cntl_dma(nxgep, st_rdc, &dma_cntl_p[j], 204344961713Sgirish rx_cntl_alloc_size); 204444961713Sgirish if (status != NXGE_OK) { 204544961713Sgirish break; 204644961713Sgirish } 204744961713Sgirish st_rdc++; 204844961713Sgirish } 204944961713Sgirish if (j < ndmas) { 205044961713Sgirish goto nxge_alloc_rx_mem_fail2; 205144961713Sgirish } 205244961713Sgirish 205344961713Sgirish dma_poolp->ndmas = ndmas; 205444961713Sgirish dma_poolp->num_chunks = num_chunks; 205544961713Sgirish dma_poolp->buf_allocated = B_TRUE; 205644961713Sgirish nxgep->rx_buf_pool_p = dma_poolp; 205744961713Sgirish dma_poolp->dma_buf_pool_p = dma_buf_p; 205844961713Sgirish 205944961713Sgirish dma_cntl_poolp->ndmas = ndmas; 206044961713Sgirish dma_cntl_poolp->buf_allocated = B_TRUE; 206144961713Sgirish nxgep->rx_cntl_pool_p = dma_cntl_poolp; 206244961713Sgirish dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 206344961713Sgirish 206444961713Sgirish goto nxge_alloc_rx_mem_pool_exit; 206544961713Sgirish 206644961713Sgirish nxge_alloc_rx_mem_fail2: 206744961713Sgirish /* Free control buffers */ 206844961713Sgirish j--; 206944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 207044961713Sgirish "==> nxge_alloc_rx_mem_pool: freeing control bufs (%d)", j)); 207144961713Sgirish for (; j >= 0; j--) { 207244961713Sgirish nxge_free_rx_cntl_dma(nxgep, 207356d930aeSspeer (p_nxge_dma_common_t)dma_cntl_p[j]); 207444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 207544961713Sgirish "==> nxge_alloc_rx_mem_pool: control bufs freed (%d)", 207644961713Sgirish j)); 207744961713Sgirish } 207844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 207944961713Sgirish "==> nxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 208044961713Sgirish 208144961713Sgirish nxge_alloc_rx_mem_fail1: 208244961713Sgirish /* Free data buffers */ 208344961713Sgirish i--; 208444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 208544961713Sgirish "==> nxge_alloc_rx_mem_pool: freeing data bufs (%d)", i)); 208644961713Sgirish for (; i >= 0; i--) { 208744961713Sgirish nxge_free_rx_buf_dma(nxgep, (p_nxge_dma_common_t)dma_buf_p[i], 208844961713Sgirish num_chunks[i]); 208944961713Sgirish } 209044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 209144961713Sgirish "==> nxge_alloc_rx_mem_pool: data bufs freed (%d)", i)); 209244961713Sgirish 209344961713Sgirish KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 209444961713Sgirish KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 209544961713Sgirish KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 209644961713Sgirish KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 209744961713Sgirish KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 209844961713Sgirish 209944961713Sgirish nxge_alloc_rx_mem_pool_exit: 210044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 210144961713Sgirish "<== nxge_alloc_rx_mem_pool:status 0x%08x", status)); 210244961713Sgirish 210344961713Sgirish return (status); 210444961713Sgirish } 210544961713Sgirish 210644961713Sgirish static void 210744961713Sgirish nxge_free_rx_mem_pool(p_nxge_t nxgep) 210844961713Sgirish { 210944961713Sgirish uint32_t i, ndmas; 211044961713Sgirish p_nxge_dma_pool_t dma_poolp; 211144961713Sgirish p_nxge_dma_common_t *dma_buf_p; 211244961713Sgirish p_nxge_dma_pool_t dma_cntl_poolp; 211344961713Sgirish p_nxge_dma_common_t *dma_cntl_p; 211444961713Sgirish uint32_t *num_chunks; 211544961713Sgirish 211644961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_free_rx_mem_pool")); 211744961713Sgirish 211844961713Sgirish dma_poolp = nxgep->rx_buf_pool_p; 211944961713Sgirish if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 212044961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 212144961713Sgirish "<== nxge_free_rx_mem_pool " 212244961713Sgirish "(null rx buf pool or buf not allocated")); 212344961713Sgirish return; 212444961713Sgirish } 212544961713Sgirish 212644961713Sgirish dma_cntl_poolp = nxgep->rx_cntl_pool_p; 212744961713Sgirish if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 212844961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 212944961713Sgirish "<== nxge_free_rx_mem_pool " 213044961713Sgirish "(null rx cntl buf pool or cntl buf not allocated")); 213144961713Sgirish return; 213244961713Sgirish } 213344961713Sgirish 213444961713Sgirish dma_buf_p = dma_poolp->dma_buf_pool_p; 213544961713Sgirish num_chunks = dma_poolp->num_chunks; 213644961713Sgirish 213744961713Sgirish dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 213844961713Sgirish ndmas = dma_cntl_poolp->ndmas; 213944961713Sgirish 214044961713Sgirish for (i = 0; i < ndmas; i++) { 214144961713Sgirish nxge_free_rx_buf_dma(nxgep, dma_buf_p[i], num_chunks[i]); 214244961713Sgirish } 214344961713Sgirish 214444961713Sgirish for (i = 0; i < ndmas; i++) { 214544961713Sgirish nxge_free_rx_cntl_dma(nxgep, dma_cntl_p[i]); 214644961713Sgirish } 214744961713Sgirish 214844961713Sgirish for (i = 0; i < ndmas; i++) { 214944961713Sgirish KMEM_FREE(dma_buf_p[i], 215044961713Sgirish sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 215144961713Sgirish KMEM_FREE(dma_cntl_p[i], sizeof (nxge_dma_common_t)); 215244961713Sgirish } 215344961713Sgirish 215444961713Sgirish KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 215544961713Sgirish KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 215644961713Sgirish KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 215744961713Sgirish KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 215844961713Sgirish KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 215944961713Sgirish 216044961713Sgirish nxgep->rx_buf_pool_p = NULL; 216144961713Sgirish nxgep->rx_cntl_pool_p = NULL; 216244961713Sgirish 216344961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "<== nxge_free_rx_mem_pool")); 216444961713Sgirish } 216544961713Sgirish 216644961713Sgirish 216744961713Sgirish static nxge_status_t 216844961713Sgirish nxge_alloc_rx_buf_dma(p_nxge_t nxgep, uint16_t dma_channel, 216944961713Sgirish p_nxge_dma_common_t *dmap, 217044961713Sgirish size_t alloc_size, size_t block_size, uint32_t *num_chunks) 217144961713Sgirish { 217244961713Sgirish p_nxge_dma_common_t rx_dmap; 217344961713Sgirish nxge_status_t status = NXGE_OK; 217444961713Sgirish size_t total_alloc_size; 217544961713Sgirish size_t allocated = 0; 217644961713Sgirish int i, size_index, array_size; 217744961713Sgirish 217844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_buf_dma")); 217944961713Sgirish 218044961713Sgirish rx_dmap = (p_nxge_dma_common_t) 218144961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK, 218244961713Sgirish KM_SLEEP); 218344961713Sgirish 218444961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 218544961713Sgirish " alloc_rx_buf_dma rdc %d asize %x bsize %x bbuf %llx ", 218644961713Sgirish dma_channel, alloc_size, block_size, dmap)); 218744961713Sgirish 218844961713Sgirish total_alloc_size = alloc_size; 218944961713Sgirish 219044961713Sgirish #if defined(RX_USE_RECLAIM_POST) 219144961713Sgirish total_alloc_size = alloc_size + alloc_size/4; 219244961713Sgirish #endif 219344961713Sgirish 219444961713Sgirish i = 0; 219544961713Sgirish size_index = 0; 219644961713Sgirish array_size = sizeof (alloc_sizes)/sizeof (size_t); 219744961713Sgirish while ((alloc_sizes[size_index] < alloc_size) && 219844961713Sgirish (size_index < array_size)) 219944961713Sgirish size_index++; 220044961713Sgirish if (size_index >= array_size) { 220144961713Sgirish size_index = array_size - 1; 220244961713Sgirish } 220344961713Sgirish 220444961713Sgirish while ((allocated < total_alloc_size) && 220544961713Sgirish (size_index >= 0) && (i < NXGE_DMA_BLOCK)) { 220644961713Sgirish rx_dmap[i].dma_chunk_index = i; 220744961713Sgirish rx_dmap[i].block_size = block_size; 220844961713Sgirish rx_dmap[i].alength = alloc_sizes[size_index]; 220944961713Sgirish rx_dmap[i].orig_alength = rx_dmap[i].alength; 221044961713Sgirish rx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 221144961713Sgirish rx_dmap[i].dma_channel = dma_channel; 221244961713Sgirish rx_dmap[i].contig_alloc_type = B_FALSE; 221344961713Sgirish 221444961713Sgirish /* 221544961713Sgirish * N2/NIU: data buffers must be contiguous as the driver 221644961713Sgirish * needs to call Hypervisor api to set up 221744961713Sgirish * logical pages. 221844961713Sgirish */ 221944961713Sgirish if ((nxgep->niu_type == N2_NIU) && (NXGE_DMA_BLOCK == 1)) { 222044961713Sgirish rx_dmap[i].contig_alloc_type = B_TRUE; 222144961713Sgirish } 222244961713Sgirish 222344961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 222444961713Sgirish "alloc_rx_buf_dma rdc %d chunk %d bufp %llx size %x " 222544961713Sgirish "i %d nblocks %d alength %d", 222644961713Sgirish dma_channel, i, &rx_dmap[i], block_size, 222744961713Sgirish i, rx_dmap[i].nblocks, 222844961713Sgirish rx_dmap[i].alength)); 222944961713Sgirish status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 223044961713Sgirish &nxge_rx_dma_attr, 223144961713Sgirish rx_dmap[i].alength, 223244961713Sgirish &nxge_dev_buf_dma_acc_attr, 223344961713Sgirish DDI_DMA_READ | DDI_DMA_STREAMING, 223444961713Sgirish (p_nxge_dma_common_t)(&rx_dmap[i])); 223544961713Sgirish if (status != NXGE_OK) { 223644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 223744961713Sgirish " nxge_alloc_rx_buf_dma: Alloc Failed ")); 223844961713Sgirish size_index--; 223944961713Sgirish } else { 224044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 224144961713Sgirish " alloc_rx_buf_dma allocated rdc %d " 224244961713Sgirish "chunk %d size %x dvma %x bufp %llx ", 224344961713Sgirish dma_channel, i, rx_dmap[i].alength, 224444961713Sgirish rx_dmap[i].ioaddr_pp, &rx_dmap[i])); 224544961713Sgirish i++; 224644961713Sgirish allocated += alloc_sizes[size_index]; 224744961713Sgirish } 224844961713Sgirish } 224944961713Sgirish 225044961713Sgirish 225144961713Sgirish if (allocated < total_alloc_size) { 225244961713Sgirish goto nxge_alloc_rx_mem_fail1; 225344961713Sgirish } 225444961713Sgirish 225544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 225644961713Sgirish " alloc_rx_buf_dma rdc %d allocated %d chunks", 225744961713Sgirish dma_channel, i)); 225844961713Sgirish *num_chunks = i; 225944961713Sgirish *dmap = rx_dmap; 226044961713Sgirish 226144961713Sgirish goto nxge_alloc_rx_mem_exit; 226244961713Sgirish 226344961713Sgirish nxge_alloc_rx_mem_fail1: 226444961713Sgirish KMEM_FREE(rx_dmap, sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 226544961713Sgirish 226644961713Sgirish nxge_alloc_rx_mem_exit: 226744961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 226844961713Sgirish "<== nxge_alloc_rx_buf_dma status 0x%08x", status)); 226944961713Sgirish 227044961713Sgirish return (status); 227144961713Sgirish } 227244961713Sgirish 227344961713Sgirish /*ARGSUSED*/ 227444961713Sgirish static void 227544961713Sgirish nxge_free_rx_buf_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap, 227644961713Sgirish uint32_t num_chunks) 227744961713Sgirish { 227844961713Sgirish int i; 227944961713Sgirish 228044961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 228144961713Sgirish "==> nxge_free_rx_buf_dma: # of chunks %d", num_chunks)); 228244961713Sgirish 228344961713Sgirish for (i = 0; i < num_chunks; i++) { 228444961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, 228544961713Sgirish "==> nxge_free_rx_buf_dma: chunk %d dmap 0x%llx", 228644961713Sgirish i, dmap)); 228744961713Sgirish nxge_dma_mem_free(dmap++); 228844961713Sgirish } 228944961713Sgirish 229044961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM2_CTL, "==> nxge_free_rx_buf_dma")); 229144961713Sgirish } 229244961713Sgirish 229344961713Sgirish /*ARGSUSED*/ 229444961713Sgirish static nxge_status_t 229544961713Sgirish nxge_alloc_rx_cntl_dma(p_nxge_t nxgep, uint16_t dma_channel, 229644961713Sgirish p_nxge_dma_common_t *dmap, size_t size) 229744961713Sgirish { 229844961713Sgirish p_nxge_dma_common_t rx_dmap; 229944961713Sgirish nxge_status_t status = NXGE_OK; 230044961713Sgirish 230144961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_rx_cntl_dma")); 230244961713Sgirish 230344961713Sgirish rx_dmap = (p_nxge_dma_common_t) 230444961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_common_t), KM_SLEEP); 230544961713Sgirish 230644961713Sgirish rx_dmap->contig_alloc_type = B_FALSE; 230744961713Sgirish 230844961713Sgirish status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 230944961713Sgirish &nxge_desc_dma_attr, 231044961713Sgirish size, 231144961713Sgirish &nxge_dev_desc_dma_acc_attr, 231244961713Sgirish DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 231344961713Sgirish rx_dmap); 231444961713Sgirish if (status != NXGE_OK) { 231544961713Sgirish goto nxge_alloc_rx_cntl_dma_fail1; 231644961713Sgirish } 231744961713Sgirish 231844961713Sgirish *dmap = rx_dmap; 231944961713Sgirish goto nxge_alloc_rx_cntl_dma_exit; 232044961713Sgirish 232144961713Sgirish nxge_alloc_rx_cntl_dma_fail1: 232244961713Sgirish KMEM_FREE(rx_dmap, sizeof (nxge_dma_common_t)); 232344961713Sgirish 232444961713Sgirish nxge_alloc_rx_cntl_dma_exit: 232544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 232644961713Sgirish "<== nxge_alloc_rx_cntl_dma status 0x%08x", status)); 232744961713Sgirish 232844961713Sgirish return (status); 232944961713Sgirish } 233044961713Sgirish 233144961713Sgirish /*ARGSUSED*/ 233244961713Sgirish static void 233344961713Sgirish nxge_free_rx_cntl_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap) 233444961713Sgirish { 233544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_free_rx_cntl_dma")); 233644961713Sgirish 233744961713Sgirish nxge_dma_mem_free(dmap); 233844961713Sgirish 233944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_free_rx_cntl_dma")); 234044961713Sgirish } 234144961713Sgirish 234244961713Sgirish static nxge_status_t 234344961713Sgirish nxge_alloc_tx_mem_pool(p_nxge_t nxgep) 234444961713Sgirish { 234544961713Sgirish nxge_status_t status = NXGE_OK; 234644961713Sgirish int i, j; 234744961713Sgirish uint32_t ndmas, st_tdc; 234844961713Sgirish p_nxge_dma_pt_cfg_t p_all_cfgp; 234944961713Sgirish p_nxge_hw_pt_cfg_t p_cfgp; 235044961713Sgirish p_nxge_dma_pool_t dma_poolp; 235144961713Sgirish p_nxge_dma_common_t *dma_buf_p; 235244961713Sgirish p_nxge_dma_pool_t dma_cntl_poolp; 235344961713Sgirish p_nxge_dma_common_t *dma_cntl_p; 235444961713Sgirish size_t tx_buf_alloc_size; 235544961713Sgirish size_t tx_cntl_alloc_size; 235644961713Sgirish uint32_t *num_chunks; /* per dma */ 23571f8914d5Sml uint32_t bcopy_thresh; 235844961713Sgirish 235944961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_alloc_tx_mem_pool")); 236044961713Sgirish 236144961713Sgirish p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 236244961713Sgirish p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 236344961713Sgirish st_tdc = p_cfgp->start_tdc; 236444961713Sgirish ndmas = p_cfgp->max_tdcs; 236544961713Sgirish 236644961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_alloc_tx_mem_pool: " 236744961713Sgirish "p_cfgp 0x%016llx start_tdc %d ndmas %d nxgep->max_tdcs %d", 236844961713Sgirish p_cfgp, p_cfgp->start_tdc, p_cfgp->max_tdcs, nxgep->max_tdcs)); 236944961713Sgirish /* 237044961713Sgirish * Allocate memory for each transmit DMA channel. 237144961713Sgirish */ 237244961713Sgirish dma_poolp = (p_nxge_dma_pool_t)KMEM_ZALLOC(sizeof (nxge_dma_pool_t), 237344961713Sgirish KM_SLEEP); 237444961713Sgirish dma_buf_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 237544961713Sgirish sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 237644961713Sgirish 237744961713Sgirish dma_cntl_poolp = (p_nxge_dma_pool_t) 237844961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_pool_t), KM_SLEEP); 237944961713Sgirish dma_cntl_p = (p_nxge_dma_common_t *)KMEM_ZALLOC( 238044961713Sgirish sizeof (p_nxge_dma_common_t) * ndmas, KM_SLEEP); 238144961713Sgirish 238244961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 238344961713Sgirish /* 238444961713Sgirish * N2/NIU has limitation on the descriptor sizes (contiguous 238544961713Sgirish * memory allocation on data buffers to 4M (contig_mem_alloc) 238644961713Sgirish * and little endian for control buffers (must use the ddi/dki mem alloc 238744961713Sgirish * function). The transmit ring is limited to 8K (includes the 238844961713Sgirish * mailbox). 238944961713Sgirish */ 239044961713Sgirish if (nxgep->niu_type == N2_NIU) { 239144961713Sgirish if ((nxge_tx_ring_size > NXGE_NIU_CONTIG_TX_MAX) || 239244961713Sgirish (!ISP2(nxge_tx_ring_size))) { 239344961713Sgirish nxge_tx_ring_size = NXGE_NIU_CONTIG_TX_MAX; 239444961713Sgirish } 239544961713Sgirish } 239644961713Sgirish #endif 239744961713Sgirish 239844961713Sgirish nxgep->nxge_port_tx_ring_size = nxge_tx_ring_size; 239944961713Sgirish 240044961713Sgirish /* 240144961713Sgirish * Assume that each DMA channel will be configured with default 240244961713Sgirish * transmit bufer size for copying transmit data. 240344961713Sgirish * (For packet payload over this limit, packets will not be 240444961713Sgirish * copied.) 240544961713Sgirish */ 24061f8914d5Sml if (nxgep->niu_type == N2_NIU) { 24071f8914d5Sml bcopy_thresh = TX_BCOPY_SIZE; 24081f8914d5Sml } else { 24091f8914d5Sml bcopy_thresh = nxge_bcopy_thresh; 24101f8914d5Sml } 24111f8914d5Sml tx_buf_alloc_size = (bcopy_thresh * nxge_tx_ring_size); 241244961713Sgirish 241344961713Sgirish /* 241444961713Sgirish * Addresses of transmit descriptor ring and the 241544961713Sgirish * mailbox must be all cache-aligned (64 bytes). 241644961713Sgirish */ 241744961713Sgirish tx_cntl_alloc_size = nxge_tx_ring_size; 241844961713Sgirish tx_cntl_alloc_size *= (sizeof (tx_desc_t)); 241944961713Sgirish tx_cntl_alloc_size += sizeof (txdma_mailbox_t); 242044961713Sgirish 242144961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 242244961713Sgirish if (nxgep->niu_type == N2_NIU) { 242344961713Sgirish if (!ISP2(tx_buf_alloc_size)) { 242444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 242544961713Sgirish "==> nxge_alloc_tx_mem_pool: " 242644961713Sgirish " must be power of 2")); 242744961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 242844961713Sgirish goto nxge_alloc_tx_mem_pool_exit; 242944961713Sgirish } 243044961713Sgirish 243144961713Sgirish if (tx_buf_alloc_size > (1 << 22)) { 243244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 243344961713Sgirish "==> nxge_alloc_tx_mem_pool: " 243444961713Sgirish " limit size to 4M")); 243544961713Sgirish status |= (NXGE_ERROR | NXGE_DDI_FAILED); 243644961713Sgirish goto nxge_alloc_tx_mem_pool_exit; 243744961713Sgirish } 243844961713Sgirish 243944961713Sgirish if (tx_cntl_alloc_size < 0x2000) { 244044961713Sgirish tx_cntl_alloc_size = 0x2000; 244144961713Sgirish } 244244961713Sgirish } 244344961713Sgirish #endif 244444961713Sgirish 244544961713Sgirish num_chunks = (uint32_t *)KMEM_ZALLOC( 244644961713Sgirish sizeof (uint32_t) * ndmas, KM_SLEEP); 244744961713Sgirish 244844961713Sgirish /* 244944961713Sgirish * Allocate memory for transmit buffers and descriptor rings. 245044961713Sgirish * Replace allocation functions with interface functions provided 245144961713Sgirish * by the partition manager when it is available. 245244961713Sgirish * 245344961713Sgirish * Allocate memory for the transmit buffer pool. 245444961713Sgirish */ 245544961713Sgirish for (i = 0; i < ndmas; i++) { 245644961713Sgirish num_chunks[i] = 0; 245744961713Sgirish status = nxge_alloc_tx_buf_dma(nxgep, st_tdc, &dma_buf_p[i], 245844961713Sgirish tx_buf_alloc_size, 24591f8914d5Sml bcopy_thresh, &num_chunks[i]); 246044961713Sgirish if (status != NXGE_OK) { 246144961713Sgirish break; 246244961713Sgirish } 246344961713Sgirish st_tdc++; 246444961713Sgirish } 246544961713Sgirish if (i < ndmas) { 246644961713Sgirish goto nxge_alloc_tx_mem_pool_fail1; 246744961713Sgirish } 246844961713Sgirish 246944961713Sgirish st_tdc = p_cfgp->start_tdc; 247044961713Sgirish /* 247144961713Sgirish * Allocate memory for descriptor rings and mailbox. 247244961713Sgirish */ 247344961713Sgirish for (j = 0; j < ndmas; j++) { 247444961713Sgirish status = nxge_alloc_tx_cntl_dma(nxgep, st_tdc, &dma_cntl_p[j], 247544961713Sgirish tx_cntl_alloc_size); 247644961713Sgirish if (status != NXGE_OK) { 247744961713Sgirish break; 247844961713Sgirish } 247944961713Sgirish st_tdc++; 248044961713Sgirish } 248144961713Sgirish if (j < ndmas) { 248244961713Sgirish goto nxge_alloc_tx_mem_pool_fail2; 248344961713Sgirish } 248444961713Sgirish 248544961713Sgirish dma_poolp->ndmas = ndmas; 248644961713Sgirish dma_poolp->num_chunks = num_chunks; 248744961713Sgirish dma_poolp->buf_allocated = B_TRUE; 248844961713Sgirish dma_poolp->dma_buf_pool_p = dma_buf_p; 248944961713Sgirish nxgep->tx_buf_pool_p = dma_poolp; 249044961713Sgirish 249144961713Sgirish dma_cntl_poolp->ndmas = ndmas; 249244961713Sgirish dma_cntl_poolp->buf_allocated = B_TRUE; 249344961713Sgirish dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 249444961713Sgirish nxgep->tx_cntl_pool_p = dma_cntl_poolp; 249544961713Sgirish 249644961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, 249744961713Sgirish "==> nxge_alloc_tx_mem_pool: start_tdc %d " 249844961713Sgirish "ndmas %d poolp->ndmas %d", 249944961713Sgirish st_tdc, ndmas, dma_poolp->ndmas)); 250044961713Sgirish 250144961713Sgirish goto nxge_alloc_tx_mem_pool_exit; 250244961713Sgirish 250344961713Sgirish nxge_alloc_tx_mem_pool_fail2: 250444961713Sgirish /* Free control buffers */ 250544961713Sgirish j--; 250644961713Sgirish for (; j >= 0; j--) { 250744961713Sgirish nxge_free_tx_cntl_dma(nxgep, 250856d930aeSspeer (p_nxge_dma_common_t)dma_cntl_p[j]); 250944961713Sgirish } 251044961713Sgirish 251144961713Sgirish nxge_alloc_tx_mem_pool_fail1: 251244961713Sgirish /* Free data buffers */ 251344961713Sgirish i--; 251444961713Sgirish for (; i >= 0; i--) { 251544961713Sgirish nxge_free_tx_buf_dma(nxgep, (p_nxge_dma_common_t)dma_buf_p[i], 251644961713Sgirish num_chunks[i]); 251744961713Sgirish } 251844961713Sgirish 251944961713Sgirish KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 252044961713Sgirish KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 252144961713Sgirish KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 252244961713Sgirish KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 252344961713Sgirish KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 252444961713Sgirish 252544961713Sgirish nxge_alloc_tx_mem_pool_exit: 252644961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, 252744961713Sgirish "<== nxge_alloc_tx_mem_pool:status 0x%08x", status)); 252844961713Sgirish 252944961713Sgirish return (status); 253044961713Sgirish } 253144961713Sgirish 253244961713Sgirish static nxge_status_t 253344961713Sgirish nxge_alloc_tx_buf_dma(p_nxge_t nxgep, uint16_t dma_channel, 253444961713Sgirish p_nxge_dma_common_t *dmap, size_t alloc_size, 253544961713Sgirish size_t block_size, uint32_t *num_chunks) 253644961713Sgirish { 253744961713Sgirish p_nxge_dma_common_t tx_dmap; 253844961713Sgirish nxge_status_t status = NXGE_OK; 253944961713Sgirish size_t total_alloc_size; 254044961713Sgirish size_t allocated = 0; 254144961713Sgirish int i, size_index, array_size; 254244961713Sgirish 254344961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_tx_buf_dma")); 254444961713Sgirish 254544961713Sgirish tx_dmap = (p_nxge_dma_common_t) 254644961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK, 254744961713Sgirish KM_SLEEP); 254844961713Sgirish 254944961713Sgirish total_alloc_size = alloc_size; 255044961713Sgirish i = 0; 255144961713Sgirish size_index = 0; 255244961713Sgirish array_size = sizeof (alloc_sizes) / sizeof (size_t); 255344961713Sgirish while ((alloc_sizes[size_index] < alloc_size) && 255444961713Sgirish (size_index < array_size)) 255544961713Sgirish size_index++; 255644961713Sgirish if (size_index >= array_size) { 255744961713Sgirish size_index = array_size - 1; 255844961713Sgirish } 255944961713Sgirish 256044961713Sgirish while ((allocated < total_alloc_size) && 256144961713Sgirish (size_index >= 0) && (i < NXGE_DMA_BLOCK)) { 256244961713Sgirish 256344961713Sgirish tx_dmap[i].dma_chunk_index = i; 256444961713Sgirish tx_dmap[i].block_size = block_size; 256544961713Sgirish tx_dmap[i].alength = alloc_sizes[size_index]; 256644961713Sgirish tx_dmap[i].orig_alength = tx_dmap[i].alength; 256744961713Sgirish tx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 256844961713Sgirish tx_dmap[i].dma_channel = dma_channel; 256944961713Sgirish tx_dmap[i].contig_alloc_type = B_FALSE; 257044961713Sgirish 257144961713Sgirish /* 257244961713Sgirish * N2/NIU: data buffers must be contiguous as the driver 257344961713Sgirish * needs to call Hypervisor api to set up 257444961713Sgirish * logical pages. 257544961713Sgirish */ 257644961713Sgirish if ((nxgep->niu_type == N2_NIU) && (NXGE_DMA_BLOCK == 1)) { 257744961713Sgirish tx_dmap[i].contig_alloc_type = B_TRUE; 257844961713Sgirish } 257944961713Sgirish 258044961713Sgirish status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 258144961713Sgirish &nxge_tx_dma_attr, 258244961713Sgirish tx_dmap[i].alength, 258344961713Sgirish &nxge_dev_buf_dma_acc_attr, 258444961713Sgirish DDI_DMA_WRITE | DDI_DMA_STREAMING, 258544961713Sgirish (p_nxge_dma_common_t)(&tx_dmap[i])); 258644961713Sgirish if (status != NXGE_OK) { 258744961713Sgirish size_index--; 258844961713Sgirish } else { 258944961713Sgirish i++; 259044961713Sgirish allocated += alloc_sizes[size_index]; 259144961713Sgirish } 259244961713Sgirish } 259344961713Sgirish 259444961713Sgirish if (allocated < total_alloc_size) { 259544961713Sgirish goto nxge_alloc_tx_mem_fail1; 259644961713Sgirish } 259744961713Sgirish 259844961713Sgirish *num_chunks = i; 259944961713Sgirish *dmap = tx_dmap; 260044961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 260144961713Sgirish "==> nxge_alloc_tx_buf_dma dmap 0x%016llx num chunks %d", 260244961713Sgirish *dmap, i)); 260344961713Sgirish goto nxge_alloc_tx_mem_exit; 260444961713Sgirish 260544961713Sgirish nxge_alloc_tx_mem_fail1: 260644961713Sgirish KMEM_FREE(tx_dmap, sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 260744961713Sgirish 260844961713Sgirish nxge_alloc_tx_mem_exit: 260944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 261044961713Sgirish "<== nxge_alloc_tx_buf_dma status 0x%08x", status)); 261144961713Sgirish 261244961713Sgirish return (status); 261344961713Sgirish } 261444961713Sgirish 261544961713Sgirish /*ARGSUSED*/ 261644961713Sgirish static void 261744961713Sgirish nxge_free_tx_buf_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap, 261844961713Sgirish uint32_t num_chunks) 261944961713Sgirish { 262044961713Sgirish int i; 262144961713Sgirish 262244961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "==> nxge_free_tx_buf_dma")); 262344961713Sgirish 262444961713Sgirish for (i = 0; i < num_chunks; i++) { 262544961713Sgirish nxge_dma_mem_free(dmap++); 262644961713Sgirish } 262744961713Sgirish 262844961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM_CTL, "<== nxge_free_tx_buf_dma")); 262944961713Sgirish } 263044961713Sgirish 263144961713Sgirish /*ARGSUSED*/ 263244961713Sgirish static nxge_status_t 263344961713Sgirish nxge_alloc_tx_cntl_dma(p_nxge_t nxgep, uint16_t dma_channel, 263444961713Sgirish p_nxge_dma_common_t *dmap, size_t size) 263544961713Sgirish { 263644961713Sgirish p_nxge_dma_common_t tx_dmap; 263744961713Sgirish nxge_status_t status = NXGE_OK; 263844961713Sgirish 263944961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_alloc_tx_cntl_dma")); 264044961713Sgirish tx_dmap = (p_nxge_dma_common_t) 264144961713Sgirish KMEM_ZALLOC(sizeof (nxge_dma_common_t), KM_SLEEP); 264244961713Sgirish 264344961713Sgirish tx_dmap->contig_alloc_type = B_FALSE; 264444961713Sgirish 264544961713Sgirish status = nxge_dma_mem_alloc(nxgep, nxge_force_dma, 264644961713Sgirish &nxge_desc_dma_attr, 264744961713Sgirish size, 264844961713Sgirish &nxge_dev_desc_dma_acc_attr, 264944961713Sgirish DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 265044961713Sgirish tx_dmap); 265144961713Sgirish if (status != NXGE_OK) { 265244961713Sgirish goto nxge_alloc_tx_cntl_dma_fail1; 265344961713Sgirish } 265444961713Sgirish 265544961713Sgirish *dmap = tx_dmap; 265644961713Sgirish goto nxge_alloc_tx_cntl_dma_exit; 265744961713Sgirish 265844961713Sgirish nxge_alloc_tx_cntl_dma_fail1: 265944961713Sgirish KMEM_FREE(tx_dmap, sizeof (nxge_dma_common_t)); 266044961713Sgirish 266144961713Sgirish nxge_alloc_tx_cntl_dma_exit: 266244961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 266344961713Sgirish "<== nxge_alloc_tx_cntl_dma status 0x%08x", status)); 266444961713Sgirish 266544961713Sgirish return (status); 266644961713Sgirish } 266744961713Sgirish 266844961713Sgirish /*ARGSUSED*/ 266944961713Sgirish static void 267044961713Sgirish nxge_free_tx_cntl_dma(p_nxge_t nxgep, p_nxge_dma_common_t dmap) 267144961713Sgirish { 267244961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_free_tx_cntl_dma")); 267344961713Sgirish 267444961713Sgirish nxge_dma_mem_free(dmap); 267544961713Sgirish 267644961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_free_tx_cntl_dma")); 267744961713Sgirish } 267844961713Sgirish 267944961713Sgirish static void 268044961713Sgirish nxge_free_tx_mem_pool(p_nxge_t nxgep) 268144961713Sgirish { 268244961713Sgirish uint32_t i, ndmas; 268344961713Sgirish p_nxge_dma_pool_t dma_poolp; 268444961713Sgirish p_nxge_dma_common_t *dma_buf_p; 268544961713Sgirish p_nxge_dma_pool_t dma_cntl_poolp; 268644961713Sgirish p_nxge_dma_common_t *dma_cntl_p; 268744961713Sgirish uint32_t *num_chunks; 268844961713Sgirish 268944961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM3_CTL, "==> nxge_free_tx_mem_pool")); 269044961713Sgirish 269144961713Sgirish dma_poolp = nxgep->tx_buf_pool_p; 269244961713Sgirish if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 269344961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM3_CTL, 269444961713Sgirish "<== nxge_free_tx_mem_pool " 269544961713Sgirish "(null rx buf pool or buf not allocated")); 269644961713Sgirish return; 269744961713Sgirish } 269844961713Sgirish 269944961713Sgirish dma_cntl_poolp = nxgep->tx_cntl_pool_p; 270044961713Sgirish if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 270144961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM3_CTL, 270244961713Sgirish "<== nxge_free_tx_mem_pool " 270344961713Sgirish "(null tx cntl buf pool or cntl buf not allocated")); 270444961713Sgirish return; 270544961713Sgirish } 270644961713Sgirish 270744961713Sgirish dma_buf_p = dma_poolp->dma_buf_pool_p; 270844961713Sgirish num_chunks = dma_poolp->num_chunks; 270944961713Sgirish 271044961713Sgirish dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 271144961713Sgirish ndmas = dma_cntl_poolp->ndmas; 271244961713Sgirish 271344961713Sgirish for (i = 0; i < ndmas; i++) { 271444961713Sgirish nxge_free_tx_buf_dma(nxgep, dma_buf_p[i], num_chunks[i]); 271544961713Sgirish } 271644961713Sgirish 271744961713Sgirish for (i = 0; i < ndmas; i++) { 271844961713Sgirish nxge_free_tx_cntl_dma(nxgep, dma_cntl_p[i]); 271944961713Sgirish } 272044961713Sgirish 272144961713Sgirish for (i = 0; i < ndmas; i++) { 272244961713Sgirish KMEM_FREE(dma_buf_p[i], 272344961713Sgirish sizeof (nxge_dma_common_t) * NXGE_DMA_BLOCK); 272444961713Sgirish KMEM_FREE(dma_cntl_p[i], sizeof (nxge_dma_common_t)); 272544961713Sgirish } 272644961713Sgirish 272744961713Sgirish KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 272844961713Sgirish KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_nxge_dma_common_t)); 272944961713Sgirish KMEM_FREE(dma_cntl_poolp, sizeof (nxge_dma_pool_t)); 273044961713Sgirish KMEM_FREE(dma_buf_p, ndmas * sizeof (p_nxge_dma_common_t)); 273144961713Sgirish KMEM_FREE(dma_poolp, sizeof (nxge_dma_pool_t)); 273244961713Sgirish 273344961713Sgirish nxgep->tx_buf_pool_p = NULL; 273444961713Sgirish nxgep->tx_cntl_pool_p = NULL; 273544961713Sgirish 273644961713Sgirish NXGE_DEBUG_MSG((nxgep, MEM3_CTL, "<== nxge_free_tx_mem_pool")); 273744961713Sgirish } 273844961713Sgirish 273944961713Sgirish /*ARGSUSED*/ 274044961713Sgirish static nxge_status_t 274144961713Sgirish nxge_dma_mem_alloc(p_nxge_t nxgep, dma_method_t method, 274244961713Sgirish struct ddi_dma_attr *dma_attrp, 274344961713Sgirish size_t length, ddi_device_acc_attr_t *acc_attr_p, uint_t xfer_flags, 274444961713Sgirish p_nxge_dma_common_t dma_p) 274544961713Sgirish { 274644961713Sgirish caddr_t kaddrp; 274744961713Sgirish int ddi_status = DDI_SUCCESS; 274844961713Sgirish boolean_t contig_alloc_type; 274944961713Sgirish 275044961713Sgirish contig_alloc_type = dma_p->contig_alloc_type; 275144961713Sgirish 275244961713Sgirish if (contig_alloc_type && (nxgep->niu_type != N2_NIU)) { 275344961713Sgirish /* 275444961713Sgirish * contig_alloc_type for contiguous memory only allowed 275544961713Sgirish * for N2/NIU. 275644961713Sgirish */ 275744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 275844961713Sgirish "nxge_dma_mem_alloc: alloc type not allows (%d)", 275944961713Sgirish dma_p->contig_alloc_type)); 276044961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 276144961713Sgirish } 276244961713Sgirish 276344961713Sgirish dma_p->dma_handle = NULL; 276444961713Sgirish dma_p->acc_handle = NULL; 276544961713Sgirish dma_p->kaddrp = dma_p->last_kaddrp = NULL; 276644961713Sgirish dma_p->first_ioaddr_pp = dma_p->last_ioaddr_pp = NULL; 276744961713Sgirish ddi_status = ddi_dma_alloc_handle(nxgep->dip, dma_attrp, 276844961713Sgirish DDI_DMA_DONTWAIT, NULL, &dma_p->dma_handle); 276944961713Sgirish if (ddi_status != DDI_SUCCESS) { 277044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 277144961713Sgirish "nxge_dma_mem_alloc:ddi_dma_alloc_handle failed.")); 277244961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 277344961713Sgirish } 277444961713Sgirish 277544961713Sgirish switch (contig_alloc_type) { 277644961713Sgirish case B_FALSE: 277744961713Sgirish ddi_status = ddi_dma_mem_alloc(dma_p->dma_handle, length, 277844961713Sgirish acc_attr_p, 277944961713Sgirish xfer_flags, 278044961713Sgirish DDI_DMA_DONTWAIT, 0, &kaddrp, &dma_p->alength, 278144961713Sgirish &dma_p->acc_handle); 278244961713Sgirish if (ddi_status != DDI_SUCCESS) { 278344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 278444961713Sgirish "nxge_dma_mem_alloc:ddi_dma_mem_alloc failed")); 278544961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 278644961713Sgirish dma_p->dma_handle = NULL; 278744961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 278844961713Sgirish } 278944961713Sgirish if (dma_p->alength < length) { 279044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 279144961713Sgirish "nxge_dma_mem_alloc:ddi_dma_mem_alloc " 279244961713Sgirish "< length.")); 279344961713Sgirish ddi_dma_mem_free(&dma_p->acc_handle); 279444961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 279544961713Sgirish dma_p->acc_handle = NULL; 279644961713Sgirish dma_p->dma_handle = NULL; 279744961713Sgirish return (NXGE_ERROR); 279844961713Sgirish } 279944961713Sgirish 280044961713Sgirish ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 280144961713Sgirish kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 280244961713Sgirish &dma_p->dma_cookie, &dma_p->ncookies); 280344961713Sgirish if (ddi_status != DDI_DMA_MAPPED) { 280444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 280544961713Sgirish "nxge_dma_mem_alloc:di_dma_addr_bind failed " 280644961713Sgirish "(staus 0x%x ncookies %d.)", ddi_status, 280744961713Sgirish dma_p->ncookies)); 280844961713Sgirish if (dma_p->acc_handle) { 280944961713Sgirish ddi_dma_mem_free(&dma_p->acc_handle); 281044961713Sgirish dma_p->acc_handle = NULL; 281144961713Sgirish } 281244961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 281344961713Sgirish dma_p->dma_handle = NULL; 281444961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 281544961713Sgirish } 281644961713Sgirish 281744961713Sgirish if (dma_p->ncookies != 1) { 281844961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 281944961713Sgirish "nxge_dma_mem_alloc:ddi_dma_addr_bind " 282044961713Sgirish "> 1 cookie" 282144961713Sgirish "(staus 0x%x ncookies %d.)", ddi_status, 282244961713Sgirish dma_p->ncookies)); 282344961713Sgirish if (dma_p->acc_handle) { 282444961713Sgirish ddi_dma_mem_free(&dma_p->acc_handle); 282544961713Sgirish dma_p->acc_handle = NULL; 282644961713Sgirish } 282756d930aeSspeer (void) ddi_dma_unbind_handle(dma_p->dma_handle); 282844961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 282944961713Sgirish dma_p->dma_handle = NULL; 283044961713Sgirish return (NXGE_ERROR); 283144961713Sgirish } 283244961713Sgirish break; 283344961713Sgirish 283444961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 283544961713Sgirish case B_TRUE: 283644961713Sgirish kaddrp = (caddr_t)contig_mem_alloc(length); 283744961713Sgirish if (kaddrp == NULL) { 283844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 283944961713Sgirish "nxge_dma_mem_alloc:contig_mem_alloc failed.")); 284044961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 284144961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 284244961713Sgirish } 284344961713Sgirish 284444961713Sgirish dma_p->alength = length; 284544961713Sgirish ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 284644961713Sgirish kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 284744961713Sgirish &dma_p->dma_cookie, &dma_p->ncookies); 284844961713Sgirish if (ddi_status != DDI_DMA_MAPPED) { 284944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 285044961713Sgirish "nxge_dma_mem_alloc:di_dma_addr_bind failed " 285144961713Sgirish "(status 0x%x ncookies %d.)", ddi_status, 285244961713Sgirish dma_p->ncookies)); 285344961713Sgirish 285444961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, 285544961713Sgirish "==> nxge_dma_mem_alloc: (not mapped)" 285644961713Sgirish "length %lu (0x%x) " 285744961713Sgirish "free contig kaddrp $%p " 285844961713Sgirish "va_to_pa $%p", 285944961713Sgirish length, length, 286044961713Sgirish kaddrp, 286144961713Sgirish va_to_pa(kaddrp))); 286244961713Sgirish 286344961713Sgirish 286444961713Sgirish contig_mem_free((void *)kaddrp, length); 286544961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 286644961713Sgirish 286744961713Sgirish dma_p->dma_handle = NULL; 286844961713Sgirish dma_p->acc_handle = NULL; 286944961713Sgirish dma_p->alength = NULL; 287044961713Sgirish dma_p->kaddrp = NULL; 287144961713Sgirish 287244961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 287344961713Sgirish } 287444961713Sgirish 287544961713Sgirish if (dma_p->ncookies != 1 || 287644961713Sgirish (dma_p->dma_cookie.dmac_laddress == NULL)) { 287744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 287844961713Sgirish "nxge_dma_mem_alloc:di_dma_addr_bind > 1 " 287944961713Sgirish "cookie or " 288044961713Sgirish "dmac_laddress is NULL $%p size %d " 288144961713Sgirish " (status 0x%x ncookies %d.)", 288244961713Sgirish ddi_status, 288344961713Sgirish dma_p->dma_cookie.dmac_laddress, 288444961713Sgirish dma_p->dma_cookie.dmac_size, 288544961713Sgirish dma_p->ncookies)); 288644961713Sgirish 288744961713Sgirish contig_mem_free((void *)kaddrp, length); 288856d930aeSspeer (void) ddi_dma_unbind_handle(dma_p->dma_handle); 288944961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 289044961713Sgirish 289144961713Sgirish dma_p->alength = 0; 289244961713Sgirish dma_p->dma_handle = NULL; 289344961713Sgirish dma_p->acc_handle = NULL; 289444961713Sgirish dma_p->kaddrp = NULL; 289544961713Sgirish 289644961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 289744961713Sgirish } 289844961713Sgirish break; 289944961713Sgirish 290044961713Sgirish #else 290144961713Sgirish case B_TRUE: 290244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 290344961713Sgirish "nxge_dma_mem_alloc: invalid alloc type for !sun4v")); 290444961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 290544961713Sgirish #endif 290644961713Sgirish } 290744961713Sgirish 290844961713Sgirish dma_p->kaddrp = kaddrp; 290944961713Sgirish dma_p->last_kaddrp = (unsigned char *)kaddrp + 291044961713Sgirish dma_p->alength - RXBUF_64B_ALIGNED; 2911adfcba55Sjoycey #if defined(__i386) 2912adfcba55Sjoycey dma_p->ioaddr_pp = 2913adfcba55Sjoycey (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress; 2914adfcba55Sjoycey #else 291544961713Sgirish dma_p->ioaddr_pp = (unsigned char *)dma_p->dma_cookie.dmac_laddress; 2916adfcba55Sjoycey #endif 291744961713Sgirish dma_p->last_ioaddr_pp = 2918adfcba55Sjoycey #if defined(__i386) 2919adfcba55Sjoycey (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress + 2920adfcba55Sjoycey #else 292144961713Sgirish (unsigned char *)dma_p->dma_cookie.dmac_laddress + 2922adfcba55Sjoycey #endif 292344961713Sgirish dma_p->alength - RXBUF_64B_ALIGNED; 292444961713Sgirish 292544961713Sgirish NPI_DMA_ACC_HANDLE_SET(dma_p, dma_p->acc_handle); 292644961713Sgirish 292744961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 292844961713Sgirish dma_p->orig_ioaddr_pp = 292944961713Sgirish (unsigned char *)dma_p->dma_cookie.dmac_laddress; 293044961713Sgirish dma_p->orig_alength = length; 293144961713Sgirish dma_p->orig_kaddrp = kaddrp; 293244961713Sgirish dma_p->orig_vatopa = (uint64_t)va_to_pa(kaddrp); 293344961713Sgirish #endif 293444961713Sgirish 293544961713Sgirish NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_dma_mem_alloc: " 293644961713Sgirish "dma buffer allocated: dma_p $%p " 293744961713Sgirish "return dmac_ladress from cookie $%p cookie dmac_size %d " 293844961713Sgirish "dma_p->ioaddr_p $%p " 293944961713Sgirish "dma_p->orig_ioaddr_p $%p " 294044961713Sgirish "orig_vatopa $%p " 294144961713Sgirish "alength %d (0x%x) " 294244961713Sgirish "kaddrp $%p " 294344961713Sgirish "length %d (0x%x)", 294444961713Sgirish dma_p, 294544961713Sgirish dma_p->dma_cookie.dmac_laddress, dma_p->dma_cookie.dmac_size, 294644961713Sgirish dma_p->ioaddr_pp, 294744961713Sgirish dma_p->orig_ioaddr_pp, 294844961713Sgirish dma_p->orig_vatopa, 294944961713Sgirish dma_p->alength, dma_p->alength, 295044961713Sgirish kaddrp, 295144961713Sgirish length, length)); 295244961713Sgirish 295344961713Sgirish return (NXGE_OK); 295444961713Sgirish } 295544961713Sgirish 295644961713Sgirish static void 295744961713Sgirish nxge_dma_mem_free(p_nxge_dma_common_t dma_p) 295844961713Sgirish { 295944961713Sgirish if (dma_p->dma_handle != NULL) { 296044961713Sgirish if (dma_p->ncookies) { 296144961713Sgirish (void) ddi_dma_unbind_handle(dma_p->dma_handle); 296244961713Sgirish dma_p->ncookies = 0; 296344961713Sgirish } 296444961713Sgirish ddi_dma_free_handle(&dma_p->dma_handle); 296544961713Sgirish dma_p->dma_handle = NULL; 296644961713Sgirish } 296744961713Sgirish 296844961713Sgirish if (dma_p->acc_handle != NULL) { 296944961713Sgirish ddi_dma_mem_free(&dma_p->acc_handle); 297044961713Sgirish dma_p->acc_handle = NULL; 297144961713Sgirish NPI_DMA_ACC_HANDLE_SET(dma_p, NULL); 297244961713Sgirish } 297344961713Sgirish 297444961713Sgirish #if defined(sun4v) && defined(NIU_LP_WORKAROUND) 297544961713Sgirish if (dma_p->contig_alloc_type && 297644961713Sgirish dma_p->orig_kaddrp && dma_p->orig_alength) { 297744961713Sgirish NXGE_DEBUG_MSG((NULL, DMA_CTL, "nxge_dma_mem_free: " 297844961713Sgirish "kaddrp $%p (orig_kaddrp $%p)" 297944961713Sgirish "mem type %d ", 298044961713Sgirish "orig_alength %d " 298144961713Sgirish "alength 0x%x (%d)", 298244961713Sgirish dma_p->kaddrp, 298344961713Sgirish dma_p->orig_kaddrp, 298444961713Sgirish dma_p->contig_alloc_type, 298544961713Sgirish dma_p->orig_alength, 298644961713Sgirish dma_p->alength, dma_p->alength)); 298744961713Sgirish 298844961713Sgirish contig_mem_free(dma_p->orig_kaddrp, dma_p->orig_alength); 298944961713Sgirish dma_p->orig_alength = NULL; 299044961713Sgirish dma_p->orig_kaddrp = NULL; 299144961713Sgirish dma_p->contig_alloc_type = B_FALSE; 299244961713Sgirish } 299344961713Sgirish #endif 299444961713Sgirish dma_p->kaddrp = NULL; 299544961713Sgirish dma_p->alength = NULL; 299644961713Sgirish } 299744961713Sgirish 299844961713Sgirish /* 299944961713Sgirish * nxge_m_start() -- start transmitting and receiving. 300044961713Sgirish * 300144961713Sgirish * This function is called by the MAC layer when the first 300244961713Sgirish * stream is open to prepare the hardware ready for sending 300344961713Sgirish * and transmitting packets. 300444961713Sgirish */ 300544961713Sgirish static int 300644961713Sgirish nxge_m_start(void *arg) 300744961713Sgirish { 300844961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 300944961713Sgirish 301044961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_start")); 301144961713Sgirish 301244961713Sgirish MUTEX_ENTER(nxgep->genlock); 301314ea4bb7Ssd if (nxge_init(nxgep) != NXGE_OK) { 301444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 301544961713Sgirish "<== nxge_m_start: initialization failed")); 301644961713Sgirish MUTEX_EXIT(nxgep->genlock); 301744961713Sgirish return (EIO); 301844961713Sgirish } 301944961713Sgirish 302014ea4bb7Ssd if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) 302114ea4bb7Ssd goto nxge_m_start_exit; 302244961713Sgirish /* 302344961713Sgirish * Start timer to check the system error and tx hangs 302444961713Sgirish */ 302544961713Sgirish nxgep->nxge_timerid = nxge_start_timer(nxgep, nxge_check_hw_state, 302644961713Sgirish NXGE_CHECK_TIMER); 302744961713Sgirish 3028a3c5bd6dSspeer nxgep->link_notify = B_TRUE; 3029a3c5bd6dSspeer 303044961713Sgirish nxgep->nxge_mac_state = NXGE_MAC_STARTED; 303144961713Sgirish 303214ea4bb7Ssd nxge_m_start_exit: 303344961713Sgirish MUTEX_EXIT(nxgep->genlock); 303444961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_start")); 303544961713Sgirish return (0); 303644961713Sgirish } 303744961713Sgirish 303844961713Sgirish /* 303944961713Sgirish * nxge_m_stop(): stop transmitting and receiving. 304044961713Sgirish */ 304144961713Sgirish static void 304244961713Sgirish nxge_m_stop(void *arg) 304344961713Sgirish { 304444961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 304544961713Sgirish 304644961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_stop")); 304744961713Sgirish 304844961713Sgirish if (nxgep->nxge_timerid) { 304944961713Sgirish nxge_stop_timer(nxgep, nxgep->nxge_timerid); 305044961713Sgirish nxgep->nxge_timerid = 0; 305144961713Sgirish } 3052a3c5bd6dSspeer 3053a3c5bd6dSspeer MUTEX_ENTER(nxgep->genlock); 305444961713Sgirish nxge_uninit(nxgep); 305544961713Sgirish 305644961713Sgirish nxgep->nxge_mac_state = NXGE_MAC_STOPPED; 305744961713Sgirish 305844961713Sgirish MUTEX_EXIT(nxgep->genlock); 305944961713Sgirish 306044961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_stop")); 306144961713Sgirish } 306244961713Sgirish 306344961713Sgirish static int 306444961713Sgirish nxge_m_unicst(void *arg, const uint8_t *macaddr) 306544961713Sgirish { 306644961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 306744961713Sgirish struct ether_addr addrp; 306844961713Sgirish 306944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_m_unicst")); 307044961713Sgirish 307144961713Sgirish bcopy(macaddr, (uint8_t *)&addrp, ETHERADDRL); 307244961713Sgirish if (nxge_set_mac_addr(nxgep, &addrp)) { 307344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 307444961713Sgirish "<== nxge_m_unicst: set unitcast failed")); 307544961713Sgirish return (EINVAL); 307644961713Sgirish } 307744961713Sgirish 307844961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_m_unicst")); 307944961713Sgirish 308044961713Sgirish return (0); 308144961713Sgirish } 308244961713Sgirish 308344961713Sgirish static int 308444961713Sgirish nxge_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 308544961713Sgirish { 308644961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 308744961713Sgirish struct ether_addr addrp; 308844961713Sgirish 308944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 309044961713Sgirish "==> nxge_m_multicst: add %d", add)); 309144961713Sgirish 309244961713Sgirish bcopy(mca, (uint8_t *)&addrp, ETHERADDRL); 309344961713Sgirish if (add) { 309444961713Sgirish if (nxge_add_mcast_addr(nxgep, &addrp)) { 309544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 309644961713Sgirish "<== nxge_m_multicst: add multicast failed")); 309744961713Sgirish return (EINVAL); 309844961713Sgirish } 309944961713Sgirish } else { 310044961713Sgirish if (nxge_del_mcast_addr(nxgep, &addrp)) { 310144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 310244961713Sgirish "<== nxge_m_multicst: del multicast failed")); 310344961713Sgirish return (EINVAL); 310444961713Sgirish } 310544961713Sgirish } 310644961713Sgirish 310744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_m_multicst")); 310844961713Sgirish 310944961713Sgirish return (0); 311044961713Sgirish } 311144961713Sgirish 311244961713Sgirish static int 311344961713Sgirish nxge_m_promisc(void *arg, boolean_t on) 311444961713Sgirish { 311544961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 311644961713Sgirish 311744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 311844961713Sgirish "==> nxge_m_promisc: on %d", on)); 311944961713Sgirish 312044961713Sgirish if (nxge_set_promisc(nxgep, on)) { 312144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 312244961713Sgirish "<== nxge_m_promisc: set promisc failed")); 312344961713Sgirish return (EINVAL); 312444961713Sgirish } 312544961713Sgirish 312644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 312744961713Sgirish "<== nxge_m_promisc: on %d", on)); 312844961713Sgirish 312944961713Sgirish return (0); 313044961713Sgirish } 313144961713Sgirish 313244961713Sgirish static void 313344961713Sgirish nxge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 313444961713Sgirish { 313544961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg; 313656d930aeSspeer struct iocblk *iocp; 313744961713Sgirish boolean_t need_privilege; 313844961713Sgirish int err; 313944961713Sgirish int cmd; 314044961713Sgirish 314144961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_ioctl")); 314244961713Sgirish 314344961713Sgirish iocp = (struct iocblk *)mp->b_rptr; 314444961713Sgirish iocp->ioc_error = 0; 314544961713Sgirish need_privilege = B_TRUE; 314644961713Sgirish cmd = iocp->ioc_cmd; 314744961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "==> nxge_m_ioctl: cmd 0x%08x", cmd)); 314844961713Sgirish switch (cmd) { 314944961713Sgirish default: 315044961713Sgirish miocnak(wq, mp, 0, EINVAL); 315144961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_ioctl: invalid")); 315244961713Sgirish return; 315344961713Sgirish 315444961713Sgirish case LB_GET_INFO_SIZE: 315544961713Sgirish case LB_GET_INFO: 315644961713Sgirish case LB_GET_MODE: 315744961713Sgirish need_privilege = B_FALSE; 315844961713Sgirish break; 315944961713Sgirish case LB_SET_MODE: 316044961713Sgirish break; 316144961713Sgirish 316244961713Sgirish case ND_GET: 316344961713Sgirish need_privilege = B_FALSE; 316444961713Sgirish break; 316544961713Sgirish case ND_SET: 316644961713Sgirish break; 316744961713Sgirish 316844961713Sgirish case NXGE_GET_MII: 316944961713Sgirish case NXGE_PUT_MII: 317044961713Sgirish case NXGE_GET64: 317144961713Sgirish case NXGE_PUT64: 317244961713Sgirish case NXGE_GET_TX_RING_SZ: 317344961713Sgirish case NXGE_GET_TX_DESC: 317444961713Sgirish case NXGE_TX_SIDE_RESET: 317544961713Sgirish case NXGE_RX_SIDE_RESET: 317644961713Sgirish case NXGE_GLOBAL_RESET: 317744961713Sgirish case NXGE_RESET_MAC: 317844961713Sgirish case NXGE_TX_REGS_DUMP: 317944961713Sgirish case NXGE_RX_REGS_DUMP: 318044961713Sgirish case NXGE_INT_REGS_DUMP: 318144961713Sgirish case NXGE_VIR_INT_REGS_DUMP: 318244961713Sgirish case NXGE_PUT_TCAM: 318344961713Sgirish case NXGE_GET_TCAM: 318444961713Sgirish case NXGE_RTRACE: 318544961713Sgirish case NXGE_RDUMP: 318644961713Sgirish 318744961713Sgirish need_privilege = B_FALSE; 318844961713Sgirish break; 318944961713Sgirish case NXGE_INJECT_ERR: 319044961713Sgirish cmn_err(CE_NOTE, "!nxge_m_ioctl: Inject error\n"); 319144961713Sgirish nxge_err_inject(nxgep, wq, mp); 319244961713Sgirish break; 319344961713Sgirish } 319444961713Sgirish 319544961713Sgirish if (need_privilege) { 319656d930aeSspeer err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 319744961713Sgirish if (err != 0) { 319844961713Sgirish miocnak(wq, mp, 0, err); 319944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 320044961713Sgirish "<== nxge_m_ioctl: no priv")); 320144961713Sgirish return; 320244961713Sgirish } 320344961713Sgirish } 320444961713Sgirish 320544961713Sgirish switch (cmd) { 320644961713Sgirish case ND_GET: 320744961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "ND_GET command")); 320844961713Sgirish case ND_SET: 320944961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "ND_SET command")); 321044961713Sgirish nxge_param_ioctl(nxgep, wq, mp, iocp); 321144961713Sgirish break; 321244961713Sgirish 321344961713Sgirish case LB_GET_MODE: 321444961713Sgirish case LB_SET_MODE: 321544961713Sgirish case LB_GET_INFO_SIZE: 321644961713Sgirish case LB_GET_INFO: 321744961713Sgirish nxge_loopback_ioctl(nxgep, wq, mp, iocp); 321844961713Sgirish break; 321944961713Sgirish 322044961713Sgirish case NXGE_GET_MII: 322144961713Sgirish case NXGE_PUT_MII: 322244961713Sgirish case NXGE_PUT_TCAM: 322344961713Sgirish case NXGE_GET_TCAM: 322444961713Sgirish case NXGE_GET64: 322544961713Sgirish case NXGE_PUT64: 322644961713Sgirish case NXGE_GET_TX_RING_SZ: 322744961713Sgirish case NXGE_GET_TX_DESC: 322844961713Sgirish case NXGE_TX_SIDE_RESET: 322944961713Sgirish case NXGE_RX_SIDE_RESET: 323044961713Sgirish case NXGE_GLOBAL_RESET: 323144961713Sgirish case NXGE_RESET_MAC: 323244961713Sgirish case NXGE_TX_REGS_DUMP: 323344961713Sgirish case NXGE_RX_REGS_DUMP: 323444961713Sgirish case NXGE_INT_REGS_DUMP: 323544961713Sgirish case NXGE_VIR_INT_REGS_DUMP: 323644961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, 323744961713Sgirish "==> nxge_m_ioctl: cmd 0x%x", cmd)); 323844961713Sgirish nxge_hw_ioctl(nxgep, wq, mp, iocp); 323944961713Sgirish break; 324044961713Sgirish } 324144961713Sgirish 324244961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, "<== nxge_m_ioctl")); 324344961713Sgirish } 324444961713Sgirish 324544961713Sgirish extern void nxge_rx_hw_blank(void *arg, time_t ticks, uint_t count); 324644961713Sgirish 324744961713Sgirish static void 324844961713Sgirish nxge_m_resources(void *arg) 324944961713Sgirish { 325044961713Sgirish p_nxge_t nxgep = arg; 325144961713Sgirish mac_rx_fifo_t mrf; 325244961713Sgirish p_rx_rcr_rings_t rcr_rings; 325344961713Sgirish p_rx_rcr_ring_t *rcr_p; 325444961713Sgirish uint32_t i, ndmas; 325514ea4bb7Ssd nxge_status_t status; 325644961713Sgirish 325744961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_m_resources")); 325844961713Sgirish 325944961713Sgirish MUTEX_ENTER(nxgep->genlock); 326014ea4bb7Ssd 326114ea4bb7Ssd /* 326258324dfcSspeer * CR 6492541 Check to see if the drv_state has been initialized, 326314ea4bb7Ssd * if not * call nxge_init(). 326414ea4bb7Ssd */ 326514ea4bb7Ssd if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 326614ea4bb7Ssd status = nxge_init(nxgep); 326714ea4bb7Ssd if (status != NXGE_OK) 326814ea4bb7Ssd goto nxge_m_resources_exit; 326914ea4bb7Ssd } 327014ea4bb7Ssd 327144961713Sgirish mrf.mrf_type = MAC_RX_FIFO; 327244961713Sgirish mrf.mrf_blank = nxge_rx_hw_blank; 327344961713Sgirish mrf.mrf_arg = (void *)nxgep; 327444961713Sgirish 327544961713Sgirish mrf.mrf_normal_blank_time = 128; 327644961713Sgirish mrf.mrf_normal_pkt_count = 8; 327744961713Sgirish rcr_rings = nxgep->rx_rcr_rings; 327844961713Sgirish rcr_p = rcr_rings->rcr_rings; 327944961713Sgirish ndmas = rcr_rings->ndmas; 328044961713Sgirish 328114ea4bb7Ssd /* 328214ea4bb7Ssd * Export our receive resources to the MAC layer. 328314ea4bb7Ssd */ 328444961713Sgirish for (i = 0; i < ndmas; i++) { 328544961713Sgirish ((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle = 328644961713Sgirish mac_resource_add(nxgep->mach, 328744961713Sgirish (mac_resource_t *)&mrf); 328844961713Sgirish 328944961713Sgirish NXGE_DEBUG_MSG((nxgep, NXGE_CTL, 329044961713Sgirish "==> nxge_m_resources: vdma %d dma %d " 329144961713Sgirish "rcrptr 0x%016llx mac_handle 0x%016llx", 329244961713Sgirish i, ((p_rx_rcr_ring_t)rcr_p[i])->rdc, 329344961713Sgirish rcr_p[i], 329444961713Sgirish ((p_rx_rcr_ring_t)rcr_p[i])->rcr_mac_handle)); 329544961713Sgirish } 329644961713Sgirish 329714ea4bb7Ssd nxge_m_resources_exit: 329844961713Sgirish MUTEX_EXIT(nxgep->genlock); 329944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_m_resources")); 330044961713Sgirish } 330144961713Sgirish 330258324dfcSspeer static void 330358324dfcSspeer nxge_mmac_kstat_update(p_nxge_t nxgep, mac_addr_slot_t slot, boolean_t factory) 330458324dfcSspeer { 330558324dfcSspeer p_nxge_mmac_stats_t mmac_stats; 330658324dfcSspeer int i; 330758324dfcSspeer nxge_mmac_t *mmac_info; 330858324dfcSspeer 330958324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 331058324dfcSspeer 331158324dfcSspeer mmac_stats = &nxgep->statsp->mmac_stats; 331258324dfcSspeer mmac_stats->mmac_max_cnt = mmac_info->num_mmac; 331358324dfcSspeer mmac_stats->mmac_avail_cnt = mmac_info->naddrfree; 331458324dfcSspeer 331558324dfcSspeer for (i = 0; i < ETHERADDRL; i++) { 331658324dfcSspeer if (factory) { 331758324dfcSspeer mmac_stats->mmac_avail_pool[slot-1].ether_addr_octet[i] 331858324dfcSspeer = mmac_info->factory_mac_pool[slot][(ETHERADDRL-1) - i]; 331958324dfcSspeer } else { 332058324dfcSspeer mmac_stats->mmac_avail_pool[slot-1].ether_addr_octet[i] 332158324dfcSspeer = mmac_info->mac_pool[slot].addr[(ETHERADDRL - 1) - i]; 332258324dfcSspeer } 332358324dfcSspeer } 332458324dfcSspeer } 332558324dfcSspeer 332658324dfcSspeer /* 332758324dfcSspeer * nxge_altmac_set() -- Set an alternate MAC address 332858324dfcSspeer */ 332958324dfcSspeer static int 333058324dfcSspeer nxge_altmac_set(p_nxge_t nxgep, uint8_t *maddr, mac_addr_slot_t slot) 333158324dfcSspeer { 333258324dfcSspeer uint8_t addrn; 333358324dfcSspeer uint8_t portn; 333458324dfcSspeer npi_mac_addr_t altmac; 33357b9fa28bSspeer hostinfo_t mac_rdc; 33367b9fa28bSspeer p_nxge_class_pt_cfg_t clscfgp; 333758324dfcSspeer 333858324dfcSspeer altmac.w2 = ((uint16_t)maddr[0] << 8) | ((uint16_t)maddr[1] & 0x0ff); 333958324dfcSspeer altmac.w1 = ((uint16_t)maddr[2] << 8) | ((uint16_t)maddr[3] & 0x0ff); 334058324dfcSspeer altmac.w0 = ((uint16_t)maddr[4] << 8) | ((uint16_t)maddr[5] & 0x0ff); 334158324dfcSspeer 334258324dfcSspeer portn = nxgep->mac.portnum; 334358324dfcSspeer addrn = (uint8_t)slot - 1; 334458324dfcSspeer 334558324dfcSspeer if (npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET, portn, 334658324dfcSspeer addrn, &altmac) != NPI_SUCCESS) 334758324dfcSspeer return (EIO); 33487b9fa28bSspeer 33497b9fa28bSspeer /* 33507b9fa28bSspeer * Set the rdc table number for the host info entry 33517b9fa28bSspeer * for this mac address slot. 33527b9fa28bSspeer */ 33537b9fa28bSspeer clscfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 33547b9fa28bSspeer mac_rdc.value = 0; 33557b9fa28bSspeer mac_rdc.bits.w0.rdc_tbl_num = clscfgp->mac_host_info[addrn].rdctbl; 33567b9fa28bSspeer mac_rdc.bits.w0.mac_pref = clscfgp->mac_host_info[addrn].mpr_npr; 33577b9fa28bSspeer 33587b9fa28bSspeer if (npi_mac_hostinfo_entry(nxgep->npi_handle, OP_SET, 33597b9fa28bSspeer nxgep->function_num, addrn, &mac_rdc) != NPI_SUCCESS) { 33607b9fa28bSspeer return (EIO); 33617b9fa28bSspeer } 33627b9fa28bSspeer 336358324dfcSspeer /* 336458324dfcSspeer * Enable comparison with the alternate MAC address. 336558324dfcSspeer * While the first alternate addr is enabled by bit 1 of register 336658324dfcSspeer * BMAC_ALTAD_CMPEN, it is enabled by bit 0 of register 336758324dfcSspeer * XMAC_ADDR_CMPEN, so slot needs to be converted to addrn 336858324dfcSspeer * accordingly before calling npi_mac_altaddr_entry. 336958324dfcSspeer */ 337058324dfcSspeer if (portn == XMAC_PORT_0 || portn == XMAC_PORT_1) 337158324dfcSspeer addrn = (uint8_t)slot - 1; 337258324dfcSspeer else 337358324dfcSspeer addrn = (uint8_t)slot; 337458324dfcSspeer 337558324dfcSspeer if (npi_mac_altaddr_enable(nxgep->npi_handle, portn, addrn) 337658324dfcSspeer != NPI_SUCCESS) 337758324dfcSspeer return (EIO); 337858324dfcSspeer 337958324dfcSspeer return (0); 338058324dfcSspeer } 338158324dfcSspeer 338258324dfcSspeer /* 338358324dfcSspeer * nxeg_m_mmac_add() - find an unused address slot, set the address 338458324dfcSspeer * value to the one specified, enable the port to start filtering on 338558324dfcSspeer * the new MAC address. Returns 0 on success. 338658324dfcSspeer */ 338758324dfcSspeer static int 338858324dfcSspeer nxge_m_mmac_add(void *arg, mac_multi_addr_t *maddr) 338958324dfcSspeer { 339058324dfcSspeer p_nxge_t nxgep = arg; 339158324dfcSspeer mac_addr_slot_t slot; 339258324dfcSspeer nxge_mmac_t *mmac_info; 339358324dfcSspeer int err; 339458324dfcSspeer nxge_status_t status; 339558324dfcSspeer 339658324dfcSspeer mutex_enter(nxgep->genlock); 339758324dfcSspeer 339858324dfcSspeer /* 339958324dfcSspeer * Make sure that nxge is initialized, if _start() has 340058324dfcSspeer * not been called. 340158324dfcSspeer */ 340258324dfcSspeer if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 340358324dfcSspeer status = nxge_init(nxgep); 340458324dfcSspeer if (status != NXGE_OK) { 340558324dfcSspeer mutex_exit(nxgep->genlock); 340658324dfcSspeer return (ENXIO); 340758324dfcSspeer } 340858324dfcSspeer } 340958324dfcSspeer 341058324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 341158324dfcSspeer if (mmac_info->naddrfree == 0) { 341258324dfcSspeer mutex_exit(nxgep->genlock); 341358324dfcSspeer return (ENOSPC); 341458324dfcSspeer } 341558324dfcSspeer if (!mac_unicst_verify(nxgep->mach, maddr->mma_addr, 341658324dfcSspeer maddr->mma_addrlen)) { 341758324dfcSspeer mutex_exit(nxgep->genlock); 341858324dfcSspeer return (EINVAL); 341958324dfcSspeer } 342058324dfcSspeer /* 342158324dfcSspeer * Search for the first available slot. Because naddrfree 342258324dfcSspeer * is not zero, we are guaranteed to find one. 342358324dfcSspeer * Slot 0 is for unique (primary) MAC. The first alternate 342458324dfcSspeer * MAC slot is slot 1. 342558324dfcSspeer * Each of the first two ports of Neptune has 16 alternate 342656d930aeSspeer * MAC slots but only the first 7 (or 15) slots have assigned factory 342758324dfcSspeer * MAC addresses. We first search among the slots without bundled 342858324dfcSspeer * factory MACs. If we fail to find one in that range, then we 342958324dfcSspeer * search the slots with bundled factory MACs. A factory MAC 343058324dfcSspeer * will be wasted while the slot is used with a user MAC address. 343158324dfcSspeer * But the slot could be used by factory MAC again after calling 343258324dfcSspeer * nxge_m_mmac_remove and nxge_m_mmac_reserve. 343358324dfcSspeer */ 343458324dfcSspeer if (mmac_info->num_factory_mmac < mmac_info->num_mmac) { 343558324dfcSspeer for (slot = mmac_info->num_factory_mmac + 1; 343658324dfcSspeer slot <= mmac_info->num_mmac; slot++) { 343758324dfcSspeer if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 343858324dfcSspeer break; 343958324dfcSspeer } 344058324dfcSspeer if (slot > mmac_info->num_mmac) { 344158324dfcSspeer for (slot = 1; slot <= mmac_info->num_factory_mmac; 344258324dfcSspeer slot++) { 344358324dfcSspeer if (!(mmac_info->mac_pool[slot].flags 344458324dfcSspeer & MMAC_SLOT_USED)) 344558324dfcSspeer break; 344658324dfcSspeer } 344758324dfcSspeer } 344858324dfcSspeer } else { 344958324dfcSspeer for (slot = 1; slot <= mmac_info->num_mmac; slot++) { 345058324dfcSspeer if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 345158324dfcSspeer break; 345258324dfcSspeer } 345358324dfcSspeer } 345458324dfcSspeer ASSERT(slot <= mmac_info->num_mmac); 345558324dfcSspeer if ((err = nxge_altmac_set(nxgep, maddr->mma_addr, slot)) != 0) { 345658324dfcSspeer mutex_exit(nxgep->genlock); 345758324dfcSspeer return (err); 345858324dfcSspeer } 345958324dfcSspeer bcopy(maddr->mma_addr, mmac_info->mac_pool[slot].addr, ETHERADDRL); 346058324dfcSspeer mmac_info->mac_pool[slot].flags |= MMAC_SLOT_USED; 346158324dfcSspeer mmac_info->mac_pool[slot].flags &= ~MMAC_VENDOR_ADDR; 346258324dfcSspeer mmac_info->naddrfree--; 346358324dfcSspeer nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 346458324dfcSspeer 346558324dfcSspeer maddr->mma_slot = slot; 346658324dfcSspeer 346758324dfcSspeer mutex_exit(nxgep->genlock); 346858324dfcSspeer return (0); 346958324dfcSspeer } 347058324dfcSspeer 347158324dfcSspeer /* 347258324dfcSspeer * This function reserves an unused slot and programs the slot and the HW 347358324dfcSspeer * with a factory mac address. 347458324dfcSspeer */ 347558324dfcSspeer static int 347658324dfcSspeer nxge_m_mmac_reserve(void *arg, mac_multi_addr_t *maddr) 347758324dfcSspeer { 347858324dfcSspeer p_nxge_t nxgep = arg; 347958324dfcSspeer mac_addr_slot_t slot; 348058324dfcSspeer nxge_mmac_t *mmac_info; 348158324dfcSspeer int err; 348258324dfcSspeer nxge_status_t status; 348358324dfcSspeer 348458324dfcSspeer mutex_enter(nxgep->genlock); 348558324dfcSspeer 348658324dfcSspeer /* 348758324dfcSspeer * Make sure that nxge is initialized, if _start() has 348858324dfcSspeer * not been called. 348958324dfcSspeer */ 349058324dfcSspeer if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 349158324dfcSspeer status = nxge_init(nxgep); 349258324dfcSspeer if (status != NXGE_OK) { 349358324dfcSspeer mutex_exit(nxgep->genlock); 349458324dfcSspeer return (ENXIO); 349558324dfcSspeer } 349658324dfcSspeer } 349758324dfcSspeer 349858324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 349958324dfcSspeer if (mmac_info->naddrfree == 0) { 350058324dfcSspeer mutex_exit(nxgep->genlock); 350158324dfcSspeer return (ENOSPC); 350258324dfcSspeer } 350358324dfcSspeer 350458324dfcSspeer slot = maddr->mma_slot; 350558324dfcSspeer if (slot == -1) { /* -1: Take the first available slot */ 350658324dfcSspeer for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) { 350758324dfcSspeer if (!(mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED)) 350858324dfcSspeer break; 350958324dfcSspeer } 351058324dfcSspeer if (slot > mmac_info->num_factory_mmac) { 351158324dfcSspeer mutex_exit(nxgep->genlock); 351258324dfcSspeer return (ENOSPC); 351358324dfcSspeer } 351458324dfcSspeer } 351558324dfcSspeer if (slot < 1 || slot > mmac_info->num_factory_mmac) { 351658324dfcSspeer /* 351758324dfcSspeer * Do not support factory MAC at a slot greater than 351858324dfcSspeer * num_factory_mmac even when there are available factory 351958324dfcSspeer * MAC addresses because the alternate MACs are bundled with 352058324dfcSspeer * slot[1] through slot[num_factory_mmac] 352158324dfcSspeer */ 352258324dfcSspeer mutex_exit(nxgep->genlock); 352358324dfcSspeer return (EINVAL); 352458324dfcSspeer } 352558324dfcSspeer if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 352658324dfcSspeer mutex_exit(nxgep->genlock); 352758324dfcSspeer return (EBUSY); 352858324dfcSspeer } 352958324dfcSspeer /* Verify the address to be reserved */ 353058324dfcSspeer if (!mac_unicst_verify(nxgep->mach, 353158324dfcSspeer mmac_info->factory_mac_pool[slot], ETHERADDRL)) { 353258324dfcSspeer mutex_exit(nxgep->genlock); 353358324dfcSspeer return (EINVAL); 353458324dfcSspeer } 353558324dfcSspeer if (err = nxge_altmac_set(nxgep, 353658324dfcSspeer mmac_info->factory_mac_pool[slot], slot)) { 353758324dfcSspeer mutex_exit(nxgep->genlock); 353858324dfcSspeer return (err); 353958324dfcSspeer } 354058324dfcSspeer bcopy(mmac_info->factory_mac_pool[slot], maddr->mma_addr, ETHERADDRL); 354158324dfcSspeer mmac_info->mac_pool[slot].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 354258324dfcSspeer mmac_info->naddrfree--; 354358324dfcSspeer 354458324dfcSspeer nxge_mmac_kstat_update(nxgep, slot, B_TRUE); 354558324dfcSspeer mutex_exit(nxgep->genlock); 354658324dfcSspeer 354758324dfcSspeer /* Pass info back to the caller */ 354858324dfcSspeer maddr->mma_slot = slot; 354958324dfcSspeer maddr->mma_addrlen = ETHERADDRL; 355058324dfcSspeer maddr->mma_flags = MMAC_SLOT_USED | MMAC_VENDOR_ADDR; 355158324dfcSspeer 355258324dfcSspeer return (0); 355358324dfcSspeer } 355458324dfcSspeer 355558324dfcSspeer /* 355658324dfcSspeer * Remove the specified mac address and update the HW not to filter 355758324dfcSspeer * the mac address anymore. 355858324dfcSspeer */ 355958324dfcSspeer static int 356058324dfcSspeer nxge_m_mmac_remove(void *arg, mac_addr_slot_t slot) 356158324dfcSspeer { 356258324dfcSspeer p_nxge_t nxgep = arg; 356358324dfcSspeer nxge_mmac_t *mmac_info; 356458324dfcSspeer uint8_t addrn; 356558324dfcSspeer uint8_t portn; 356658324dfcSspeer int err = 0; 356758324dfcSspeer nxge_status_t status; 356858324dfcSspeer 356958324dfcSspeer mutex_enter(nxgep->genlock); 357058324dfcSspeer 357158324dfcSspeer /* 357258324dfcSspeer * Make sure that nxge is initialized, if _start() has 357358324dfcSspeer * not been called. 357458324dfcSspeer */ 357558324dfcSspeer if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 357658324dfcSspeer status = nxge_init(nxgep); 357758324dfcSspeer if (status != NXGE_OK) { 357858324dfcSspeer mutex_exit(nxgep->genlock); 357958324dfcSspeer return (ENXIO); 358058324dfcSspeer } 358158324dfcSspeer } 358258324dfcSspeer 358358324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 358458324dfcSspeer if (slot < 1 || slot > mmac_info->num_mmac) { 358558324dfcSspeer mutex_exit(nxgep->genlock); 358658324dfcSspeer return (EINVAL); 358758324dfcSspeer } 358858324dfcSspeer 358958324dfcSspeer portn = nxgep->mac.portnum; 359058324dfcSspeer if (portn == XMAC_PORT_0 || portn == XMAC_PORT_1) 359158324dfcSspeer addrn = (uint8_t)slot - 1; 359258324dfcSspeer else 359358324dfcSspeer addrn = (uint8_t)slot; 359458324dfcSspeer 359558324dfcSspeer if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 359658324dfcSspeer if (npi_mac_altaddr_disable(nxgep->npi_handle, portn, addrn) 359758324dfcSspeer == NPI_SUCCESS) { 359858324dfcSspeer mmac_info->naddrfree++; 359958324dfcSspeer mmac_info->mac_pool[slot].flags &= ~MMAC_SLOT_USED; 360058324dfcSspeer /* 360158324dfcSspeer * Regardless if the MAC we just stopped filtering 360258324dfcSspeer * is a user addr or a facory addr, we must set 360358324dfcSspeer * the MMAC_VENDOR_ADDR flag if this slot has an 360458324dfcSspeer * associated factory MAC to indicate that a factory 360558324dfcSspeer * MAC is available. 360658324dfcSspeer */ 360758324dfcSspeer if (slot <= mmac_info->num_factory_mmac) { 360858324dfcSspeer mmac_info->mac_pool[slot].flags 360958324dfcSspeer |= MMAC_VENDOR_ADDR; 361058324dfcSspeer } 361158324dfcSspeer /* 361258324dfcSspeer * Clear mac_pool[slot].addr so that kstat shows 0 361358324dfcSspeer * alternate MAC address if the slot is not used. 361458324dfcSspeer * (But nxge_m_mmac_get returns the factory MAC even 361558324dfcSspeer * when the slot is not used!) 361658324dfcSspeer */ 361758324dfcSspeer bzero(mmac_info->mac_pool[slot].addr, ETHERADDRL); 361858324dfcSspeer nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 361958324dfcSspeer } else { 362058324dfcSspeer err = EIO; 362158324dfcSspeer } 362258324dfcSspeer } else { 362358324dfcSspeer err = EINVAL; 362458324dfcSspeer } 362558324dfcSspeer 362658324dfcSspeer mutex_exit(nxgep->genlock); 362758324dfcSspeer return (err); 362858324dfcSspeer } 362958324dfcSspeer 363058324dfcSspeer 363158324dfcSspeer /* 363258324dfcSspeer * Modify a mac address added by nxge_m_mmac_add or nxge_m_mmac_reserve(). 363358324dfcSspeer */ 363458324dfcSspeer static int 363558324dfcSspeer nxge_m_mmac_modify(void *arg, mac_multi_addr_t *maddr) 363658324dfcSspeer { 363758324dfcSspeer p_nxge_t nxgep = arg; 363858324dfcSspeer mac_addr_slot_t slot; 363958324dfcSspeer nxge_mmac_t *mmac_info; 364058324dfcSspeer int err = 0; 364158324dfcSspeer nxge_status_t status; 364258324dfcSspeer 364358324dfcSspeer if (!mac_unicst_verify(nxgep->mach, maddr->mma_addr, 364458324dfcSspeer maddr->mma_addrlen)) 364558324dfcSspeer return (EINVAL); 364658324dfcSspeer 364758324dfcSspeer slot = maddr->mma_slot; 364858324dfcSspeer 364958324dfcSspeer mutex_enter(nxgep->genlock); 365058324dfcSspeer 365158324dfcSspeer /* 365258324dfcSspeer * Make sure that nxge is initialized, if _start() has 365358324dfcSspeer * not been called. 365458324dfcSspeer */ 365558324dfcSspeer if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 365658324dfcSspeer status = nxge_init(nxgep); 365758324dfcSspeer if (status != NXGE_OK) { 365858324dfcSspeer mutex_exit(nxgep->genlock); 365958324dfcSspeer return (ENXIO); 366058324dfcSspeer } 366158324dfcSspeer } 366258324dfcSspeer 366358324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 366458324dfcSspeer if (slot < 1 || slot > mmac_info->num_mmac) { 366558324dfcSspeer mutex_exit(nxgep->genlock); 366658324dfcSspeer return (EINVAL); 366758324dfcSspeer } 366858324dfcSspeer if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) { 366958324dfcSspeer if ((err = nxge_altmac_set(nxgep, maddr->mma_addr, slot)) 367058324dfcSspeer != 0) { 367158324dfcSspeer bcopy(maddr->mma_addr, mmac_info->mac_pool[slot].addr, 367258324dfcSspeer ETHERADDRL); 367358324dfcSspeer /* 367458324dfcSspeer * Assume that the MAC passed down from the caller 367558324dfcSspeer * is not a factory MAC address (The user should 367658324dfcSspeer * call mmac_remove followed by mmac_reserve if 367758324dfcSspeer * he wants to use the factory MAC for this slot). 367858324dfcSspeer */ 367958324dfcSspeer mmac_info->mac_pool[slot].flags &= ~MMAC_VENDOR_ADDR; 368058324dfcSspeer nxge_mmac_kstat_update(nxgep, slot, B_FALSE); 368158324dfcSspeer } 368258324dfcSspeer } else { 368358324dfcSspeer err = EINVAL; 368458324dfcSspeer } 368558324dfcSspeer mutex_exit(nxgep->genlock); 368658324dfcSspeer return (err); 368758324dfcSspeer } 368858324dfcSspeer 368958324dfcSspeer /* 369058324dfcSspeer * nxge_m_mmac_get() - Get the MAC address and other information 369158324dfcSspeer * related to the slot. mma_flags should be set to 0 in the call. 369258324dfcSspeer * Note: although kstat shows MAC address as zero when a slot is 369358324dfcSspeer * not used, Crossbow expects nxge_m_mmac_get to copy factory MAC 369458324dfcSspeer * to the caller as long as the slot is not using a user MAC address. 369558324dfcSspeer * The following table shows the rules, 369658324dfcSspeer * 369758324dfcSspeer * USED VENDOR mma_addr 369858324dfcSspeer * ------------------------------------------------------------ 369958324dfcSspeer * (1) Slot uses a user MAC: yes no user MAC 370058324dfcSspeer * (2) Slot uses a factory MAC: yes yes factory MAC 370158324dfcSspeer * (3) Slot is not used but is 370258324dfcSspeer * factory MAC capable: no yes factory MAC 370358324dfcSspeer * (4) Slot is not used and is 370458324dfcSspeer * not factory MAC capable: no no 0 370558324dfcSspeer * ------------------------------------------------------------ 370658324dfcSspeer */ 370758324dfcSspeer static int 370858324dfcSspeer nxge_m_mmac_get(void *arg, mac_multi_addr_t *maddr) 370958324dfcSspeer { 371058324dfcSspeer nxge_t *nxgep = arg; 371158324dfcSspeer mac_addr_slot_t slot; 371258324dfcSspeer nxge_mmac_t *mmac_info; 371358324dfcSspeer nxge_status_t status; 371458324dfcSspeer 371558324dfcSspeer slot = maddr->mma_slot; 371658324dfcSspeer 371758324dfcSspeer mutex_enter(nxgep->genlock); 371858324dfcSspeer 371958324dfcSspeer /* 372058324dfcSspeer * Make sure that nxge is initialized, if _start() has 372158324dfcSspeer * not been called. 372258324dfcSspeer */ 372358324dfcSspeer if (!(nxgep->drv_state & STATE_HW_INITIALIZED)) { 372458324dfcSspeer status = nxge_init(nxgep); 372558324dfcSspeer if (status != NXGE_OK) { 372658324dfcSspeer mutex_exit(nxgep->genlock); 372758324dfcSspeer return (ENXIO); 372858324dfcSspeer } 372958324dfcSspeer } 373058324dfcSspeer 373158324dfcSspeer mmac_info = &nxgep->nxge_mmac_info; 373258324dfcSspeer 373358324dfcSspeer if (slot < 1 || slot > mmac_info->num_mmac) { 373458324dfcSspeer mutex_exit(nxgep->genlock); 373558324dfcSspeer return (EINVAL); 373658324dfcSspeer } 373758324dfcSspeer maddr->mma_flags = 0; 373858324dfcSspeer if (mmac_info->mac_pool[slot].flags & MMAC_SLOT_USED) 373958324dfcSspeer maddr->mma_flags |= MMAC_SLOT_USED; 374058324dfcSspeer 374158324dfcSspeer if (mmac_info->mac_pool[slot].flags & MMAC_VENDOR_ADDR) { 374258324dfcSspeer maddr->mma_flags |= MMAC_VENDOR_ADDR; 374358324dfcSspeer bcopy(mmac_info->factory_mac_pool[slot], 374458324dfcSspeer maddr->mma_addr, ETHERADDRL); 374558324dfcSspeer maddr->mma_addrlen = ETHERADDRL; 374658324dfcSspeer } else { 374758324dfcSspeer if (maddr->mma_flags & MMAC_SLOT_USED) { 374858324dfcSspeer bcopy(mmac_info->mac_pool[slot].addr, 374958324dfcSspeer maddr->mma_addr, ETHERADDRL); 375058324dfcSspeer maddr->mma_addrlen = ETHERADDRL; 375158324dfcSspeer } else { 375258324dfcSspeer bzero(maddr->mma_addr, ETHERADDRL); 375358324dfcSspeer maddr->mma_addrlen = 0; 375458324dfcSspeer } 375558324dfcSspeer } 375658324dfcSspeer mutex_exit(nxgep->genlock); 375758324dfcSspeer return (0); 375858324dfcSspeer } 375958324dfcSspeer 376058324dfcSspeer 376144961713Sgirish static boolean_t 376244961713Sgirish nxge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 376344961713Sgirish { 376458324dfcSspeer nxge_t *nxgep = arg; 376558324dfcSspeer uint32_t *txflags = cap_data; 376658324dfcSspeer multiaddress_capab_t *mmacp = cap_data; 376744961713Sgirish 376858324dfcSspeer switch (cap) { 376958324dfcSspeer case MAC_CAPAB_HCKSUM: 377044961713Sgirish *txflags = HCKSUM_INET_PARTIAL; 377144961713Sgirish break; 377244961713Sgirish case MAC_CAPAB_POLL: 377344961713Sgirish /* 377444961713Sgirish * There's nothing for us to fill in, simply returning 377544961713Sgirish * B_TRUE stating that we support polling is sufficient. 377644961713Sgirish */ 377744961713Sgirish break; 377844961713Sgirish 377958324dfcSspeer case MAC_CAPAB_MULTIADDRESS: 378058324dfcSspeer mutex_enter(nxgep->genlock); 378158324dfcSspeer 378258324dfcSspeer mmacp->maddr_naddr = nxgep->nxge_mmac_info.num_mmac; 378358324dfcSspeer mmacp->maddr_naddrfree = nxgep->nxge_mmac_info.naddrfree; 378458324dfcSspeer mmacp->maddr_flag = 0; /* 0 is requried by PSARC2006/265 */ 378558324dfcSspeer /* 378658324dfcSspeer * maddr_handle is driver's private data, passed back to 378758324dfcSspeer * entry point functions as arg. 378858324dfcSspeer */ 378958324dfcSspeer mmacp->maddr_handle = nxgep; 379058324dfcSspeer mmacp->maddr_add = nxge_m_mmac_add; 379158324dfcSspeer mmacp->maddr_remove = nxge_m_mmac_remove; 379258324dfcSspeer mmacp->maddr_modify = nxge_m_mmac_modify; 379358324dfcSspeer mmacp->maddr_get = nxge_m_mmac_get; 379458324dfcSspeer mmacp->maddr_reserve = nxge_m_mmac_reserve; 379558324dfcSspeer 379658324dfcSspeer mutex_exit(nxgep->genlock); 379758324dfcSspeer break; 379844961713Sgirish default: 379944961713Sgirish return (B_FALSE); 380044961713Sgirish } 380144961713Sgirish return (B_TRUE); 380244961713Sgirish } 380344961713Sgirish 380444961713Sgirish /* 380544961713Sgirish * Module loading and removing entry points. 380644961713Sgirish */ 380744961713Sgirish 380844961713Sgirish static struct cb_ops nxge_cb_ops = { 380944961713Sgirish nodev, /* cb_open */ 381044961713Sgirish nodev, /* cb_close */ 381144961713Sgirish nodev, /* cb_strategy */ 381244961713Sgirish nodev, /* cb_print */ 381344961713Sgirish nodev, /* cb_dump */ 381444961713Sgirish nodev, /* cb_read */ 381544961713Sgirish nodev, /* cb_write */ 381644961713Sgirish nodev, /* cb_ioctl */ 381744961713Sgirish nodev, /* cb_devmap */ 381844961713Sgirish nodev, /* cb_mmap */ 381944961713Sgirish nodev, /* cb_segmap */ 382044961713Sgirish nochpoll, /* cb_chpoll */ 382144961713Sgirish ddi_prop_op, /* cb_prop_op */ 382244961713Sgirish NULL, 382344961713Sgirish D_MP, /* cb_flag */ 382444961713Sgirish CB_REV, /* rev */ 382544961713Sgirish nodev, /* int (*cb_aread)() */ 382644961713Sgirish nodev /* int (*cb_awrite)() */ 382744961713Sgirish }; 382844961713Sgirish 382944961713Sgirish static struct dev_ops nxge_dev_ops = { 383044961713Sgirish DEVO_REV, /* devo_rev */ 383144961713Sgirish 0, /* devo_refcnt */ 383244961713Sgirish nulldev, 383358324dfcSspeer nulldev, /* devo_identify */ 383458324dfcSspeer nulldev, /* devo_probe */ 383558324dfcSspeer nxge_attach, /* devo_attach */ 383658324dfcSspeer nxge_detach, /* devo_detach */ 383758324dfcSspeer nodev, /* devo_reset */ 383858324dfcSspeer &nxge_cb_ops, /* devo_cb_ops */ 383958324dfcSspeer (struct bus_ops *)NULL, /* devo_bus_ops */ 384058324dfcSspeer ddi_power /* devo_power */ 384144961713Sgirish }; 384244961713Sgirish 384344961713Sgirish extern struct mod_ops mod_driverops; 384444961713Sgirish 38452e59129aSraghus #define NXGE_DESC_VER "Sun NIU 10Gb Ethernet" 384644961713Sgirish 384744961713Sgirish /* 384844961713Sgirish * Module linkage information for the kernel. 384944961713Sgirish */ 385044961713Sgirish static struct modldrv nxge_modldrv = { 385144961713Sgirish &mod_driverops, 385244961713Sgirish NXGE_DESC_VER, 385344961713Sgirish &nxge_dev_ops 385444961713Sgirish }; 385544961713Sgirish 385644961713Sgirish static struct modlinkage modlinkage = { 385744961713Sgirish MODREV_1, (void *) &nxge_modldrv, NULL 385844961713Sgirish }; 385944961713Sgirish 386044961713Sgirish int 386144961713Sgirish _init(void) 386244961713Sgirish { 386344961713Sgirish int status; 386444961713Sgirish 386544961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _init")); 386644961713Sgirish mac_init_ops(&nxge_dev_ops, "nxge"); 386744961713Sgirish status = ddi_soft_state_init(&nxge_list, sizeof (nxge_t), 0); 386844961713Sgirish if (status != 0) { 386944961713Sgirish NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 387044961713Sgirish "failed to init device soft state")); 387144961713Sgirish goto _init_exit; 387244961713Sgirish } 387344961713Sgirish 387444961713Sgirish status = mod_install(&modlinkage); 387544961713Sgirish if (status != 0) { 387644961713Sgirish ddi_soft_state_fini(&nxge_list); 387744961713Sgirish NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "Mod install failed")); 387844961713Sgirish goto _init_exit; 387944961713Sgirish } 388044961713Sgirish 388144961713Sgirish MUTEX_INIT(&nxge_common_lock, NULL, MUTEX_DRIVER, NULL); 388244961713Sgirish 388344961713Sgirish _init_exit: 388444961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "_init status = 0x%X", status)); 388544961713Sgirish 388644961713Sgirish return (status); 388744961713Sgirish } 388844961713Sgirish 388944961713Sgirish int 389044961713Sgirish _fini(void) 389144961713Sgirish { 389244961713Sgirish int status; 389344961713Sgirish 389444961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini")); 389544961713Sgirish 389644961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini: mod_remove")); 3897a3c5bd6dSspeer 3898a3c5bd6dSspeer if (nxge_mblks_pending) 3899a3c5bd6dSspeer return (EBUSY); 3900a3c5bd6dSspeer 390144961713Sgirish status = mod_remove(&modlinkage); 390244961713Sgirish if (status != DDI_SUCCESS) { 390344961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, 390444961713Sgirish "Module removal failed 0x%08x", 390544961713Sgirish status)); 390644961713Sgirish goto _fini_exit; 390744961713Sgirish } 390844961713Sgirish 390944961713Sgirish mac_fini_ops(&nxge_dev_ops); 391044961713Sgirish 391144961713Sgirish ddi_soft_state_fini(&nxge_list); 391244961713Sgirish 391344961713Sgirish MUTEX_DESTROY(&nxge_common_lock); 391444961713Sgirish _fini_exit: 391544961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "_fini status = 0x%08x", status)); 391644961713Sgirish 391744961713Sgirish return (status); 391844961713Sgirish } 391944961713Sgirish 392044961713Sgirish int 392144961713Sgirish _info(struct modinfo *modinfop) 392244961713Sgirish { 392344961713Sgirish int status; 392444961713Sgirish 392544961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _info")); 392644961713Sgirish status = mod_info(&modlinkage, modinfop); 392744961713Sgirish NXGE_DEBUG_MSG((NULL, MOD_CTL, " _info status = 0x%X", status)); 392844961713Sgirish 392944961713Sgirish return (status); 393044961713Sgirish } 393144961713Sgirish 393244961713Sgirish /*ARGSUSED*/ 393344961713Sgirish static nxge_status_t 393444961713Sgirish nxge_add_intrs(p_nxge_t nxgep) 393544961713Sgirish { 393644961713Sgirish 393744961713Sgirish int intr_types; 393844961713Sgirish int type = 0; 393944961713Sgirish int ddi_status = DDI_SUCCESS; 394044961713Sgirish nxge_status_t status = NXGE_OK; 394144961713Sgirish 394244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs")); 394344961713Sgirish 394444961713Sgirish nxgep->nxge_intr_type.intr_registered = B_FALSE; 394544961713Sgirish nxgep->nxge_intr_type.intr_enabled = B_FALSE; 394644961713Sgirish nxgep->nxge_intr_type.msi_intx_cnt = 0; 394744961713Sgirish nxgep->nxge_intr_type.intr_added = 0; 394844961713Sgirish nxgep->nxge_intr_type.niu_msi_enable = B_FALSE; 394944961713Sgirish nxgep->nxge_intr_type.intr_type = 0; 395044961713Sgirish 395144961713Sgirish if (nxgep->niu_type == N2_NIU) { 395244961713Sgirish nxgep->nxge_intr_type.niu_msi_enable = B_TRUE; 395344961713Sgirish } else if (nxge_msi_enable) { 395444961713Sgirish nxgep->nxge_intr_type.niu_msi_enable = B_TRUE; 395544961713Sgirish } 395644961713Sgirish 395744961713Sgirish /* Get the supported interrupt types */ 395844961713Sgirish if ((ddi_status = ddi_intr_get_supported_types(nxgep->dip, &intr_types)) 395944961713Sgirish != DDI_SUCCESS) { 396044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_add_intrs: " 396144961713Sgirish "ddi_intr_get_supported_types failed: status 0x%08x", 396244961713Sgirish ddi_status)); 396344961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 396444961713Sgirish } 396544961713Sgirish nxgep->nxge_intr_type.intr_types = intr_types; 396644961713Sgirish 396744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 396844961713Sgirish "ddi_intr_get_supported_types: 0x%08x", intr_types)); 396944961713Sgirish 397044961713Sgirish /* 397144961713Sgirish * Solaris MSIX is not supported yet. use MSI for now. 397244961713Sgirish * nxge_msi_enable (1): 397344961713Sgirish * 1 - MSI 2 - MSI-X others - FIXED 397444961713Sgirish */ 397544961713Sgirish switch (nxge_msi_enable) { 397644961713Sgirish default: 397744961713Sgirish type = DDI_INTR_TYPE_FIXED; 397844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 397944961713Sgirish "use fixed (intx emulation) type %08x", 398044961713Sgirish type)); 398144961713Sgirish break; 398244961713Sgirish 398344961713Sgirish case 2: 398444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 398544961713Sgirish "ddi_intr_get_supported_types: 0x%08x", intr_types)); 398644961713Sgirish if (intr_types & DDI_INTR_TYPE_MSIX) { 398744961713Sgirish type = DDI_INTR_TYPE_MSIX; 398844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 398944961713Sgirish "ddi_intr_get_supported_types: MSIX 0x%08x", 399044961713Sgirish type)); 399144961713Sgirish } else if (intr_types & DDI_INTR_TYPE_MSI) { 399244961713Sgirish type = DDI_INTR_TYPE_MSI; 399344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 399444961713Sgirish "ddi_intr_get_supported_types: MSI 0x%08x", 399544961713Sgirish type)); 399644961713Sgirish } else if (intr_types & DDI_INTR_TYPE_FIXED) { 399744961713Sgirish type = DDI_INTR_TYPE_FIXED; 399844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 399944961713Sgirish "ddi_intr_get_supported_types: MSXED0x%08x", 400044961713Sgirish type)); 400144961713Sgirish } 400244961713Sgirish break; 400344961713Sgirish 400444961713Sgirish case 1: 400544961713Sgirish if (intr_types & DDI_INTR_TYPE_MSI) { 400644961713Sgirish type = DDI_INTR_TYPE_MSI; 400744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs: " 400844961713Sgirish "ddi_intr_get_supported_types: MSI 0x%08x", 400944961713Sgirish type)); 401044961713Sgirish } else if (intr_types & DDI_INTR_TYPE_MSIX) { 401144961713Sgirish type = DDI_INTR_TYPE_MSIX; 401244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 401344961713Sgirish "ddi_intr_get_supported_types: MSIX 0x%08x", 401444961713Sgirish type)); 401544961713Sgirish } else if (intr_types & DDI_INTR_TYPE_FIXED) { 401644961713Sgirish type = DDI_INTR_TYPE_FIXED; 401744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 401844961713Sgirish "ddi_intr_get_supported_types: MSXED0x%08x", 401944961713Sgirish type)); 402044961713Sgirish } 402144961713Sgirish } 402244961713Sgirish 402344961713Sgirish nxgep->nxge_intr_type.intr_type = type; 402444961713Sgirish if ((type == DDI_INTR_TYPE_MSIX || type == DDI_INTR_TYPE_MSI || 402544961713Sgirish type == DDI_INTR_TYPE_FIXED) && 402644961713Sgirish nxgep->nxge_intr_type.niu_msi_enable) { 402744961713Sgirish if ((status = nxge_add_intrs_adv(nxgep)) != DDI_SUCCESS) { 402844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 402944961713Sgirish " nxge_add_intrs: " 403044961713Sgirish " nxge_add_intrs_adv failed: status 0x%08x", 403144961713Sgirish status)); 403244961713Sgirish return (status); 403344961713Sgirish } else { 403444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs: " 403544961713Sgirish "interrupts registered : type %d", type)); 403644961713Sgirish nxgep->nxge_intr_type.intr_registered = B_TRUE; 403744961713Sgirish 403844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 403944961713Sgirish "\nAdded advanced nxge add_intr_adv " 404044961713Sgirish "intr type 0x%x\n", type)); 404144961713Sgirish 404244961713Sgirish return (status); 404344961713Sgirish } 404444961713Sgirish } 404544961713Sgirish 404644961713Sgirish if (!nxgep->nxge_intr_type.intr_registered) { 404744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_add_intrs: " 404844961713Sgirish "failed to register interrupts")); 404944961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 405044961713Sgirish } 405144961713Sgirish 405244961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_add_intrs")); 405344961713Sgirish return (status); 405444961713Sgirish } 405544961713Sgirish 405644961713Sgirish /*ARGSUSED*/ 405744961713Sgirish static nxge_status_t 405844961713Sgirish nxge_add_soft_intrs(p_nxge_t nxgep) 405944961713Sgirish { 406044961713Sgirish 406144961713Sgirish int ddi_status = DDI_SUCCESS; 406244961713Sgirish nxge_status_t status = NXGE_OK; 406344961713Sgirish 406444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_soft_intrs")); 406544961713Sgirish 406644961713Sgirish nxgep->resched_id = NULL; 406744961713Sgirish nxgep->resched_running = B_FALSE; 406844961713Sgirish ddi_status = ddi_add_softintr(nxgep->dip, DDI_SOFTINT_LOW, 406944961713Sgirish &nxgep->resched_id, 407044961713Sgirish NULL, NULL, nxge_reschedule, (caddr_t)nxgep); 407144961713Sgirish if (ddi_status != DDI_SUCCESS) { 407244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_add_soft_intrs: " 407344961713Sgirish "ddi_add_softintrs failed: status 0x%08x", 407444961713Sgirish ddi_status)); 407544961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 407644961713Sgirish } 407744961713Sgirish 407844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_ddi_add_soft_intrs")); 407944961713Sgirish 408044961713Sgirish return (status); 408144961713Sgirish } 408244961713Sgirish 408344961713Sgirish static nxge_status_t 408444961713Sgirish nxge_add_intrs_adv(p_nxge_t nxgep) 408544961713Sgirish { 408644961713Sgirish int intr_type; 408744961713Sgirish p_nxge_intr_t intrp; 408844961713Sgirish 408944961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs_adv")); 409044961713Sgirish 409144961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 409244961713Sgirish intr_type = intrp->intr_type; 409344961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_add_intrs_adv: type 0x%x", 409444961713Sgirish intr_type)); 409544961713Sgirish 409644961713Sgirish switch (intr_type) { 409744961713Sgirish case DDI_INTR_TYPE_MSI: /* 0x2 */ 409844961713Sgirish case DDI_INTR_TYPE_MSIX: /* 0x4 */ 409944961713Sgirish return (nxge_add_intrs_adv_type(nxgep, intr_type)); 410044961713Sgirish 410144961713Sgirish case DDI_INTR_TYPE_FIXED: /* 0x1 */ 410244961713Sgirish return (nxge_add_intrs_adv_type_fix(nxgep, intr_type)); 410344961713Sgirish 410444961713Sgirish default: 410544961713Sgirish return (NXGE_ERROR); 410644961713Sgirish } 410744961713Sgirish } 410844961713Sgirish 410944961713Sgirish 411044961713Sgirish /*ARGSUSED*/ 411144961713Sgirish static nxge_status_t 411244961713Sgirish nxge_add_intrs_adv_type(p_nxge_t nxgep, uint32_t int_type) 411344961713Sgirish { 411444961713Sgirish dev_info_t *dip = nxgep->dip; 411544961713Sgirish p_nxge_ldg_t ldgp; 411644961713Sgirish p_nxge_intr_t intrp; 411744961713Sgirish uint_t *inthandler; 411844961713Sgirish void *arg1, *arg2; 411944961713Sgirish int behavior; 4120ec090658Sml int nintrs, navail, nrequest; 412144961713Sgirish int nactual, nrequired; 412244961713Sgirish int inum = 0; 412344961713Sgirish int x, y; 412444961713Sgirish int ddi_status = DDI_SUCCESS; 412544961713Sgirish nxge_status_t status = NXGE_OK; 412644961713Sgirish 412744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs_adv_type")); 412844961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 412944961713Sgirish intrp->start_inum = 0; 413044961713Sgirish 413144961713Sgirish ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 413244961713Sgirish if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 413344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 413444961713Sgirish "ddi_intr_get_nintrs() failed, status: 0x%x%, " 413544961713Sgirish "nintrs: %d", ddi_status, nintrs)); 413644961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 413744961713Sgirish } 413844961713Sgirish 413944961713Sgirish ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 414044961713Sgirish if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 414144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 414244961713Sgirish "ddi_intr_get_navail() failed, status: 0x%x%, " 414344961713Sgirish "nintrs: %d", ddi_status, navail)); 414444961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 414544961713Sgirish } 414644961713Sgirish 414744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 414844961713Sgirish "ddi_intr_get_navail() returned: nintrs %d, navail %d", 414944961713Sgirish nintrs, navail)); 415044961713Sgirish 4151ec090658Sml /* PSARC/2007/453 MSI-X interrupt limit override */ 4152ec090658Sml if (int_type == DDI_INTR_TYPE_MSIX) { 4153ec090658Sml nrequest = nxge_create_msi_property(nxgep); 4154ec090658Sml if (nrequest < navail) { 4155ec090658Sml navail = nrequest; 4156ec090658Sml NXGE_DEBUG_MSG((nxgep, INT_CTL, 4157ec090658Sml "nxge_add_intrs_adv_type: nintrs %d " 4158ec090658Sml "navail %d (nrequest %d)", 4159ec090658Sml nintrs, navail, nrequest)); 4160ec090658Sml } 4161ec090658Sml } 4162ec090658Sml 416344961713Sgirish if (int_type == DDI_INTR_TYPE_MSI && !ISP2(navail)) { 416444961713Sgirish /* MSI must be power of 2 */ 416544961713Sgirish if ((navail & 16) == 16) { 416644961713Sgirish navail = 16; 416744961713Sgirish } else if ((navail & 8) == 8) { 416844961713Sgirish navail = 8; 416944961713Sgirish } else if ((navail & 4) == 4) { 417044961713Sgirish navail = 4; 417144961713Sgirish } else if ((navail & 2) == 2) { 417244961713Sgirish navail = 2; 417344961713Sgirish } else { 417444961713Sgirish navail = 1; 417544961713Sgirish } 417644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 417744961713Sgirish "ddi_intr_get_navail(): (msi power of 2) nintrs %d, " 417844961713Sgirish "navail %d", nintrs, navail)); 417944961713Sgirish } 418044961713Sgirish 418144961713Sgirish behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 418244961713Sgirish DDI_INTR_ALLOC_NORMAL); 418344961713Sgirish intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 418444961713Sgirish intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 418544961713Sgirish ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 418644961713Sgirish navail, &nactual, behavior); 418744961713Sgirish if (ddi_status != DDI_SUCCESS || nactual == 0) { 418844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 418944961713Sgirish " ddi_intr_alloc() failed: %d", 419044961713Sgirish ddi_status)); 419144961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 419244961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 419344961713Sgirish } 419444961713Sgirish 419544961713Sgirish if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 419644961713Sgirish (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 419744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 419844961713Sgirish " ddi_intr_get_pri() failed: %d", 419944961713Sgirish ddi_status)); 420044961713Sgirish /* Free already allocated interrupts */ 420144961713Sgirish for (y = 0; y < nactual; y++) { 420244961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 420344961713Sgirish } 420444961713Sgirish 420544961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 420644961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 420744961713Sgirish } 420844961713Sgirish 420944961713Sgirish nrequired = 0; 421044961713Sgirish switch (nxgep->niu_type) { 421144961713Sgirish default: 421244961713Sgirish status = nxge_ldgv_init(nxgep, &nactual, &nrequired); 421344961713Sgirish break; 421444961713Sgirish 421544961713Sgirish case N2_NIU: 421644961713Sgirish status = nxge_ldgv_init_n2(nxgep, &nactual, &nrequired); 421744961713Sgirish break; 421844961713Sgirish } 421944961713Sgirish 422044961713Sgirish if (status != NXGE_OK) { 422144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 422244961713Sgirish "nxge_add_intrs_adv_typ:nxge_ldgv_init " 422344961713Sgirish "failed: 0x%x", status)); 422444961713Sgirish /* Free already allocated interrupts */ 422544961713Sgirish for (y = 0; y < nactual; y++) { 422644961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 422744961713Sgirish } 422844961713Sgirish 422944961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 423044961713Sgirish return (status); 423144961713Sgirish } 423244961713Sgirish 423344961713Sgirish ldgp = nxgep->ldgvp->ldgp; 423444961713Sgirish for (x = 0; x < nrequired; x++, ldgp++) { 423544961713Sgirish ldgp->vector = (uint8_t)x; 423644961713Sgirish ldgp->intdata = SID_DATA(ldgp->func, x); 423744961713Sgirish arg1 = ldgp->ldvp; 423844961713Sgirish arg2 = nxgep; 423944961713Sgirish if (ldgp->nldvs == 1) { 424044961713Sgirish inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 424144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 424244961713Sgirish "nxge_add_intrs_adv_type: " 424344961713Sgirish "arg1 0x%x arg2 0x%x: " 424444961713Sgirish "1-1 int handler (entry %d intdata 0x%x)\n", 424544961713Sgirish arg1, arg2, 424644961713Sgirish x, ldgp->intdata)); 424744961713Sgirish } else if (ldgp->nldvs > 1) { 424844961713Sgirish inthandler = (uint_t *)ldgp->sys_intr_handler; 424944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 425044961713Sgirish "nxge_add_intrs_adv_type: " 425144961713Sgirish "arg1 0x%x arg2 0x%x: " 425244961713Sgirish "nldevs %d int handler " 425344961713Sgirish "(entry %d intdata 0x%x)\n", 425444961713Sgirish arg1, arg2, 425544961713Sgirish ldgp->nldvs, x, ldgp->intdata)); 425644961713Sgirish } 425744961713Sgirish 425844961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 425944961713Sgirish "==> nxge_add_intrs_adv_type: ddi_add_intr(inum) #%d " 426044961713Sgirish "htable 0x%llx", x, intrp->htable[x])); 426144961713Sgirish 426244961713Sgirish if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 426344961713Sgirish (ddi_intr_handler_t *)inthandler, arg1, arg2)) 426444961713Sgirish != DDI_SUCCESS) { 426544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 426644961713Sgirish "==> nxge_add_intrs_adv_type: failed #%d " 426744961713Sgirish "status 0x%x", x, ddi_status)); 426844961713Sgirish for (y = 0; y < intrp->intr_added; y++) { 426944961713Sgirish (void) ddi_intr_remove_handler( 427044961713Sgirish intrp->htable[y]); 427144961713Sgirish } 427244961713Sgirish /* Free already allocated intr */ 427344961713Sgirish for (y = 0; y < nactual; y++) { 427444961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 427544961713Sgirish } 427644961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 427744961713Sgirish 427844961713Sgirish (void) nxge_ldgv_uninit(nxgep); 427944961713Sgirish 428044961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 428144961713Sgirish } 428244961713Sgirish intrp->intr_added++; 428344961713Sgirish } 428444961713Sgirish 428544961713Sgirish intrp->msi_intx_cnt = nactual; 428644961713Sgirish 428744961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 428844961713Sgirish "Requested: %d, Allowed: %d msi_intx_cnt %d intr_added %d", 428944961713Sgirish navail, nactual, 429044961713Sgirish intrp->msi_intx_cnt, 429144961713Sgirish intrp->intr_added)); 429244961713Sgirish 429344961713Sgirish (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 429444961713Sgirish 429544961713Sgirish (void) nxge_intr_ldgv_init(nxgep); 429644961713Sgirish 429744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_add_intrs_adv_type")); 429844961713Sgirish 429944961713Sgirish return (status); 430044961713Sgirish } 430144961713Sgirish 430244961713Sgirish /*ARGSUSED*/ 430344961713Sgirish static nxge_status_t 430444961713Sgirish nxge_add_intrs_adv_type_fix(p_nxge_t nxgep, uint32_t int_type) 430544961713Sgirish { 430644961713Sgirish dev_info_t *dip = nxgep->dip; 430744961713Sgirish p_nxge_ldg_t ldgp; 430844961713Sgirish p_nxge_intr_t intrp; 430944961713Sgirish uint_t *inthandler; 431044961713Sgirish void *arg1, *arg2; 431144961713Sgirish int behavior; 431244961713Sgirish int nintrs, navail; 431344961713Sgirish int nactual, nrequired; 431444961713Sgirish int inum = 0; 431544961713Sgirish int x, y; 431644961713Sgirish int ddi_status = DDI_SUCCESS; 431744961713Sgirish nxge_status_t status = NXGE_OK; 431844961713Sgirish 431944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_add_intrs_adv_type_fix")); 432044961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 432144961713Sgirish intrp->start_inum = 0; 432244961713Sgirish 432344961713Sgirish ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 432444961713Sgirish if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 432544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 432644961713Sgirish "ddi_intr_get_nintrs() failed, status: 0x%x%, " 432744961713Sgirish "nintrs: %d", status, nintrs)); 432844961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 432944961713Sgirish } 433044961713Sgirish 433144961713Sgirish ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 433244961713Sgirish if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 433344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 433444961713Sgirish "ddi_intr_get_navail() failed, status: 0x%x%, " 433544961713Sgirish "nintrs: %d", ddi_status, navail)); 433644961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 433744961713Sgirish } 433844961713Sgirish 433944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 434044961713Sgirish "ddi_intr_get_navail() returned: nintrs %d, naavail %d", 434144961713Sgirish nintrs, navail)); 434244961713Sgirish 434344961713Sgirish behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 434444961713Sgirish DDI_INTR_ALLOC_NORMAL); 434544961713Sgirish intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 434644961713Sgirish intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 434744961713Sgirish ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 434844961713Sgirish navail, &nactual, behavior); 434944961713Sgirish if (ddi_status != DDI_SUCCESS || nactual == 0) { 435044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 435144961713Sgirish " ddi_intr_alloc() failed: %d", 435244961713Sgirish ddi_status)); 435344961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 435444961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 435544961713Sgirish } 435644961713Sgirish 435744961713Sgirish if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 435844961713Sgirish (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 435944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 436044961713Sgirish " ddi_intr_get_pri() failed: %d", 436144961713Sgirish ddi_status)); 436244961713Sgirish /* Free already allocated interrupts */ 436344961713Sgirish for (y = 0; y < nactual; y++) { 436444961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 436544961713Sgirish } 436644961713Sgirish 436744961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 436844961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 436944961713Sgirish } 437044961713Sgirish 437144961713Sgirish nrequired = 0; 437244961713Sgirish switch (nxgep->niu_type) { 437344961713Sgirish default: 437444961713Sgirish status = nxge_ldgv_init(nxgep, &nactual, &nrequired); 437544961713Sgirish break; 437644961713Sgirish 437744961713Sgirish case N2_NIU: 437844961713Sgirish status = nxge_ldgv_init_n2(nxgep, &nactual, &nrequired); 437944961713Sgirish break; 438044961713Sgirish } 438144961713Sgirish 438244961713Sgirish if (status != NXGE_OK) { 438344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 438444961713Sgirish "nxge_add_intrs_adv_type_fix:nxge_ldgv_init " 438544961713Sgirish "failed: 0x%x", status)); 438644961713Sgirish /* Free already allocated interrupts */ 438744961713Sgirish for (y = 0; y < nactual; y++) { 438844961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 438944961713Sgirish } 439044961713Sgirish 439144961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 439244961713Sgirish return (status); 439344961713Sgirish } 439444961713Sgirish 439544961713Sgirish ldgp = nxgep->ldgvp->ldgp; 439644961713Sgirish for (x = 0; x < nrequired; x++, ldgp++) { 439744961713Sgirish ldgp->vector = (uint8_t)x; 439844961713Sgirish if (nxgep->niu_type != N2_NIU) { 439944961713Sgirish ldgp->intdata = SID_DATA(ldgp->func, x); 440044961713Sgirish } 440144961713Sgirish 440244961713Sgirish arg1 = ldgp->ldvp; 440344961713Sgirish arg2 = nxgep; 440444961713Sgirish if (ldgp->nldvs == 1) { 440544961713Sgirish inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 440644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 440744961713Sgirish "nxge_add_intrs_adv_type_fix: " 440844961713Sgirish "1-1 int handler(%d) ldg %d ldv %d " 440944961713Sgirish "arg1 $%p arg2 $%p\n", 441044961713Sgirish x, ldgp->ldg, ldgp->ldvp->ldv, 441144961713Sgirish arg1, arg2)); 441244961713Sgirish } else if (ldgp->nldvs > 1) { 441344961713Sgirish inthandler = (uint_t *)ldgp->sys_intr_handler; 441444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 441544961713Sgirish "nxge_add_intrs_adv_type_fix: " 441644961713Sgirish "shared ldv %d int handler(%d) ldv %d ldg %d" 441744961713Sgirish "arg1 0x%016llx arg2 0x%016llx\n", 441844961713Sgirish x, ldgp->nldvs, ldgp->ldg, ldgp->ldvp->ldv, 441944961713Sgirish arg1, arg2)); 442044961713Sgirish } 442144961713Sgirish 442244961713Sgirish if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 442344961713Sgirish (ddi_intr_handler_t *)inthandler, arg1, arg2)) 442444961713Sgirish != DDI_SUCCESS) { 442544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 442644961713Sgirish "==> nxge_add_intrs_adv_type_fix: failed #%d " 442744961713Sgirish "status 0x%x", x, ddi_status)); 442844961713Sgirish for (y = 0; y < intrp->intr_added; y++) { 442944961713Sgirish (void) ddi_intr_remove_handler( 443044961713Sgirish intrp->htable[y]); 443144961713Sgirish } 443244961713Sgirish for (y = 0; y < nactual; y++) { 443344961713Sgirish (void) ddi_intr_free(intrp->htable[y]); 443444961713Sgirish } 443544961713Sgirish /* Free already allocated intr */ 443644961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 443744961713Sgirish 443844961713Sgirish (void) nxge_ldgv_uninit(nxgep); 443944961713Sgirish 444044961713Sgirish return (NXGE_ERROR | NXGE_DDI_FAILED); 444144961713Sgirish } 444244961713Sgirish intrp->intr_added++; 444344961713Sgirish } 444444961713Sgirish 444544961713Sgirish intrp->msi_intx_cnt = nactual; 444644961713Sgirish 444744961713Sgirish (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 444844961713Sgirish 444944961713Sgirish status = nxge_intr_ldgv_init(nxgep); 445044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_add_intrs_adv_type_fix")); 445144961713Sgirish 445244961713Sgirish return (status); 445344961713Sgirish } 445444961713Sgirish 445544961713Sgirish static void 445644961713Sgirish nxge_remove_intrs(p_nxge_t nxgep) 445744961713Sgirish { 445844961713Sgirish int i, inum; 445944961713Sgirish p_nxge_intr_t intrp; 446044961713Sgirish 446144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_intrs")); 446244961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 446344961713Sgirish if (!intrp->intr_registered) { 446444961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 446544961713Sgirish "<== nxge_remove_intrs: interrupts not registered")); 446644961713Sgirish return; 446744961713Sgirish } 446844961713Sgirish 446944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_intrs:advanced")); 447044961713Sgirish 447144961713Sgirish if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 447244961713Sgirish (void) ddi_intr_block_disable(intrp->htable, 447344961713Sgirish intrp->intr_added); 447444961713Sgirish } else { 447544961713Sgirish for (i = 0; i < intrp->intr_added; i++) { 447644961713Sgirish (void) ddi_intr_disable(intrp->htable[i]); 447744961713Sgirish } 447844961713Sgirish } 447944961713Sgirish 448044961713Sgirish for (inum = 0; inum < intrp->intr_added; inum++) { 448144961713Sgirish if (intrp->htable[inum]) { 448244961713Sgirish (void) ddi_intr_remove_handler(intrp->htable[inum]); 448344961713Sgirish } 448444961713Sgirish } 448544961713Sgirish 448644961713Sgirish for (inum = 0; inum < intrp->msi_intx_cnt; inum++) { 448744961713Sgirish if (intrp->htable[inum]) { 448844961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, 448944961713Sgirish "nxge_remove_intrs: ddi_intr_free inum %d " 449044961713Sgirish "msi_intx_cnt %d intr_added %d", 449144961713Sgirish inum, 449244961713Sgirish intrp->msi_intx_cnt, 449344961713Sgirish intrp->intr_added)); 449444961713Sgirish 449544961713Sgirish (void) ddi_intr_free(intrp->htable[inum]); 449644961713Sgirish } 449744961713Sgirish } 449844961713Sgirish 449944961713Sgirish kmem_free(intrp->htable, intrp->intr_size); 450044961713Sgirish intrp->intr_registered = B_FALSE; 450144961713Sgirish intrp->intr_enabled = B_FALSE; 450244961713Sgirish intrp->msi_intx_cnt = 0; 450344961713Sgirish intrp->intr_added = 0; 450444961713Sgirish 4505a3c5bd6dSspeer (void) nxge_ldgv_uninit(nxgep); 4506a3c5bd6dSspeer 4507ec090658Sml (void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip, 4508ec090658Sml "#msix-request"); 4509ec090658Sml 451044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_remove_intrs")); 451144961713Sgirish } 451244961713Sgirish 451344961713Sgirish /*ARGSUSED*/ 451444961713Sgirish static void 451544961713Sgirish nxge_remove_soft_intrs(p_nxge_t nxgep) 451644961713Sgirish { 451744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_remove_soft_intrs")); 451844961713Sgirish if (nxgep->resched_id) { 451944961713Sgirish ddi_remove_softintr(nxgep->resched_id); 452044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 452144961713Sgirish "==> nxge_remove_soft_intrs: removed")); 452244961713Sgirish nxgep->resched_id = NULL; 452344961713Sgirish } 452444961713Sgirish 452544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_remove_soft_intrs")); 452644961713Sgirish } 452744961713Sgirish 452844961713Sgirish /*ARGSUSED*/ 452944961713Sgirish static void 453044961713Sgirish nxge_intrs_enable(p_nxge_t nxgep) 453144961713Sgirish { 453244961713Sgirish p_nxge_intr_t intrp; 453344961713Sgirish int i; 453444961713Sgirish int status; 453544961713Sgirish 453644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable")); 453744961713Sgirish 453844961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 453944961713Sgirish 454044961713Sgirish if (!intrp->intr_registered) { 454144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_intrs_enable: " 454244961713Sgirish "interrupts are not registered")); 454344961713Sgirish return; 454444961713Sgirish } 454544961713Sgirish 454644961713Sgirish if (intrp->intr_enabled) { 454744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 454844961713Sgirish "<== nxge_intrs_enable: already enabled")); 454944961713Sgirish return; 455044961713Sgirish } 455144961713Sgirish 455244961713Sgirish if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 455344961713Sgirish status = ddi_intr_block_enable(intrp->htable, 455444961713Sgirish intrp->intr_added); 455544961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable " 455644961713Sgirish "block enable - status 0x%x total inums #%d\n", 455744961713Sgirish status, intrp->intr_added)); 455844961713Sgirish } else { 455944961713Sgirish for (i = 0; i < intrp->intr_added; i++) { 456044961713Sgirish status = ddi_intr_enable(intrp->htable[i]); 456144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_enable " 456244961713Sgirish "ddi_intr_enable:enable - status 0x%x " 456344961713Sgirish "total inums %d enable inum #%d\n", 456444961713Sgirish status, intrp->intr_added, i)); 456544961713Sgirish if (status == DDI_SUCCESS) { 456644961713Sgirish intrp->intr_enabled = B_TRUE; 456744961713Sgirish } 456844961713Sgirish } 456944961713Sgirish } 457044961713Sgirish 457144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_enable")); 457244961713Sgirish } 457344961713Sgirish 457444961713Sgirish /*ARGSUSED*/ 457544961713Sgirish static void 457644961713Sgirish nxge_intrs_disable(p_nxge_t nxgep) 457744961713Sgirish { 457844961713Sgirish p_nxge_intr_t intrp; 457944961713Sgirish int i; 458044961713Sgirish 458144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intrs_disable")); 458244961713Sgirish 458344961713Sgirish intrp = (p_nxge_intr_t)&nxgep->nxge_intr_type; 458444961713Sgirish 458544961713Sgirish if (!intrp->intr_registered) { 458644961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_disable: " 458744961713Sgirish "interrupts are not registered")); 458844961713Sgirish return; 458944961713Sgirish } 459044961713Sgirish 459144961713Sgirish if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 459244961713Sgirish (void) ddi_intr_block_disable(intrp->htable, 459344961713Sgirish intrp->intr_added); 459444961713Sgirish } else { 459544961713Sgirish for (i = 0; i < intrp->intr_added; i++) { 459644961713Sgirish (void) ddi_intr_disable(intrp->htable[i]); 459744961713Sgirish } 459844961713Sgirish } 459944961713Sgirish 460044961713Sgirish intrp->intr_enabled = B_FALSE; 460144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intrs_disable")); 460244961713Sgirish } 460344961713Sgirish 460444961713Sgirish static nxge_status_t 460544961713Sgirish nxge_mac_register(p_nxge_t nxgep) 460644961713Sgirish { 460744961713Sgirish mac_register_t *macp; 460844961713Sgirish int status; 460944961713Sgirish 461044961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_mac_register")); 461144961713Sgirish 461244961713Sgirish if ((macp = mac_alloc(MAC_VERSION)) == NULL) 461344961713Sgirish return (NXGE_ERROR); 461444961713Sgirish 461544961713Sgirish macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 461644961713Sgirish macp->m_driver = nxgep; 461744961713Sgirish macp->m_dip = nxgep->dip; 461844961713Sgirish macp->m_src_addr = nxgep->ouraddr.ether_addr_octet; 461944961713Sgirish macp->m_callbacks = &nxge_m_callbacks; 462044961713Sgirish macp->m_min_sdu = 0; 462144961713Sgirish macp->m_max_sdu = nxgep->mac.maxframesize - 462244961713Sgirish sizeof (struct ether_header) - ETHERFCSL - 4; 462344961713Sgirish 462444961713Sgirish status = mac_register(macp, &nxgep->mach); 462544961713Sgirish mac_free(macp); 462644961713Sgirish 462744961713Sgirish if (status != 0) { 462844961713Sgirish cmn_err(CE_WARN, 462944961713Sgirish "!nxge_mac_register failed (status %d instance %d)", 463044961713Sgirish status, nxgep->instance); 463144961713Sgirish return (NXGE_ERROR); 463244961713Sgirish } 463344961713Sgirish 463444961713Sgirish NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_mac_register success " 463544961713Sgirish "(instance %d)", nxgep->instance)); 463644961713Sgirish 463744961713Sgirish return (NXGE_OK); 463844961713Sgirish } 463944961713Sgirish 464044961713Sgirish void 464144961713Sgirish nxge_err_inject(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 464244961713Sgirish { 464344961713Sgirish ssize_t size; 464444961713Sgirish mblk_t *nmp; 464544961713Sgirish uint8_t blk_id; 464644961713Sgirish uint8_t chan; 464744961713Sgirish uint32_t err_id; 464844961713Sgirish err_inject_t *eip; 464944961713Sgirish 465044961713Sgirish NXGE_DEBUG_MSG((nxgep, STR_CTL, "==> nxge_err_inject")); 465144961713Sgirish 465244961713Sgirish size = 1024; 465344961713Sgirish nmp = mp->b_cont; 465444961713Sgirish eip = (err_inject_t *)nmp->b_rptr; 465544961713Sgirish blk_id = eip->blk_id; 465644961713Sgirish err_id = eip->err_id; 465744961713Sgirish chan = eip->chan; 465844961713Sgirish cmn_err(CE_NOTE, "!blk_id = 0x%x\n", blk_id); 465944961713Sgirish cmn_err(CE_NOTE, "!err_id = 0x%x\n", err_id); 466044961713Sgirish cmn_err(CE_NOTE, "!chan = 0x%x\n", chan); 466144961713Sgirish switch (blk_id) { 466244961713Sgirish case MAC_BLK_ID: 466344961713Sgirish break; 466444961713Sgirish case TXMAC_BLK_ID: 466544961713Sgirish break; 466644961713Sgirish case RXMAC_BLK_ID: 466744961713Sgirish break; 466844961713Sgirish case MIF_BLK_ID: 466944961713Sgirish break; 467044961713Sgirish case IPP_BLK_ID: 467144961713Sgirish nxge_ipp_inject_err(nxgep, err_id); 467244961713Sgirish break; 467344961713Sgirish case TXC_BLK_ID: 467444961713Sgirish nxge_txc_inject_err(nxgep, err_id); 467544961713Sgirish break; 467644961713Sgirish case TXDMA_BLK_ID: 467744961713Sgirish nxge_txdma_inject_err(nxgep, err_id, chan); 467844961713Sgirish break; 467944961713Sgirish case RXDMA_BLK_ID: 468044961713Sgirish nxge_rxdma_inject_err(nxgep, err_id, chan); 468144961713Sgirish break; 468244961713Sgirish case ZCP_BLK_ID: 468344961713Sgirish nxge_zcp_inject_err(nxgep, err_id); 468444961713Sgirish break; 468544961713Sgirish case ESPC_BLK_ID: 468644961713Sgirish break; 468744961713Sgirish case FFLP_BLK_ID: 468844961713Sgirish break; 468944961713Sgirish case PHY_BLK_ID: 469044961713Sgirish break; 469144961713Sgirish case ETHER_SERDES_BLK_ID: 469244961713Sgirish break; 469344961713Sgirish case PCIE_SERDES_BLK_ID: 469444961713Sgirish break; 469544961713Sgirish case VIR_BLK_ID: 469644961713Sgirish break; 469744961713Sgirish } 469844961713Sgirish 469944961713Sgirish nmp->b_wptr = nmp->b_rptr + size; 470044961713Sgirish NXGE_DEBUG_MSG((nxgep, STR_CTL, "<== nxge_err_inject")); 470144961713Sgirish 470244961713Sgirish miocack(wq, mp, (int)size, 0); 470344961713Sgirish } 470444961713Sgirish 470544961713Sgirish static int 470644961713Sgirish nxge_init_common_dev(p_nxge_t nxgep) 470744961713Sgirish { 470844961713Sgirish p_nxge_hw_list_t hw_p; 470944961713Sgirish dev_info_t *p_dip; 471044961713Sgirish 471144961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_init_common_device")); 471244961713Sgirish 471344961713Sgirish p_dip = nxgep->p_dip; 471444961713Sgirish MUTEX_ENTER(&nxge_common_lock); 471544961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 471644961713Sgirish "==> nxge_init_common_dev:func # %d", 471744961713Sgirish nxgep->function_num)); 471844961713Sgirish /* 471944961713Sgirish * Loop through existing per neptune hardware list. 472044961713Sgirish */ 472144961713Sgirish for (hw_p = nxge_hw_list; hw_p; hw_p = hw_p->next) { 472244961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 472344961713Sgirish "==> nxge_init_common_device:func # %d " 472444961713Sgirish "hw_p $%p parent dip $%p", 472544961713Sgirish nxgep->function_num, 472644961713Sgirish hw_p, 472744961713Sgirish p_dip)); 472844961713Sgirish if (hw_p->parent_devp == p_dip) { 472944961713Sgirish nxgep->nxge_hw_p = hw_p; 473044961713Sgirish hw_p->ndevs++; 473144961713Sgirish hw_p->nxge_p[nxgep->function_num] = nxgep; 473244961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 473344961713Sgirish "==> nxge_init_common_device:func # %d " 473444961713Sgirish "hw_p $%p parent dip $%p " 473544961713Sgirish "ndevs %d (found)", 473644961713Sgirish nxgep->function_num, 473744961713Sgirish hw_p, 473844961713Sgirish p_dip, 473944961713Sgirish hw_p->ndevs)); 474044961713Sgirish break; 474144961713Sgirish } 474244961713Sgirish } 474344961713Sgirish 474444961713Sgirish if (hw_p == NULL) { 474544961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 474644961713Sgirish "==> nxge_init_common_device:func # %d " 474744961713Sgirish "parent dip $%p (new)", 474844961713Sgirish nxgep->function_num, 474944961713Sgirish p_dip)); 475044961713Sgirish hw_p = kmem_zalloc(sizeof (nxge_hw_list_t), KM_SLEEP); 475144961713Sgirish hw_p->parent_devp = p_dip; 475244961713Sgirish hw_p->magic = NXGE_NEPTUNE_MAGIC; 475344961713Sgirish nxgep->nxge_hw_p = hw_p; 475444961713Sgirish hw_p->ndevs++; 475544961713Sgirish hw_p->nxge_p[nxgep->function_num] = nxgep; 475644961713Sgirish hw_p->next = nxge_hw_list; 475759ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 475859ac0c16Sdavemq hw_p->niu_type = N2_NIU; 475959ac0c16Sdavemq hw_p->platform_type = P_NEPTUNE_NIU; 476059ac0c16Sdavemq } else { 476159ac0c16Sdavemq hw_p->niu_type = NIU_TYPE_NONE; 47622e59129aSraghus hw_p->platform_type = P_NEPTUNE_NONE; 476359ac0c16Sdavemq } 476444961713Sgirish 476544961713Sgirish MUTEX_INIT(&hw_p->nxge_cfg_lock, NULL, MUTEX_DRIVER, NULL); 476644961713Sgirish MUTEX_INIT(&hw_p->nxge_tcam_lock, NULL, MUTEX_DRIVER, NULL); 476744961713Sgirish MUTEX_INIT(&hw_p->nxge_vlan_lock, NULL, MUTEX_DRIVER, NULL); 476844961713Sgirish MUTEX_INIT(&hw_p->nxge_mdio_lock, NULL, MUTEX_DRIVER, NULL); 476944961713Sgirish MUTEX_INIT(&hw_p->nxge_mii_lock, NULL, MUTEX_DRIVER, NULL); 477044961713Sgirish 477144961713Sgirish nxge_hw_list = hw_p; 477259ac0c16Sdavemq 477359ac0c16Sdavemq (void) nxge_scan_ports_phy(nxgep, nxge_hw_list); 477444961713Sgirish } 477544961713Sgirish 477644961713Sgirish MUTEX_EXIT(&nxge_common_lock); 477759ac0c16Sdavemq 47782e59129aSraghus nxgep->platform_type = hw_p->platform_type; 477959ac0c16Sdavemq if (nxgep->niu_type != N2_NIU) { 478059ac0c16Sdavemq nxgep->niu_type = hw_p->niu_type; 478159ac0c16Sdavemq } 478259ac0c16Sdavemq 478344961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 478444961713Sgirish "==> nxge_init_common_device (nxge_hw_list) $%p", 478544961713Sgirish nxge_hw_list)); 478644961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<== nxge_init_common_device")); 478744961713Sgirish 478844961713Sgirish return (NXGE_OK); 478944961713Sgirish } 479044961713Sgirish 479144961713Sgirish static void 479244961713Sgirish nxge_uninit_common_dev(p_nxge_t nxgep) 479344961713Sgirish { 479444961713Sgirish p_nxge_hw_list_t hw_p, h_hw_p; 479544961713Sgirish dev_info_t *p_dip; 479644961713Sgirish 479744961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_uninit_common_device")); 479844961713Sgirish if (nxgep->nxge_hw_p == NULL) { 479944961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 480044961713Sgirish "<== nxge_uninit_common_device (no common)")); 480144961713Sgirish return; 480244961713Sgirish } 480344961713Sgirish 480444961713Sgirish MUTEX_ENTER(&nxge_common_lock); 480544961713Sgirish h_hw_p = nxge_hw_list; 480644961713Sgirish for (hw_p = nxge_hw_list; hw_p; hw_p = hw_p->next) { 480744961713Sgirish p_dip = hw_p->parent_devp; 480844961713Sgirish if (nxgep->nxge_hw_p == hw_p && 480944961713Sgirish p_dip == nxgep->p_dip && 481044961713Sgirish nxgep->nxge_hw_p->magic == NXGE_NEPTUNE_MAGIC && 481144961713Sgirish hw_p->magic == NXGE_NEPTUNE_MAGIC) { 481244961713Sgirish 481344961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 481444961713Sgirish "==> nxge_uninit_common_device:func # %d " 481544961713Sgirish "hw_p $%p parent dip $%p " 481644961713Sgirish "ndevs %d (found)", 481744961713Sgirish nxgep->function_num, 481844961713Sgirish hw_p, 481944961713Sgirish p_dip, 482044961713Sgirish hw_p->ndevs)); 482144961713Sgirish 482244961713Sgirish nxgep->nxge_hw_p = NULL; 482344961713Sgirish if (hw_p->ndevs) { 482444961713Sgirish hw_p->ndevs--; 482544961713Sgirish } 482644961713Sgirish hw_p->nxge_p[nxgep->function_num] = NULL; 482744961713Sgirish if (!hw_p->ndevs) { 482844961713Sgirish MUTEX_DESTROY(&hw_p->nxge_vlan_lock); 482944961713Sgirish MUTEX_DESTROY(&hw_p->nxge_tcam_lock); 483044961713Sgirish MUTEX_DESTROY(&hw_p->nxge_cfg_lock); 483144961713Sgirish MUTEX_DESTROY(&hw_p->nxge_mdio_lock); 483244961713Sgirish MUTEX_DESTROY(&hw_p->nxge_mii_lock); 483344961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 483444961713Sgirish "==> nxge_uninit_common_device: " 483544961713Sgirish "func # %d " 483644961713Sgirish "hw_p $%p parent dip $%p " 483744961713Sgirish "ndevs %d (last)", 483844961713Sgirish nxgep->function_num, 483944961713Sgirish hw_p, 484044961713Sgirish p_dip, 484144961713Sgirish hw_p->ndevs)); 484244961713Sgirish 484344961713Sgirish if (hw_p == nxge_hw_list) { 484444961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 484544961713Sgirish "==> nxge_uninit_common_device:" 484644961713Sgirish "remove head func # %d " 484744961713Sgirish "hw_p $%p parent dip $%p " 484844961713Sgirish "ndevs %d (head)", 484944961713Sgirish nxgep->function_num, 485044961713Sgirish hw_p, 485144961713Sgirish p_dip, 485244961713Sgirish hw_p->ndevs)); 485344961713Sgirish nxge_hw_list = hw_p->next; 485444961713Sgirish } else { 485544961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 485644961713Sgirish "==> nxge_uninit_common_device:" 485744961713Sgirish "remove middle func # %d " 485844961713Sgirish "hw_p $%p parent dip $%p " 485944961713Sgirish "ndevs %d (middle)", 486044961713Sgirish nxgep->function_num, 486144961713Sgirish hw_p, 486244961713Sgirish p_dip, 486344961713Sgirish hw_p->ndevs)); 486444961713Sgirish h_hw_p->next = hw_p->next; 486544961713Sgirish } 486644961713Sgirish 486744961713Sgirish KMEM_FREE(hw_p, sizeof (nxge_hw_list_t)); 486844961713Sgirish } 486944961713Sgirish break; 487044961713Sgirish } else { 487144961713Sgirish h_hw_p = hw_p; 487244961713Sgirish } 487344961713Sgirish } 487444961713Sgirish 487544961713Sgirish MUTEX_EXIT(&nxge_common_lock); 487644961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, 487744961713Sgirish "==> nxge_uninit_common_device (nxge_hw_list) $%p", 487844961713Sgirish nxge_hw_list)); 487944961713Sgirish 488044961713Sgirish NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<= nxge_uninit_common_device")); 488144961713Sgirish } 488259ac0c16Sdavemq 488359ac0c16Sdavemq /* 48842e59129aSraghus * Determines the number of ports from the niu_type or the platform type. 488559ac0c16Sdavemq * Returns the number of ports, or returns zero on failure. 488659ac0c16Sdavemq */ 488759ac0c16Sdavemq 488859ac0c16Sdavemq int 48892e59129aSraghus nxge_get_nports(p_nxge_t nxgep) 489059ac0c16Sdavemq { 489159ac0c16Sdavemq int nports = 0; 489259ac0c16Sdavemq 48932e59129aSraghus switch (nxgep->niu_type) { 489459ac0c16Sdavemq case N2_NIU: 489559ac0c16Sdavemq case NEPTUNE_2_10GF: 489659ac0c16Sdavemq nports = 2; 489759ac0c16Sdavemq break; 489859ac0c16Sdavemq case NEPTUNE_4_1GC: 489959ac0c16Sdavemq case NEPTUNE_2_10GF_2_1GC: 490059ac0c16Sdavemq case NEPTUNE_1_10GF_3_1GC: 490159ac0c16Sdavemq case NEPTUNE_1_1GC_1_10GF_2_1GC: 490259ac0c16Sdavemq nports = 4; 490359ac0c16Sdavemq break; 490459ac0c16Sdavemq default: 49052e59129aSraghus switch (nxgep->platform_type) { 49062e59129aSraghus case P_NEPTUNE_NIU: 49072e59129aSraghus case P_NEPTUNE_ATLAS_2PORT: 49082e59129aSraghus nports = 2; 49092e59129aSraghus break; 49102e59129aSraghus case P_NEPTUNE_ATLAS_4PORT: 49112e59129aSraghus case P_NEPTUNE_MARAMBA_P0: 49122e59129aSraghus case P_NEPTUNE_MARAMBA_P1: 4913*d81011f0Ssbehera case P_NEPTUNE_ALONSO: 49142e59129aSraghus nports = 4; 49152e59129aSraghus break; 49162e59129aSraghus default: 49172e59129aSraghus break; 49182e59129aSraghus } 491959ac0c16Sdavemq break; 492059ac0c16Sdavemq } 492159ac0c16Sdavemq 492259ac0c16Sdavemq return (nports); 492359ac0c16Sdavemq } 4924ec090658Sml 4925ec090658Sml /* 4926ec090658Sml * The following two functions are to support 4927ec090658Sml * PSARC/2007/453 MSI-X interrupt limit override. 4928ec090658Sml */ 4929ec090658Sml static int 4930ec090658Sml nxge_create_msi_property(p_nxge_t nxgep) 4931ec090658Sml { 4932ec090658Sml int nmsi; 4933ec090658Sml extern int ncpus; 4934ec090658Sml 4935ec090658Sml NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==>nxge_create_msi_property")); 4936ec090658Sml 4937ec090658Sml switch (nxgep->mac.portmode) { 4938ec090658Sml case PORT_10G_COPPER: 4939ec090658Sml case PORT_10G_FIBER: 4940ec090658Sml (void) ddi_prop_create(DDI_DEV_T_NONE, nxgep->dip, 4941ec090658Sml DDI_PROP_CANSLEEP, "#msix-request", NULL, 0); 4942ec090658Sml /* 4943ec090658Sml * The maximum MSI-X requested will be 8. 4944ec090658Sml * If the # of CPUs is less than 8, we will reqeust 4945ec090658Sml * # MSI-X based on the # of CPUs. 4946ec090658Sml */ 4947ec090658Sml if (ncpus >= NXGE_MSIX_REQUEST_10G) { 4948ec090658Sml nmsi = NXGE_MSIX_REQUEST_10G; 4949ec090658Sml } else { 4950ec090658Sml nmsi = ncpus; 4951ec090658Sml } 4952ec090658Sml NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4953ec090658Sml "==>nxge_create_msi_property(10G): exists 0x%x (nmsi %d)", 4954ec090658Sml ddi_prop_exists(DDI_DEV_T_NONE, nxgep->dip, 4955ec090658Sml DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 4956ec090658Sml break; 4957ec090658Sml 4958ec090658Sml default: 4959ec090658Sml nmsi = NXGE_MSIX_REQUEST_1G; 4960ec090658Sml NXGE_DEBUG_MSG((nxgep, MOD_CTL, 4961ec090658Sml "==>nxge_create_msi_property(1G): exists 0x%x (nmsi %d)", 4962ec090658Sml ddi_prop_exists(DDI_DEV_T_NONE, nxgep->dip, 4963ec090658Sml DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 4964ec090658Sml break; 4965ec090658Sml } 4966ec090658Sml 4967ec090658Sml NXGE_DEBUG_MSG((nxgep, MOD_CTL, "<==nxge_create_msi_property")); 4968ec090658Sml return (nmsi); 4969ec090658Sml } 4970