13dec9fcdSqs /* 23dec9fcdSqs * CDDL HEADER START 33dec9fcdSqs * 43dec9fcdSqs * The contents of this file are subject to the terms of the 53dec9fcdSqs * Common Development and Distribution License (the "License"). 63dec9fcdSqs * You may not use this file except in compliance with the License. 73dec9fcdSqs * 83dec9fcdSqs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93dec9fcdSqs * or http://www.opensolaris.org/os/licensing. 103dec9fcdSqs * See the License for the specific language governing permissions 113dec9fcdSqs * and limitations under the License. 123dec9fcdSqs * 133dec9fcdSqs * When distributing Covered Code, include this CDDL HEADER in each 143dec9fcdSqs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153dec9fcdSqs * If applicable, add the following below this CDDL HEADER, with the 163dec9fcdSqs * fields enclosed by brackets "[]" replaced with your own identifying 173dec9fcdSqs * information: Portions Copyright [yyyy] [name of copyright owner] 183dec9fcdSqs * 193dec9fcdSqs * CDDL HEADER END 203dec9fcdSqs */ 213dec9fcdSqs /* 221ed83081SMichael Speer * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233dec9fcdSqs * Use is subject to license terms. 243dec9fcdSqs */ 253dec9fcdSqs 263dec9fcdSqs /* 273dec9fcdSqs * SunOs MT STREAMS Hydra 10Gb Ethernet Device Driver. 283dec9fcdSqs */ 293dec9fcdSqs #include <hxge_impl.h> 303dec9fcdSqs #include <hxge_pfc.h> 313dec9fcdSqs 323dec9fcdSqs /* 333dec9fcdSqs * PSARC/2007/453 MSI-X interrupt limit override 343dec9fcdSqs * (This PSARC case is limited to MSI-X vectors 353dec9fcdSqs * and SPARC platforms only). 363dec9fcdSqs */ 373dec9fcdSqs #if defined(_BIG_ENDIAN) 383dec9fcdSqs uint32_t hxge_msi_enable = 2; 393dec9fcdSqs #else 401ed83081SMichael Speer uint32_t hxge_msi_enable = 2; 413dec9fcdSqs #endif 423dec9fcdSqs 433dec9fcdSqs /* 443dec9fcdSqs * Globals: tunable parameters (/etc/system or adb) 453dec9fcdSqs * 463dec9fcdSqs */ 473dec9fcdSqs uint32_t hxge_rbr_size = HXGE_RBR_RBB_DEFAULT; 483dec9fcdSqs uint32_t hxge_rbr_spare_size = 0; 493dec9fcdSqs uint32_t hxge_rcr_size = HXGE_RCR_DEFAULT; 503dec9fcdSqs uint32_t hxge_tx_ring_size = HXGE_TX_RING_DEFAULT; 513dec9fcdSqs uint32_t hxge_bcopy_thresh = TX_BCOPY_MAX; 523dec9fcdSqs uint32_t hxge_dvma_thresh = TX_FASTDVMA_MIN; 533dec9fcdSqs uint32_t hxge_dma_stream_thresh = TX_STREAM_MIN; 54a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint32_t hxge_jumbo_frame_size = MAX_FRAME_SIZE; 553dec9fcdSqs 563dec9fcdSqs static hxge_os_mutex_t hxgedebuglock; 573dec9fcdSqs static int hxge_debug_init = 0; 583dec9fcdSqs 593dec9fcdSqs /* 603dec9fcdSqs * Debugging flags: 613dec9fcdSqs * hxge_no_tx_lb : transmit load balancing 623dec9fcdSqs * hxge_tx_lb_policy: 0 - TCP/UDP port (default) 633dec9fcdSqs * 1 - From the Stack 643dec9fcdSqs * 2 - Destination IP Address 653dec9fcdSqs */ 663dec9fcdSqs uint32_t hxge_no_tx_lb = 0; 673dec9fcdSqs uint32_t hxge_tx_lb_policy = HXGE_TX_LB_TCPUDP; 683dec9fcdSqs 693dec9fcdSqs /* 703dec9fcdSqs * Tunables to manage the receive buffer blocks. 713dec9fcdSqs * 723dec9fcdSqs * hxge_rx_threshold_hi: copy all buffers. 733dec9fcdSqs * hxge_rx_bcopy_size_type: receive buffer block size type. 743dec9fcdSqs * hxge_rx_threshold_lo: copy only up to tunable block size type. 753dec9fcdSqs */ 7657c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_rxbuf_threshold_t hxge_rx_threshold_hi = HXGE_RX_COPY_NONE; 773dec9fcdSqs hxge_rxbuf_type_t hxge_rx_buf_size_type = RCR_PKTBUFSZ_0; 7857c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_rxbuf_threshold_t hxge_rx_threshold_lo = HXGE_RX_COPY_NONE; 793dec9fcdSqs 803dec9fcdSqs rtrace_t hpi_rtracebuf; 813dec9fcdSqs 823dec9fcdSqs /* 833dec9fcdSqs * Function Prototypes 843dec9fcdSqs */ 853dec9fcdSqs static int hxge_attach(dev_info_t *, ddi_attach_cmd_t); 863dec9fcdSqs static int hxge_detach(dev_info_t *, ddi_detach_cmd_t); 873dec9fcdSqs static void hxge_unattach(p_hxge_t); 883dec9fcdSqs 893dec9fcdSqs static hxge_status_t hxge_setup_system_dma_pages(p_hxge_t); 903dec9fcdSqs 913dec9fcdSqs static hxge_status_t hxge_setup_mutexes(p_hxge_t); 923dec9fcdSqs static void hxge_destroy_mutexes(p_hxge_t); 933dec9fcdSqs 943dec9fcdSqs static hxge_status_t hxge_map_regs(p_hxge_t hxgep); 953dec9fcdSqs static void hxge_unmap_regs(p_hxge_t hxgep); 963dec9fcdSqs 973dec9fcdSqs hxge_status_t hxge_add_intrs(p_hxge_t hxgep); 983dec9fcdSqs static void hxge_remove_intrs(p_hxge_t hxgep); 993dec9fcdSqs static hxge_status_t hxge_add_intrs_adv(p_hxge_t hxgep); 1003dec9fcdSqs static hxge_status_t hxge_add_intrs_adv_type(p_hxge_t, uint32_t); 1013dec9fcdSqs static hxge_status_t hxge_add_intrs_adv_type_fix(p_hxge_t, uint32_t); 1023dec9fcdSqs void hxge_intrs_enable(p_hxge_t hxgep); 1033dec9fcdSqs static void hxge_intrs_disable(p_hxge_t hxgep); 1043dec9fcdSqs static void hxge_suspend(p_hxge_t); 1053dec9fcdSqs static hxge_status_t hxge_resume(p_hxge_t); 1063dec9fcdSqs hxge_status_t hxge_setup_dev(p_hxge_t); 1073dec9fcdSqs static void hxge_destroy_dev(p_hxge_t); 1083dec9fcdSqs hxge_status_t hxge_alloc_mem_pool(p_hxge_t); 1093dec9fcdSqs static void hxge_free_mem_pool(p_hxge_t); 1103dec9fcdSqs static hxge_status_t hxge_alloc_rx_mem_pool(p_hxge_t); 1113dec9fcdSqs static void hxge_free_rx_mem_pool(p_hxge_t); 1123dec9fcdSqs static hxge_status_t hxge_alloc_tx_mem_pool(p_hxge_t); 1133dec9fcdSqs static void hxge_free_tx_mem_pool(p_hxge_t); 1143dec9fcdSqs static hxge_status_t hxge_dma_mem_alloc(p_hxge_t, dma_method_t, 1153dec9fcdSqs struct ddi_dma_attr *, size_t, ddi_device_acc_attr_t *, uint_t, 1163dec9fcdSqs p_hxge_dma_common_t); 1173dec9fcdSqs static void hxge_dma_mem_free(p_hxge_dma_common_t); 1183dec9fcdSqs static hxge_status_t hxge_alloc_rx_buf_dma(p_hxge_t, uint16_t, 1193dec9fcdSqs p_hxge_dma_common_t *, size_t, size_t, uint32_t *); 1203dec9fcdSqs static void hxge_free_rx_buf_dma(p_hxge_t, p_hxge_dma_common_t, uint32_t); 1213dec9fcdSqs static hxge_status_t hxge_alloc_rx_cntl_dma(p_hxge_t, uint16_t, 1228ad8db65SMichael Speer p_hxge_dma_common_t *, struct ddi_dma_attr *, size_t); 1233dec9fcdSqs static void hxge_free_rx_cntl_dma(p_hxge_t, p_hxge_dma_common_t); 1243dec9fcdSqs static hxge_status_t hxge_alloc_tx_buf_dma(p_hxge_t, uint16_t, 1253dec9fcdSqs p_hxge_dma_common_t *, size_t, size_t, uint32_t *); 1263dec9fcdSqs static void hxge_free_tx_buf_dma(p_hxge_t, p_hxge_dma_common_t, uint32_t); 1273dec9fcdSqs static hxge_status_t hxge_alloc_tx_cntl_dma(p_hxge_t, uint16_t, 1283dec9fcdSqs p_hxge_dma_common_t *, size_t); 1293dec9fcdSqs static void hxge_free_tx_cntl_dma(p_hxge_t, p_hxge_dma_common_t); 1303dec9fcdSqs static int hxge_init_common_dev(p_hxge_t); 1313dec9fcdSqs static void hxge_uninit_common_dev(p_hxge_t); 1323dec9fcdSqs 1333dec9fcdSqs /* 1343dec9fcdSqs * The next declarations are for the GLDv3 interface. 1353dec9fcdSqs */ 1363dec9fcdSqs static int hxge_m_start(void *); 1373dec9fcdSqs static void hxge_m_stop(void *); 1383dec9fcdSqs static int hxge_m_multicst(void *, boolean_t, const uint8_t *); 1393dec9fcdSqs static int hxge_m_promisc(void *, boolean_t); 1403dec9fcdSqs static void hxge_m_ioctl(void *, queue_t *, mblk_t *); 1413dec9fcdSqs static hxge_status_t hxge_mac_register(p_hxge_t hxgep); 1423dec9fcdSqs 1433dec9fcdSqs static boolean_t hxge_m_getcapab(void *, mac_capab_t, void *); 144a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static boolean_t hxge_param_locked(mac_prop_id_t pr_num); 145a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 146a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val); 147a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 148afdda45fSVasumathi Sundaram - Sun Microsystems uint_t pr_flags, uint_t pr_valsize, void *pr_val, uint_t *); 149a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_get_def_val(hxge_t *hxgep, mac_prop_id_t pr_num, 150a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, void *pr_val); 151a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_set_priv_prop(p_hxge_t hxgep, const char *pr_name, 152a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val); 153a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_get_priv_prop(p_hxge_t hxgep, const char *pr_name, 154a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_flags, uint_t pr_valsize, void *pr_val); 155a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_link_poll(void *arg); 156e5d97391SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_link_update(p_hxge_t hxge, link_state_t state); 1571c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_msix_init(p_hxge_t hxgep); 15857c5371aSQiyan Sun - Sun Microsystems - San Diego United States static void hxge_store_msix_table(p_hxge_t hxgep); 15957c5371aSQiyan Sun - Sun Microsystems - San Diego United States static void hxge_check_1entry_msix_table(p_hxge_t hxgep, int msix_index); 160a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 161a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States mac_priv_prop_t hxge_priv_props[] = { 162a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_rxdma_intr_time", MAC_PROP_PERM_RW}, 163a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_rxdma_intr_pkts", MAC_PROP_PERM_RW}, 164a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv4_tcp", MAC_PROP_PERM_RW}, 165a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv4_udp", MAC_PROP_PERM_RW}, 166a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv4_ah", MAC_PROP_PERM_RW}, 167a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv4_sctp", MAC_PROP_PERM_RW}, 168a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv6_tcp", MAC_PROP_PERM_RW}, 169a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv6_udp", MAC_PROP_PERM_RW}, 170a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv6_ah", MAC_PROP_PERM_RW}, 171a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States {"_class_opt_ipv6_sctp", MAC_PROP_PERM_RW} 172a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States }; 173a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 174a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MAX_PRIV_PROPS \ 175a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (sizeof (hxge_priv_props)/sizeof (mac_priv_prop_t)) 1763dec9fcdSqs 1773dec9fcdSqs #define HXGE_MAGIC 0x4E584745UL 1783dec9fcdSqs #define MAX_DUMP_SZ 256 1793dec9fcdSqs 180a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_M_CALLBACK_FLAGS \ 181da14cebeSEric Cheng (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP) 1823dec9fcdSqs 1833dec9fcdSqs extern hxge_status_t hxge_pfc_set_default_mac_addr(p_hxge_t hxgep); 1843dec9fcdSqs 1853dec9fcdSqs static mac_callbacks_t hxge_m_callbacks = { 1863dec9fcdSqs HXGE_M_CALLBACK_FLAGS, 1873dec9fcdSqs hxge_m_stat, 1883dec9fcdSqs hxge_m_start, 1893dec9fcdSqs hxge_m_stop, 1903dec9fcdSqs hxge_m_promisc, 1913dec9fcdSqs hxge_m_multicst, 1921ed83081SMichael Speer NULL, 1931ed83081SMichael Speer NULL, 1943dec9fcdSqs hxge_m_ioctl, 195a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_getcapab, 196a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States NULL, 197a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States NULL, 198a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_setprop, 199a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_getprop 2003dec9fcdSqs }; 2013dec9fcdSqs 20257c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* PSARC/2007/453 MSI-X interrupt limit override. */ 20357c5371aSQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_REQUEST_10G 8 20457c5371aSQiyan Sun - Sun Microsystems - San Diego United States static int hxge_create_msi_property(p_hxge_t); 20557c5371aSQiyan Sun - Sun Microsystems - San Diego United States 2063dec9fcdSqs /* Enable debug messages as necessary. */ 207a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint64_t hxge_debug_level = 0; 2083dec9fcdSqs 2093dec9fcdSqs /* 2103dec9fcdSqs * This list contains the instance structures for the Hydra 2113dec9fcdSqs * devices present in the system. The lock exists to guarantee 2123dec9fcdSqs * mutually exclusive access to the list. 2133dec9fcdSqs */ 2143dec9fcdSqs void *hxge_list = NULL; 2153dec9fcdSqs void *hxge_hw_list = NULL; 2163dec9fcdSqs hxge_os_mutex_t hxge_common_lock; 2173dec9fcdSqs 2183dec9fcdSqs extern uint64_t hpi_debug_level; 2193dec9fcdSqs 2203dec9fcdSqs extern hxge_status_t hxge_ldgv_init(); 2213dec9fcdSqs extern hxge_status_t hxge_ldgv_uninit(); 2223dec9fcdSqs extern hxge_status_t hxge_intr_ldgv_init(); 2233dec9fcdSqs extern void hxge_fm_init(p_hxge_t hxgep, ddi_device_acc_attr_t *reg_attr, 2243dec9fcdSqs ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr); 2253dec9fcdSqs extern void hxge_fm_fini(p_hxge_t hxgep); 2263dec9fcdSqs 2273dec9fcdSqs /* 2283dec9fcdSqs * Count used to maintain the number of buffers being used 2293dec9fcdSqs * by Hydra instances and loaned up to the upper layers. 2303dec9fcdSqs */ 2313dec9fcdSqs uint32_t hxge_mblks_pending = 0; 2323dec9fcdSqs 2333dec9fcdSqs /* 2343dec9fcdSqs * Device register access attributes for PIO. 2353dec9fcdSqs */ 2363dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_reg_acc_attr = { 2373dec9fcdSqs DDI_DEVICE_ATTR_V0, 2383dec9fcdSqs DDI_STRUCTURE_LE_ACC, 2393dec9fcdSqs DDI_STRICTORDER_ACC, 2403dec9fcdSqs }; 2413dec9fcdSqs 2423dec9fcdSqs /* 2433dec9fcdSqs * Device descriptor access attributes for DMA. 2443dec9fcdSqs */ 2453dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_desc_dma_acc_attr = { 2463dec9fcdSqs DDI_DEVICE_ATTR_V0, 2473dec9fcdSqs DDI_STRUCTURE_LE_ACC, 2483dec9fcdSqs DDI_STRICTORDER_ACC 2493dec9fcdSqs }; 2503dec9fcdSqs 2513dec9fcdSqs /* 2523dec9fcdSqs * Device buffer access attributes for DMA. 2533dec9fcdSqs */ 2543dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_buf_dma_acc_attr = { 2553dec9fcdSqs DDI_DEVICE_ATTR_V0, 2563dec9fcdSqs DDI_STRUCTURE_BE_ACC, 2573dec9fcdSqs DDI_STRICTORDER_ACC 2583dec9fcdSqs }; 2593dec9fcdSqs 2608ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_rcr_desc_dma_attr = { 2618ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 2628ad8db65SMichael Speer 0, /* low address */ 2638ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 2648ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 2658ad8db65SMichael Speer 0x80000, /* alignment */ 2668ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 2678ad8db65SMichael Speer 0x1, /* minimum transfer size */ 2688ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 2698ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 2708ad8db65SMichael Speer 1, /* scatter/gather list length */ 2718ad8db65SMichael Speer (unsigned int)1, /* granularity */ 2728ad8db65SMichael Speer 0 /* attribute flags */ 2738ad8db65SMichael Speer }; 2748ad8db65SMichael Speer 2758ad8db65SMichael Speer ddi_dma_attr_t hxge_tx_desc_dma_attr = { 2763dec9fcdSqs DMA_ATTR_V0, /* version number. */ 2773dec9fcdSqs 0, /* low address */ 2783dec9fcdSqs 0xffffffffffffffff, /* high address */ 2793dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 2803dec9fcdSqs 0x100000, /* alignment */ 2813dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 2823dec9fcdSqs 0x1, /* minimum transfer size */ 2833dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 2843dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 2853dec9fcdSqs 1, /* scatter/gather list length */ 2863dec9fcdSqs (unsigned int)1, /* granularity */ 2873dec9fcdSqs 0 /* attribute flags */ 2883dec9fcdSqs }; 2893dec9fcdSqs 2908ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_rbr_desc_dma_attr = { 2918ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 2928ad8db65SMichael Speer 0, /* low address */ 2938ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 2948ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 2958ad8db65SMichael Speer 0x40000, /* alignment */ 2968ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 2978ad8db65SMichael Speer 0x1, /* minimum transfer size */ 2988ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 2998ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 3008ad8db65SMichael Speer 1, /* scatter/gather list length */ 3018ad8db65SMichael Speer (unsigned int)1, /* granularity */ 3028ad8db65SMichael Speer 0 /* attribute flags */ 3038ad8db65SMichael Speer }; 3048ad8db65SMichael Speer 3058ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_mbox_dma_attr = { 3068ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 3078ad8db65SMichael Speer 0, /* low address */ 3088ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 3098ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 3108ad8db65SMichael Speer #if defined(_BIG_ENDIAN) 3118ad8db65SMichael Speer 0x2000, /* alignment */ 3128ad8db65SMichael Speer #else 3138ad8db65SMichael Speer 0x1000, /* alignment */ 3148ad8db65SMichael Speer #endif 3158ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 3168ad8db65SMichael Speer 0x1, /* minimum transfer size */ 3178ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 3188ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 3198ad8db65SMichael Speer 5, /* scatter/gather list length */ 3208ad8db65SMichael Speer (unsigned int)1, /* granularity */ 3218ad8db65SMichael Speer 0 /* attribute flags */ 3228ad8db65SMichael Speer }; 3238ad8db65SMichael Speer 3243dec9fcdSqs ddi_dma_attr_t hxge_tx_dma_attr = { 3253dec9fcdSqs DMA_ATTR_V0, /* version number. */ 3263dec9fcdSqs 0, /* low address */ 3273dec9fcdSqs 0xffffffffffffffff, /* high address */ 3283dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 3293dec9fcdSqs #if defined(_BIG_ENDIAN) 3303dec9fcdSqs 0x2000, /* alignment */ 3313dec9fcdSqs #else 3323dec9fcdSqs 0x1000, /* alignment */ 3333dec9fcdSqs #endif 3343dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 3353dec9fcdSqs 0x1, /* minimum transfer size */ 3363dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 3373dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 3383dec9fcdSqs 5, /* scatter/gather list length */ 3393dec9fcdSqs (unsigned int)1, /* granularity */ 3403dec9fcdSqs 0 /* attribute flags */ 3413dec9fcdSqs }; 3423dec9fcdSqs 3433dec9fcdSqs ddi_dma_attr_t hxge_rx_dma_attr = { 3443dec9fcdSqs DMA_ATTR_V0, /* version number. */ 3453dec9fcdSqs 0, /* low address */ 3463dec9fcdSqs 0xffffffffffffffff, /* high address */ 3473dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 3483dec9fcdSqs 0x10000, /* alignment */ 3493dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 3503dec9fcdSqs 0x1, /* minimum transfer size */ 3513dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 3523dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 3533dec9fcdSqs 1, /* scatter/gather list length */ 3543dec9fcdSqs (unsigned int)1, /* granularity */ 3553dec9fcdSqs DDI_DMA_RELAXED_ORDERING /* attribute flags */ 3563dec9fcdSqs }; 3573dec9fcdSqs 3583dec9fcdSqs ddi_dma_lim_t hxge_dma_limits = { 3593dec9fcdSqs (uint_t)0, /* dlim_addr_lo */ 3603dec9fcdSqs (uint_t)0xffffffff, /* dlim_addr_hi */ 3613dec9fcdSqs (uint_t)0xffffffff, /* dlim_cntr_max */ 3623dec9fcdSqs (uint_t)0xfc00fc, /* dlim_burstsizes for 32 and 64 bit xfers */ 3633dec9fcdSqs 0x1, /* dlim_minxfer */ 3643dec9fcdSqs 1024 /* dlim_speed */ 3653dec9fcdSqs }; 3663dec9fcdSqs 3673dec9fcdSqs dma_method_t hxge_force_dma = DVMA; 3683dec9fcdSqs 3693dec9fcdSqs /* 3703dec9fcdSqs * dma chunk sizes. 3713dec9fcdSqs * 3723dec9fcdSqs * Try to allocate the largest possible size 3733dec9fcdSqs * so that fewer number of dma chunks would be managed 3743dec9fcdSqs */ 3753dec9fcdSqs size_t alloc_sizes[] = { 3763dec9fcdSqs 0x1000, 0x2000, 0x4000, 0x8000, 3773dec9fcdSqs 0x10000, 0x20000, 0x40000, 0x80000, 3783dec9fcdSqs 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000 3793dec9fcdSqs }; 3803dec9fcdSqs 3813dec9fcdSqs /* 3823dec9fcdSqs * Translate "dev_t" to a pointer to the associated "dev_info_t". 3833dec9fcdSqs */ 3843dec9fcdSqs static int 3853dec9fcdSqs hxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 3863dec9fcdSqs { 3873dec9fcdSqs p_hxge_t hxgep = NULL; 3883dec9fcdSqs int instance; 3893dec9fcdSqs int status = DDI_SUCCESS; 3901ed83081SMichael Speer int i; 3913dec9fcdSqs 3923dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_attach")); 3933dec9fcdSqs 3943dec9fcdSqs /* 3953dec9fcdSqs * Get the device instance since we'll need to setup or retrieve a soft 3963dec9fcdSqs * state for this instance. 3973dec9fcdSqs */ 3983dec9fcdSqs instance = ddi_get_instance(dip); 3993dec9fcdSqs 4003dec9fcdSqs switch (cmd) { 4013dec9fcdSqs case DDI_ATTACH: 4023dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_ATTACH")); 4033dec9fcdSqs break; 4043dec9fcdSqs 4053dec9fcdSqs case DDI_RESUME: 4063dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_RESUME")); 4073dec9fcdSqs hxgep = (p_hxge_t)ddi_get_soft_state(hxge_list, instance); 4083dec9fcdSqs if (hxgep == NULL) { 4093dec9fcdSqs status = DDI_FAILURE; 4103dec9fcdSqs break; 4113dec9fcdSqs } 4123dec9fcdSqs if (hxgep->dip != dip) { 4133dec9fcdSqs status = DDI_FAILURE; 4143dec9fcdSqs break; 4153dec9fcdSqs } 4163dec9fcdSqs if (hxgep->suspended == DDI_PM_SUSPEND) { 4173dec9fcdSqs status = ddi_dev_is_needed(hxgep->dip, 0, 1); 4183dec9fcdSqs } else { 4193dec9fcdSqs (void) hxge_resume(hxgep); 4203dec9fcdSqs } 4213dec9fcdSqs goto hxge_attach_exit; 4223dec9fcdSqs 4233dec9fcdSqs case DDI_PM_RESUME: 4243dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_PM_RESUME")); 4253dec9fcdSqs hxgep = (p_hxge_t)ddi_get_soft_state(hxge_list, instance); 4263dec9fcdSqs if (hxgep == NULL) { 4273dec9fcdSqs status = DDI_FAILURE; 4283dec9fcdSqs break; 4293dec9fcdSqs } 4303dec9fcdSqs if (hxgep->dip != dip) { 4313dec9fcdSqs status = DDI_FAILURE; 4323dec9fcdSqs break; 4333dec9fcdSqs } 4343dec9fcdSqs (void) hxge_resume(hxgep); 4353dec9fcdSqs goto hxge_attach_exit; 4363dec9fcdSqs 4373dec9fcdSqs default: 4383dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing unknown")); 4393dec9fcdSqs status = DDI_FAILURE; 4403dec9fcdSqs goto hxge_attach_exit; 4413dec9fcdSqs } 4423dec9fcdSqs 4433dec9fcdSqs if (ddi_soft_state_zalloc(hxge_list, instance) == DDI_FAILURE) { 4443dec9fcdSqs status = DDI_FAILURE; 4453dec9fcdSqs HXGE_ERROR_MSG((hxgep, DDI_CTL, 4463dec9fcdSqs "ddi_soft_state_zalloc failed")); 4473dec9fcdSqs goto hxge_attach_exit; 4483dec9fcdSqs } 4493dec9fcdSqs 4503dec9fcdSqs hxgep = ddi_get_soft_state(hxge_list, instance); 4513dec9fcdSqs if (hxgep == NULL) { 4523dec9fcdSqs status = HXGE_ERROR; 4533dec9fcdSqs HXGE_ERROR_MSG((hxgep, DDI_CTL, 4543dec9fcdSqs "ddi_get_soft_state failed")); 4553dec9fcdSqs goto hxge_attach_fail2; 4563dec9fcdSqs } 4573dec9fcdSqs 4583dec9fcdSqs hxgep->drv_state = 0; 4593dec9fcdSqs hxgep->dip = dip; 4603dec9fcdSqs hxgep->instance = instance; 4613dec9fcdSqs hxgep->p_dip = ddi_get_parent(dip); 4623dec9fcdSqs hxgep->hxge_debug_level = hxge_debug_level; 4633dec9fcdSqs hpi_debug_level = hxge_debug_level; 4643dec9fcdSqs 4651ed83081SMichael Speer /* 4661ed83081SMichael Speer * Initialize MMAC struture. 4671ed83081SMichael Speer */ 4681ed83081SMichael Speer (void) hxge_pfc_num_macs_get(hxgep, &hxgep->mmac.total); 4691ed83081SMichael Speer hxgep->mmac.available = hxgep->mmac.total; 4701ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 4711ed83081SMichael Speer hxgep->mmac.addrs[i].set = B_FALSE; 4721ed83081SMichael Speer hxgep->mmac.addrs[i].primary = B_FALSE; 4731ed83081SMichael Speer } 4741ed83081SMichael Speer 4753dec9fcdSqs hxge_fm_init(hxgep, &hxge_dev_reg_acc_attr, &hxge_dev_desc_dma_acc_attr, 4763dec9fcdSqs &hxge_rx_dma_attr); 4773dec9fcdSqs 4783dec9fcdSqs status = hxge_map_regs(hxgep); 4793dec9fcdSqs if (status != HXGE_OK) { 4803dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "hxge_map_regs failed")); 4813dec9fcdSqs goto hxge_attach_fail3; 4823dec9fcdSqs } 4833dec9fcdSqs 4843dec9fcdSqs status = hxge_init_common_dev(hxgep); 4853dec9fcdSqs if (status != HXGE_OK) { 4863dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 4873dec9fcdSqs "hxge_init_common_dev failed")); 4883dec9fcdSqs goto hxge_attach_fail4; 4893dec9fcdSqs } 4903dec9fcdSqs 4913dec9fcdSqs /* 4923dec9fcdSqs * Setup the Ndd parameters for this instance. 4933dec9fcdSqs */ 4943dec9fcdSqs hxge_init_param(hxgep); 4953dec9fcdSqs 4963dec9fcdSqs /* 4973dec9fcdSqs * Setup Register Tracing Buffer. 4983dec9fcdSqs */ 4993dec9fcdSqs hpi_rtrace_buf_init((rtrace_t *)&hpi_rtracebuf); 5003dec9fcdSqs 5013dec9fcdSqs /* init stats ptr */ 5023dec9fcdSqs hxge_init_statsp(hxgep); 5033dec9fcdSqs 504a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States status = hxge_setup_mutexes(hxgep); 505a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (status != HXGE_OK) { 506a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DDI_CTL, "set mutex failed")); 507a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States goto hxge_attach_fail; 508a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 509a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 510*23b519b2SMichael Speer /* Scrub the MSI-X memory */ 511*23b519b2SMichael Speer hxge_msix_init(hxgep); 512*23b519b2SMichael Speer 5133dec9fcdSqs status = hxge_get_config_properties(hxgep); 5143dec9fcdSqs if (status != HXGE_OK) { 5153dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "get_hw create failed")); 5163dec9fcdSqs goto hxge_attach_fail; 5173dec9fcdSqs } 5183dec9fcdSqs 5193dec9fcdSqs /* 5203dec9fcdSqs * Setup the Kstats for the driver. 5213dec9fcdSqs */ 5223dec9fcdSqs hxge_setup_kstats(hxgep); 5233dec9fcdSqs hxge_setup_param(hxgep); 5243dec9fcdSqs 5253dec9fcdSqs status = hxge_setup_system_dma_pages(hxgep); 5263dec9fcdSqs if (status != HXGE_OK) { 5273dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "set dma page failed")); 5283dec9fcdSqs goto hxge_attach_fail; 5293dec9fcdSqs } 5303dec9fcdSqs 5313dec9fcdSqs hxge_hw_id_init(hxgep); 5323dec9fcdSqs hxge_hw_init_niu_common(hxgep); 5333dec9fcdSqs 5343dec9fcdSqs status = hxge_setup_dev(hxgep); 5353dec9fcdSqs if (status != DDI_SUCCESS) { 5363dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "set dev failed")); 5373dec9fcdSqs goto hxge_attach_fail; 5383dec9fcdSqs } 5393dec9fcdSqs 5403dec9fcdSqs status = hxge_add_intrs(hxgep); 5413dec9fcdSqs if (status != DDI_SUCCESS) { 5423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "add_intr failed")); 5433dec9fcdSqs goto hxge_attach_fail; 5443dec9fcdSqs } 5453dec9fcdSqs 5463dec9fcdSqs /* 5473dec9fcdSqs * Enable interrupts. 5483dec9fcdSqs */ 5493dec9fcdSqs hxge_intrs_enable(hxgep); 5503dec9fcdSqs 55157c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Keep copy of MSIx table written */ 55257c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_store_msix_table(hxgep); 55357c5371aSQiyan Sun - Sun Microsystems - San Diego United States 5543dec9fcdSqs if ((status = hxge_mac_register(hxgep)) != HXGE_OK) { 5553dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 5563dec9fcdSqs "unable to register to mac layer (%d)", status)); 5573dec9fcdSqs goto hxge_attach_fail; 5583dec9fcdSqs } 559a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States mac_link_update(hxgep->mach, LINK_STATE_UNKNOWN); 5603dec9fcdSqs 5613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "registered to mac (instance %d)", 5623dec9fcdSqs instance)); 5633dec9fcdSqs 5643dec9fcdSqs goto hxge_attach_exit; 5653dec9fcdSqs 5663dec9fcdSqs hxge_attach_fail: 5673dec9fcdSqs hxge_unattach(hxgep); 5683dec9fcdSqs goto hxge_attach_fail1; 5693dec9fcdSqs 5703dec9fcdSqs hxge_attach_fail5: 5713dec9fcdSqs /* 5723dec9fcdSqs * Tear down the ndd parameters setup. 5733dec9fcdSqs */ 5743dec9fcdSqs hxge_destroy_param(hxgep); 5753dec9fcdSqs 5763dec9fcdSqs /* 5773dec9fcdSqs * Tear down the kstat setup. 5783dec9fcdSqs */ 5793dec9fcdSqs hxge_destroy_kstats(hxgep); 5803dec9fcdSqs 5813dec9fcdSqs hxge_attach_fail4: 5823dec9fcdSqs if (hxgep->hxge_hw_p) { 5833dec9fcdSqs hxge_uninit_common_dev(hxgep); 5843dec9fcdSqs hxgep->hxge_hw_p = NULL; 5853dec9fcdSqs } 5863dec9fcdSqs hxge_attach_fail3: 5873dec9fcdSqs /* 5883dec9fcdSqs * Unmap the register setup. 5893dec9fcdSqs */ 5903dec9fcdSqs hxge_unmap_regs(hxgep); 5913dec9fcdSqs 5923dec9fcdSqs hxge_fm_fini(hxgep); 5933dec9fcdSqs 5943dec9fcdSqs hxge_attach_fail2: 5953dec9fcdSqs ddi_soft_state_free(hxge_list, hxgep->instance); 5963dec9fcdSqs 5973dec9fcdSqs hxge_attach_fail1: 5983dec9fcdSqs if (status != HXGE_OK) 5993dec9fcdSqs status = (HXGE_ERROR | HXGE_DDI_FAILED); 6003dec9fcdSqs hxgep = NULL; 6013dec9fcdSqs 6023dec9fcdSqs hxge_attach_exit: 6033dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_attach status = 0x%08x", 6043dec9fcdSqs status)); 6053dec9fcdSqs 6063dec9fcdSqs return (status); 6073dec9fcdSqs } 6083dec9fcdSqs 6093dec9fcdSqs static int 6103dec9fcdSqs hxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 6113dec9fcdSqs { 6123dec9fcdSqs int status = DDI_SUCCESS; 6133dec9fcdSqs int instance; 6143dec9fcdSqs p_hxge_t hxgep = NULL; 6153dec9fcdSqs 6163dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_detach")); 6173dec9fcdSqs instance = ddi_get_instance(dip); 6183dec9fcdSqs hxgep = ddi_get_soft_state(hxge_list, instance); 6193dec9fcdSqs if (hxgep == NULL) { 6203dec9fcdSqs status = DDI_FAILURE; 6213dec9fcdSqs goto hxge_detach_exit; 6223dec9fcdSqs } 6233dec9fcdSqs 6243dec9fcdSqs switch (cmd) { 6253dec9fcdSqs case DDI_DETACH: 6263dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_DETACH")); 6273dec9fcdSqs break; 6283dec9fcdSqs 6293dec9fcdSqs case DDI_PM_SUSPEND: 6303dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_PM_SUSPEND")); 6313dec9fcdSqs hxgep->suspended = DDI_PM_SUSPEND; 6323dec9fcdSqs hxge_suspend(hxgep); 6333dec9fcdSqs break; 6343dec9fcdSqs 6353dec9fcdSqs case DDI_SUSPEND: 6363dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_SUSPEND")); 6373dec9fcdSqs if (hxgep->suspended != DDI_PM_SUSPEND) { 6383dec9fcdSqs hxgep->suspended = DDI_SUSPEND; 6393dec9fcdSqs hxge_suspend(hxgep); 6403dec9fcdSqs } 6413dec9fcdSqs break; 6423dec9fcdSqs 6433dec9fcdSqs default: 6443dec9fcdSqs status = DDI_FAILURE; 6453dec9fcdSqs break; 6463dec9fcdSqs } 6473dec9fcdSqs 6483dec9fcdSqs if (cmd != DDI_DETACH) 6493dec9fcdSqs goto hxge_detach_exit; 6503dec9fcdSqs 6513dec9fcdSqs /* 6523dec9fcdSqs * Stop the xcvr polling. 6533dec9fcdSqs */ 6543dec9fcdSqs hxgep->suspended = cmd; 6553dec9fcdSqs 6563dec9fcdSqs if (hxgep->mach && (status = mac_unregister(hxgep->mach)) != 0) { 6573dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 6583dec9fcdSqs "<== hxge_detach status = 0x%08X", status)); 6593dec9fcdSqs return (DDI_FAILURE); 6603dec9fcdSqs } 6613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 6623dec9fcdSqs "<== hxge_detach (mac_unregister) status = 0x%08X", status)); 6633dec9fcdSqs 6643dec9fcdSqs hxge_unattach(hxgep); 6653dec9fcdSqs hxgep = NULL; 6663dec9fcdSqs 6673dec9fcdSqs hxge_detach_exit: 6683dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_detach status = 0x%08X", 6693dec9fcdSqs status)); 6703dec9fcdSqs 6713dec9fcdSqs return (status); 6723dec9fcdSqs } 6733dec9fcdSqs 6743dec9fcdSqs static void 6753dec9fcdSqs hxge_unattach(p_hxge_t hxgep) 6763dec9fcdSqs { 6773dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_unattach")); 6783dec9fcdSqs 6793dec9fcdSqs if (hxgep == NULL || hxgep->dev_regs == NULL) { 6803dec9fcdSqs return; 6813dec9fcdSqs } 6823dec9fcdSqs 6833dec9fcdSqs if (hxgep->hxge_hw_p) { 6843dec9fcdSqs hxge_uninit_common_dev(hxgep); 6853dec9fcdSqs hxgep->hxge_hw_p = NULL; 6863dec9fcdSqs } 6873dec9fcdSqs 6883dec9fcdSqs if (hxgep->hxge_timerid) { 6893dec9fcdSqs hxge_stop_timer(hxgep, hxgep->hxge_timerid); 6903dec9fcdSqs hxgep->hxge_timerid = 0; 6913dec9fcdSqs } 6923dec9fcdSqs 6933dec9fcdSqs /* Stop any further interrupts. */ 6943dec9fcdSqs hxge_remove_intrs(hxgep); 6953dec9fcdSqs 6963dec9fcdSqs /* Stop the device and free resources. */ 6973dec9fcdSqs hxge_destroy_dev(hxgep); 6983dec9fcdSqs 6993dec9fcdSqs /* Tear down the ndd parameters setup. */ 7003dec9fcdSqs hxge_destroy_param(hxgep); 7013dec9fcdSqs 7023dec9fcdSqs /* Tear down the kstat setup. */ 7033dec9fcdSqs hxge_destroy_kstats(hxgep); 7043dec9fcdSqs 7053dec9fcdSqs /* 7063dec9fcdSqs * Remove the list of ndd parameters which were setup during attach. 7073dec9fcdSqs */ 7083dec9fcdSqs if (hxgep->dip) { 7093dec9fcdSqs HXGE_DEBUG_MSG((hxgep, OBP_CTL, 7103dec9fcdSqs " hxge_unattach: remove all properties")); 7113dec9fcdSqs (void) ddi_prop_remove_all(hxgep->dip); 7123dec9fcdSqs } 7133dec9fcdSqs 714fe930412Sqs /* 715fe930412Sqs * Reset RDC, TDC, PFC, and VMAC blocks from PEU to clear any 716fe930412Sqs * previous state before unmapping the registers. 717fe930412Sqs */ 718fe930412Sqs HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, 0x0000001E); 719fe930412Sqs HXGE_DELAY(1000); 720fe930412Sqs 7213dec9fcdSqs /* 7223dec9fcdSqs * Unmap the register setup. 7233dec9fcdSqs */ 7243dec9fcdSqs hxge_unmap_regs(hxgep); 7253dec9fcdSqs 7263dec9fcdSqs hxge_fm_fini(hxgep); 7273dec9fcdSqs 728a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Destroy all mutexes. */ 729a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_destroy_mutexes(hxgep); 730a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 7313dec9fcdSqs /* 7323dec9fcdSqs * Free the soft state data structures allocated with this instance. 7333dec9fcdSqs */ 7343dec9fcdSqs ddi_soft_state_free(hxge_list, hxgep->instance); 7353dec9fcdSqs 7363dec9fcdSqs HXGE_DEBUG_MSG((NULL, DDI_CTL, "<== hxge_unattach")); 7373dec9fcdSqs } 7383dec9fcdSqs 7393dec9fcdSqs static hxge_status_t 7403dec9fcdSqs hxge_map_regs(p_hxge_t hxgep) 7413dec9fcdSqs { 7423dec9fcdSqs int ddi_status = DDI_SUCCESS; 7433dec9fcdSqs p_dev_regs_t dev_regs; 7443dec9fcdSqs 7453dec9fcdSqs #ifdef HXGE_DEBUG 7463dec9fcdSqs char *sysname; 7473dec9fcdSqs #endif 7483dec9fcdSqs 7493dec9fcdSqs off_t regsize; 7503dec9fcdSqs hxge_status_t status = HXGE_OK; 7513dec9fcdSqs int nregs; 7523dec9fcdSqs 7533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_map_regs")); 7543dec9fcdSqs 7553dec9fcdSqs if (ddi_dev_nregs(hxgep->dip, &nregs) != DDI_SUCCESS) 7563dec9fcdSqs return (HXGE_ERROR); 7573dec9fcdSqs 7583dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "hxge_map_regs: nregs: %d", nregs)); 7593dec9fcdSqs 7603dec9fcdSqs hxgep->dev_regs = NULL; 7613dec9fcdSqs dev_regs = KMEM_ZALLOC(sizeof (dev_regs_t), KM_SLEEP); 7623dec9fcdSqs dev_regs->hxge_regh = NULL; 7633dec9fcdSqs dev_regs->hxge_pciregh = NULL; 7643dec9fcdSqs dev_regs->hxge_msix_regh = NULL; 7653dec9fcdSqs 7663dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 0, ®size); 7673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7683dec9fcdSqs "hxge_map_regs: pci config size 0x%x", regsize)); 7693dec9fcdSqs 7703dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 0, 7713dec9fcdSqs (caddr_t *)&(dev_regs->hxge_pciregp), 0, 0, 7723dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_pciregh); 7733dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 7743dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 7753dec9fcdSqs "ddi_map_regs, hxge bus config regs failed")); 7763dec9fcdSqs goto hxge_map_regs_fail0; 7773dec9fcdSqs } 7783dec9fcdSqs 7793dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7803dec9fcdSqs "hxge_map_reg: PCI config addr 0x%0llx handle 0x%0llx", 7813dec9fcdSqs dev_regs->hxge_pciregp, 7823dec9fcdSqs dev_regs->hxge_pciregh)); 7833dec9fcdSqs 7843dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 1, ®size); 7853dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7863dec9fcdSqs "hxge_map_regs: pio size 0x%x", regsize)); 7873dec9fcdSqs 7883dec9fcdSqs /* set up the device mapped register */ 7893dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 1, 7903dec9fcdSqs (caddr_t *)&(dev_regs->hxge_regp), 0, 0, 7913dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_regh); 7923dec9fcdSqs 7933dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 7943dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 7953dec9fcdSqs "ddi_map_regs for Hydra global reg failed")); 7963dec9fcdSqs goto hxge_map_regs_fail1; 7973dec9fcdSqs } 7983dec9fcdSqs 7993dec9fcdSqs /* set up the msi/msi-x mapped register */ 8003dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 2, ®size); 8013dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8023dec9fcdSqs "hxge_map_regs: msix size 0x%x", regsize)); 8033dec9fcdSqs 8043dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 2, 8053dec9fcdSqs (caddr_t *)&(dev_regs->hxge_msix_regp), 0, 0, 8063dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_msix_regh); 8073dec9fcdSqs 8083dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 8093dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 8103dec9fcdSqs "ddi_map_regs for msi reg failed")); 8113dec9fcdSqs goto hxge_map_regs_fail2; 8123dec9fcdSqs } 8133dec9fcdSqs 8143dec9fcdSqs hxgep->dev_regs = dev_regs; 8153dec9fcdSqs 8163dec9fcdSqs HPI_PCI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_pciregh); 8173dec9fcdSqs HPI_PCI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_pciregp); 8183dec9fcdSqs HPI_MSI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_msix_regh); 8193dec9fcdSqs HPI_MSI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_msix_regp); 8203dec9fcdSqs 8213dec9fcdSqs HPI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_regh); 8223dec9fcdSqs HPI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_regp); 8233dec9fcdSqs 8243dec9fcdSqs HPI_REG_ACC_HANDLE_SET(hxgep, dev_regs->hxge_regh); 8253dec9fcdSqs HPI_REG_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_regp); 8263dec9fcdSqs 8273dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "hxge_map_reg: hardware addr 0x%0llx " 8283dec9fcdSqs " handle 0x%0llx", dev_regs->hxge_regp, dev_regs->hxge_regh)); 8293dec9fcdSqs 8303dec9fcdSqs goto hxge_map_regs_exit; 8313dec9fcdSqs 8323dec9fcdSqs hxge_map_regs_fail3: 8333dec9fcdSqs if (dev_regs->hxge_msix_regh) { 8343dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_msix_regh); 8353dec9fcdSqs } 8363dec9fcdSqs 8373dec9fcdSqs hxge_map_regs_fail2: 8383dec9fcdSqs if (dev_regs->hxge_regh) { 8393dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_regh); 8403dec9fcdSqs } 8413dec9fcdSqs 8423dec9fcdSqs hxge_map_regs_fail1: 8433dec9fcdSqs if (dev_regs->hxge_pciregh) { 8443dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_pciregh); 8453dec9fcdSqs } 8463dec9fcdSqs 8473dec9fcdSqs hxge_map_regs_fail0: 8483dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "Freeing register set memory")); 8493dec9fcdSqs kmem_free(dev_regs, sizeof (dev_regs_t)); 8503dec9fcdSqs 8513dec9fcdSqs hxge_map_regs_exit: 8523dec9fcdSqs if (ddi_status != DDI_SUCCESS) 8533dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 8543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_map_regs")); 8553dec9fcdSqs return (status); 8563dec9fcdSqs } 8573dec9fcdSqs 8583dec9fcdSqs static void 8593dec9fcdSqs hxge_unmap_regs(p_hxge_t hxgep) 8603dec9fcdSqs { 8613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_unmap_regs")); 8623dec9fcdSqs if (hxgep->dev_regs) { 8633dec9fcdSqs if (hxgep->dev_regs->hxge_pciregh) { 8643dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8653dec9fcdSqs "==> hxge_unmap_regs: bus")); 8663dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_pciregh); 8673dec9fcdSqs hxgep->dev_regs->hxge_pciregh = NULL; 8683dec9fcdSqs } 8693dec9fcdSqs 8703dec9fcdSqs if (hxgep->dev_regs->hxge_regh) { 8713dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8723dec9fcdSqs "==> hxge_unmap_regs: device registers")); 8733dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_regh); 8743dec9fcdSqs hxgep->dev_regs->hxge_regh = NULL; 8753dec9fcdSqs } 8763dec9fcdSqs 8773dec9fcdSqs if (hxgep->dev_regs->hxge_msix_regh) { 8783dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8793dec9fcdSqs "==> hxge_unmap_regs: device interrupts")); 8803dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_msix_regh); 8813dec9fcdSqs hxgep->dev_regs->hxge_msix_regh = NULL; 8823dec9fcdSqs } 8833dec9fcdSqs kmem_free(hxgep->dev_regs, sizeof (dev_regs_t)); 8843dec9fcdSqs hxgep->dev_regs = NULL; 8853dec9fcdSqs } 8863dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_unmap_regs")); 8873dec9fcdSqs } 8883dec9fcdSqs 8893dec9fcdSqs static hxge_status_t 8903dec9fcdSqs hxge_setup_mutexes(p_hxge_t hxgep) 8913dec9fcdSqs { 8923dec9fcdSqs int ddi_status = DDI_SUCCESS; 8933dec9fcdSqs hxge_status_t status = HXGE_OK; 8943dec9fcdSqs 8953dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_mutexes")); 8963dec9fcdSqs 8973dec9fcdSqs /* 8983dec9fcdSqs * Get the interrupt cookie so the mutexes can be Initialised. 8993dec9fcdSqs */ 9003dec9fcdSqs ddi_status = ddi_get_iblock_cookie(hxgep->dip, 0, 9013dec9fcdSqs &hxgep->interrupt_cookie); 9023dec9fcdSqs 9033dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 9043dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 9053dec9fcdSqs "<== hxge_setup_mutexes: failed 0x%x", ddi_status)); 9063dec9fcdSqs goto hxge_setup_mutexes_exit; 9073dec9fcdSqs } 9083dec9fcdSqs 9093dec9fcdSqs /* 9103dec9fcdSqs * Initialize mutex's for this device. 9113dec9fcdSqs */ 9123dec9fcdSqs MUTEX_INIT(hxgep->genlock, NULL, 9133dec9fcdSqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9143dec9fcdSqs MUTEX_INIT(&hxgep->ouraddr_lock, NULL, 9153dec9fcdSqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9163dec9fcdSqs RW_INIT(&hxgep->filter_lock, NULL, 9173dec9fcdSqs RW_DRIVER, (void *) hxgep->interrupt_cookie); 918fe930412Sqs MUTEX_INIT(&hxgep->pio_lock, NULL, 919fe930412Sqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 920a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_INIT(&hxgep->timeout.lock, NULL, 921a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9223dec9fcdSqs 9233dec9fcdSqs hxge_setup_mutexes_exit: 9243dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 9253dec9fcdSqs "<== hxge_setup_mutexes status = %x", status)); 9263dec9fcdSqs 9273dec9fcdSqs if (ddi_status != DDI_SUCCESS) 9283dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 9293dec9fcdSqs 9303dec9fcdSqs return (status); 9313dec9fcdSqs } 9323dec9fcdSqs 9333dec9fcdSqs static void 9343dec9fcdSqs hxge_destroy_mutexes(p_hxge_t hxgep) 9353dec9fcdSqs { 9363dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_mutexes")); 9373dec9fcdSqs RW_DESTROY(&hxgep->filter_lock); 9383dec9fcdSqs MUTEX_DESTROY(&hxgep->ouraddr_lock); 9393dec9fcdSqs MUTEX_DESTROY(hxgep->genlock); 940fe930412Sqs MUTEX_DESTROY(&hxgep->pio_lock); 941a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_DESTROY(&hxgep->timeout.lock); 9423dec9fcdSqs 9433dec9fcdSqs if (hxge_debug_init == 1) { 9443dec9fcdSqs MUTEX_DESTROY(&hxgedebuglock); 9453dec9fcdSqs hxge_debug_init = 0; 9463dec9fcdSqs } 9473dec9fcdSqs 9483dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_mutexes")); 9493dec9fcdSqs } 9503dec9fcdSqs 9513dec9fcdSqs hxge_status_t 9523dec9fcdSqs hxge_init(p_hxge_t hxgep) 9533dec9fcdSqs { 9543dec9fcdSqs hxge_status_t status = HXGE_OK; 9553dec9fcdSqs 9563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, STR_CTL, "==> hxge_init")); 9573dec9fcdSqs 9583dec9fcdSqs if (hxgep->drv_state & STATE_HW_INITIALIZED) { 9593dec9fcdSqs return (status); 9603dec9fcdSqs } 9613dec9fcdSqs 9623dec9fcdSqs /* 9633dec9fcdSqs * Allocate system memory for the receive/transmit buffer blocks and 9643dec9fcdSqs * receive/transmit descriptor rings. 9653dec9fcdSqs */ 9663dec9fcdSqs status = hxge_alloc_mem_pool(hxgep); 9673dec9fcdSqs if (status != HXGE_OK) { 9683dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "alloc mem failed\n")); 9693dec9fcdSqs goto hxge_init_fail1; 9703dec9fcdSqs } 9713dec9fcdSqs 9723dec9fcdSqs /* 9733dec9fcdSqs * Initialize and enable TXDMA channels. 9743dec9fcdSqs */ 9753dec9fcdSqs status = hxge_init_txdma_channels(hxgep); 9763dec9fcdSqs if (status != HXGE_OK) { 9773dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init txdma failed\n")); 9783dec9fcdSqs goto hxge_init_fail3; 9793dec9fcdSqs } 9803dec9fcdSqs 9813dec9fcdSqs /* 9823dec9fcdSqs * Initialize and enable RXDMA channels. 9833dec9fcdSqs */ 9843dec9fcdSqs status = hxge_init_rxdma_channels(hxgep); 9853dec9fcdSqs if (status != HXGE_OK) { 9863dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init rxdma failed\n")); 9873dec9fcdSqs goto hxge_init_fail4; 9883dec9fcdSqs } 9893dec9fcdSqs 9903dec9fcdSqs /* 9913dec9fcdSqs * Initialize TCAM 9923dec9fcdSqs */ 9933dec9fcdSqs status = hxge_classify_init(hxgep); 9943dec9fcdSqs if (status != HXGE_OK) { 9953dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init classify failed\n")); 9963dec9fcdSqs goto hxge_init_fail5; 9973dec9fcdSqs } 9983dec9fcdSqs 9993dec9fcdSqs /* 10003dec9fcdSqs * Initialize the VMAC block. 10013dec9fcdSqs */ 10023dec9fcdSqs status = hxge_vmac_init(hxgep); 10033dec9fcdSqs if (status != HXGE_OK) { 10043dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init MAC failed\n")); 10053dec9fcdSqs goto hxge_init_fail5; 10063dec9fcdSqs } 10073dec9fcdSqs 10083dec9fcdSqs /* Bringup - this may be unnecessary when PXE and FCODE available */ 10093dec9fcdSqs status = hxge_pfc_set_default_mac_addr(hxgep); 10103dec9fcdSqs if (status != HXGE_OK) { 10113dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 10123dec9fcdSqs "Default Address Failure\n")); 10133dec9fcdSqs goto hxge_init_fail5; 10143dec9fcdSqs } 10153dec9fcdSqs 10163dec9fcdSqs hxge_intrs_enable(hxgep); 10173dec9fcdSqs 101857c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Keep copy of MSIx table written */ 101957c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_store_msix_table(hxgep); 102057c5371aSQiyan Sun - Sun Microsystems - San Diego United States 10213dec9fcdSqs /* 10223dec9fcdSqs * Enable hardware interrupts. 10233dec9fcdSqs */ 10243dec9fcdSqs hxge_intr_hw_enable(hxgep); 10253dec9fcdSqs hxgep->drv_state |= STATE_HW_INITIALIZED; 10263dec9fcdSqs 10273dec9fcdSqs goto hxge_init_exit; 10283dec9fcdSqs 10293dec9fcdSqs hxge_init_fail5: 10303dec9fcdSqs hxge_uninit_rxdma_channels(hxgep); 10313dec9fcdSqs hxge_init_fail4: 10323dec9fcdSqs hxge_uninit_txdma_channels(hxgep); 10333dec9fcdSqs hxge_init_fail3: 10343dec9fcdSqs hxge_free_mem_pool(hxgep); 10353dec9fcdSqs hxge_init_fail1: 10363dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 10373dec9fcdSqs "<== hxge_init status (failed) = 0x%08x", status)); 10383dec9fcdSqs return (status); 10393dec9fcdSqs 10403dec9fcdSqs hxge_init_exit: 10413dec9fcdSqs 10423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_init status = 0x%08x", 10433dec9fcdSqs status)); 10443dec9fcdSqs 10453dec9fcdSqs return (status); 10463dec9fcdSqs } 10473dec9fcdSqs 10483dec9fcdSqs timeout_id_t 10493dec9fcdSqs hxge_start_timer(p_hxge_t hxgep, fptrv_t func, int msec) 10503dec9fcdSqs { 10513dec9fcdSqs if ((hxgep->suspended == 0) || (hxgep->suspended == DDI_RESUME)) { 10523dec9fcdSqs return (timeout(func, (caddr_t)hxgep, 10533dec9fcdSqs drv_usectohz(1000 * msec))); 10543dec9fcdSqs } 10553dec9fcdSqs return (NULL); 10563dec9fcdSqs } 10573dec9fcdSqs 10583dec9fcdSqs /*ARGSUSED*/ 10593dec9fcdSqs void 10603dec9fcdSqs hxge_stop_timer(p_hxge_t hxgep, timeout_id_t timerid) 10613dec9fcdSqs { 10623dec9fcdSqs if (timerid) { 10633dec9fcdSqs (void) untimeout(timerid); 10643dec9fcdSqs } 10653dec9fcdSqs } 10663dec9fcdSqs 10673dec9fcdSqs void 10683dec9fcdSqs hxge_uninit(p_hxge_t hxgep) 10693dec9fcdSqs { 10703dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_uninit")); 10713dec9fcdSqs 10723dec9fcdSqs if (!(hxgep->drv_state & STATE_HW_INITIALIZED)) { 10733dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 10743dec9fcdSqs "==> hxge_uninit: not initialized")); 10753dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_uninit")); 10763dec9fcdSqs return; 10773dec9fcdSqs } 10783dec9fcdSqs 10793dec9fcdSqs /* Stop timer */ 10803dec9fcdSqs if (hxgep->hxge_timerid) { 10813dec9fcdSqs hxge_stop_timer(hxgep, hxgep->hxge_timerid); 10823dec9fcdSqs hxgep->hxge_timerid = 0; 10833dec9fcdSqs } 10843dec9fcdSqs 10853dec9fcdSqs (void) hxge_intr_hw_disable(hxgep); 10863dec9fcdSqs 10873dec9fcdSqs /* Reset the receive VMAC side. */ 10883dec9fcdSqs (void) hxge_rx_vmac_disable(hxgep); 10893dec9fcdSqs 10903dec9fcdSqs /* Free classification resources */ 10913dec9fcdSqs (void) hxge_classify_uninit(hxgep); 10923dec9fcdSqs 10933dec9fcdSqs /* Reset the transmit/receive DMA side. */ 10943dec9fcdSqs (void) hxge_txdma_hw_mode(hxgep, HXGE_DMA_STOP); 10953dec9fcdSqs (void) hxge_rxdma_hw_mode(hxgep, HXGE_DMA_STOP); 10963dec9fcdSqs 10973dec9fcdSqs hxge_uninit_txdma_channels(hxgep); 10983dec9fcdSqs hxge_uninit_rxdma_channels(hxgep); 10993dec9fcdSqs 11003dec9fcdSqs /* Reset the transmit VMAC side. */ 11013dec9fcdSqs (void) hxge_tx_vmac_disable(hxgep); 11023dec9fcdSqs 11033dec9fcdSqs hxge_free_mem_pool(hxgep); 11043dec9fcdSqs 11053dec9fcdSqs hxgep->drv_state &= ~STATE_HW_INITIALIZED; 11063dec9fcdSqs 11073dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_uninit")); 11083dec9fcdSqs } 11093dec9fcdSqs 11103dec9fcdSqs /*ARGSUSED*/ 11113dec9fcdSqs /*VARARGS*/ 11123dec9fcdSqs void 11133dec9fcdSqs hxge_debug_msg(p_hxge_t hxgep, uint64_t level, char *fmt, ...) 11143dec9fcdSqs { 11153dec9fcdSqs char msg_buffer[1048]; 11163dec9fcdSqs char prefix_buffer[32]; 11173dec9fcdSqs int instance; 11183dec9fcdSqs uint64_t debug_level; 11193dec9fcdSqs int cmn_level = CE_CONT; 11203dec9fcdSqs va_list ap; 11213dec9fcdSqs 11223dec9fcdSqs debug_level = (hxgep == NULL) ? hxge_debug_level : 11233dec9fcdSqs hxgep->hxge_debug_level; 11243dec9fcdSqs 11253dec9fcdSqs if ((level & debug_level) || (level == HXGE_NOTE) || 11263dec9fcdSqs (level == HXGE_ERR_CTL)) { 11273dec9fcdSqs /* do the msg processing */ 11283dec9fcdSqs if (hxge_debug_init == 0) { 11293dec9fcdSqs MUTEX_INIT(&hxgedebuglock, NULL, MUTEX_DRIVER, NULL); 11303dec9fcdSqs hxge_debug_init = 1; 11313dec9fcdSqs } 11323dec9fcdSqs 11333dec9fcdSqs MUTEX_ENTER(&hxgedebuglock); 11343dec9fcdSqs 11353dec9fcdSqs if ((level & HXGE_NOTE)) { 11363dec9fcdSqs cmn_level = CE_NOTE; 11373dec9fcdSqs } 11383dec9fcdSqs 11393dec9fcdSqs if (level & HXGE_ERR_CTL) { 11403dec9fcdSqs cmn_level = CE_WARN; 11413dec9fcdSqs } 11423dec9fcdSqs 11433dec9fcdSqs va_start(ap, fmt); 11443dec9fcdSqs (void) vsprintf(msg_buffer, fmt, ap); 11453dec9fcdSqs va_end(ap); 11463dec9fcdSqs 11473dec9fcdSqs if (hxgep == NULL) { 11483dec9fcdSqs instance = -1; 11493dec9fcdSqs (void) sprintf(prefix_buffer, "%s :", "hxge"); 11503dec9fcdSqs } else { 11513dec9fcdSqs instance = hxgep->instance; 11523dec9fcdSqs (void) sprintf(prefix_buffer, 11533dec9fcdSqs "%s%d :", "hxge", instance); 11543dec9fcdSqs } 11553dec9fcdSqs 11563dec9fcdSqs MUTEX_EXIT(&hxgedebuglock); 11573dec9fcdSqs cmn_err(cmn_level, "%s %s\n", prefix_buffer, msg_buffer); 11583dec9fcdSqs } 11593dec9fcdSqs } 11603dec9fcdSqs 11613dec9fcdSqs char * 11623dec9fcdSqs hxge_dump_packet(char *addr, int size) 11633dec9fcdSqs { 11643dec9fcdSqs uchar_t *ap = (uchar_t *)addr; 11653dec9fcdSqs int i; 11663dec9fcdSqs static char etherbuf[1024]; 11673dec9fcdSqs char *cp = etherbuf; 11683dec9fcdSqs char digits[] = "0123456789abcdef"; 11693dec9fcdSqs 11703dec9fcdSqs if (!size) 11713dec9fcdSqs size = 60; 11723dec9fcdSqs 11733dec9fcdSqs if (size > MAX_DUMP_SZ) { 11743dec9fcdSqs /* Dump the leading bytes */ 11753dec9fcdSqs for (i = 0; i < MAX_DUMP_SZ / 2; i++) { 11763dec9fcdSqs if (*ap > 0x0f) 11773dec9fcdSqs *cp++ = digits[*ap >> 4]; 11783dec9fcdSqs *cp++ = digits[*ap++ & 0xf]; 11793dec9fcdSqs *cp++ = ':'; 11803dec9fcdSqs } 11813dec9fcdSqs for (i = 0; i < 20; i++) 11823dec9fcdSqs *cp++ = '.'; 11833dec9fcdSqs /* Dump the last MAX_DUMP_SZ/2 bytes */ 11843dec9fcdSqs ap = (uchar_t *)(addr + (size - MAX_DUMP_SZ / 2)); 11853dec9fcdSqs for (i = 0; i < MAX_DUMP_SZ / 2; i++) { 11863dec9fcdSqs if (*ap > 0x0f) 11873dec9fcdSqs *cp++ = digits[*ap >> 4]; 11883dec9fcdSqs *cp++ = digits[*ap++ & 0xf]; 11893dec9fcdSqs *cp++ = ':'; 11903dec9fcdSqs } 11913dec9fcdSqs } else { 11923dec9fcdSqs for (i = 0; i < size; i++) { 11933dec9fcdSqs if (*ap > 0x0f) 11943dec9fcdSqs *cp++ = digits[*ap >> 4]; 11953dec9fcdSqs *cp++ = digits[*ap++ & 0xf]; 11963dec9fcdSqs *cp++ = ':'; 11973dec9fcdSqs } 11983dec9fcdSqs } 11993dec9fcdSqs *--cp = 0; 12003dec9fcdSqs return (etherbuf); 12013dec9fcdSqs } 12023dec9fcdSqs 12033dec9fcdSqs static void 12043dec9fcdSqs hxge_suspend(p_hxge_t hxgep) 12053dec9fcdSqs { 12063dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_suspend")); 12073dec9fcdSqs 12081c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States /* 12091c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * Stop the link status timer before hxge_intrs_disable() to avoid 12101c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * accessing the the MSIX table simultaneously. Note that the timer 12111c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * routine polls for MSIX parity errors. 12121c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States */ 1213a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 1214a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->timeout.id) 1215a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) untimeout(hxgep->timeout.id); 1216a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 1217a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 12181c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States hxge_intrs_disable(hxgep); 12191c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States hxge_destroy_dev(hxgep); 12201c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 12213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_suspend")); 12223dec9fcdSqs } 12233dec9fcdSqs 12243dec9fcdSqs static hxge_status_t 12253dec9fcdSqs hxge_resume(p_hxge_t hxgep) 12263dec9fcdSqs { 12273dec9fcdSqs hxge_status_t status = HXGE_OK; 12283dec9fcdSqs 12293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_resume")); 12303dec9fcdSqs hxgep->suspended = DDI_RESUME; 12313dec9fcdSqs 12323dec9fcdSqs (void) hxge_rxdma_hw_mode(hxgep, HXGE_DMA_START); 12333dec9fcdSqs (void) hxge_txdma_hw_mode(hxgep, HXGE_DMA_START); 12343dec9fcdSqs 12353dec9fcdSqs (void) hxge_rx_vmac_enable(hxgep); 12363dec9fcdSqs (void) hxge_tx_vmac_enable(hxgep); 12373dec9fcdSqs 12383dec9fcdSqs hxge_intrs_enable(hxgep); 12393dec9fcdSqs 124057c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Keep copy of MSIx table written */ 124157c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_store_msix_table(hxgep); 124257c5371aSQiyan Sun - Sun Microsystems - San Diego United States 12433dec9fcdSqs hxgep->suspended = 0; 12443dec9fcdSqs 12451c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States /* 12461c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * Resume the link status timer after hxge_intrs_enable to avoid 12471c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * accessing MSIX table simultaneously. 12481c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States */ 1249a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 1250a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = timeout(hxge_link_poll, (void *)hxgep, 1251a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks); 1252a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 1253a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 12543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 12553dec9fcdSqs "<== hxge_resume status = 0x%x", status)); 12563dec9fcdSqs 12573dec9fcdSqs return (status); 12583dec9fcdSqs } 12593dec9fcdSqs 12603dec9fcdSqs hxge_status_t 12613dec9fcdSqs hxge_setup_dev(p_hxge_t hxgep) 12623dec9fcdSqs { 12633dec9fcdSqs hxge_status_t status = HXGE_OK; 12643dec9fcdSqs 12653dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_dev")); 12663dec9fcdSqs 12673dec9fcdSqs status = hxge_link_init(hxgep); 12683dec9fcdSqs if (fm_check_acc_handle(hxgep->dev_regs->hxge_regh) != DDI_FM_OK) { 12693dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 12703dec9fcdSqs "Bad register acc handle")); 12713dec9fcdSqs status = HXGE_ERROR; 12723dec9fcdSqs } 12733dec9fcdSqs 12743dec9fcdSqs if (status != HXGE_OK) { 12753dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, 12763dec9fcdSqs " hxge_setup_dev status (link init 0x%08x)", status)); 12773dec9fcdSqs goto hxge_setup_dev_exit; 12783dec9fcdSqs } 12793dec9fcdSqs 12803dec9fcdSqs hxge_setup_dev_exit: 12813dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 12823dec9fcdSqs "<== hxge_setup_dev status = 0x%08x", status)); 12833dec9fcdSqs 12843dec9fcdSqs return (status); 12853dec9fcdSqs } 12863dec9fcdSqs 12873dec9fcdSqs static void 12883dec9fcdSqs hxge_destroy_dev(p_hxge_t hxgep) 12893dec9fcdSqs { 12903dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_dev")); 12913dec9fcdSqs 12923dec9fcdSqs (void) hxge_hw_stop(hxgep); 12933dec9fcdSqs 12943dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_dev")); 12953dec9fcdSqs } 12963dec9fcdSqs 12973dec9fcdSqs static hxge_status_t 12983dec9fcdSqs hxge_setup_system_dma_pages(p_hxge_t hxgep) 12993dec9fcdSqs { 13003dec9fcdSqs int ddi_status = DDI_SUCCESS; 13013dec9fcdSqs uint_t count; 13023dec9fcdSqs ddi_dma_cookie_t cookie; 13033dec9fcdSqs uint_t iommu_pagesize; 13043dec9fcdSqs hxge_status_t status = HXGE_OK; 13053dec9fcdSqs 13063dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_system_dma_pages")); 13073dec9fcdSqs 13083dec9fcdSqs hxgep->sys_page_sz = ddi_ptob(hxgep->dip, (ulong_t)1); 13093dec9fcdSqs iommu_pagesize = dvma_pagesize(hxgep->dip); 13103dec9fcdSqs 13113dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13123dec9fcdSqs " hxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 13133dec9fcdSqs " default_block_size %d iommu_pagesize %d", 13143dec9fcdSqs hxgep->sys_page_sz, ddi_ptob(hxgep->dip, (ulong_t)1), 13153dec9fcdSqs hxgep->rx_default_block_size, iommu_pagesize)); 13163dec9fcdSqs 13173dec9fcdSqs if (iommu_pagesize != 0) { 13183dec9fcdSqs if (hxgep->sys_page_sz == iommu_pagesize) { 13193dec9fcdSqs /* Hydra support up to 8K pages */ 13203dec9fcdSqs if (iommu_pagesize > 0x2000) 13213dec9fcdSqs hxgep->sys_page_sz = 0x2000; 13223dec9fcdSqs } else { 13233dec9fcdSqs if (hxgep->sys_page_sz > iommu_pagesize) 13243dec9fcdSqs hxgep->sys_page_sz = iommu_pagesize; 13253dec9fcdSqs } 13263dec9fcdSqs } 13273dec9fcdSqs 13283dec9fcdSqs hxgep->sys_page_mask = ~(hxgep->sys_page_sz - 1); 13293dec9fcdSqs 13303dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13313dec9fcdSqs "==> hxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 13323dec9fcdSqs "default_block_size %d page mask %d", 13333dec9fcdSqs hxgep->sys_page_sz, ddi_ptob(hxgep->dip, (ulong_t)1), 13343dec9fcdSqs hxgep->rx_default_block_size, hxgep->sys_page_mask)); 13353dec9fcdSqs 13363dec9fcdSqs switch (hxgep->sys_page_sz) { 13373dec9fcdSqs default: 13383dec9fcdSqs hxgep->sys_page_sz = 0x1000; 13393dec9fcdSqs hxgep->sys_page_mask = ~(hxgep->sys_page_sz - 1); 13403dec9fcdSqs hxgep->rx_default_block_size = 0x1000; 13413dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_4K; 13423dec9fcdSqs break; 13433dec9fcdSqs case 0x1000: 13443dec9fcdSqs hxgep->rx_default_block_size = 0x1000; 13453dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_4K; 13463dec9fcdSqs break; 13473dec9fcdSqs case 0x2000: 13483dec9fcdSqs hxgep->rx_default_block_size = 0x2000; 13493dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_8K; 13503dec9fcdSqs break; 13513dec9fcdSqs } 13523dec9fcdSqs 13533dec9fcdSqs hxge_rx_dma_attr.dma_attr_align = hxgep->sys_page_sz; 13543dec9fcdSqs hxge_tx_dma_attr.dma_attr_align = hxgep->sys_page_sz; 13553dec9fcdSqs 13563dec9fcdSqs /* 13573dec9fcdSqs * Get the system DMA burst size. 13583dec9fcdSqs */ 13593dec9fcdSqs ddi_status = ddi_dma_alloc_handle(hxgep->dip, &hxge_tx_dma_attr, 13603dec9fcdSqs DDI_DMA_DONTWAIT, 0, &hxgep->dmasparehandle); 13613dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 13623dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 13633dec9fcdSqs "ddi_dma_alloc_handle: failed status 0x%x", ddi_status)); 13643dec9fcdSqs goto hxge_get_soft_properties_exit; 13653dec9fcdSqs } 13663dec9fcdSqs 13673dec9fcdSqs ddi_status = ddi_dma_addr_bind_handle(hxgep->dmasparehandle, NULL, 13683dec9fcdSqs (caddr_t)hxgep->dmasparehandle, sizeof (hxgep->dmasparehandle), 13693dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, 13703dec9fcdSqs &cookie, &count); 13713dec9fcdSqs if (ddi_status != DDI_DMA_MAPPED) { 13723dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 13733dec9fcdSqs "Binding spare handle to find system burstsize failed.")); 13743dec9fcdSqs ddi_status = DDI_FAILURE; 13753dec9fcdSqs goto hxge_get_soft_properties_fail1; 13763dec9fcdSqs } 13773dec9fcdSqs 13783dec9fcdSqs hxgep->sys_burst_sz = ddi_dma_burstsizes(hxgep->dmasparehandle); 13793dec9fcdSqs (void) ddi_dma_unbind_handle(hxgep->dmasparehandle); 13803dec9fcdSqs 13813dec9fcdSqs hxge_get_soft_properties_fail1: 13823dec9fcdSqs ddi_dma_free_handle(&hxgep->dmasparehandle); 13833dec9fcdSqs 13843dec9fcdSqs hxge_get_soft_properties_exit: 13853dec9fcdSqs 13863dec9fcdSqs if (ddi_status != DDI_SUCCESS) 13873dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 13883dec9fcdSqs 13893dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13903dec9fcdSqs "<== hxge_setup_system_dma_pages status = 0x%08x", status)); 13913dec9fcdSqs 13923dec9fcdSqs return (status); 13933dec9fcdSqs } 13943dec9fcdSqs 13953dec9fcdSqs hxge_status_t 13963dec9fcdSqs hxge_alloc_mem_pool(p_hxge_t hxgep) 13973dec9fcdSqs { 13983dec9fcdSqs hxge_status_t status = HXGE_OK; 13993dec9fcdSqs 14003dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_alloc_mem_pool")); 14013dec9fcdSqs 14023dec9fcdSqs status = hxge_alloc_rx_mem_pool(hxgep); 14033dec9fcdSqs if (status != HXGE_OK) { 14043dec9fcdSqs return (HXGE_ERROR); 14053dec9fcdSqs } 14063dec9fcdSqs 14073dec9fcdSqs status = hxge_alloc_tx_mem_pool(hxgep); 14083dec9fcdSqs if (status != HXGE_OK) { 14093dec9fcdSqs hxge_free_rx_mem_pool(hxgep); 14103dec9fcdSqs return (HXGE_ERROR); 14113dec9fcdSqs } 14123dec9fcdSqs 14133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_alloc_mem_pool")); 14143dec9fcdSqs return (HXGE_OK); 14153dec9fcdSqs } 14163dec9fcdSqs 14173dec9fcdSqs static void 14183dec9fcdSqs hxge_free_mem_pool(p_hxge_t hxgep) 14193dec9fcdSqs { 14203dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_free_mem_pool")); 14213dec9fcdSqs 14223dec9fcdSqs hxge_free_rx_mem_pool(hxgep); 14233dec9fcdSqs hxge_free_tx_mem_pool(hxgep); 14243dec9fcdSqs 14253dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "<== hxge_free_mem_pool")); 14263dec9fcdSqs } 14273dec9fcdSqs 14283dec9fcdSqs static hxge_status_t 14293dec9fcdSqs hxge_alloc_rx_mem_pool(p_hxge_t hxgep) 14303dec9fcdSqs { 14313dec9fcdSqs int i, j; 14323dec9fcdSqs uint32_t ndmas, st_rdc; 14333dec9fcdSqs p_hxge_dma_pt_cfg_t p_all_cfgp; 14343dec9fcdSqs p_hxge_hw_pt_cfg_t p_cfgp; 14353dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 14363dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 14378ad8db65SMichael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp; 14388ad8db65SMichael Speer p_hxge_dma_common_t *dma_rbr_cntl_p; 14398ad8db65SMichael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp; 14408ad8db65SMichael Speer p_hxge_dma_common_t *dma_rcr_cntl_p; 14418ad8db65SMichael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp; 14428ad8db65SMichael Speer p_hxge_dma_common_t *dma_mbox_cntl_p; 14433dec9fcdSqs size_t rx_buf_alloc_size; 14448ad8db65SMichael Speer size_t rx_rbr_cntl_alloc_size; 14458ad8db65SMichael Speer size_t rx_rcr_cntl_alloc_size; 14468ad8db65SMichael Speer size_t rx_mbox_cntl_alloc_size; 14473dec9fcdSqs uint32_t *num_chunks; /* per dma */ 14483dec9fcdSqs hxge_status_t status = HXGE_OK; 14493dec9fcdSqs 14503dec9fcdSqs uint32_t hxge_port_rbr_size; 14513dec9fcdSqs uint32_t hxge_port_rbr_spare_size; 14523dec9fcdSqs uint32_t hxge_port_rcr_size; 14533dec9fcdSqs 14543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_mem_pool")); 14553dec9fcdSqs 14563dec9fcdSqs p_all_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 14573dec9fcdSqs p_cfgp = (p_hxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 14583dec9fcdSqs st_rdc = p_cfgp->start_rdc; 14593dec9fcdSqs ndmas = p_cfgp->max_rdcs; 14603dec9fcdSqs 14613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 14623dec9fcdSqs " hxge_alloc_rx_mem_pool st_rdc %d ndmas %d", st_rdc, ndmas)); 14633dec9fcdSqs 14643dec9fcdSqs /* 14653dec9fcdSqs * Allocate memory for each receive DMA channel. 14663dec9fcdSqs */ 14673dec9fcdSqs dma_poolp = (p_hxge_dma_pool_t)KMEM_ZALLOC(sizeof (hxge_dma_pool_t), 14683dec9fcdSqs KM_SLEEP); 14693dec9fcdSqs dma_buf_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14703dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14713dec9fcdSqs 14728ad8db65SMichael Speer dma_rbr_cntl_poolp = (p_hxge_dma_pool_t) 14733dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14748ad8db65SMichael Speer dma_rbr_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14758ad8db65SMichael Speer sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14768ad8db65SMichael Speer dma_rcr_cntl_poolp = (p_hxge_dma_pool_t) 14778ad8db65SMichael Speer KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14788ad8db65SMichael Speer dma_rcr_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14798ad8db65SMichael Speer sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14808ad8db65SMichael Speer dma_mbox_cntl_poolp = (p_hxge_dma_pool_t) 14818ad8db65SMichael Speer KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14828ad8db65SMichael Speer dma_mbox_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14833dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14843dec9fcdSqs 14853dec9fcdSqs num_chunks = (uint32_t *)KMEM_ZALLOC(sizeof (uint32_t) * ndmas, 14863dec9fcdSqs KM_SLEEP); 14873dec9fcdSqs 14883dec9fcdSqs /* 14893dec9fcdSqs * Assume that each DMA channel will be configured with default block 14903dec9fcdSqs * size. rbr block counts are mod of batch count (16). 14913dec9fcdSqs */ 14923dec9fcdSqs hxge_port_rbr_size = p_all_cfgp->rbr_size; 14933dec9fcdSqs hxge_port_rcr_size = p_all_cfgp->rcr_size; 14943dec9fcdSqs 14953dec9fcdSqs if (!hxge_port_rbr_size) { 14963dec9fcdSqs hxge_port_rbr_size = HXGE_RBR_RBB_DEFAULT; 14973dec9fcdSqs } 14983dec9fcdSqs 14993dec9fcdSqs if (hxge_port_rbr_size % HXGE_RXDMA_POST_BATCH) { 15003dec9fcdSqs hxge_port_rbr_size = (HXGE_RXDMA_POST_BATCH * 15013dec9fcdSqs (hxge_port_rbr_size / HXGE_RXDMA_POST_BATCH + 1)); 15023dec9fcdSqs } 15033dec9fcdSqs 15043dec9fcdSqs p_all_cfgp->rbr_size = hxge_port_rbr_size; 15053dec9fcdSqs hxge_port_rbr_spare_size = hxge_rbr_spare_size; 15063dec9fcdSqs 15073dec9fcdSqs if (hxge_port_rbr_spare_size % HXGE_RXDMA_POST_BATCH) { 15083dec9fcdSqs hxge_port_rbr_spare_size = (HXGE_RXDMA_POST_BATCH * 15093dec9fcdSqs (hxge_port_rbr_spare_size / HXGE_RXDMA_POST_BATCH + 1)); 15103dec9fcdSqs } 15113dec9fcdSqs 15123dec9fcdSqs rx_buf_alloc_size = (hxgep->rx_default_block_size * 15133dec9fcdSqs (hxge_port_rbr_size + hxge_port_rbr_spare_size)); 15143dec9fcdSqs 15153dec9fcdSqs /* 15163dec9fcdSqs * Addresses of receive block ring, receive completion ring and the 15173dec9fcdSqs * mailbox must be all cache-aligned (64 bytes). 15183dec9fcdSqs */ 15198ad8db65SMichael Speer rx_rbr_cntl_alloc_size = hxge_port_rbr_size + hxge_port_rbr_spare_size; 15208ad8db65SMichael Speer rx_rbr_cntl_alloc_size *= sizeof (rx_desc_t); 15218ad8db65SMichael Speer rx_rcr_cntl_alloc_size = sizeof (rcr_entry_t) * hxge_port_rcr_size; 15228ad8db65SMichael Speer rx_mbox_cntl_alloc_size = sizeof (rxdma_mailbox_t); 15233dec9fcdSqs 15243dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_alloc_rx_mem_pool: " 15253dec9fcdSqs "hxge_port_rbr_size = %d hxge_port_rbr_spare_size = %d " 15263dec9fcdSqs "hxge_port_rcr_size = %d rx_cntl_alloc_size = %d", 15273dec9fcdSqs hxge_port_rbr_size, hxge_port_rbr_spare_size, 15283dec9fcdSqs hxge_port_rcr_size, rx_cntl_alloc_size)); 15293dec9fcdSqs 15303dec9fcdSqs hxgep->hxge_port_rbr_size = hxge_port_rbr_size; 15313dec9fcdSqs hxgep->hxge_port_rcr_size = hxge_port_rcr_size; 15323dec9fcdSqs 15333dec9fcdSqs /* 15343dec9fcdSqs * Allocate memory for receive buffers and descriptor rings. Replace 15353dec9fcdSqs * allocation functions with interface functions provided by the 15363dec9fcdSqs * partition manager when it is available. 15373dec9fcdSqs */ 15383dec9fcdSqs /* 15393dec9fcdSqs * Allocate memory for the receive buffer blocks. 15403dec9fcdSqs */ 15413dec9fcdSqs for (i = 0; i < ndmas; i++) { 15423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 15433dec9fcdSqs " hxge_alloc_rx_mem_pool to alloc mem: " 15443dec9fcdSqs " dma %d dma_buf_p %llx &dma_buf_p %llx", 15453dec9fcdSqs i, dma_buf_p[i], &dma_buf_p[i])); 15463dec9fcdSqs 15473dec9fcdSqs num_chunks[i] = 0; 15483dec9fcdSqs 15493dec9fcdSqs status = hxge_alloc_rx_buf_dma(hxgep, st_rdc, &dma_buf_p[i], 15503dec9fcdSqs rx_buf_alloc_size, hxgep->rx_default_block_size, 15513dec9fcdSqs &num_chunks[i]); 15523dec9fcdSqs if (status != HXGE_OK) { 15533dec9fcdSqs break; 15543dec9fcdSqs } 15553dec9fcdSqs 15563dec9fcdSqs st_rdc++; 15573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 15583dec9fcdSqs " hxge_alloc_rx_mem_pool DONE alloc mem: " 15593dec9fcdSqs "dma %d dma_buf_p %llx &dma_buf_p %llx", i, 15603dec9fcdSqs dma_buf_p[i], &dma_buf_p[i])); 15613dec9fcdSqs } 15623dec9fcdSqs 15633dec9fcdSqs if (i < ndmas) { 15643dec9fcdSqs goto hxge_alloc_rx_mem_fail1; 15653dec9fcdSqs } 15663dec9fcdSqs 15673dec9fcdSqs /* 15683dec9fcdSqs * Allocate memory for descriptor rings and mailbox. 15693dec9fcdSqs */ 15703dec9fcdSqs st_rdc = p_cfgp->start_rdc; 15713dec9fcdSqs for (j = 0; j < ndmas; j++) { 15728ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15738ad8db65SMichael Speer &dma_rbr_cntl_p[j], &hxge_rx_rbr_desc_dma_attr, 15748ad8db65SMichael Speer rx_rbr_cntl_alloc_size)) != HXGE_OK) { 15758ad8db65SMichael Speer break; 15768ad8db65SMichael Speer } 15778ad8db65SMichael Speer 15788ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15798ad8db65SMichael Speer &dma_rcr_cntl_p[j], &hxge_rx_rcr_desc_dma_attr, 15808ad8db65SMichael Speer rx_rcr_cntl_alloc_size)) != HXGE_OK) { 15818ad8db65SMichael Speer break; 15828ad8db65SMichael Speer } 15838ad8db65SMichael Speer 15848ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15858ad8db65SMichael Speer &dma_mbox_cntl_p[j], &hxge_rx_mbox_dma_attr, 15868ad8db65SMichael Speer rx_mbox_cntl_alloc_size)) != HXGE_OK) { 15873dec9fcdSqs break; 15883dec9fcdSqs } 15893dec9fcdSqs st_rdc++; 15903dec9fcdSqs } 15913dec9fcdSqs 15923dec9fcdSqs if (j < ndmas) { 15933dec9fcdSqs goto hxge_alloc_rx_mem_fail2; 15943dec9fcdSqs } 15953dec9fcdSqs 15963dec9fcdSqs dma_poolp->ndmas = ndmas; 15973dec9fcdSqs dma_poolp->num_chunks = num_chunks; 15983dec9fcdSqs dma_poolp->buf_allocated = B_TRUE; 15993dec9fcdSqs hxgep->rx_buf_pool_p = dma_poolp; 16003dec9fcdSqs dma_poolp->dma_buf_pool_p = dma_buf_p; 16013dec9fcdSqs 16028ad8db65SMichael Speer dma_rbr_cntl_poolp->ndmas = ndmas; 16038ad8db65SMichael Speer dma_rbr_cntl_poolp->buf_allocated = B_TRUE; 16048ad8db65SMichael Speer hxgep->rx_rbr_cntl_pool_p = dma_rbr_cntl_poolp; 16058ad8db65SMichael Speer dma_rbr_cntl_poolp->dma_buf_pool_p = dma_rbr_cntl_p; 16068ad8db65SMichael Speer 16078ad8db65SMichael Speer dma_rcr_cntl_poolp->ndmas = ndmas; 16088ad8db65SMichael Speer dma_rcr_cntl_poolp->buf_allocated = B_TRUE; 16098ad8db65SMichael Speer hxgep->rx_rcr_cntl_pool_p = dma_rcr_cntl_poolp; 16108ad8db65SMichael Speer dma_rcr_cntl_poolp->dma_buf_pool_p = dma_rcr_cntl_p; 16118ad8db65SMichael Speer 16128ad8db65SMichael Speer dma_mbox_cntl_poolp->ndmas = ndmas; 16138ad8db65SMichael Speer dma_mbox_cntl_poolp->buf_allocated = B_TRUE; 16148ad8db65SMichael Speer hxgep->rx_mbox_cntl_pool_p = dma_mbox_cntl_poolp; 16158ad8db65SMichael Speer dma_mbox_cntl_poolp->dma_buf_pool_p = dma_mbox_cntl_p; 16163dec9fcdSqs 16173dec9fcdSqs goto hxge_alloc_rx_mem_pool_exit; 16183dec9fcdSqs 16193dec9fcdSqs hxge_alloc_rx_mem_fail2: 16203dec9fcdSqs /* Free control buffers */ 16213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16223dec9fcdSqs "==> hxge_alloc_rx_mem_pool: freeing control bufs (%d)", j)); 16233dec9fcdSqs for (; j >= 0; j--) { 16243dec9fcdSqs hxge_free_rx_cntl_dma(hxgep, 16258ad8db65SMichael Speer (p_hxge_dma_common_t)dma_rbr_cntl_p[j]); 16268ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, 16278ad8db65SMichael Speer (p_hxge_dma_common_t)dma_rcr_cntl_p[j]); 16288ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, 16298ad8db65SMichael Speer (p_hxge_dma_common_t)dma_mbox_cntl_p[j]); 16303dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16313dec9fcdSqs "==> hxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 16323dec9fcdSqs } 16333dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16343dec9fcdSqs "==> hxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 16353dec9fcdSqs 16363dec9fcdSqs hxge_alloc_rx_mem_fail1: 16373dec9fcdSqs /* Free data buffers */ 16383dec9fcdSqs i--; 16393dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16403dec9fcdSqs "==> hxge_alloc_rx_mem_pool: freeing data bufs (%d)", i)); 16413dec9fcdSqs for (; i >= 0; i--) { 16423dec9fcdSqs hxge_free_rx_buf_dma(hxgep, (p_hxge_dma_common_t)dma_buf_p[i], 16433dec9fcdSqs num_chunks[i]); 16443dec9fcdSqs } 16453dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16463dec9fcdSqs "==> hxge_alloc_rx_mem_pool: data bufs freed (%d)", i)); 16473dec9fcdSqs 16483dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 16493dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 16503dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 16518ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_poolp, sizeof (hxge_dma_pool_t)); 16528ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16538ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_poolp, sizeof (hxge_dma_pool_t)); 16548ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16558ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_poolp, sizeof (hxge_dma_pool_t)); 16568ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16573dec9fcdSqs 16583dec9fcdSqs hxge_alloc_rx_mem_pool_exit: 16593dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16603dec9fcdSqs "<== hxge_alloc_rx_mem_pool:status 0x%08x", status)); 16613dec9fcdSqs 16623dec9fcdSqs return (status); 16633dec9fcdSqs } 16643dec9fcdSqs 16653dec9fcdSqs static void 16663dec9fcdSqs hxge_free_rx_mem_pool(p_hxge_t hxgep) 16673dec9fcdSqs { 16683dec9fcdSqs uint32_t i, ndmas; 16693dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 16703dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 16718ad8db65SMichael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp; 16728ad8db65SMichael Speer p_hxge_dma_common_t *dma_rbr_cntl_p; 16738ad8db65SMichael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp; 16748ad8db65SMichael Speer p_hxge_dma_common_t *dma_rcr_cntl_p; 16758ad8db65SMichael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp; 16768ad8db65SMichael Speer p_hxge_dma_common_t *dma_mbox_cntl_p; 16773dec9fcdSqs uint32_t *num_chunks; 16783dec9fcdSqs 16793dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_free_rx_mem_pool")); 16803dec9fcdSqs 16813dec9fcdSqs dma_poolp = hxgep->rx_buf_pool_p; 16823dec9fcdSqs if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 16833dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_mem_pool " 16843dec9fcdSqs "(null rx buf pool or buf not allocated")); 16853dec9fcdSqs return; 16863dec9fcdSqs } 16873dec9fcdSqs 16888ad8db65SMichael Speer dma_rbr_cntl_poolp = hxgep->rx_rbr_cntl_pool_p; 16898ad8db65SMichael Speer if (dma_rbr_cntl_poolp == NULL || 16908ad8db65SMichael Speer (!dma_rbr_cntl_poolp->buf_allocated)) { 16918ad8db65SMichael Speer HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 16928ad8db65SMichael Speer "<== hxge_free_rx_mem_pool " 16938ad8db65SMichael Speer "(null rbr cntl buf pool or rbr cntl buf not allocated")); 16948ad8db65SMichael Speer return; 16958ad8db65SMichael Speer } 16968ad8db65SMichael Speer 16978ad8db65SMichael Speer dma_rcr_cntl_poolp = hxgep->rx_rcr_cntl_pool_p; 16988ad8db65SMichael Speer if (dma_rcr_cntl_poolp == NULL || 16998ad8db65SMichael Speer (!dma_rcr_cntl_poolp->buf_allocated)) { 17003dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17013dec9fcdSqs "<== hxge_free_rx_mem_pool " 17028ad8db65SMichael Speer "(null rcr cntl buf pool or rcr cntl buf not allocated")); 17038ad8db65SMichael Speer return; 17048ad8db65SMichael Speer } 17058ad8db65SMichael Speer 17068ad8db65SMichael Speer dma_mbox_cntl_poolp = hxgep->rx_mbox_cntl_pool_p; 17078ad8db65SMichael Speer if (dma_mbox_cntl_poolp == NULL || 17088ad8db65SMichael Speer (!dma_mbox_cntl_poolp->buf_allocated)) { 17098ad8db65SMichael Speer HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17108ad8db65SMichael Speer "<== hxge_free_rx_mem_pool " 17118ad8db65SMichael Speer "(null mbox cntl buf pool or mbox cntl buf not allocated")); 17123dec9fcdSqs return; 17133dec9fcdSqs } 17143dec9fcdSqs 17153dec9fcdSqs dma_buf_p = dma_poolp->dma_buf_pool_p; 17163dec9fcdSqs num_chunks = dma_poolp->num_chunks; 17173dec9fcdSqs 17188ad8db65SMichael Speer dma_rbr_cntl_p = dma_rbr_cntl_poolp->dma_buf_pool_p; 17198ad8db65SMichael Speer dma_rcr_cntl_p = dma_rcr_cntl_poolp->dma_buf_pool_p; 17208ad8db65SMichael Speer dma_mbox_cntl_p = dma_mbox_cntl_poolp->dma_buf_pool_p; 17218ad8db65SMichael Speer ndmas = dma_rbr_cntl_poolp->ndmas; 17223dec9fcdSqs 17233dec9fcdSqs for (i = 0; i < ndmas; i++) { 17243dec9fcdSqs hxge_free_rx_buf_dma(hxgep, dma_buf_p[i], num_chunks[i]); 17253dec9fcdSqs } 17263dec9fcdSqs 17273dec9fcdSqs for (i = 0; i < ndmas; i++) { 17288ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_rbr_cntl_p[i]); 17298ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_rcr_cntl_p[i]); 17308ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_mbox_cntl_p[i]); 17313dec9fcdSqs } 17323dec9fcdSqs 17333dec9fcdSqs for (i = 0; i < ndmas; i++) { 17343dec9fcdSqs KMEM_FREE(dma_buf_p[i], 17353dec9fcdSqs sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 17368ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p[i], sizeof (hxge_dma_common_t)); 17378ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p[i], sizeof (hxge_dma_common_t)); 17388ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p[i], sizeof (hxge_dma_common_t)); 17393dec9fcdSqs } 17403dec9fcdSqs 17413dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 17428ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17438ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_poolp, sizeof (hxge_dma_pool_t)); 17448ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17458ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_poolp, sizeof (hxge_dma_pool_t)); 17468ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17478ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_poolp, sizeof (hxge_dma_pool_t)); 17483dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 17493dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 17503dec9fcdSqs 17513dec9fcdSqs hxgep->rx_buf_pool_p = NULL; 17528ad8db65SMichael Speer hxgep->rx_rbr_cntl_pool_p = NULL; 17538ad8db65SMichael Speer hxgep->rx_rcr_cntl_pool_p = NULL; 17548ad8db65SMichael Speer hxgep->rx_mbox_cntl_pool_p = NULL; 17553dec9fcdSqs 17563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_mem_pool")); 17573dec9fcdSqs } 17583dec9fcdSqs 17593dec9fcdSqs static hxge_status_t 17603dec9fcdSqs hxge_alloc_rx_buf_dma(p_hxge_t hxgep, uint16_t dma_channel, 17613dec9fcdSqs p_hxge_dma_common_t *dmap, 17623dec9fcdSqs size_t alloc_size, size_t block_size, uint32_t *num_chunks) 17633dec9fcdSqs { 17643dec9fcdSqs p_hxge_dma_common_t rx_dmap; 17653dec9fcdSqs hxge_status_t status = HXGE_OK; 17663dec9fcdSqs size_t total_alloc_size; 17673dec9fcdSqs size_t allocated = 0; 17683dec9fcdSqs int i, size_index, array_size; 17693dec9fcdSqs 17703dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_buf_dma")); 17713dec9fcdSqs 17723dec9fcdSqs rx_dmap = (p_hxge_dma_common_t) 17733dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK, KM_SLEEP); 17743dec9fcdSqs 17753dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17763dec9fcdSqs " alloc_rx_buf_dma rdc %d asize %x bsize %x bbuf %llx ", 17773dec9fcdSqs dma_channel, alloc_size, block_size, dmap)); 17783dec9fcdSqs 17793dec9fcdSqs total_alloc_size = alloc_size; 17803dec9fcdSqs 17813dec9fcdSqs i = 0; 17823dec9fcdSqs size_index = 0; 17833dec9fcdSqs array_size = sizeof (alloc_sizes) / sizeof (size_t); 1784b83cd2c3SMichael Speer while ((size_index < array_size) && 1785b83cd2c3SMichael Speer (alloc_sizes[size_index] < alloc_size)) 17863dec9fcdSqs size_index++; 17873dec9fcdSqs if (size_index >= array_size) { 17883dec9fcdSqs size_index = array_size - 1; 17893dec9fcdSqs } 17903dec9fcdSqs 17913dec9fcdSqs while ((allocated < total_alloc_size) && 17923dec9fcdSqs (size_index >= 0) && (i < HXGE_DMA_BLOCK)) { 17933dec9fcdSqs rx_dmap[i].dma_chunk_index = i; 17943dec9fcdSqs rx_dmap[i].block_size = block_size; 17953dec9fcdSqs rx_dmap[i].alength = alloc_sizes[size_index]; 17963dec9fcdSqs rx_dmap[i].orig_alength = rx_dmap[i].alength; 17973dec9fcdSqs rx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 17983dec9fcdSqs rx_dmap[i].dma_channel = dma_channel; 17993dec9fcdSqs rx_dmap[i].contig_alloc_type = B_FALSE; 18003dec9fcdSqs 18013dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 18023dec9fcdSqs "alloc_rx_buf_dma rdc %d chunk %d bufp %llx size %x " 18033dec9fcdSqs "i %d nblocks %d alength %d", 18043dec9fcdSqs dma_channel, i, &rx_dmap[i], block_size, 18053dec9fcdSqs i, rx_dmap[i].nblocks, rx_dmap[i].alength)); 18063dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 18073dec9fcdSqs &hxge_rx_dma_attr, rx_dmap[i].alength, 18083dec9fcdSqs &hxge_dev_buf_dma_acc_attr, 18093dec9fcdSqs DDI_DMA_READ | DDI_DMA_STREAMING, 18103dec9fcdSqs (p_hxge_dma_common_t)(&rx_dmap[i])); 18113dec9fcdSqs if (status != HXGE_OK) { 18123dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18133dec9fcdSqs " hxge_alloc_rx_buf_dma: Alloc Failed: " 18143dec9fcdSqs " for size: %d", alloc_sizes[size_index])); 18153dec9fcdSqs size_index--; 18163dec9fcdSqs } else { 18173dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18183dec9fcdSqs " alloc_rx_buf_dma allocated rdc %d " 18193dec9fcdSqs "chunk %d size %x dvma %x bufp %llx ", 18203dec9fcdSqs dma_channel, i, rx_dmap[i].alength, 18213dec9fcdSqs rx_dmap[i].ioaddr_pp, &rx_dmap[i])); 18223dec9fcdSqs i++; 18233dec9fcdSqs allocated += alloc_sizes[size_index]; 18243dec9fcdSqs } 18253dec9fcdSqs } 18263dec9fcdSqs 18273dec9fcdSqs if (allocated < total_alloc_size) { 18283dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 18293dec9fcdSqs " hxge_alloc_rx_buf_dma failed due to" 18303dec9fcdSqs " allocated(%d) < required(%d)", 18313dec9fcdSqs allocated, total_alloc_size)); 18323dec9fcdSqs goto hxge_alloc_rx_mem_fail1; 18333dec9fcdSqs } 18343dec9fcdSqs 18353dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18363dec9fcdSqs " alloc_rx_buf_dma rdc %d allocated %d chunks", dma_channel, i)); 18373dec9fcdSqs 18383dec9fcdSqs *num_chunks = i; 18393dec9fcdSqs *dmap = rx_dmap; 18403dec9fcdSqs 18413dec9fcdSqs goto hxge_alloc_rx_mem_exit; 18423dec9fcdSqs 18433dec9fcdSqs hxge_alloc_rx_mem_fail1: 18443dec9fcdSqs KMEM_FREE(rx_dmap, sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 18453dec9fcdSqs 18463dec9fcdSqs hxge_alloc_rx_mem_exit: 18473dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18483dec9fcdSqs "<== hxge_alloc_rx_buf_dma status 0x%08x", status)); 18493dec9fcdSqs 18503dec9fcdSqs return (status); 18513dec9fcdSqs } 18523dec9fcdSqs 18533dec9fcdSqs /*ARGSUSED*/ 18543dec9fcdSqs static void 18553dec9fcdSqs hxge_free_rx_buf_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap, 18563dec9fcdSqs uint32_t num_chunks) 18573dec9fcdSqs { 18583dec9fcdSqs int i; 18593dec9fcdSqs 18603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 18613dec9fcdSqs "==> hxge_free_rx_buf_dma: # of chunks %d", num_chunks)); 18623dec9fcdSqs 18633dec9fcdSqs for (i = 0; i < num_chunks; i++) { 18643dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 18653dec9fcdSqs "==> hxge_free_rx_buf_dma: chunk %d dmap 0x%llx", i, dmap)); 18663dec9fcdSqs hxge_dma_mem_free(dmap++); 18673dec9fcdSqs } 18683dec9fcdSqs 18693dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_buf_dma")); 18703dec9fcdSqs } 18713dec9fcdSqs 18723dec9fcdSqs /*ARGSUSED*/ 18733dec9fcdSqs static hxge_status_t 18743dec9fcdSqs hxge_alloc_rx_cntl_dma(p_hxge_t hxgep, uint16_t dma_channel, 18758ad8db65SMichael Speer p_hxge_dma_common_t *dmap, struct ddi_dma_attr *attr, size_t size) 18763dec9fcdSqs { 18773dec9fcdSqs p_hxge_dma_common_t rx_dmap; 18783dec9fcdSqs hxge_status_t status = HXGE_OK; 18793dec9fcdSqs 18803dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_cntl_dma")); 18813dec9fcdSqs 18823dec9fcdSqs rx_dmap = (p_hxge_dma_common_t) 18833dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t), KM_SLEEP); 18843dec9fcdSqs 18853dec9fcdSqs rx_dmap->contig_alloc_type = B_FALSE; 18863dec9fcdSqs 18873dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 18888ad8db65SMichael Speer attr, size, &hxge_dev_desc_dma_acc_attr, 18893dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, rx_dmap); 18903dec9fcdSqs if (status != HXGE_OK) { 18913dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 18923dec9fcdSqs " hxge_alloc_rx_cntl_dma: Alloc Failed: " 18933dec9fcdSqs " for size: %d", size)); 18943dec9fcdSqs goto hxge_alloc_rx_cntl_dma_fail1; 18953dec9fcdSqs } 18963dec9fcdSqs 18973dec9fcdSqs *dmap = rx_dmap; 18983dec9fcdSqs 18993dec9fcdSqs goto hxge_alloc_rx_cntl_dma_exit; 19003dec9fcdSqs 19013dec9fcdSqs hxge_alloc_rx_cntl_dma_fail1: 19023dec9fcdSqs KMEM_FREE(rx_dmap, sizeof (hxge_dma_common_t)); 19033dec9fcdSqs 19043dec9fcdSqs hxge_alloc_rx_cntl_dma_exit: 19053dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 19063dec9fcdSqs "<== hxge_alloc_rx_cntl_dma status 0x%08x", status)); 19073dec9fcdSqs 19083dec9fcdSqs return (status); 19093dec9fcdSqs } 19103dec9fcdSqs 19113dec9fcdSqs /*ARGSUSED*/ 19123dec9fcdSqs static void 19133dec9fcdSqs hxge_free_rx_cntl_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap) 19143dec9fcdSqs { 19153dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_free_rx_cntl_dma")); 19163dec9fcdSqs 19173dec9fcdSqs hxge_dma_mem_free(dmap); 19183dec9fcdSqs 19193dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_free_rx_cntl_dma")); 19203dec9fcdSqs } 19213dec9fcdSqs 19223dec9fcdSqs static hxge_status_t 19233dec9fcdSqs hxge_alloc_tx_mem_pool(p_hxge_t hxgep) 19243dec9fcdSqs { 19253dec9fcdSqs hxge_status_t status = HXGE_OK; 19263dec9fcdSqs int i, j; 19273dec9fcdSqs uint32_t ndmas, st_tdc; 19283dec9fcdSqs p_hxge_dma_pt_cfg_t p_all_cfgp; 19293dec9fcdSqs p_hxge_hw_pt_cfg_t p_cfgp; 19303dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 19313dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 19323dec9fcdSqs p_hxge_dma_pool_t dma_cntl_poolp; 19333dec9fcdSqs p_hxge_dma_common_t *dma_cntl_p; 19343dec9fcdSqs size_t tx_buf_alloc_size; 19353dec9fcdSqs size_t tx_cntl_alloc_size; 19363dec9fcdSqs uint32_t *num_chunks; /* per dma */ 19373dec9fcdSqs 19383dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_alloc_tx_mem_pool")); 19393dec9fcdSqs 19403dec9fcdSqs p_all_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 19413dec9fcdSqs p_cfgp = (p_hxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 19423dec9fcdSqs st_tdc = p_cfgp->start_tdc; 19433dec9fcdSqs ndmas = p_cfgp->max_tdcs; 19443dec9fcdSqs 19453dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_alloc_tx_mem_pool: " 19463dec9fcdSqs "p_cfgp 0x%016llx start_tdc %d ndmas %d hxgep->max_tdcs %d", 19473dec9fcdSqs p_cfgp, p_cfgp->start_tdc, p_cfgp->max_tdcs, hxgep->max_tdcs)); 19483dec9fcdSqs /* 19493dec9fcdSqs * Allocate memory for each transmit DMA channel. 19503dec9fcdSqs */ 19513dec9fcdSqs dma_poolp = (p_hxge_dma_pool_t)KMEM_ZALLOC(sizeof (hxge_dma_pool_t), 19523dec9fcdSqs KM_SLEEP); 19533dec9fcdSqs dma_buf_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 19543dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 19553dec9fcdSqs 19563dec9fcdSqs dma_cntl_poolp = (p_hxge_dma_pool_t) 19573dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 19583dec9fcdSqs dma_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 19593dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 19603dec9fcdSqs 19613dec9fcdSqs hxgep->hxge_port_tx_ring_size = hxge_tx_ring_size; 19623dec9fcdSqs 19633dec9fcdSqs /* 19643dec9fcdSqs * Assume that each DMA channel will be configured with default 19653dec9fcdSqs * transmit bufer size for copying transmit data. (For packet payload 19663dec9fcdSqs * over this limit, packets will not be copied.) 19673dec9fcdSqs */ 19683dec9fcdSqs tx_buf_alloc_size = (hxge_bcopy_thresh * hxge_tx_ring_size); 19693dec9fcdSqs 19703dec9fcdSqs /* 19713dec9fcdSqs * Addresses of transmit descriptor ring and the mailbox must be all 19723dec9fcdSqs * cache-aligned (64 bytes). 19733dec9fcdSqs */ 19743dec9fcdSqs tx_cntl_alloc_size = hxge_tx_ring_size; 19753dec9fcdSqs tx_cntl_alloc_size *= (sizeof (tx_desc_t)); 19763dec9fcdSqs tx_cntl_alloc_size += sizeof (txdma_mailbox_t); 19773dec9fcdSqs 19783dec9fcdSqs num_chunks = (uint32_t *)KMEM_ZALLOC(sizeof (uint32_t) * ndmas, 19793dec9fcdSqs KM_SLEEP); 19803dec9fcdSqs 19813dec9fcdSqs /* 19823dec9fcdSqs * Allocate memory for transmit buffers and descriptor rings. Replace 19833dec9fcdSqs * allocation functions with interface functions provided by the 19843dec9fcdSqs * partition manager when it is available. 19853dec9fcdSqs * 19863dec9fcdSqs * Allocate memory for the transmit buffer pool. 19873dec9fcdSqs */ 19883dec9fcdSqs for (i = 0; i < ndmas; i++) { 19893dec9fcdSqs num_chunks[i] = 0; 19903dec9fcdSqs status = hxge_alloc_tx_buf_dma(hxgep, st_tdc, &dma_buf_p[i], 19913dec9fcdSqs tx_buf_alloc_size, hxge_bcopy_thresh, &num_chunks[i]); 19923dec9fcdSqs if (status != HXGE_OK) { 19933dec9fcdSqs break; 19943dec9fcdSqs } 19953dec9fcdSqs st_tdc++; 19963dec9fcdSqs } 19973dec9fcdSqs 19983dec9fcdSqs if (i < ndmas) { 19993dec9fcdSqs goto hxge_alloc_tx_mem_pool_fail1; 20003dec9fcdSqs } 20013dec9fcdSqs 20023dec9fcdSqs st_tdc = p_cfgp->start_tdc; 20033dec9fcdSqs 20043dec9fcdSqs /* 20053dec9fcdSqs * Allocate memory for descriptor rings and mailbox. 20063dec9fcdSqs */ 20073dec9fcdSqs for (j = 0; j < ndmas; j++) { 20083dec9fcdSqs status = hxge_alloc_tx_cntl_dma(hxgep, st_tdc, &dma_cntl_p[j], 20093dec9fcdSqs tx_cntl_alloc_size); 20103dec9fcdSqs if (status != HXGE_OK) { 20113dec9fcdSqs break; 20123dec9fcdSqs } 20133dec9fcdSqs st_tdc++; 20143dec9fcdSqs } 20153dec9fcdSqs 20163dec9fcdSqs if (j < ndmas) { 20173dec9fcdSqs goto hxge_alloc_tx_mem_pool_fail2; 20183dec9fcdSqs } 20193dec9fcdSqs 20203dec9fcdSqs dma_poolp->ndmas = ndmas; 20213dec9fcdSqs dma_poolp->num_chunks = num_chunks; 20223dec9fcdSqs dma_poolp->buf_allocated = B_TRUE; 20233dec9fcdSqs dma_poolp->dma_buf_pool_p = dma_buf_p; 20243dec9fcdSqs hxgep->tx_buf_pool_p = dma_poolp; 20253dec9fcdSqs 20263dec9fcdSqs dma_cntl_poolp->ndmas = ndmas; 20273dec9fcdSqs dma_cntl_poolp->buf_allocated = B_TRUE; 20283dec9fcdSqs dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 20293dec9fcdSqs hxgep->tx_cntl_pool_p = dma_cntl_poolp; 20303dec9fcdSqs 20313dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, 20323dec9fcdSqs "==> hxge_alloc_tx_mem_pool: start_tdc %d " 20333dec9fcdSqs "ndmas %d poolp->ndmas %d", st_tdc, ndmas, dma_poolp->ndmas)); 20343dec9fcdSqs 20353dec9fcdSqs goto hxge_alloc_tx_mem_pool_exit; 20363dec9fcdSqs 20373dec9fcdSqs hxge_alloc_tx_mem_pool_fail2: 20383dec9fcdSqs /* Free control buffers */ 20393dec9fcdSqs j--; 20403dec9fcdSqs for (; j >= 0; j--) { 20413dec9fcdSqs hxge_free_tx_cntl_dma(hxgep, 20423dec9fcdSqs (p_hxge_dma_common_t)dma_cntl_p[j]); 20433dec9fcdSqs } 20443dec9fcdSqs 20453dec9fcdSqs hxge_alloc_tx_mem_pool_fail1: 20463dec9fcdSqs /* Free data buffers */ 20473dec9fcdSqs i--; 20483dec9fcdSqs for (; i >= 0; i--) { 20493dec9fcdSqs hxge_free_tx_buf_dma(hxgep, (p_hxge_dma_common_t)dma_buf_p[i], 20503dec9fcdSqs num_chunks[i]); 20513dec9fcdSqs } 20523dec9fcdSqs 20533dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 20543dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 20553dec9fcdSqs KMEM_FREE(dma_cntl_poolp, sizeof (hxge_dma_pool_t)); 20563dec9fcdSqs KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 20573dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 20583dec9fcdSqs 20593dec9fcdSqs hxge_alloc_tx_mem_pool_exit: 20603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, 20613dec9fcdSqs "<== hxge_alloc_tx_mem_pool:status 0x%08x", status)); 20623dec9fcdSqs 20633dec9fcdSqs return (status); 20643dec9fcdSqs } 20653dec9fcdSqs 20663dec9fcdSqs static hxge_status_t 20673dec9fcdSqs hxge_alloc_tx_buf_dma(p_hxge_t hxgep, uint16_t dma_channel, 20683dec9fcdSqs p_hxge_dma_common_t *dmap, size_t alloc_size, 20693dec9fcdSqs size_t block_size, uint32_t *num_chunks) 20703dec9fcdSqs { 20713dec9fcdSqs p_hxge_dma_common_t tx_dmap; 20723dec9fcdSqs hxge_status_t status = HXGE_OK; 20733dec9fcdSqs size_t total_alloc_size; 20743dec9fcdSqs size_t allocated = 0; 20753dec9fcdSqs int i, size_index, array_size; 20763dec9fcdSqs 20773dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_tx_buf_dma")); 20783dec9fcdSqs 20793dec9fcdSqs tx_dmap = (p_hxge_dma_common_t) 20803dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK, KM_SLEEP); 20813dec9fcdSqs 20823dec9fcdSqs total_alloc_size = alloc_size; 20833dec9fcdSqs i = 0; 20843dec9fcdSqs size_index = 0; 20853dec9fcdSqs array_size = sizeof (alloc_sizes) / sizeof (size_t); 2086b83cd2c3SMichael Speer while ((size_index < array_size) && 2087b83cd2c3SMichael Speer (alloc_sizes[size_index] < alloc_size)) 20883dec9fcdSqs size_index++; 20893dec9fcdSqs if (size_index >= array_size) { 20903dec9fcdSqs size_index = array_size - 1; 20913dec9fcdSqs } 20923dec9fcdSqs 20933dec9fcdSqs while ((allocated < total_alloc_size) && 20943dec9fcdSqs (size_index >= 0) && (i < HXGE_DMA_BLOCK)) { 20953dec9fcdSqs tx_dmap[i].dma_chunk_index = i; 20963dec9fcdSqs tx_dmap[i].block_size = block_size; 20973dec9fcdSqs tx_dmap[i].alength = alloc_sizes[size_index]; 20983dec9fcdSqs tx_dmap[i].orig_alength = tx_dmap[i].alength; 20993dec9fcdSqs tx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 21003dec9fcdSqs tx_dmap[i].dma_channel = dma_channel; 21013dec9fcdSqs tx_dmap[i].contig_alloc_type = B_FALSE; 21023dec9fcdSqs 21033dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 21043dec9fcdSqs &hxge_tx_dma_attr, tx_dmap[i].alength, 21053dec9fcdSqs &hxge_dev_buf_dma_acc_attr, 21063dec9fcdSqs DDI_DMA_WRITE | DDI_DMA_STREAMING, 21073dec9fcdSqs (p_hxge_dma_common_t)(&tx_dmap[i])); 21083dec9fcdSqs if (status != HXGE_OK) { 21093dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21103dec9fcdSqs " hxge_alloc_tx_buf_dma: Alloc Failed: " 21113dec9fcdSqs " for size: %d", alloc_sizes[size_index])); 21123dec9fcdSqs size_index--; 21133dec9fcdSqs } else { 21143dec9fcdSqs i++; 21153dec9fcdSqs allocated += alloc_sizes[size_index]; 21163dec9fcdSqs } 21173dec9fcdSqs } 21183dec9fcdSqs 21193dec9fcdSqs if (allocated < total_alloc_size) { 21203dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 21213dec9fcdSqs " hxge_alloc_tx_buf_dma: failed due to" 21223dec9fcdSqs " allocated(%d) < required(%d)", 21233dec9fcdSqs allocated, total_alloc_size)); 21243dec9fcdSqs goto hxge_alloc_tx_mem_fail1; 21253dec9fcdSqs } 21263dec9fcdSqs 21273dec9fcdSqs *num_chunks = i; 21283dec9fcdSqs *dmap = tx_dmap; 21293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21303dec9fcdSqs "==> hxge_alloc_tx_buf_dma dmap 0x%016llx num chunks %d", 21313dec9fcdSqs *dmap, i)); 21323dec9fcdSqs goto hxge_alloc_tx_mem_exit; 21333dec9fcdSqs 21343dec9fcdSqs hxge_alloc_tx_mem_fail1: 21353dec9fcdSqs KMEM_FREE(tx_dmap, sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 21363dec9fcdSqs 21373dec9fcdSqs hxge_alloc_tx_mem_exit: 21383dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21393dec9fcdSqs "<== hxge_alloc_tx_buf_dma status 0x%08x", status)); 21403dec9fcdSqs 21413dec9fcdSqs return (status); 21423dec9fcdSqs } 21433dec9fcdSqs 21443dec9fcdSqs /*ARGSUSED*/ 21453dec9fcdSqs static void 21463dec9fcdSqs hxge_free_tx_buf_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap, 21473dec9fcdSqs uint32_t num_chunks) 21483dec9fcdSqs { 21493dec9fcdSqs int i; 21503dec9fcdSqs 21513dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_free_tx_buf_dma")); 21523dec9fcdSqs 21533dec9fcdSqs for (i = 0; i < num_chunks; i++) { 21543dec9fcdSqs hxge_dma_mem_free(dmap++); 21553dec9fcdSqs } 21563dec9fcdSqs 21573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "<== hxge_free_tx_buf_dma")); 21583dec9fcdSqs } 21593dec9fcdSqs 21603dec9fcdSqs /*ARGSUSED*/ 21613dec9fcdSqs static hxge_status_t 21623dec9fcdSqs hxge_alloc_tx_cntl_dma(p_hxge_t hxgep, uint16_t dma_channel, 21633dec9fcdSqs p_hxge_dma_common_t *dmap, size_t size) 21643dec9fcdSqs { 21653dec9fcdSqs p_hxge_dma_common_t tx_dmap; 21663dec9fcdSqs hxge_status_t status = HXGE_OK; 21673dec9fcdSqs 21683dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_tx_cntl_dma")); 21693dec9fcdSqs 21703dec9fcdSqs tx_dmap = (p_hxge_dma_common_t)KMEM_ZALLOC(sizeof (hxge_dma_common_t), 21713dec9fcdSqs KM_SLEEP); 21723dec9fcdSqs 21733dec9fcdSqs tx_dmap->contig_alloc_type = B_FALSE; 21743dec9fcdSqs 21753dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 21768ad8db65SMichael Speer &hxge_tx_desc_dma_attr, size, &hxge_dev_desc_dma_acc_attr, 21773dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, tx_dmap); 21783dec9fcdSqs if (status != HXGE_OK) { 21793dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 21803dec9fcdSqs " hxge_alloc_tx_cntl_dma: Alloc Failed: " 21813dec9fcdSqs " for size: %d", size)); 21823dec9fcdSqs goto hxge_alloc_tx_cntl_dma_fail1; 21833dec9fcdSqs } 21843dec9fcdSqs 21853dec9fcdSqs *dmap = tx_dmap; 21863dec9fcdSqs 21873dec9fcdSqs goto hxge_alloc_tx_cntl_dma_exit; 21883dec9fcdSqs 21893dec9fcdSqs hxge_alloc_tx_cntl_dma_fail1: 21903dec9fcdSqs KMEM_FREE(tx_dmap, sizeof (hxge_dma_common_t)); 21913dec9fcdSqs 21923dec9fcdSqs hxge_alloc_tx_cntl_dma_exit: 21933dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21943dec9fcdSqs "<== hxge_alloc_tx_cntl_dma status 0x%08x", status)); 21953dec9fcdSqs 21963dec9fcdSqs return (status); 21973dec9fcdSqs } 21983dec9fcdSqs 21993dec9fcdSqs /*ARGSUSED*/ 22003dec9fcdSqs static void 22013dec9fcdSqs hxge_free_tx_cntl_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap) 22023dec9fcdSqs { 22033dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_free_tx_cntl_dma")); 22043dec9fcdSqs 22053dec9fcdSqs hxge_dma_mem_free(dmap); 22063dec9fcdSqs 22073dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_free_tx_cntl_dma")); 22083dec9fcdSqs } 22093dec9fcdSqs 22103dec9fcdSqs static void 22113dec9fcdSqs hxge_free_tx_mem_pool(p_hxge_t hxgep) 22123dec9fcdSqs { 22133dec9fcdSqs uint32_t i, ndmas; 22143dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 22153dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 22163dec9fcdSqs p_hxge_dma_pool_t dma_cntl_poolp; 22173dec9fcdSqs p_hxge_dma_common_t *dma_cntl_p; 22183dec9fcdSqs uint32_t *num_chunks; 22193dec9fcdSqs 22203dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, "==> hxge_free_tx_mem_pool")); 22213dec9fcdSqs 22223dec9fcdSqs dma_poolp = hxgep->tx_buf_pool_p; 22233dec9fcdSqs if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 22243dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, 22253dec9fcdSqs "<== hxge_free_tx_mem_pool " 22263dec9fcdSqs "(null rx buf pool or buf not allocated")); 22273dec9fcdSqs return; 22283dec9fcdSqs } 22293dec9fcdSqs 22303dec9fcdSqs dma_cntl_poolp = hxgep->tx_cntl_pool_p; 22313dec9fcdSqs if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 22323dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, 22333dec9fcdSqs "<== hxge_free_tx_mem_pool " 22343dec9fcdSqs "(null tx cntl buf pool or cntl buf not allocated")); 22353dec9fcdSqs return; 22363dec9fcdSqs } 22373dec9fcdSqs 22383dec9fcdSqs dma_buf_p = dma_poolp->dma_buf_pool_p; 22393dec9fcdSqs num_chunks = dma_poolp->num_chunks; 22403dec9fcdSqs 22413dec9fcdSqs dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 22423dec9fcdSqs ndmas = dma_cntl_poolp->ndmas; 22433dec9fcdSqs 22443dec9fcdSqs for (i = 0; i < ndmas; i++) { 22453dec9fcdSqs hxge_free_tx_buf_dma(hxgep, dma_buf_p[i], num_chunks[i]); 22463dec9fcdSqs } 22473dec9fcdSqs 22483dec9fcdSqs for (i = 0; i < ndmas; i++) { 22493dec9fcdSqs hxge_free_tx_cntl_dma(hxgep, dma_cntl_p[i]); 22503dec9fcdSqs } 22513dec9fcdSqs 22523dec9fcdSqs for (i = 0; i < ndmas; i++) { 22533dec9fcdSqs KMEM_FREE(dma_buf_p[i], 22543dec9fcdSqs sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 22553dec9fcdSqs KMEM_FREE(dma_cntl_p[i], sizeof (hxge_dma_common_t)); 22563dec9fcdSqs } 22573dec9fcdSqs 22583dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 22593dec9fcdSqs KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 22603dec9fcdSqs KMEM_FREE(dma_cntl_poolp, sizeof (hxge_dma_pool_t)); 22613dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 22623dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 22633dec9fcdSqs 22643dec9fcdSqs hxgep->tx_buf_pool_p = NULL; 22653dec9fcdSqs hxgep->tx_cntl_pool_p = NULL; 22663dec9fcdSqs 22673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, "<== hxge_free_tx_mem_pool")); 22683dec9fcdSqs } 22693dec9fcdSqs 22703dec9fcdSqs /*ARGSUSED*/ 22713dec9fcdSqs static hxge_status_t 22723dec9fcdSqs hxge_dma_mem_alloc(p_hxge_t hxgep, dma_method_t method, 22733dec9fcdSqs struct ddi_dma_attr *dma_attrp, 22743dec9fcdSqs size_t length, ddi_device_acc_attr_t *acc_attr_p, uint_t xfer_flags, 22753dec9fcdSqs p_hxge_dma_common_t dma_p) 22763dec9fcdSqs { 22773dec9fcdSqs caddr_t kaddrp; 22783dec9fcdSqs int ddi_status = DDI_SUCCESS; 22793dec9fcdSqs 22803dec9fcdSqs dma_p->dma_handle = NULL; 22813dec9fcdSqs dma_p->acc_handle = NULL; 22823dec9fcdSqs dma_p->kaddrp = NULL; 22833dec9fcdSqs 22843dec9fcdSqs ddi_status = ddi_dma_alloc_handle(hxgep->dip, dma_attrp, 22853dec9fcdSqs DDI_DMA_DONTWAIT, NULL, &dma_p->dma_handle); 22863dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 22873dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 22883dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_alloc_handle failed.")); 22893dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 22903dec9fcdSqs } 22913dec9fcdSqs 22923dec9fcdSqs ddi_status = ddi_dma_mem_alloc(dma_p->dma_handle, length, acc_attr_p, 22933dec9fcdSqs xfer_flags, DDI_DMA_DONTWAIT, 0, &kaddrp, &dma_p->alength, 22943dec9fcdSqs &dma_p->acc_handle); 22953dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 22963dec9fcdSqs /* The caller will decide whether it is fatal */ 22973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 22983dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_mem_alloc failed")); 22993dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23003dec9fcdSqs dma_p->dma_handle = NULL; 23013dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 23023dec9fcdSqs } 23033dec9fcdSqs 23043dec9fcdSqs if (dma_p->alength < length) { 23053dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 23063dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_mem_alloc < length.")); 23073dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23083dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23093dec9fcdSqs dma_p->acc_handle = NULL; 23103dec9fcdSqs dma_p->dma_handle = NULL; 23113dec9fcdSqs return (HXGE_ERROR); 23123dec9fcdSqs } 23133dec9fcdSqs 23143dec9fcdSqs ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 23153dec9fcdSqs kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 23163dec9fcdSqs &dma_p->dma_cookie, &dma_p->ncookies); 23173dec9fcdSqs if (ddi_status != DDI_DMA_MAPPED) { 23183dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 23193dec9fcdSqs "hxge_dma_mem_alloc:di_dma_addr_bind failed " 23203dec9fcdSqs "(staus 0x%x ncookies %d.)", ddi_status, dma_p->ncookies)); 23213dec9fcdSqs if (dma_p->acc_handle) { 23223dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23233dec9fcdSqs dma_p->acc_handle = NULL; 23243dec9fcdSqs } 23253dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23263dec9fcdSqs dma_p->dma_handle = NULL; 23273dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 23283dec9fcdSqs } 23293dec9fcdSqs 23303dec9fcdSqs if (dma_p->ncookies != 1) { 23313dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 23323dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_addr_bind > 1 cookie" 23333dec9fcdSqs "(staus 0x%x ncookies %d.)", ddi_status, dma_p->ncookies)); 23343dec9fcdSqs if (dma_p->acc_handle) { 23353dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23363dec9fcdSqs dma_p->acc_handle = NULL; 23373dec9fcdSqs } 23383dec9fcdSqs (void) ddi_dma_unbind_handle(dma_p->dma_handle); 23393dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23403dec9fcdSqs dma_p->dma_handle = NULL; 23413dec9fcdSqs return (HXGE_ERROR); 23423dec9fcdSqs } 23433dec9fcdSqs 23443dec9fcdSqs dma_p->kaddrp = kaddrp; 23453dec9fcdSqs #if defined(__i386) 23463dec9fcdSqs dma_p->ioaddr_pp = 23473dec9fcdSqs (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress; 23483dec9fcdSqs #else 23493dec9fcdSqs dma_p->ioaddr_pp = (unsigned char *) dma_p->dma_cookie.dmac_laddress; 23503dec9fcdSqs #endif 23513dec9fcdSqs 23523dec9fcdSqs HPI_DMA_ACC_HANDLE_SET(dma_p, dma_p->acc_handle); 23533dec9fcdSqs 23543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_dma_mem_alloc: " 23553dec9fcdSqs "dma buffer allocated: dma_p $%p " 23563dec9fcdSqs "return dmac_ladress from cookie $%p dmac_size %d " 23573dec9fcdSqs "dma_p->ioaddr_p $%p " 23583dec9fcdSqs "dma_p->orig_ioaddr_p $%p " 23593dec9fcdSqs "orig_vatopa $%p " 23603dec9fcdSqs "alength %d (0x%x) " 23613dec9fcdSqs "kaddrp $%p " 23623dec9fcdSqs "length %d (0x%x)", 23633dec9fcdSqs dma_p, 23643dec9fcdSqs dma_p->dma_cookie.dmac_laddress, 23653dec9fcdSqs dma_p->dma_cookie.dmac_size, 23663dec9fcdSqs dma_p->ioaddr_pp, 23673dec9fcdSqs dma_p->orig_ioaddr_pp, 23683dec9fcdSqs dma_p->orig_vatopa, 23693dec9fcdSqs dma_p->alength, dma_p->alength, 23703dec9fcdSqs kaddrp, 23713dec9fcdSqs length, length)); 23723dec9fcdSqs 23733dec9fcdSqs return (HXGE_OK); 23743dec9fcdSqs } 23753dec9fcdSqs 23763dec9fcdSqs static void 23773dec9fcdSqs hxge_dma_mem_free(p_hxge_dma_common_t dma_p) 23783dec9fcdSqs { 23798ad8db65SMichael Speer if (dma_p == NULL) 23808ad8db65SMichael Speer return; 23818ad8db65SMichael Speer 23823dec9fcdSqs if (dma_p->dma_handle != NULL) { 23833dec9fcdSqs if (dma_p->ncookies) { 23843dec9fcdSqs (void) ddi_dma_unbind_handle(dma_p->dma_handle); 23853dec9fcdSqs dma_p->ncookies = 0; 23863dec9fcdSqs } 23873dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23883dec9fcdSqs dma_p->dma_handle = NULL; 23893dec9fcdSqs } 23908ad8db65SMichael Speer 23913dec9fcdSqs if (dma_p->acc_handle != NULL) { 23923dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23933dec9fcdSqs dma_p->acc_handle = NULL; 23943dec9fcdSqs HPI_DMA_ACC_HANDLE_SET(dma_p, NULL); 23953dec9fcdSqs } 23968ad8db65SMichael Speer 23973dec9fcdSqs dma_p->kaddrp = NULL; 23983dec9fcdSqs dma_p->alength = NULL; 23993dec9fcdSqs } 24003dec9fcdSqs 24013dec9fcdSqs /* 24023dec9fcdSqs * hxge_m_start() -- start transmitting and receiving. 24033dec9fcdSqs * 24043dec9fcdSqs * This function is called by the MAC layer when the first 24053dec9fcdSqs * stream is open to prepare the hardware ready for sending 24063dec9fcdSqs * and transmitting packets. 24073dec9fcdSqs */ 24083dec9fcdSqs static int 24093dec9fcdSqs hxge_m_start(void *arg) 24103dec9fcdSqs { 24113dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24123dec9fcdSqs 24133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_start")); 24143dec9fcdSqs 24153dec9fcdSqs MUTEX_ENTER(hxgep->genlock); 24163dec9fcdSqs 24173dec9fcdSqs if (hxge_init(hxgep) != DDI_SUCCESS) { 24183dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 24193dec9fcdSqs "<== hxge_m_start: initialization failed")); 24203dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24213dec9fcdSqs return (EIO); 24223dec9fcdSqs } 24233dec9fcdSqs 24243dec9fcdSqs if (hxgep->hxge_mac_state != HXGE_MAC_STARTED) { 24253dec9fcdSqs /* 24263dec9fcdSqs * Start timer to check the system error and tx hangs 24273dec9fcdSqs */ 24283dec9fcdSqs hxgep->hxge_timerid = hxge_start_timer(hxgep, 24293dec9fcdSqs hxge_check_hw_state, HXGE_CHECK_TIMER); 24303dec9fcdSqs 24313dec9fcdSqs hxgep->hxge_mac_state = HXGE_MAC_STARTED; 2432e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 2433e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.link_status = 0; 2434e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.report_link_status = B_TRUE; 2435e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks = drv_usectohz(2 * 1000000); 2436e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 2437e5d97391SQiyan Sun - Sun Microsystems - San Diego United States /* Start the link status timer to check the link status */ 2438e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 2439e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = timeout(hxge_link_poll, (void *)hxgep, 2440e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks); 2441e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 24423dec9fcdSqs } 24433dec9fcdSqs 24443dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24453dec9fcdSqs 24463dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_start")); 24473dec9fcdSqs 24483dec9fcdSqs return (0); 24493dec9fcdSqs } 24503dec9fcdSqs 24513dec9fcdSqs /* 24523dec9fcdSqs * hxge_m_stop(): stop transmitting and receiving. 24533dec9fcdSqs */ 24543dec9fcdSqs static void 24553dec9fcdSqs hxge_m_stop(void *arg) 24563dec9fcdSqs { 24573dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24583dec9fcdSqs 24593dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_stop")); 24603dec9fcdSqs 24613dec9fcdSqs if (hxgep->hxge_timerid) { 24623dec9fcdSqs hxge_stop_timer(hxgep, hxgep->hxge_timerid); 24633dec9fcdSqs hxgep->hxge_timerid = 0; 24643dec9fcdSqs } 24653dec9fcdSqs 2466e5d97391SQiyan Sun - Sun Microsystems - San Diego United States /* Stop the link status timer before unregistering */ 2467e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 2468e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->timeout.id) { 2469e5d97391SQiyan Sun - Sun Microsystems - San Diego United States (void) untimeout(hxgep->timeout.id); 2470e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = 0; 2471e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 2472e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_DOWN); 2473e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 2474e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 24753dec9fcdSqs MUTEX_ENTER(hxgep->genlock); 24763dec9fcdSqs 24773dec9fcdSqs hxge_uninit(hxgep); 24783dec9fcdSqs 24793dec9fcdSqs hxgep->hxge_mac_state = HXGE_MAC_STOPPED; 24803dec9fcdSqs 24813dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24823dec9fcdSqs 24833dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_stop")); 24843dec9fcdSqs } 24853dec9fcdSqs 24863dec9fcdSqs static int 24873dec9fcdSqs hxge_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 24883dec9fcdSqs { 24893dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24903dec9fcdSqs struct ether_addr addrp; 24913dec9fcdSqs 24923dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_m_multicst: add %d", add)); 24933dec9fcdSqs 24943dec9fcdSqs bcopy(mca, (uint8_t *)&addrp, ETHERADDRL); 24953dec9fcdSqs 24963dec9fcdSqs if (add) { 24973dec9fcdSqs if (hxge_add_mcast_addr(hxgep, &addrp)) { 24983dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 24993dec9fcdSqs "<== hxge_m_multicst: add multicast failed")); 25003dec9fcdSqs return (EINVAL); 25013dec9fcdSqs } 25023dec9fcdSqs } else { 25033dec9fcdSqs if (hxge_del_mcast_addr(hxgep, &addrp)) { 25043dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25053dec9fcdSqs "<== hxge_m_multicst: del multicast failed")); 25063dec9fcdSqs return (EINVAL); 25073dec9fcdSqs } 25083dec9fcdSqs } 25093dec9fcdSqs 25103dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_m_multicst")); 25113dec9fcdSqs 25123dec9fcdSqs return (0); 25133dec9fcdSqs } 25143dec9fcdSqs 25153dec9fcdSqs static int 25163dec9fcdSqs hxge_m_promisc(void *arg, boolean_t on) 25173dec9fcdSqs { 25183dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 25193dec9fcdSqs 25203dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_m_promisc: on %d", on)); 25213dec9fcdSqs 25223dec9fcdSqs if (hxge_set_promisc(hxgep, on)) { 25233dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25243dec9fcdSqs "<== hxge_m_promisc: set promisc failed")); 25253dec9fcdSqs return (EINVAL); 25263dec9fcdSqs } 25273dec9fcdSqs 25283dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_m_promisc: on %d", on)); 25293dec9fcdSqs 25303dec9fcdSqs return (0); 25313dec9fcdSqs } 25323dec9fcdSqs 25333dec9fcdSqs static void 25343dec9fcdSqs hxge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 25353dec9fcdSqs { 25363dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 25373dec9fcdSqs struct iocblk *iocp = (struct iocblk *)mp->b_rptr; 25383dec9fcdSqs boolean_t need_privilege; 25393dec9fcdSqs int err; 25403dec9fcdSqs int cmd; 25413dec9fcdSqs 25423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_ioctl")); 25433dec9fcdSqs 25443dec9fcdSqs iocp = (struct iocblk *)mp->b_rptr; 25453dec9fcdSqs iocp->ioc_error = 0; 25463dec9fcdSqs need_privilege = B_TRUE; 25473dec9fcdSqs cmd = iocp->ioc_cmd; 25483dec9fcdSqs 25493dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_ioctl: cmd 0x%08x", cmd)); 25503dec9fcdSqs switch (cmd) { 25513dec9fcdSqs default: 25523dec9fcdSqs miocnak(wq, mp, 0, EINVAL); 25533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_ioctl: invalid")); 25543dec9fcdSqs return; 25553dec9fcdSqs 25563dec9fcdSqs case LB_GET_INFO_SIZE: 25573dec9fcdSqs case LB_GET_INFO: 25583dec9fcdSqs case LB_GET_MODE: 25593dec9fcdSqs need_privilege = B_FALSE; 25603dec9fcdSqs break; 25613dec9fcdSqs 25623dec9fcdSqs case LB_SET_MODE: 25633dec9fcdSqs break; 25643dec9fcdSqs 25653dec9fcdSqs case ND_GET: 25663dec9fcdSqs need_privilege = B_FALSE; 25673dec9fcdSqs break; 25683dec9fcdSqs case ND_SET: 25693dec9fcdSqs break; 25703dec9fcdSqs 25713dec9fcdSqs case HXGE_GET_TX_RING_SZ: 25723dec9fcdSqs case HXGE_GET_TX_DESC: 25733dec9fcdSqs case HXGE_TX_SIDE_RESET: 25743dec9fcdSqs case HXGE_RX_SIDE_RESET: 25753dec9fcdSqs case HXGE_GLOBAL_RESET: 25763dec9fcdSqs case HXGE_RESET_MAC: 25773dec9fcdSqs case HXGE_PUT_TCAM: 25783dec9fcdSqs case HXGE_GET_TCAM: 25793dec9fcdSqs case HXGE_RTRACE: 25803dec9fcdSqs 25813dec9fcdSqs need_privilege = B_FALSE; 25823dec9fcdSqs break; 25833dec9fcdSqs } 25843dec9fcdSqs 25853dec9fcdSqs if (need_privilege) { 25863dec9fcdSqs err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 25873dec9fcdSqs if (err != 0) { 25883dec9fcdSqs miocnak(wq, mp, 0, err); 25893dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25903dec9fcdSqs "<== hxge_m_ioctl: no priv")); 25913dec9fcdSqs return; 25923dec9fcdSqs } 25933dec9fcdSqs } 25943dec9fcdSqs 25953dec9fcdSqs switch (cmd) { 25963dec9fcdSqs case ND_GET: 25973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "ND_GET command")); 25983dec9fcdSqs case ND_SET: 25993dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "ND_SET command")); 26003dec9fcdSqs hxge_param_ioctl(hxgep, wq, mp, iocp); 26013dec9fcdSqs break; 26023dec9fcdSqs 26033dec9fcdSqs case LB_GET_MODE: 26043dec9fcdSqs case LB_SET_MODE: 26053dec9fcdSqs case LB_GET_INFO_SIZE: 26063dec9fcdSqs case LB_GET_INFO: 26073dec9fcdSqs hxge_loopback_ioctl(hxgep, wq, mp, iocp); 26083dec9fcdSqs break; 26093dec9fcdSqs 26103dec9fcdSqs case HXGE_PUT_TCAM: 26113dec9fcdSqs case HXGE_GET_TCAM: 26123dec9fcdSqs case HXGE_GET_TX_RING_SZ: 26133dec9fcdSqs case HXGE_GET_TX_DESC: 26143dec9fcdSqs case HXGE_TX_SIDE_RESET: 26153dec9fcdSqs case HXGE_RX_SIDE_RESET: 26163dec9fcdSqs case HXGE_GLOBAL_RESET: 26173dec9fcdSqs case HXGE_RESET_MAC: 26183dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, 26193dec9fcdSqs "==> hxge_m_ioctl: cmd 0x%x", cmd)); 26203dec9fcdSqs hxge_hw_ioctl(hxgep, wq, mp, iocp); 26213dec9fcdSqs break; 26223dec9fcdSqs } 26233dec9fcdSqs 26243dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_ioctl")); 26253dec9fcdSqs } 26263dec9fcdSqs 26271ed83081SMichael Speer /*ARGSUSED*/ 26281ed83081SMichael Speer static int 26291ed83081SMichael Speer hxge_tx_ring_start(mac_ring_driver_t rdriver, uint64_t mr_gen_num) 26301ed83081SMichael Speer { 26311ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26321ed83081SMichael Speer p_hxge_t hxgep; 26331ed83081SMichael Speer p_tx_ring_t ring; 26341ed83081SMichael Speer 26351ed83081SMichael Speer ASSERT(rhp != NULL); 26361ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26371ed83081SMichael Speer 26381ed83081SMichael Speer hxgep = rhp->hxgep; 26391ed83081SMichael Speer 26401ed83081SMichael Speer /* 26411ed83081SMichael Speer * Get the ring pointer. 26421ed83081SMichael Speer */ 26431ed83081SMichael Speer ring = hxgep->tx_rings->rings[rhp->index]; 26441ed83081SMichael Speer 26451ed83081SMichael Speer /* 26461ed83081SMichael Speer * Fill in the handle for the transmit. 26471ed83081SMichael Speer */ 26481ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26491ed83081SMichael Speer ring->ring_handle = rhp->ring_handle; 26501ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26511ed83081SMichael Speer 26521ed83081SMichael Speer return (0); 26531ed83081SMichael Speer } 26541ed83081SMichael Speer 26551ed83081SMichael Speer static void 26561ed83081SMichael Speer hxge_tx_ring_stop(mac_ring_driver_t rdriver) 26571ed83081SMichael Speer { 26581ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26591ed83081SMichael Speer p_hxge_t hxgep; 26601ed83081SMichael Speer p_tx_ring_t ring; 26611ed83081SMichael Speer 26621ed83081SMichael Speer ASSERT(rhp != NULL); 26631ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26641ed83081SMichael Speer 26651ed83081SMichael Speer hxgep = rhp->hxgep; 26661ed83081SMichael Speer ring = hxgep->tx_rings->rings[rhp->index]; 26671ed83081SMichael Speer 26681ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26691ed83081SMichael Speer ring->ring_handle = (mac_ring_handle_t)NULL; 26701ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26711ed83081SMichael Speer } 26721ed83081SMichael Speer 26731ed83081SMichael Speer static int 26741ed83081SMichael Speer hxge_rx_ring_start(mac_ring_driver_t rdriver, uint64_t mr_gen_num) 26751ed83081SMichael Speer { 26761ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26771ed83081SMichael Speer p_hxge_t hxgep; 26781ed83081SMichael Speer p_rx_rcr_ring_t ring; 26791ed83081SMichael Speer int i; 26801ed83081SMichael Speer 26811ed83081SMichael Speer ASSERT(rhp != NULL); 26821ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26831ed83081SMichael Speer 26841ed83081SMichael Speer hxgep = rhp->hxgep; 26851ed83081SMichael Speer 26861ed83081SMichael Speer /* 26871ed83081SMichael Speer * Get pointer to ring. 26881ed83081SMichael Speer */ 26891ed83081SMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index]; 26901ed83081SMichael Speer 26911ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26921ed83081SMichael Speer 26931ed83081SMichael Speer if (rhp->started) { 26941ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26951ed83081SMichael Speer return (0); 26961ed83081SMichael Speer } 26971ed83081SMichael Speer 26981ed83081SMichael Speer /* 26991ed83081SMichael Speer * Set the ldvp and ldgp pointers to enable/disable 27001ed83081SMichael Speer * polling. 27011ed83081SMichael Speer */ 27021ed83081SMichael Speer for (i = 0; i < hxgep->ldgvp->maxldvs; i++) { 27031ed83081SMichael Speer if ((hxgep->ldgvp->ldvp[i].is_rxdma == 1) && 27041ed83081SMichael Speer (hxgep->ldgvp->ldvp[i].channel == rhp->index)) { 27051ed83081SMichael Speer ring->ldvp = &hxgep->ldgvp->ldvp[i]; 27061ed83081SMichael Speer ring->ldgp = hxgep->ldgvp->ldvp[i].ldgp; 27071ed83081SMichael Speer break; 27081ed83081SMichael Speer } 27091ed83081SMichael Speer } 27101ed83081SMichael Speer 27111ed83081SMichael Speer rhp->started = B_TRUE; 27121ed83081SMichael Speer ring->rcr_mac_handle = rhp->ring_handle; 27131ed83081SMichael Speer ring->rcr_gen_num = mr_gen_num; 27141ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 27151ed83081SMichael Speer 27161ed83081SMichael Speer return (0); 27171ed83081SMichael Speer } 27181ed83081SMichael Speer 27191ed83081SMichael Speer static void 27201ed83081SMichael Speer hxge_rx_ring_stop(mac_ring_driver_t rdriver) 27211ed83081SMichael Speer { 27221ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 27231ed83081SMichael Speer p_hxge_t hxgep; 27241ed83081SMichael Speer p_rx_rcr_ring_t ring; 27251ed83081SMichael Speer 27261ed83081SMichael Speer ASSERT(rhp != NULL); 27271ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 27281ed83081SMichael Speer 27291ed83081SMichael Speer hxgep = rhp->hxgep; 27301ed83081SMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index]; 27311ed83081SMichael Speer 27321ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 27331ed83081SMichael Speer rhp->started = B_TRUE; 27341ed83081SMichael Speer ring->rcr_mac_handle = NULL; 27351ed83081SMichael Speer ring->ldvp = NULL; 27361ed83081SMichael Speer ring->ldgp = NULL; 27371ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 27381ed83081SMichael Speer } 27391ed83081SMichael Speer 27401ed83081SMichael Speer static int 27411ed83081SMichael Speer hxge_rx_group_start(mac_group_driver_t gdriver) 27421ed83081SMichael Speer { 27431ed83081SMichael Speer hxge_ring_group_t *group = (hxge_ring_group_t *)gdriver; 27441ed83081SMichael Speer 27451ed83081SMichael Speer ASSERT(group->hxgep != NULL); 27461ed83081SMichael Speer ASSERT(group->hxgep->hxge_mac_state == HXGE_MAC_STARTED); 27471ed83081SMichael Speer 27481ed83081SMichael Speer MUTEX_ENTER(group->hxgep->genlock); 27491ed83081SMichael Speer group->started = B_TRUE; 27501ed83081SMichael Speer MUTEX_EXIT(group->hxgep->genlock); 27511ed83081SMichael Speer 27521ed83081SMichael Speer return (0); 27531ed83081SMichael Speer } 27541ed83081SMichael Speer 27551ed83081SMichael Speer static void 27561ed83081SMichael Speer hxge_rx_group_stop(mac_group_driver_t gdriver) 27571ed83081SMichael Speer { 27581ed83081SMichael Speer hxge_ring_group_t *group = (hxge_ring_group_t *)gdriver; 27591ed83081SMichael Speer 27601ed83081SMichael Speer ASSERT(group->hxgep != NULL); 27611ed83081SMichael Speer ASSERT(group->hxgep->hxge_mac_state == HXGE_MAC_STARTED); 27621ed83081SMichael Speer ASSERT(group->started == B_TRUE); 27631ed83081SMichael Speer 27641ed83081SMichael Speer MUTEX_ENTER(group->hxgep->genlock); 27651ed83081SMichael Speer group->started = B_FALSE; 27661ed83081SMichael Speer MUTEX_EXIT(group->hxgep->genlock); 27671ed83081SMichael Speer } 27681ed83081SMichael Speer 27691ed83081SMichael Speer static int 27701ed83081SMichael Speer hxge_mmac_get_slot(p_hxge_t hxgep, int *slot) 27711ed83081SMichael Speer { 27721ed83081SMichael Speer int i; 27731ed83081SMichael Speer 27741ed83081SMichael Speer /* 27751ed83081SMichael Speer * Find an open slot. 27761ed83081SMichael Speer */ 27771ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 27781ed83081SMichael Speer if (!hxgep->mmac.addrs[i].set) { 27791ed83081SMichael Speer *slot = i; 27801ed83081SMichael Speer return (0); 27811ed83081SMichael Speer } 27821ed83081SMichael Speer } 27831ed83081SMichael Speer 27841ed83081SMichael Speer return (ENXIO); 27851ed83081SMichael Speer } 27861ed83081SMichael Speer 27871ed83081SMichael Speer static int 27881ed83081SMichael Speer hxge_mmac_set_addr(p_hxge_t hxgep, int slot, const uint8_t *addr) 27891ed83081SMichael Speer { 27901ed83081SMichael Speer struct ether_addr eaddr; 27911ed83081SMichael Speer hxge_status_t status = HXGE_OK; 27921ed83081SMichael Speer 27931ed83081SMichael Speer bcopy(addr, (uint8_t *)&eaddr, ETHERADDRL); 27941ed83081SMichael Speer 27951ed83081SMichael Speer /* 27961ed83081SMichael Speer * Set new interface local address and re-init device. 27971ed83081SMichael Speer * This is destructive to any other streams attached 27981ed83081SMichael Speer * to this device. 27991ed83081SMichael Speer */ 28001ed83081SMichael Speer RW_ENTER_WRITER(&hxgep->filter_lock); 28011ed83081SMichael Speer status = hxge_pfc_set_mac_address(hxgep, slot, &eaddr); 28021ed83081SMichael Speer RW_EXIT(&hxgep->filter_lock); 28031ed83081SMichael Speer if (status != HXGE_OK) 28041ed83081SMichael Speer return (status); 28051ed83081SMichael Speer 28061ed83081SMichael Speer hxgep->mmac.addrs[slot].set = B_TRUE; 28071ed83081SMichael Speer bcopy(addr, hxgep->mmac.addrs[slot].addr, ETHERADDRL); 28081ed83081SMichael Speer hxgep->mmac.available--; 28091ed83081SMichael Speer if (slot == HXGE_MAC_DEFAULT_ADDR_SLOT) 28101ed83081SMichael Speer hxgep->mmac.addrs[slot].primary = B_TRUE; 28111ed83081SMichael Speer 28121ed83081SMichael Speer return (0); 28131ed83081SMichael Speer } 28141ed83081SMichael Speer 28151ed83081SMichael Speer static int 28161ed83081SMichael Speer hxge_mmac_find_addr(p_hxge_t hxgep, const uint8_t *addr, int *slot) 28171ed83081SMichael Speer { 28181ed83081SMichael Speer int i, result; 28191ed83081SMichael Speer 28201ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 28211ed83081SMichael Speer if (hxgep->mmac.addrs[i].set) { 28221ed83081SMichael Speer result = memcmp(hxgep->mmac.addrs[i].addr, 28231ed83081SMichael Speer addr, ETHERADDRL); 28241ed83081SMichael Speer if (result == 0) { 28251ed83081SMichael Speer *slot = i; 28261ed83081SMichael Speer return (0); 28271ed83081SMichael Speer } 28281ed83081SMichael Speer } 28291ed83081SMichael Speer } 28301ed83081SMichael Speer 28311ed83081SMichael Speer return (EINVAL); 28321ed83081SMichael Speer } 28331ed83081SMichael Speer 28341ed83081SMichael Speer static int 28351ed83081SMichael Speer hxge_mmac_unset_addr(p_hxge_t hxgep, int slot) 28361ed83081SMichael Speer { 28371ed83081SMichael Speer hxge_status_t status; 28381ed83081SMichael Speer int i; 28391ed83081SMichael Speer 28401ed83081SMichael Speer status = hxge_pfc_clear_mac_address(hxgep, slot); 28411ed83081SMichael Speer if (status != HXGE_OK) 28421ed83081SMichael Speer return (status); 28431ed83081SMichael Speer 28441ed83081SMichael Speer for (i = 0; i < ETHERADDRL; i++) 28451ed83081SMichael Speer hxgep->mmac.addrs[slot].addr[i] = 0; 28461ed83081SMichael Speer 28471ed83081SMichael Speer hxgep->mmac.addrs[slot].set = B_FALSE; 28481ed83081SMichael Speer if (slot == HXGE_MAC_DEFAULT_ADDR_SLOT) 28491ed83081SMichael Speer hxgep->mmac.addrs[slot].primary = B_FALSE; 28501ed83081SMichael Speer hxgep->mmac.available++; 28511ed83081SMichael Speer 28521ed83081SMichael Speer return (0); 28531ed83081SMichael Speer } 28541ed83081SMichael Speer 28551ed83081SMichael Speer static int 28561ed83081SMichael Speer hxge_rx_group_add_mac(void *arg, const uint8_t *mac_addr) 28571ed83081SMichael Speer { 28581ed83081SMichael Speer hxge_ring_group_t *group = arg; 28591ed83081SMichael Speer p_hxge_t hxgep = group->hxgep; 28601ed83081SMichael Speer int slot = 0; 28611ed83081SMichael Speer 28621ed83081SMichael Speer ASSERT(group->type == MAC_RING_TYPE_RX); 28631ed83081SMichael Speer 28641ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 28651ed83081SMichael Speer 28661ed83081SMichael Speer /* 28671ed83081SMichael Speer * Find a slot for the address. 28681ed83081SMichael Speer */ 28691ed83081SMichael Speer if (hxge_mmac_get_slot(hxgep, &slot) != 0) { 28701ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28711ed83081SMichael Speer return (ENOSPC); 28721ed83081SMichael Speer } 28731ed83081SMichael Speer 28741ed83081SMichael Speer /* 28751ed83081SMichael Speer * Program the MAC address. 28761ed83081SMichael Speer */ 28771ed83081SMichael Speer if (hxge_mmac_set_addr(hxgep, slot, mac_addr) != 0) { 28781ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28791ed83081SMichael Speer return (ENOSPC); 28801ed83081SMichael Speer } 28811ed83081SMichael Speer 28821ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28831ed83081SMichael Speer return (0); 28841ed83081SMichael Speer } 28851ed83081SMichael Speer 28861ed83081SMichael Speer static int 28871ed83081SMichael Speer hxge_rx_group_rem_mac(void *arg, const uint8_t *mac_addr) 28881ed83081SMichael Speer { 28891ed83081SMichael Speer hxge_ring_group_t *group = arg; 28901ed83081SMichael Speer p_hxge_t hxgep = group->hxgep; 28911ed83081SMichael Speer int rv, slot; 28921ed83081SMichael Speer 28931ed83081SMichael Speer ASSERT(group->type == MAC_RING_TYPE_RX); 28941ed83081SMichael Speer 28951ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 28961ed83081SMichael Speer 28971ed83081SMichael Speer if ((rv = hxge_mmac_find_addr(hxgep, mac_addr, &slot)) != 0) { 28981ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28991ed83081SMichael Speer return (rv); 29001ed83081SMichael Speer } 29011ed83081SMichael Speer 29021ed83081SMichael Speer if ((rv = hxge_mmac_unset_addr(hxgep, slot)) != 0) { 29031ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 29041ed83081SMichael Speer return (rv); 29051ed83081SMichael Speer } 29061ed83081SMichael Speer 29071ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 29081ed83081SMichael Speer return (0); 29091ed83081SMichael Speer } 29101ed83081SMichael Speer 29111ed83081SMichael Speer static void 29121ed83081SMichael Speer hxge_group_get(void *arg, mac_ring_type_t type, int groupid, 29131ed83081SMichael Speer mac_group_info_t *infop, mac_group_handle_t gh) 29141ed83081SMichael Speer { 29151ed83081SMichael Speer p_hxge_t hxgep = arg; 29161ed83081SMichael Speer hxge_ring_group_t *group; 29171ed83081SMichael Speer 29181ed83081SMichael Speer ASSERT(type == MAC_RING_TYPE_RX); 29191ed83081SMichael Speer 29201ed83081SMichael Speer switch (type) { 29211ed83081SMichael Speer case MAC_RING_TYPE_RX: 29221ed83081SMichael Speer group = &hxgep->rx_groups[groupid]; 29231ed83081SMichael Speer group->hxgep = hxgep; 29241ed83081SMichael Speer group->ghandle = gh; 29251ed83081SMichael Speer group->index = groupid; 29261ed83081SMichael Speer group->type = type; 29271ed83081SMichael Speer 29281ed83081SMichael Speer infop->mgi_driver = (mac_group_driver_t)group; 29291ed83081SMichael Speer infop->mgi_start = hxge_rx_group_start; 29301ed83081SMichael Speer infop->mgi_stop = hxge_rx_group_stop; 29311ed83081SMichael Speer infop->mgi_addmac = hxge_rx_group_add_mac; 29321ed83081SMichael Speer infop->mgi_remmac = hxge_rx_group_rem_mac; 29331ed83081SMichael Speer infop->mgi_count = HXGE_MAX_RDCS; 29341ed83081SMichael Speer break; 29351ed83081SMichael Speer 29361ed83081SMichael Speer case MAC_RING_TYPE_TX: 29371ed83081SMichael Speer default: 29381ed83081SMichael Speer break; 29391ed83081SMichael Speer } 29401ed83081SMichael Speer } 29411ed83081SMichael Speer 29421ed83081SMichael Speer /* 29431ed83081SMichael Speer * Callback function for the GLDv3 layer to register all rings. 29441ed83081SMichael Speer */ 29451ed83081SMichael Speer /*ARGSUSED*/ 29461ed83081SMichael Speer static void 29471ed83081SMichael Speer hxge_fill_ring(void *arg, mac_ring_type_t type, const int rg_index, 29481ed83081SMichael Speer const int index, mac_ring_info_t *infop, mac_ring_handle_t rh) 29491ed83081SMichael Speer { 29501ed83081SMichael Speer p_hxge_t hxgep = arg; 29511ed83081SMichael Speer 29521ed83081SMichael Speer switch (type) { 29531ed83081SMichael Speer case MAC_RING_TYPE_TX: { 29541ed83081SMichael Speer p_hxge_ring_handle_t rhp; 29551ed83081SMichael Speer 29561ed83081SMichael Speer ASSERT((index >= 0) && (index < HXGE_MAX_TDCS)); 29571ed83081SMichael Speer rhp = &hxgep->tx_ring_handles[index]; 29581ed83081SMichael Speer rhp->hxgep = hxgep; 29591ed83081SMichael Speer rhp->index = index; 29601ed83081SMichael Speer rhp->ring_handle = rh; 29611ed83081SMichael Speer infop->mri_driver = (mac_ring_driver_t)rhp; 29621ed83081SMichael Speer infop->mri_start = hxge_tx_ring_start; 29631ed83081SMichael Speer infop->mri_stop = hxge_tx_ring_stop; 29641ed83081SMichael Speer infop->mri_tx = hxge_tx_ring_send; 29651ed83081SMichael Speer break; 29661ed83081SMichael Speer } 29671ed83081SMichael Speer case MAC_RING_TYPE_RX: { 29681ed83081SMichael Speer p_hxge_ring_handle_t rhp; 29691ed83081SMichael Speer mac_intr_t hxge_mac_intr; 29701ed83081SMichael Speer 29711ed83081SMichael Speer ASSERT((index >= 0) && (index < HXGE_MAX_RDCS)); 29721ed83081SMichael Speer rhp = &hxgep->rx_ring_handles[index]; 29731ed83081SMichael Speer rhp->hxgep = hxgep; 29741ed83081SMichael Speer rhp->index = index; 29751ed83081SMichael Speer rhp->ring_handle = rh; 29761ed83081SMichael Speer 29771ed83081SMichael Speer /* 29781ed83081SMichael Speer * Entrypoint to enable interrupt (disable poll) and 29791ed83081SMichael Speer * disable interrupt (enable poll). 29801ed83081SMichael Speer */ 29811ed83081SMichael Speer hxge_mac_intr.mi_handle = (mac_intr_handle_t)rhp; 29821ed83081SMichael Speer hxge_mac_intr.mi_enable = 29831ed83081SMichael Speer (mac_intr_enable_t)hxge_disable_poll; 29841ed83081SMichael Speer hxge_mac_intr.mi_disable = 29851ed83081SMichael Speer (mac_intr_disable_t)hxge_enable_poll; 29861ed83081SMichael Speer infop->mri_driver = (mac_ring_driver_t)rhp; 29871ed83081SMichael Speer infop->mri_start = hxge_rx_ring_start; 29881ed83081SMichael Speer infop->mri_stop = hxge_rx_ring_stop; 29891ed83081SMichael Speer infop->mri_intr = hxge_mac_intr; 29901ed83081SMichael Speer infop->mri_poll = hxge_rx_poll; 29911ed83081SMichael Speer break; 29921ed83081SMichael Speer } 29931ed83081SMichael Speer default: 29941ed83081SMichael Speer break; 29951ed83081SMichael Speer } 29961ed83081SMichael Speer } 29971ed83081SMichael Speer 29983dec9fcdSqs /*ARGSUSED*/ 29993dec9fcdSqs boolean_t 30003dec9fcdSqs hxge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 30013dec9fcdSqs { 30021ed83081SMichael Speer p_hxge_t hxgep = arg; 30033dec9fcdSqs 30043dec9fcdSqs switch (cap) { 30051ed83081SMichael Speer case MAC_CAPAB_HCKSUM: { 30061ed83081SMichael Speer uint32_t *txflags = cap_data; 30071ed83081SMichael Speer 30083dec9fcdSqs *txflags = HCKSUM_INET_PARTIAL; 30093dec9fcdSqs break; 30101ed83081SMichael Speer } 30111ed83081SMichael Speer 30121ed83081SMichael Speer case MAC_CAPAB_RINGS: { 30131ed83081SMichael Speer mac_capab_rings_t *cap_rings = cap_data; 30141ed83081SMichael Speer 30151ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 30161ed83081SMichael Speer if (cap_rings->mr_type == MAC_RING_TYPE_RX) { 30171ed83081SMichael Speer cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 30181ed83081SMichael Speer cap_rings->mr_rnum = HXGE_MAX_RDCS; 30191ed83081SMichael Speer cap_rings->mr_rget = hxge_fill_ring; 30201ed83081SMichael Speer cap_rings->mr_gnum = HXGE_MAX_RX_GROUPS; 30211ed83081SMichael Speer cap_rings->mr_gget = hxge_group_get; 30221ed83081SMichael Speer cap_rings->mr_gaddring = NULL; 30231ed83081SMichael Speer cap_rings->mr_gremring = NULL; 30241ed83081SMichael Speer } else { 30251ed83081SMichael Speer cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 30261ed83081SMichael Speer cap_rings->mr_rnum = HXGE_MAX_TDCS; 30271ed83081SMichael Speer cap_rings->mr_rget = hxge_fill_ring; 30281ed83081SMichael Speer cap_rings->mr_gnum = 0; 30291ed83081SMichael Speer cap_rings->mr_gget = NULL; 30301ed83081SMichael Speer cap_rings->mr_gaddring = NULL; 30311ed83081SMichael Speer cap_rings->mr_gremring = NULL; 30321ed83081SMichael Speer } 30331ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 30341ed83081SMichael Speer break; 30351ed83081SMichael Speer } 30363dec9fcdSqs 30373dec9fcdSqs default: 30383dec9fcdSqs return (B_FALSE); 30393dec9fcdSqs } 30403dec9fcdSqs return (B_TRUE); 30413dec9fcdSqs } 30423dec9fcdSqs 3043a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static boolean_t 3044a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_param_locked(mac_prop_id_t pr_num) 3045a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3046a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3047a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * All adv_* parameters are locked (read-only) while 3048a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * the device is in any sort of loopback mode ... 3049a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3050a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3051a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3052a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3053a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3054a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3055a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3056a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3057a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3058a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3059a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3060a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3061a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3062a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3063a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3064a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3065a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (B_TRUE); 3066a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3067a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (B_FALSE); 3068a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3069a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3070a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3071a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * callback functions for set/get of properties 3072a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3073a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3074a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 3075a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val) 3076a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3077a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_t *hxgep = barg; 3078a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp; 3079a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3080a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint32_t new_mtu, old_framesize, new_framesize; 3081a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3082a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, "==> hxge_m_setprop")); 3083a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3084a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States statsp = hxgep->statsp; 30851ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 3086a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (statsp->port_stats.lb_mode != hxge_lb_normal && 3087a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_param_locked(pr_num)) { 3088a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3089a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * All adv_* parameters are locked (read-only) 3090a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * while the device is in any sort of loopback mode. 3091a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3092a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3093a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: loopback mode: read only")); 30941ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 3095a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EBUSY); 3096a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3097a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3098a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3099a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3100a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * These properties are either not exist or read only 3101a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3102a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3103a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3104a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3105a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3106a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3107a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3108a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3109a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3110a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3111a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3112a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3113a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3114a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_STATUS: 3115a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_SPEED: 3116a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_DUPLEX: 3117a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3118a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3119a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * Flow control is handled in the shared domain and 3120a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * it is readonly here. 3121a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3122a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3123a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3124a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3125a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: read only property %d", 3126a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States pr_num)); 3127a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3128a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3129a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_MTU: 3130a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 3131a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3132a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: set MTU: %d", new_mtu)); 3133a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3134a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_framesize = new_mtu + MTU_TO_FRAME_SIZE; 3135a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (new_framesize == hxgep->vmac.maxframesize) { 3136a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = 0; 3137a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3138a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3139a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3140afdda45fSVasumathi Sundaram - Sun Microsystems if (hxgep->hxge_mac_state == HXGE_MAC_STARTED) { 3141afdda45fSVasumathi Sundaram - Sun Microsystems err = EBUSY; 3142afdda45fSVasumathi Sundaram - Sun Microsystems break; 3143afdda45fSVasumathi Sundaram - Sun Microsystems } 3144afdda45fSVasumathi Sundaram - Sun Microsystems 3145a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (new_framesize < MIN_FRAME_SIZE || 3146a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_framesize > MAX_FRAME_SIZE) { 3147a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3148a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3149a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3150a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3151a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States old_framesize = hxgep->vmac.maxframesize; 3152a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = (uint16_t)new_framesize; 3153a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3154a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (hxge_vmac_set_framesize(hxgep)) { 3155a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = 3156a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (uint16_t)old_framesize; 3157a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3158a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3159a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3160a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3161a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = mac_maxsdu_update(hxgep->mach, new_mtu); 3162a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (err) { 3163a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = 3164a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (uint16_t)old_framesize; 3165a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) hxge_vmac_set_framesize(hxgep); 3166a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3167a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3168a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3169a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: set MTU: %d maxframe %d", 3170a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_mtu, hxgep->vmac.maxframesize)); 3171a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3172a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3173a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_PRIVATE: 3174a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3175a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: private property")); 3176a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_set_priv_prop(hxgep, pr_name, pr_valsize, 3177a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States pr_val); 3178a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3179a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3180a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States default: 3181a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOTSUP; 3182a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3183a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3184a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 31851ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 3186a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3187a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3188a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_m_setprop (return %d)", err)); 3189a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3190a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3191a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3192a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3193a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* ARGSUSED */ 3194a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3195a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_get_def_val(hxge_t *hxgep, mac_prop_id_t pr_num, uint_t pr_valsize, 3196a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States void *pr_val) 3197a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3198a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3199a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States link_flowctrl_t fl; 3200a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3201a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3202a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_DUPLEX: 3203a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = 2; 3204a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3205a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3206a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = 0; 3207a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3208a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3209a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < sizeof (link_flowctrl_t)) 3210a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3211a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States fl = LINK_FLOWCTRL_TX; 3212a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&fl, pr_val, sizeof (fl)); 3213a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3214a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States default: 3215a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOTSUP; 3216a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3217a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3218a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3219a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3220a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3221a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3222a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 3223afdda45fSVasumathi Sundaram - Sun Microsystems uint_t pr_flags, uint_t pr_valsize, void *pr_val, uint_t *perm) 3224a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3225a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_t *hxgep = barg; 3226a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp = hxgep->statsp; 3227a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3228a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States link_flowctrl_t fl; 3229a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint64_t tmp = 0; 3230a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States link_state_t ls; 3231a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3232a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3233a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_getprop: pr_num %d", pr_num)); 3234a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3235a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize == 0) 3236a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3237a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3238afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_RW; 3239afdda45fSVasumathi Sundaram - Sun Microsystems 3240a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if ((pr_flags & MAC_PROP_DEFAULT) && (pr_num != MAC_PROP_PRIVATE)) { 3241a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_get_def_val(hxgep, pr_num, pr_valsize, pr_val); 3242a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3243a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3244a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3245a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bzero(pr_val, pr_valsize); 3246a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3247a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_DUPLEX: 3248afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_READ; 3249a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = statsp->mac_stats.link_duplex; 3250a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3251a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_getprop: duplex mode %d", 3252a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val)); 3253a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3254a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3255a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_SPEED: 3256afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_READ; 3257a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < sizeof (uint64_t)) 3258a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3259a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States tmp = statsp->mac_stats.link_speed * 1000000ull; 3260a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&tmp, pr_val, sizeof (tmp)); 3261a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3262a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3263a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_STATUS: 3264afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_READ; 3265a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < sizeof (link_state_t)) 3266a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3267a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (!statsp->mac_stats.link_up) 3268a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States ls = LINK_STATE_DOWN; 3269a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States else 3270a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States ls = LINK_STATE_UP; 3271a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&ls, pr_val, sizeof (ls)); 3272a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3273a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3274a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3275a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3276a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * Flow control is supported by the shared domain and 3277a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * it is currently transmit only 3278a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3279afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_READ; 3280a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < sizeof (link_flowctrl_t)) 3281a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3282a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States fl = LINK_FLOWCTRL_TX; 3283a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&fl, pr_val, sizeof (fl)); 3284a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3285a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3286a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 10G link only and it is not negotiable */ 3287afdda45fSVasumathi Sundaram - Sun Microsystems *perm = MAC_PROP_PERM_READ; 3288a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = 0; 3289a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3290a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3291a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3292a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3293a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3294a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3295a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3296a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3297a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3298a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3299a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3300a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3301a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3302a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOTSUP; 3303a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3304a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3305a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_PRIVATE: 3306a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_get_priv_prop(hxgep, pr_name, pr_flags, 3307a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States pr_valsize, pr_val); 3308a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3309a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States default: 3310a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3311a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3312a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3313a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3314a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, "<== hxge_m_getprop")); 3315a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3316a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3317a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3318a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3319a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* ARGSUSED */ 3320a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3321a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_set_priv_prop(p_hxge_t hxgep, const char *pr_name, uint_t pr_valsize, 3322a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States const void *pr_val) 3323a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3324a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_param_t param_arr = hxgep->param_arr; 3325a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3326a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3327a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3328a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_set_priv_prop: name %s (value %s)", pr_name, pr_val)); 3329a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3330a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_val == NULL) { 3331a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3332a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3333a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3334a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Blanking */ 3335a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3336a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_rx_intr_time(hxgep, NULL, NULL, 3337a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (char *)pr_val, (caddr_t)¶m_arr[param_rxdma_intr_time]); 3338a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3339a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_rx_intr_pkts(hxgep, NULL, NULL, 3340a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (char *)pr_val, (caddr_t)¶m_arr[param_rxdma_intr_pkts]); 3341a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3342a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Classification */ 3343a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0) { 3344a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3345a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_tcp]); 3346a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_udp") == 0) { 3347a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3348a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_udp]); 3349a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_ah") == 0) { 3350a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3351a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_ah]); 3352a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_sctp") == 0) { 3353a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3354a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_sctp]); 3355a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_tcp") == 0) { 3356a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3357a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_tcp]); 3358a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_udp") == 0) { 3359a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3360a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_udp]); 3361a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_ah") == 0) { 3362a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3363a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_ah]); 3364a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3365a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3366a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_sctp]); 3367a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3368a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3369a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3370a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3371a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3372a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_set_priv_prop: err %d", err)); 3373a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3374a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3375a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3376a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3377a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3378a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_get_priv_prop(p_hxge_t hxgep, const char *pr_name, uint_t pr_flags, 3379a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, void *pr_val) 3380a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3381a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_param_t param_arr = hxgep->param_arr; 3382a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States char valstr[MAXNAMELEN]; 3383a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3384a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t strsize; 3385a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int value = 0; 3386a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3387a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3388a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_get_priv_prop: property %s", pr_name)); 3389a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3390a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_flags & MAC_PROP_DEFAULT) { 3391a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Receive Interrupt Blanking Parameters */ 3392a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3393a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = RXDMA_RCR_TO_DEFAULT; 3394a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3395a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = RXDMA_RCR_PTHRES_DEFAULT; 3396a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3397a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Classification and Load Distribution Configuration */ 3398a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0 || 3399a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv4_udp") == 0 || 3400a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv4_ah") == 0 || 3401a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv4_sctp") == 0 || 3402a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv6_tcp") == 0 || 3403a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv6_udp") == 0 || 3404a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv6_ah") == 0 || 3405a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3406a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = HXGE_CLASS_TCAM_LOOKUP; 3407a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3408a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3409a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3410a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3411a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Receive Interrupt Blanking Parameters */ 3412a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3413a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = hxgep->intr_timeout; 3414a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3415a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = hxgep->intr_threshold; 3416a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3417a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Classification and Load Distribution Configuration */ 3418a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0) { 3419a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3420a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_tcp]); 3421a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3422a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv4_tcp].value; 3423a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_udp") == 0) { 3424a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3425a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_udp]); 3426a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3427a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv4_udp].value; 3428a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_ah") == 0) { 3429a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3430a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_ah]); 3431a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3432a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv4_ah].value; 3433a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_sctp") == 0) { 3434a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3435a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_sctp]); 3436a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3437a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv4_sctp].value; 3438a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_tcp") == 0) { 3439a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3440a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_tcp]); 3441a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3442a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv6_tcp].value; 3443a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_udp") == 0) { 3444a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3445a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_udp]); 3446a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3447a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv6_udp].value; 3448a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_ah") == 0) { 3449a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3450a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_ah]); 3451a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3452a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv6_ah].value; 3453a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3454a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3455a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_sctp]); 3456a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3457a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value = (int)param_arr[param_class_opt_ipv6_sctp].value; 3458a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3459a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3460a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3461a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3462a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3463a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (err == 0) { 3464a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) snprintf(valstr, sizeof (valstr), "0x%x", value); 3465a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3466a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strsize = (uint_t)strlen(valstr); 3467a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < strsize) { 3468a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOBUFS; 3469a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3470a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) strlcpy(pr_val, valstr, pr_valsize); 3471a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3472a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3473a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3474a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3475a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_get_priv_prop: return %d", err)); 3476a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3477a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3478a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 34793dec9fcdSqs /* 34803dec9fcdSqs * Module loading and removing entry points. 34813dec9fcdSqs */ 34823dec9fcdSqs DDI_DEFINE_STREAM_OPS(hxge_dev_ops, nulldev, nulldev, hxge_attach, hxge_detach, 34833a109ad9SQiyan Sun - Sun Microsystems - San Diego United States nodev, NULL, D_MP, NULL, NULL); 34843dec9fcdSqs 34853dec9fcdSqs extern struct mod_ops mod_driverops; 34863dec9fcdSqs 34873dec9fcdSqs #define HXGE_DESC_VER "HXGE 10Gb Ethernet Driver" 34883dec9fcdSqs 34893dec9fcdSqs /* 34903dec9fcdSqs * Module linkage information for the kernel. 34913dec9fcdSqs */ 34923dec9fcdSqs static struct modldrv hxge_modldrv = { 34933dec9fcdSqs &mod_driverops, 34943dec9fcdSqs HXGE_DESC_VER, 34953dec9fcdSqs &hxge_dev_ops 34963dec9fcdSqs }; 34973dec9fcdSqs 34983dec9fcdSqs static struct modlinkage modlinkage = { 34993dec9fcdSqs MODREV_1, (void *) &hxge_modldrv, NULL 35003dec9fcdSqs }; 35013dec9fcdSqs 35023dec9fcdSqs int 35033dec9fcdSqs _init(void) 35043dec9fcdSqs { 35053dec9fcdSqs int status; 35063dec9fcdSqs 35073dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _init")); 35083dec9fcdSqs mac_init_ops(&hxge_dev_ops, "hxge"); 35093dec9fcdSqs status = ddi_soft_state_init(&hxge_list, sizeof (hxge_t), 0); 35103dec9fcdSqs if (status != 0) { 35113dec9fcdSqs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, 35123dec9fcdSqs "failed to init device soft state")); 35133dec9fcdSqs mac_fini_ops(&hxge_dev_ops); 35143dec9fcdSqs goto _init_exit; 35153dec9fcdSqs } 35163dec9fcdSqs 35173dec9fcdSqs status = mod_install(&modlinkage); 35183dec9fcdSqs if (status != 0) { 35193dec9fcdSqs ddi_soft_state_fini(&hxge_list); 35203dec9fcdSqs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, "Mod install failed")); 35213dec9fcdSqs goto _init_exit; 35223dec9fcdSqs } 35233dec9fcdSqs 35243dec9fcdSqs MUTEX_INIT(&hxge_common_lock, NULL, MUTEX_DRIVER, NULL); 35253dec9fcdSqs 35263dec9fcdSqs _init_exit: 35273dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "_init status = 0x%X", status)); 35283dec9fcdSqs 35293dec9fcdSqs return (status); 35303dec9fcdSqs } 35313dec9fcdSqs 35323dec9fcdSqs int 35333dec9fcdSqs _fini(void) 35343dec9fcdSqs { 35353dec9fcdSqs int status; 35363dec9fcdSqs 35373dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini")); 35383dec9fcdSqs 35393dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini: mod_remove")); 35403dec9fcdSqs 35413dec9fcdSqs if (hxge_mblks_pending) 35423dec9fcdSqs return (EBUSY); 35433dec9fcdSqs 35443dec9fcdSqs status = mod_remove(&modlinkage); 35453dec9fcdSqs if (status != DDI_SUCCESS) { 35463dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, 35473dec9fcdSqs "Module removal failed 0x%08x", status)); 35483dec9fcdSqs goto _fini_exit; 35493dec9fcdSqs } 35503dec9fcdSqs 35513dec9fcdSqs mac_fini_ops(&hxge_dev_ops); 35523dec9fcdSqs 35533dec9fcdSqs ddi_soft_state_fini(&hxge_list); 35543dec9fcdSqs 35553dec9fcdSqs MUTEX_DESTROY(&hxge_common_lock); 35563dec9fcdSqs 35573dec9fcdSqs _fini_exit: 35583dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "_fini status = 0x%08x", status)); 35593dec9fcdSqs 35603dec9fcdSqs return (status); 35613dec9fcdSqs } 35623dec9fcdSqs 35633dec9fcdSqs int 35643dec9fcdSqs _info(struct modinfo *modinfop) 35653dec9fcdSqs { 35663dec9fcdSqs int status; 35673dec9fcdSqs 35683dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _info")); 35693dec9fcdSqs status = mod_info(&modlinkage, modinfop); 35703dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, " _info status = 0x%X", status)); 35713dec9fcdSqs 35723dec9fcdSqs return (status); 35733dec9fcdSqs } 35743dec9fcdSqs 35753dec9fcdSqs /*ARGSUSED*/ 35763dec9fcdSqs hxge_status_t 35773dec9fcdSqs hxge_add_intrs(p_hxge_t hxgep) 35783dec9fcdSqs { 35793dec9fcdSqs int intr_types; 35803dec9fcdSqs int type = 0; 35813dec9fcdSqs int ddi_status = DDI_SUCCESS; 35823dec9fcdSqs hxge_status_t status = HXGE_OK; 35833dec9fcdSqs 35843dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs")); 35853dec9fcdSqs 35863dec9fcdSqs hxgep->hxge_intr_type.intr_registered = B_FALSE; 35873dec9fcdSqs hxgep->hxge_intr_type.intr_enabled = B_FALSE; 35883dec9fcdSqs hxgep->hxge_intr_type.msi_intx_cnt = 0; 35893dec9fcdSqs hxgep->hxge_intr_type.intr_added = 0; 35903dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable = B_FALSE; 35913dec9fcdSqs hxgep->hxge_intr_type.intr_type = 0; 35923dec9fcdSqs 35933dec9fcdSqs if (hxge_msi_enable) { 35943dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable = B_TRUE; 35953dec9fcdSqs } 35963dec9fcdSqs 35973dec9fcdSqs /* Get the supported interrupt types */ 35983dec9fcdSqs if ((ddi_status = ddi_intr_get_supported_types(hxgep->dip, &intr_types)) 35993dec9fcdSqs != DDI_SUCCESS) { 36003dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "<== hxge_add_intrs: " 36013dec9fcdSqs "ddi_intr_get_supported_types failed: status 0x%08x", 36023dec9fcdSqs ddi_status)); 36033dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 36043dec9fcdSqs } 36053dec9fcdSqs 36063dec9fcdSqs hxgep->hxge_intr_type.intr_types = intr_types; 36073dec9fcdSqs 36083dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36093dec9fcdSqs "ddi_intr_get_supported_types: 0x%08x", intr_types)); 36103dec9fcdSqs 36113dec9fcdSqs /* 36123dec9fcdSqs * Pick the interrupt type to use MSIX, MSI, INTX hxge_msi_enable: 36133dec9fcdSqs * (1): 1 - MSI 36143dec9fcdSqs * (2): 2 - MSI-X 36153dec9fcdSqs * others - FIXED 36163dec9fcdSqs */ 36173dec9fcdSqs switch (hxge_msi_enable) { 36183dec9fcdSqs default: 36193dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 36203dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36213dec9fcdSqs "use fixed (intx emulation) type %08x", type)); 36223dec9fcdSqs break; 36233dec9fcdSqs 36243dec9fcdSqs case 2: 36253dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36263dec9fcdSqs "ddi_intr_get_supported_types: 0x%08x", intr_types)); 36273dec9fcdSqs if (intr_types & DDI_INTR_TYPE_MSIX) { 36283dec9fcdSqs type = DDI_INTR_TYPE_MSIX; 36293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36303dec9fcdSqs "==> hxge_add_intrs: " 36313dec9fcdSqs "ddi_intr_get_supported_types: MSIX 0x%08x", type)); 36323dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_MSI) { 36333dec9fcdSqs type = DDI_INTR_TYPE_MSI; 36343dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36353dec9fcdSqs "==> hxge_add_intrs: " 36363dec9fcdSqs "ddi_intr_get_supported_types: MSI 0x%08x", type)); 36373dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_FIXED) { 36383dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 36393dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36403dec9fcdSqs "ddi_intr_get_supported_types: MSXED0x%08x", type)); 36413dec9fcdSqs } 36423dec9fcdSqs break; 36433dec9fcdSqs 36443dec9fcdSqs case 1: 36453dec9fcdSqs if (intr_types & DDI_INTR_TYPE_MSI) { 36463dec9fcdSqs type = DDI_INTR_TYPE_MSI; 36473dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36483dec9fcdSqs "==> hxge_add_intrs: " 36493dec9fcdSqs "ddi_intr_get_supported_types: MSI 0x%08x", type)); 36503dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_MSIX) { 36513dec9fcdSqs type = DDI_INTR_TYPE_MSIX; 36523dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36533dec9fcdSqs "==> hxge_add_intrs: " 36543dec9fcdSqs "ddi_intr_get_supported_types: MSIX 0x%08x", type)); 36553dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_FIXED) { 36563dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 36573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36583dec9fcdSqs "==> hxge_add_intrs: " 36593dec9fcdSqs "ddi_intr_get_supported_types: MSXED0x%08x", type)); 36603dec9fcdSqs } 36613dec9fcdSqs } 36623dec9fcdSqs 36633dec9fcdSqs hxgep->hxge_intr_type.intr_type = type; 36643dec9fcdSqs if ((type == DDI_INTR_TYPE_MSIX || type == DDI_INTR_TYPE_MSI || 36653dec9fcdSqs type == DDI_INTR_TYPE_FIXED) && 36663dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable) { 36673dec9fcdSqs if ((status = hxge_add_intrs_adv(hxgep)) != DDI_SUCCESS) { 36683dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 36693dec9fcdSqs " hxge_add_intrs: " 36703dec9fcdSqs " hxge_add_intrs_adv failed: status 0x%08x", 36713dec9fcdSqs status)); 36723dec9fcdSqs return (status); 36733dec9fcdSqs } else { 36743dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_add_intrs: " 36753dec9fcdSqs "interrupts registered : type %d", type)); 36763dec9fcdSqs hxgep->hxge_intr_type.intr_registered = B_TRUE; 36773dec9fcdSqs 36783dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 36793dec9fcdSqs "\nAdded advanced hxge add_intr_adv " 36803dec9fcdSqs "intr type 0x%x\n", type)); 36813dec9fcdSqs 36823dec9fcdSqs return (status); 36833dec9fcdSqs } 36843dec9fcdSqs } 36853dec9fcdSqs 36863dec9fcdSqs if (!hxgep->hxge_intr_type.intr_registered) { 36873dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 36883dec9fcdSqs "==> hxge_add_intrs: failed to register interrupts")); 36893dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 36903dec9fcdSqs } 36913dec9fcdSqs 36923dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs")); 36933dec9fcdSqs 36943dec9fcdSqs return (status); 36953dec9fcdSqs } 36963dec9fcdSqs 36973dec9fcdSqs /*ARGSUSED*/ 36983dec9fcdSqs static hxge_status_t 36993dec9fcdSqs hxge_add_intrs_adv(p_hxge_t hxgep) 37003dec9fcdSqs { 37013dec9fcdSqs int intr_type; 37023dec9fcdSqs p_hxge_intr_t intrp; 37033dec9fcdSqs hxge_status_t status; 37043dec9fcdSqs 37053dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv")); 37063dec9fcdSqs 37073dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 37083dec9fcdSqs intr_type = intrp->intr_type; 37093dec9fcdSqs 37103dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv: type 0x%x", 37113dec9fcdSqs intr_type)); 37123dec9fcdSqs 37133dec9fcdSqs switch (intr_type) { 37143dec9fcdSqs case DDI_INTR_TYPE_MSI: /* 0x2 */ 37153dec9fcdSqs case DDI_INTR_TYPE_MSIX: /* 0x4 */ 37163dec9fcdSqs status = hxge_add_intrs_adv_type(hxgep, intr_type); 37173dec9fcdSqs break; 37183dec9fcdSqs 37193dec9fcdSqs case DDI_INTR_TYPE_FIXED: /* 0x1 */ 37203dec9fcdSqs status = hxge_add_intrs_adv_type_fix(hxgep, intr_type); 37213dec9fcdSqs break; 37223dec9fcdSqs 37233dec9fcdSqs default: 37243dec9fcdSqs status = HXGE_ERROR; 37253dec9fcdSqs break; 37263dec9fcdSqs } 37273dec9fcdSqs 37283dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv")); 37293dec9fcdSqs 37303dec9fcdSqs return (status); 37313dec9fcdSqs } 37323dec9fcdSqs 37333dec9fcdSqs /*ARGSUSED*/ 37343dec9fcdSqs static hxge_status_t 37353dec9fcdSqs hxge_add_intrs_adv_type(p_hxge_t hxgep, uint32_t int_type) 37363dec9fcdSqs { 37373dec9fcdSqs dev_info_t *dip = hxgep->dip; 37383dec9fcdSqs p_hxge_ldg_t ldgp; 37393dec9fcdSqs p_hxge_intr_t intrp; 37403dec9fcdSqs uint_t *inthandler; 37413dec9fcdSqs void *arg1, *arg2; 37423dec9fcdSqs int behavior; 37433dec9fcdSqs int nintrs, navail; 374457c5371aSQiyan Sun - Sun Microsystems - San Diego United States int nactual, nrequired, nrequest; 37453dec9fcdSqs int inum = 0; 37463dec9fcdSqs int loop = 0; 37473dec9fcdSqs int x, y; 37483dec9fcdSqs int ddi_status = DDI_SUCCESS; 37493dec9fcdSqs hxge_status_t status = HXGE_OK; 37503dec9fcdSqs 37513dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv_type")); 37523dec9fcdSqs 37533dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 37543dec9fcdSqs 37553dec9fcdSqs ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 37563dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 37573dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 37583dec9fcdSqs "ddi_intr_get_nintrs() failed, status: 0x%x%, " 37593dec9fcdSqs "nintrs: %d", ddi_status, nintrs)); 37603dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 37613dec9fcdSqs } 37623dec9fcdSqs 37633dec9fcdSqs ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 37643dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 37653dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 37663dec9fcdSqs "ddi_intr_get_navail() failed, status: 0x%x%, " 37673dec9fcdSqs "nintrs: %d", ddi_status, navail)); 37683dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 37693dec9fcdSqs } 37703dec9fcdSqs 37713dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 37723dec9fcdSqs "ddi_intr_get_navail() returned: intr type %d nintrs %d, navail %d", 37733dec9fcdSqs int_type, nintrs, navail)); 37743dec9fcdSqs 377557c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* PSARC/2007/453 MSI-X interrupt limit override */ 377657c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (int_type == DDI_INTR_TYPE_MSIX) { 377757c5371aSQiyan Sun - Sun Microsystems - San Diego United States nrequest = hxge_create_msi_property(hxgep); 377857c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (nrequest < navail) { 377957c5371aSQiyan Sun - Sun Microsystems - San Diego United States navail = nrequest; 378057c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, INT_CTL, 378157c5371aSQiyan Sun - Sun Microsystems - San Diego United States "hxge_add_intrs_adv_type: nintrs %d " 378257c5371aSQiyan Sun - Sun Microsystems - San Diego United States "navail %d (nrequest %d)", 378357c5371aSQiyan Sun - Sun Microsystems - San Diego United States nintrs, navail, nrequest)); 378457c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 378557c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 378657c5371aSQiyan Sun - Sun Microsystems - San Diego United States 37873dec9fcdSqs if (int_type == DDI_INTR_TYPE_MSI && !ISP2(navail)) { 37883dec9fcdSqs /* MSI must be power of 2 */ 37893dec9fcdSqs if ((navail & 16) == 16) { 37903dec9fcdSqs navail = 16; 37913dec9fcdSqs } else if ((navail & 8) == 8) { 37923dec9fcdSqs navail = 8; 37933dec9fcdSqs } else if ((navail & 4) == 4) { 37943dec9fcdSqs navail = 4; 37953dec9fcdSqs } else if ((navail & 2) == 2) { 37963dec9fcdSqs navail = 2; 37973dec9fcdSqs } else { 37983dec9fcdSqs navail = 1; 37993dec9fcdSqs } 38003dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38013dec9fcdSqs "ddi_intr_get_navail(): (msi power of 2) nintrs %d, " 38023dec9fcdSqs "navail %d", nintrs, navail)); 38033dec9fcdSqs } 38043dec9fcdSqs 38053dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38063dec9fcdSqs "requesting: intr type %d nintrs %d, navail %d", 38073dec9fcdSqs int_type, nintrs, navail)); 38083dec9fcdSqs 38093dec9fcdSqs behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 38103dec9fcdSqs DDI_INTR_ALLOC_NORMAL); 38113dec9fcdSqs intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 38123dec9fcdSqs intrp->htable = kmem_zalloc(intrp->intr_size, KM_SLEEP); 38133dec9fcdSqs 38143dec9fcdSqs ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 38153dec9fcdSqs navail, &nactual, behavior); 38163dec9fcdSqs if (ddi_status != DDI_SUCCESS || nactual == 0) { 38173dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38183dec9fcdSqs " ddi_intr_alloc() failed: %d", ddi_status)); 38193dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38203dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38213dec9fcdSqs } 38223dec9fcdSqs 38233dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38243dec9fcdSqs "ddi_intr_alloc() returned: navail %d nactual %d", 38253dec9fcdSqs navail, nactual)); 38263dec9fcdSqs 38273dec9fcdSqs if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 38283dec9fcdSqs (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 38293dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38303dec9fcdSqs " ddi_intr_get_pri() failed: %d", ddi_status)); 38313dec9fcdSqs /* Free already allocated interrupts */ 38323dec9fcdSqs for (y = 0; y < nactual; y++) { 38333dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 38343dec9fcdSqs } 38353dec9fcdSqs 38363dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38373dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38383dec9fcdSqs } 38393dec9fcdSqs 38403dec9fcdSqs nrequired = 0; 38413dec9fcdSqs status = hxge_ldgv_init(hxgep, &nactual, &nrequired); 38423dec9fcdSqs if (status != HXGE_OK) { 38433dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38443dec9fcdSqs "hxge_add_intrs_adv_typ:hxge_ldgv_init " 38453dec9fcdSqs "failed: 0x%x", status)); 38463dec9fcdSqs /* Free already allocated interrupts */ 38473dec9fcdSqs for (y = 0; y < nactual; y++) { 38483dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 38493dec9fcdSqs } 38503dec9fcdSqs 38513dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38523dec9fcdSqs return (status); 38533dec9fcdSqs } 38543dec9fcdSqs 38553dec9fcdSqs ldgp = hxgep->ldgvp->ldgp; 38563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38573dec9fcdSqs "After hxge_ldgv_init(): nreq %d nactual %d", nrequired, nactual)); 38583dec9fcdSqs 38593dec9fcdSqs if (nactual < nrequired) 38603dec9fcdSqs loop = nactual; 38613dec9fcdSqs else 38623dec9fcdSqs loop = nrequired; 38633dec9fcdSqs 38643dec9fcdSqs for (x = 0; x < loop; x++, ldgp++) { 38653dec9fcdSqs ldgp->vector = (uint8_t)x; 38663dec9fcdSqs arg1 = ldgp->ldvp; 38673dec9fcdSqs arg2 = hxgep; 38683dec9fcdSqs if (ldgp->nldvs == 1) { 38693dec9fcdSqs inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 38703dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38713dec9fcdSqs "hxge_add_intrs_adv_type: arg1 0x%x arg2 0x%x: " 38723dec9fcdSqs "1-1 int handler (entry %d)\n", 38733dec9fcdSqs arg1, arg2, x)); 38743dec9fcdSqs } else if (ldgp->nldvs > 1) { 38753dec9fcdSqs inthandler = (uint_t *)ldgp->sys_intr_handler; 38763dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38773dec9fcdSqs "hxge_add_intrs_adv_type: arg1 0x%x arg2 0x%x: " 38783dec9fcdSqs "nldevs %d int handler (entry %d)\n", 38793dec9fcdSqs arg1, arg2, ldgp->nldvs, x)); 38803dec9fcdSqs } 38813dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38823dec9fcdSqs "==> hxge_add_intrs_adv_type: ddi_add_intr(inum) #%d " 38833dec9fcdSqs "htable 0x%llx", x, intrp->htable[x])); 38843dec9fcdSqs 38853dec9fcdSqs if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 38863dec9fcdSqs (ddi_intr_handler_t *)inthandler, arg1, arg2)) != 38873dec9fcdSqs DDI_SUCCESS) { 38883dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38893dec9fcdSqs "==> hxge_add_intrs_adv_type: failed #%d " 38903dec9fcdSqs "status 0x%x", x, ddi_status)); 38913dec9fcdSqs for (y = 0; y < intrp->intr_added; y++) { 38923dec9fcdSqs (void) ddi_intr_remove_handler( 38933dec9fcdSqs intrp->htable[y]); 38943dec9fcdSqs } 38953dec9fcdSqs 38963dec9fcdSqs /* Free already allocated intr */ 38973dec9fcdSqs for (y = 0; y < nactual; y++) { 38983dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 38993dec9fcdSqs } 39003dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 39013dec9fcdSqs 39023dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 39033dec9fcdSqs 39043dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39053dec9fcdSqs } 39063dec9fcdSqs 39073dec9fcdSqs intrp->intr_added++; 39083dec9fcdSqs } 39093dec9fcdSqs intrp->msi_intx_cnt = nactual; 39103dec9fcdSqs 39113dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39123dec9fcdSqs "Requested: %d, Allowed: %d msi_intx_cnt %d intr_added %d", 39133dec9fcdSqs navail, nactual, intrp->msi_intx_cnt, intrp->intr_added)); 39143dec9fcdSqs 39153dec9fcdSqs (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 39163dec9fcdSqs (void) hxge_intr_ldgv_init(hxgep); 39173dec9fcdSqs 39183dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv_type")); 39193dec9fcdSqs 39203dec9fcdSqs return (status); 39213dec9fcdSqs } 39223dec9fcdSqs 39233dec9fcdSqs /*ARGSUSED*/ 39243dec9fcdSqs static hxge_status_t 39253dec9fcdSqs hxge_add_intrs_adv_type_fix(p_hxge_t hxgep, uint32_t int_type) 39263dec9fcdSqs { 39273dec9fcdSqs dev_info_t *dip = hxgep->dip; 39283dec9fcdSqs p_hxge_ldg_t ldgp; 39293dec9fcdSqs p_hxge_intr_t intrp; 39303dec9fcdSqs uint_t *inthandler; 39313dec9fcdSqs void *arg1, *arg2; 39323dec9fcdSqs int behavior; 39333dec9fcdSqs int nintrs, navail; 39343dec9fcdSqs int nactual, nrequired; 39353dec9fcdSqs int inum = 0; 39363dec9fcdSqs int x, y; 39373dec9fcdSqs int ddi_status = DDI_SUCCESS; 39383dec9fcdSqs hxge_status_t status = HXGE_OK; 39393dec9fcdSqs 39403dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv_type_fix")); 39413dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 39423dec9fcdSqs 39433dec9fcdSqs ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 39443dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 39453dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39463dec9fcdSqs "ddi_intr_get_nintrs() failed, status: 0x%x%, " 39473dec9fcdSqs "nintrs: %d", status, nintrs)); 39483dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39493dec9fcdSqs } 39503dec9fcdSqs 39513dec9fcdSqs ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 39523dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 39533dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 39543dec9fcdSqs "ddi_intr_get_navail() failed, status: 0x%x%, " 39553dec9fcdSqs "nintrs: %d", ddi_status, navail)); 39563dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39573dec9fcdSqs } 39583dec9fcdSqs 39593dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39603dec9fcdSqs "ddi_intr_get_navail() returned: nintrs %d, naavail %d", 39613dec9fcdSqs nintrs, navail)); 39623dec9fcdSqs 39633dec9fcdSqs behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 39643dec9fcdSqs DDI_INTR_ALLOC_NORMAL); 39653dec9fcdSqs intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 39663dec9fcdSqs intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 39673dec9fcdSqs ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 39683dec9fcdSqs navail, &nactual, behavior); 39693dec9fcdSqs if (ddi_status != DDI_SUCCESS || nactual == 0) { 39703dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 39713dec9fcdSqs " ddi_intr_alloc() failed: %d", ddi_status)); 39723dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 39733dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39743dec9fcdSqs } 39753dec9fcdSqs 39763dec9fcdSqs if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 39773dec9fcdSqs (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 39783dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 39793dec9fcdSqs " ddi_intr_get_pri() failed: %d", ddi_status)); 39803dec9fcdSqs /* Free already allocated interrupts */ 39813dec9fcdSqs for (y = 0; y < nactual; y++) { 39823dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 39833dec9fcdSqs } 39843dec9fcdSqs 39853dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 39863dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39873dec9fcdSqs } 39883dec9fcdSqs 39893dec9fcdSqs nrequired = 0; 39903dec9fcdSqs status = hxge_ldgv_init(hxgep, &nactual, &nrequired); 39913dec9fcdSqs if (status != HXGE_OK) { 39923dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 39933dec9fcdSqs "hxge_add_intrs_adv_type_fix:hxge_ldgv_init " 39943dec9fcdSqs "failed: 0x%x", status)); 39953dec9fcdSqs /* Free already allocated interrupts */ 39963dec9fcdSqs for (y = 0; y < nactual; y++) { 39973dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 39983dec9fcdSqs } 39993dec9fcdSqs 40003dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40013dec9fcdSqs return (status); 40023dec9fcdSqs } 40033dec9fcdSqs 40043dec9fcdSqs ldgp = hxgep->ldgvp->ldgp; 40053dec9fcdSqs for (x = 0; x < nrequired; x++, ldgp++) { 40063dec9fcdSqs ldgp->vector = (uint8_t)x; 40073dec9fcdSqs arg1 = ldgp->ldvp; 40083dec9fcdSqs arg2 = hxgep; 40093dec9fcdSqs if (ldgp->nldvs == 1) { 40103dec9fcdSqs inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 40113dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40123dec9fcdSqs "hxge_add_intrs_adv_type_fix: " 40133dec9fcdSqs "1-1 int handler(%d) ldg %d ldv %d " 40143dec9fcdSqs "arg1 $%p arg2 $%p\n", 40153dec9fcdSqs x, ldgp->ldg, ldgp->ldvp->ldv, arg1, arg2)); 40163dec9fcdSqs } else if (ldgp->nldvs > 1) { 40173dec9fcdSqs inthandler = (uint_t *)ldgp->sys_intr_handler; 40183dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40193dec9fcdSqs "hxge_add_intrs_adv_type_fix: " 40203dec9fcdSqs "shared ldv %d int handler(%d) ldv %d ldg %d" 40213dec9fcdSqs "arg1 0x%016llx arg2 0x%016llx\n", 40223dec9fcdSqs x, ldgp->nldvs, ldgp->ldg, ldgp->ldvp->ldv, 40233dec9fcdSqs arg1, arg2)); 40243dec9fcdSqs } 40253dec9fcdSqs 40263dec9fcdSqs if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 40273dec9fcdSqs (ddi_intr_handler_t *)inthandler, arg1, arg2)) != 40283dec9fcdSqs DDI_SUCCESS) { 40293dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40303dec9fcdSqs "==> hxge_add_intrs_adv_type_fix: failed #%d " 40313dec9fcdSqs "status 0x%x", x, ddi_status)); 40323dec9fcdSqs for (y = 0; y < intrp->intr_added; y++) { 40333dec9fcdSqs (void) ddi_intr_remove_handler( 40343dec9fcdSqs intrp->htable[y]); 40353dec9fcdSqs } 40363dec9fcdSqs for (y = 0; y < nactual; y++) { 40373dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 40383dec9fcdSqs } 40393dec9fcdSqs /* Free already allocated intr */ 40403dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40413dec9fcdSqs 40423dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 40433dec9fcdSqs 40443dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 40453dec9fcdSqs } 40463dec9fcdSqs intrp->intr_added++; 40473dec9fcdSqs } 40483dec9fcdSqs 40493dec9fcdSqs intrp->msi_intx_cnt = nactual; 40503dec9fcdSqs 40513dec9fcdSqs (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 40523dec9fcdSqs 40533dec9fcdSqs status = hxge_intr_ldgv_init(hxgep); 40543dec9fcdSqs 40553dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv_type_fix")); 40563dec9fcdSqs 40573dec9fcdSqs return (status); 40583dec9fcdSqs } 40593dec9fcdSqs 40603dec9fcdSqs /*ARGSUSED*/ 40613dec9fcdSqs static void 40623dec9fcdSqs hxge_remove_intrs(p_hxge_t hxgep) 40633dec9fcdSqs { 40643dec9fcdSqs int i, inum; 40653dec9fcdSqs p_hxge_intr_t intrp; 40663dec9fcdSqs 40673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_remove_intrs")); 40683dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 40693dec9fcdSqs if (!intrp->intr_registered) { 40703dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40713dec9fcdSqs "<== hxge_remove_intrs: interrupts not registered")); 40723dec9fcdSqs return; 40733dec9fcdSqs } 40743dec9fcdSqs 40753dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_remove_intrs:advanced")); 40763dec9fcdSqs 40773dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 40783dec9fcdSqs (void) ddi_intr_block_disable(intrp->htable, 40793dec9fcdSqs intrp->intr_added); 40803dec9fcdSqs } else { 40813dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 40823dec9fcdSqs (void) ddi_intr_disable(intrp->htable[i]); 40833dec9fcdSqs } 40843dec9fcdSqs } 40853dec9fcdSqs 40863dec9fcdSqs for (inum = 0; inum < intrp->intr_added; inum++) { 40873dec9fcdSqs if (intrp->htable[inum]) { 40883dec9fcdSqs (void) ddi_intr_remove_handler(intrp->htable[inum]); 40893dec9fcdSqs } 40903dec9fcdSqs } 40913dec9fcdSqs 40923dec9fcdSqs for (inum = 0; inum < intrp->msi_intx_cnt; inum++) { 40933dec9fcdSqs if (intrp->htable[inum]) { 40943dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 40953dec9fcdSqs "hxge_remove_intrs: ddi_intr_free inum %d " 40963dec9fcdSqs "msi_intx_cnt %d intr_added %d", 40973dec9fcdSqs inum, intrp->msi_intx_cnt, intrp->intr_added)); 40983dec9fcdSqs 40993dec9fcdSqs (void) ddi_intr_free(intrp->htable[inum]); 41003dec9fcdSqs } 41013dec9fcdSqs } 41023dec9fcdSqs 41033dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 41043dec9fcdSqs intrp->intr_registered = B_FALSE; 41053dec9fcdSqs intrp->intr_enabled = B_FALSE; 41063dec9fcdSqs intrp->msi_intx_cnt = 0; 41073dec9fcdSqs intrp->intr_added = 0; 41083dec9fcdSqs 41093dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 41103dec9fcdSqs 41113dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_remove_intrs")); 41123dec9fcdSqs } 41133dec9fcdSqs 41143dec9fcdSqs /*ARGSUSED*/ 41153dec9fcdSqs void 41163dec9fcdSqs hxge_intrs_enable(p_hxge_t hxgep) 41173dec9fcdSqs { 41183dec9fcdSqs p_hxge_intr_t intrp; 41193dec9fcdSqs int i; 41203dec9fcdSqs int status; 41213dec9fcdSqs 41223dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable")); 41233dec9fcdSqs 41243dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 41253dec9fcdSqs 41263dec9fcdSqs if (!intrp->intr_registered) { 41273dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "<== hxge_intrs_enable: " 41283dec9fcdSqs "interrupts are not registered")); 41293dec9fcdSqs return; 41303dec9fcdSqs } 41313dec9fcdSqs 41323dec9fcdSqs if (intrp->intr_enabled) { 41333dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 41343dec9fcdSqs "<== hxge_intrs_enable: already enabled")); 41353dec9fcdSqs return; 41363dec9fcdSqs } 41373dec9fcdSqs 41383dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 41393dec9fcdSqs status = ddi_intr_block_enable(intrp->htable, 41403dec9fcdSqs intrp->intr_added); 41413dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable " 41423dec9fcdSqs "block enable - status 0x%x total inums #%d\n", 41433dec9fcdSqs status, intrp->intr_added)); 41443dec9fcdSqs } else { 41453dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 41463dec9fcdSqs status = ddi_intr_enable(intrp->htable[i]); 41473dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable " 41483dec9fcdSqs "ddi_intr_enable:enable - status 0x%x " 41493dec9fcdSqs "total inums %d enable inum #%d\n", 41503dec9fcdSqs status, intrp->intr_added, i)); 41513dec9fcdSqs if (status == DDI_SUCCESS) { 41523dec9fcdSqs intrp->intr_enabled = B_TRUE; 41533dec9fcdSqs } 41543dec9fcdSqs } 41553dec9fcdSqs } 41563dec9fcdSqs 41573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_enable")); 41583dec9fcdSqs } 41593dec9fcdSqs 41603dec9fcdSqs /*ARGSUSED*/ 41613dec9fcdSqs static void 41623dec9fcdSqs hxge_intrs_disable(p_hxge_t hxgep) 41633dec9fcdSqs { 41643dec9fcdSqs p_hxge_intr_t intrp; 41653dec9fcdSqs int i; 41663dec9fcdSqs 41673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_disable")); 41683dec9fcdSqs 41693dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 41703dec9fcdSqs 41713dec9fcdSqs if (!intrp->intr_registered) { 41723dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_disable: " 41733dec9fcdSqs "interrupts are not registered")); 41743dec9fcdSqs return; 41753dec9fcdSqs } 41763dec9fcdSqs 41773dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 41783dec9fcdSqs (void) ddi_intr_block_disable(intrp->htable, 41793dec9fcdSqs intrp->intr_added); 41803dec9fcdSqs } else { 41813dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 41823dec9fcdSqs (void) ddi_intr_disable(intrp->htable[i]); 41833dec9fcdSqs } 41843dec9fcdSqs } 41853dec9fcdSqs 41863dec9fcdSqs intrp->intr_enabled = B_FALSE; 41873dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_disable")); 41883dec9fcdSqs } 41893dec9fcdSqs 41903dec9fcdSqs static hxge_status_t 41913dec9fcdSqs hxge_mac_register(p_hxge_t hxgep) 41923dec9fcdSqs { 41933dec9fcdSqs mac_register_t *macp; 41943dec9fcdSqs int status; 41953dec9fcdSqs 41963dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_mac_register")); 41973dec9fcdSqs 41983dec9fcdSqs if ((macp = mac_alloc(MAC_VERSION)) == NULL) 41993dec9fcdSqs return (HXGE_ERROR); 42003dec9fcdSqs 42013dec9fcdSqs macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 42023dec9fcdSqs macp->m_driver = hxgep; 42033dec9fcdSqs macp->m_dip = hxgep->dip; 42043dec9fcdSqs macp->m_src_addr = hxgep->ouraddr.ether_addr_octet; 42051ed83081SMichael Speer macp->m_callbacks = &hxge_m_callbacks; 42061ed83081SMichael Speer macp->m_min_sdu = 0; 42071ed83081SMichael Speer macp->m_max_sdu = hxgep->vmac.maxframesize - MTU_TO_FRAME_SIZE; 42081ed83081SMichael Speer macp->m_margin = VLAN_TAGSZ; 42091ed83081SMichael Speer macp->m_priv_props = hxge_priv_props; 42101ed83081SMichael Speer macp->m_priv_prop_count = HXGE_MAX_PRIV_PROPS; 42111ed83081SMichael Speer macp->m_v12n = MAC_VIRT_LEVEL1; 42123dec9fcdSqs 42133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 42143dec9fcdSqs "hxge_mac_register: ether addr is %x:%x:%x:%x:%x:%x", 42153dec9fcdSqs macp->m_src_addr[0], 42163dec9fcdSqs macp->m_src_addr[1], 42173dec9fcdSqs macp->m_src_addr[2], 42183dec9fcdSqs macp->m_src_addr[3], 42193dec9fcdSqs macp->m_src_addr[4], 42203dec9fcdSqs macp->m_src_addr[5])); 42213dec9fcdSqs 42223dec9fcdSqs status = mac_register(macp, &hxgep->mach); 42233dec9fcdSqs mac_free(macp); 42243dec9fcdSqs 42253dec9fcdSqs if (status != 0) { 42263dec9fcdSqs cmn_err(CE_WARN, 42273dec9fcdSqs "hxge_mac_register failed (status %d instance %d)", 42283dec9fcdSqs status, hxgep->instance); 42293dec9fcdSqs return (HXGE_ERROR); 42303dec9fcdSqs } 42313dec9fcdSqs 42323dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_mac_register success " 42333dec9fcdSqs "(instance %d)", hxgep->instance)); 42343dec9fcdSqs 42353dec9fcdSqs return (HXGE_OK); 42363dec9fcdSqs } 42373dec9fcdSqs 42383dec9fcdSqs static int 42393dec9fcdSqs hxge_init_common_dev(p_hxge_t hxgep) 42403dec9fcdSqs { 42413dec9fcdSqs p_hxge_hw_list_t hw_p; 42423dec9fcdSqs dev_info_t *p_dip; 42433dec9fcdSqs 42443dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==> hxge_init_common_dev")); 42453dec9fcdSqs 42463dec9fcdSqs p_dip = hxgep->p_dip; 42473dec9fcdSqs MUTEX_ENTER(&hxge_common_lock); 42483dec9fcdSqs 42493dec9fcdSqs /* 42503dec9fcdSqs * Loop through existing per Hydra hardware list. 42513dec9fcdSqs */ 42523dec9fcdSqs for (hw_p = hxge_hw_list; hw_p; hw_p = hw_p->next) { 42533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 42543dec9fcdSqs "==> hxge_init_common_dev: hw_p $%p parent dip $%p", 42553dec9fcdSqs hw_p, p_dip)); 42563dec9fcdSqs if (hw_p->parent_devp == p_dip) { 42573dec9fcdSqs hxgep->hxge_hw_p = hw_p; 42583dec9fcdSqs hw_p->ndevs++; 42593dec9fcdSqs hw_p->hxge_p = hxgep; 42603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 42613dec9fcdSqs "==> hxge_init_common_device: " 42623dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (found)", 42633dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 42643dec9fcdSqs break; 42653dec9fcdSqs } 42663dec9fcdSqs } 42673dec9fcdSqs 42683dec9fcdSqs if (hw_p == NULL) { 42693dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 42703dec9fcdSqs "==> hxge_init_common_dev: parent dip $%p (new)", p_dip)); 42713dec9fcdSqs hw_p = kmem_zalloc(sizeof (hxge_hw_list_t), KM_SLEEP); 42723dec9fcdSqs hw_p->parent_devp = p_dip; 42733dec9fcdSqs hw_p->magic = HXGE_MAGIC; 42743dec9fcdSqs hxgep->hxge_hw_p = hw_p; 42753dec9fcdSqs hw_p->ndevs++; 42763dec9fcdSqs hw_p->hxge_p = hxgep; 42773dec9fcdSqs hw_p->next = hxge_hw_list; 42783dec9fcdSqs 42793dec9fcdSqs MUTEX_INIT(&hw_p->hxge_cfg_lock, NULL, MUTEX_DRIVER, NULL); 42803dec9fcdSqs MUTEX_INIT(&hw_p->hxge_tcam_lock, NULL, MUTEX_DRIVER, NULL); 42813dec9fcdSqs MUTEX_INIT(&hw_p->hxge_vlan_lock, NULL, MUTEX_DRIVER, NULL); 42823dec9fcdSqs 42833dec9fcdSqs hxge_hw_list = hw_p; 42843dec9fcdSqs } 42853dec9fcdSqs MUTEX_EXIT(&hxge_common_lock); 42863dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 42873dec9fcdSqs "==> hxge_init_common_dev (hxge_hw_list) $%p", hxge_hw_list)); 42883dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<== hxge_init_common_dev")); 42893dec9fcdSqs 42903dec9fcdSqs return (HXGE_OK); 42913dec9fcdSqs } 42923dec9fcdSqs 42933dec9fcdSqs static void 42943dec9fcdSqs hxge_uninit_common_dev(p_hxge_t hxgep) 42953dec9fcdSqs { 42963dec9fcdSqs p_hxge_hw_list_t hw_p, h_hw_p; 42973dec9fcdSqs dev_info_t *p_dip; 42983dec9fcdSqs 42993dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==> hxge_uninit_common_dev")); 43003dec9fcdSqs if (hxgep->hxge_hw_p == NULL) { 43013dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43023dec9fcdSqs "<== hxge_uninit_common_dev (no common)")); 43033dec9fcdSqs return; 43043dec9fcdSqs } 43053dec9fcdSqs 43063dec9fcdSqs MUTEX_ENTER(&hxge_common_lock); 43073dec9fcdSqs h_hw_p = hxge_hw_list; 43083dec9fcdSqs for (hw_p = hxge_hw_list; hw_p; hw_p = hw_p->next) { 43093dec9fcdSqs p_dip = hw_p->parent_devp; 43103dec9fcdSqs if (hxgep->hxge_hw_p == hw_p && p_dip == hxgep->p_dip && 43113dec9fcdSqs hxgep->hxge_hw_p->magic == HXGE_MAGIC && 43123dec9fcdSqs hw_p->magic == HXGE_MAGIC) { 43133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43143dec9fcdSqs "==> hxge_uninit_common_dev: " 43153dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (found)", 43163dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43173dec9fcdSqs 43183dec9fcdSqs hxgep->hxge_hw_p = NULL; 43193dec9fcdSqs if (hw_p->ndevs) { 43203dec9fcdSqs hw_p->ndevs--; 43213dec9fcdSqs } 43223dec9fcdSqs hw_p->hxge_p = NULL; 43233dec9fcdSqs if (!hw_p->ndevs) { 43243dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_vlan_lock); 43253dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_tcam_lock); 43263dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_cfg_lock); 43273dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43283dec9fcdSqs "==> hxge_uninit_common_dev: " 43293dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (last)", 43303dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43313dec9fcdSqs 43323dec9fcdSqs if (hw_p == hxge_hw_list) { 43333dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43343dec9fcdSqs "==> hxge_uninit_common_dev:" 43353dec9fcdSqs "remove head " 43363dec9fcdSqs "hw_p $%p parent dip $%p " 43373dec9fcdSqs "ndevs %d (head)", 43383dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43393dec9fcdSqs hxge_hw_list = hw_p->next; 43403dec9fcdSqs } else { 43413dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43423dec9fcdSqs "==> hxge_uninit_common_dev:" 43433dec9fcdSqs "remove middle " 43443dec9fcdSqs "hw_p $%p parent dip $%p " 43453dec9fcdSqs "ndevs %d (middle)", 43463dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43473dec9fcdSqs h_hw_p->next = hw_p->next; 43483dec9fcdSqs } 43493dec9fcdSqs 43503dec9fcdSqs KMEM_FREE(hw_p, sizeof (hxge_hw_list_t)); 43513dec9fcdSqs } 43523dec9fcdSqs break; 43533dec9fcdSqs } else { 43543dec9fcdSqs h_hw_p = hw_p; 43553dec9fcdSqs } 43563dec9fcdSqs } 43573dec9fcdSqs 43583dec9fcdSqs MUTEX_EXIT(&hxge_common_lock); 43593dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43603dec9fcdSqs "==> hxge_uninit_common_dev (hxge_hw_list) $%p", hxge_hw_list)); 43613dec9fcdSqs 43623dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<= hxge_uninit_common_dev")); 43633dec9fcdSqs } 4364a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 43651c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_ENTRIES 32 43661c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_WAIT_COUNT 10 43671c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_PARITY_CHECK_COUNT 30 43681c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 4369a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static void 4370a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_poll(void *arg) 4371a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 4372a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_t hxgep = (p_hxge_t)arg; 4373a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hpi_handle_t handle; 4374a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States cip_link_stat_t link_stat; 4375a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_timeout *to = &hxgep->timeout; 4376a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4377a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States handle = HXGE_DEV_HPI_HANDLE(hxgep); 4378a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(handle, CIP_LINK_STAT, &link_stat.value); 4379a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4380e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (to->report_link_status || 4381e5d97391SQiyan Sun - Sun Microsystems - San Diego United States (to->link_status != link_stat.bits.xpcs0_link_up)) { 4382a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States to->link_status = link_stat.bits.xpcs0_link_up; 4383e5d97391SQiyan Sun - Sun Microsystems - San Diego United States to->report_link_status = B_FALSE; 4384a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4385a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (link_stat.bits.xpcs0_link_up) { 4386e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_UP); 4387a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 4388e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_DOWN); 4389a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4390a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4391a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 439257c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->msix_count++ >= HXGE_MSIX_PARITY_CHECK_COUNT) { 439357c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_count = 0; 439457c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_index++; 439557c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->msix_index >= HXGE_MSIX_ENTRIES) 439657c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_index = 0; 439757c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_check_1entry_msix_table(hxgep, hxgep->msix_index); 439857c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 439957c5371aSQiyan Sun - Sun Microsystems - San Diego United States 4400a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Restart the link status timer to check the link status */ 4401a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&to->lock); 4402a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States to->id = timeout(hxge_link_poll, arg, to->ticks); 4403a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&to->lock); 4404a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4405e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 4406e5d97391SQiyan Sun - Sun Microsystems - San Diego United States static void 4407e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(p_hxge_t hxgep, link_state_t state) 4408e5d97391SQiyan Sun - Sun Microsystems - San Diego United States { 4409e5d97391SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp = (p_hxge_stats_t)hxgep->statsp; 4410e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 4411e5d97391SQiyan Sun - Sun Microsystems - San Diego United States mac_link_update(hxgep->mach, state); 4412e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (state == LINK_STATE_UP) { 4413e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_speed = 10000; 4414e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_duplex = 2; 4415e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_up = 1; 4416e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } else { 4417e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_speed = 0; 4418e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_duplex = 0; 4419e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_up = 0; 4420e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 4421e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 44221c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 44231c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States static void 44241c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States hxge_msix_init(p_hxge_t hxgep) 44251c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States { 442657c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data0; 442757c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data1; 442857c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data2; 44291c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States int i; 443057c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry0; 443157c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry1; 443257c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry2; 443357c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry3; 44341c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 443557c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Change to use MSIx bar instead of indirect access */ 44361c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States for (i = 0; i < HXGE_MSIX_ENTRIES; i++) { 443757c5371aSQiyan Sun - Sun Microsystems - San Diego United States data0 = 0xffffffff - i; 443857c5371aSQiyan Sun - Sun Microsystems - San Diego United States data1 = 0xffffffff - i - 1; 443957c5371aSQiyan Sun - Sun Microsystems - San Diego United States data2 = 0xffffffff - i - 2; 444057c5371aSQiyan Sun - Sun Microsystems - San Diego United States 444157c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16, data0); 444257c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16 + 4, data1); 444357c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16 + 8, data2); 44441c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 44451c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 444657c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Initialize ram data out buffer. */ 44471c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States for (i = 0; i < HXGE_MSIX_ENTRIES; i++) { 444857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16, &msix_entry0); 444957c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 4, &msix_entry1); 445057c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 8, &msix_entry2); 445157c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 12, &msix_entry3); 445257c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 445357c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 44541c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 445557c5371aSQiyan Sun - Sun Microsystems - San Diego United States static void 445657c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_store_msix_table(p_hxge_t hxgep) 445757c5371aSQiyan Sun - Sun Microsystems - San Diego United States { 445857c5371aSQiyan Sun - Sun Microsystems - San Diego United States int i; 445957c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry0; 446057c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry1; 446157c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry2; 44621c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 446357c5371aSQiyan Sun - Sun Microsystems - San Diego United States for (i = 0; i < HXGE_MSIX_ENTRIES; i++) { 446457c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16, &msix_entry0); 446557c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 4, 446657c5371aSQiyan Sun - Sun Microsystems - San Diego United States &msix_entry1); 446757c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 8, 446857c5371aSQiyan Sun - Sun Microsystems - San Diego United States &msix_entry2); 44691c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 447057c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table[i][0] = msix_entry0; 447157c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table[i][1] = msix_entry1; 447257c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table[i][2] = msix_entry2; 44731c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 44741c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 44751c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 447657c5371aSQiyan Sun - Sun Microsystems - San Diego United States static void 447757c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_check_1entry_msix_table(p_hxge_t hxgep, int i) 44781c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States { 447957c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry0; 448057c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry1; 448157c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry2; 44821c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_peu_sys_stats_t statsp; 44831c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 44841c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States statsp = (p_hxge_peu_sys_stats_t)&hxgep->statsp->peu_sys_stats; 44851c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 448657c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16, &msix_entry0); 448757c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 4, &msix_entry1); 448857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 8, &msix_entry2); 44891c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 449057c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table_check[i][0] = msix_entry0; 449157c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table_check[i][1] = msix_entry1; 449257c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxgep->msix_table_check[i][2] = msix_entry2; 449357c5371aSQiyan Sun - Sun Microsystems - San Diego United States 449457c5371aSQiyan Sun - Sun Microsystems - San Diego United States if ((hxgep->msix_table[i][0] != hxgep->msix_table_check[i][0]) || 449557c5371aSQiyan Sun - Sun Microsystems - San Diego United States (hxgep->msix_table[i][1] != hxgep->msix_table_check[i][1]) || 449657c5371aSQiyan Sun - Sun Microsystems - San Diego United States (hxgep->msix_table[i][2] != hxgep->msix_table_check[i][2])) { 449757c5371aSQiyan Sun - Sun Microsystems - San Diego United States statsp->eic_msix_parerr++; 449857c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (statsp->eic_msix_parerr == 1) { 449957c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 450057c5371aSQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_check_1entry_msix_table: " 450157c5371aSQiyan Sun - Sun Microsystems - San Diego United States "eic_msix_parerr at index: %d", i)); 450257c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_FM_REPORT_ERROR(hxgep, NULL, 450357c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_FM_EREPORT_PEU_ERR); 45041c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 45051c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 45061c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 45071c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 450857c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* 450957c5371aSQiyan Sun - Sun Microsystems - San Diego United States * The following function is to support 451057c5371aSQiyan Sun - Sun Microsystems - San Diego United States * PSARC/2007/453 MSI-X interrupt limit override. 451157c5371aSQiyan Sun - Sun Microsystems - San Diego United States */ 451257c5371aSQiyan Sun - Sun Microsystems - San Diego United States static int 451357c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_create_msi_property(p_hxge_t hxgep) 45141c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States { 451557c5371aSQiyan Sun - Sun Microsystems - San Diego United States int nmsi; 451657c5371aSQiyan Sun - Sun Microsystems - San Diego United States extern int ncpus; 451757c5371aSQiyan Sun - Sun Microsystems - San Diego United States 451857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==>hxge_create_msi_property")); 451957c5371aSQiyan Sun - Sun Microsystems - San Diego United States 452057c5371aSQiyan Sun - Sun Microsystems - San Diego United States (void) ddi_prop_create(DDI_DEV_T_NONE, hxgep->dip, 452157c5371aSQiyan Sun - Sun Microsystems - San Diego United States DDI_PROP_CANSLEEP, "#msix-request", NULL, 0); 452257c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* 452357c5371aSQiyan Sun - Sun Microsystems - San Diego United States * The maximum MSI-X requested will be 8. 452457c5371aSQiyan Sun - Sun Microsystems - San Diego United States * If the # of CPUs is less than 8, we will reqeust 452557c5371aSQiyan Sun - Sun Microsystems - San Diego United States * # MSI-X based on the # of CPUs. 452657c5371aSQiyan Sun - Sun Microsystems - San Diego United States */ 452757c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (ncpus >= HXGE_MSIX_REQUEST_10G) { 452857c5371aSQiyan Sun - Sun Microsystems - San Diego United States nmsi = HXGE_MSIX_REQUEST_10G; 452957c5371aSQiyan Sun - Sun Microsystems - San Diego United States } else { 453057c5371aSQiyan Sun - Sun Microsystems - San Diego United States nmsi = ncpus; 45311c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 45321c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 453357c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, 453457c5371aSQiyan Sun - Sun Microsystems - San Diego United States "==>hxge_create_msi_property(10G): exists 0x%x (nmsi %d)", 453557c5371aSQiyan Sun - Sun Microsystems - San Diego United States ddi_prop_exists(DDI_DEV_T_NONE, hxgep->dip, 453657c5371aSQiyan Sun - Sun Microsystems - San Diego United States DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 453757c5371aSQiyan Sun - Sun Microsystems - San Diego United States 453857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<==hxge_create_msi_property")); 453957c5371aSQiyan Sun - Sun Microsystems - San Diego United States return (nmsi); 45401c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 4541