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 /* 22*0dc2366fSVenugopal Iyer * Copyright 2010 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 */ 371ed83081SMichael Speer uint32_t hxge_msi_enable = 2; 383dec9fcdSqs 393dec9fcdSqs /* 403dec9fcdSqs * Globals: tunable parameters (/etc/system or adb) 413dec9fcdSqs * 423dec9fcdSqs */ 433dec9fcdSqs uint32_t hxge_rbr_size = HXGE_RBR_RBB_DEFAULT; 443dec9fcdSqs uint32_t hxge_rbr_spare_size = 0; 453dec9fcdSqs uint32_t hxge_rcr_size = HXGE_RCR_DEFAULT; 463dec9fcdSqs uint32_t hxge_tx_ring_size = HXGE_TX_RING_DEFAULT; 473dec9fcdSqs uint32_t hxge_bcopy_thresh = TX_BCOPY_MAX; 483dec9fcdSqs uint32_t hxge_dvma_thresh = TX_FASTDVMA_MIN; 493dec9fcdSqs uint32_t hxge_dma_stream_thresh = TX_STREAM_MIN; 50a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint32_t hxge_jumbo_frame_size = MAX_FRAME_SIZE; 513dec9fcdSqs 523dec9fcdSqs static hxge_os_mutex_t hxgedebuglock; 533dec9fcdSqs static int hxge_debug_init = 0; 543dec9fcdSqs 553dec9fcdSqs /* 563dec9fcdSqs * Debugging flags: 573dec9fcdSqs * hxge_no_tx_lb : transmit load balancing 583dec9fcdSqs * hxge_tx_lb_policy: 0 - TCP/UDP port (default) 593dec9fcdSqs * 1 - From the Stack 603dec9fcdSqs * 2 - Destination IP Address 613dec9fcdSqs */ 623dec9fcdSqs uint32_t hxge_no_tx_lb = 0; 633dec9fcdSqs uint32_t hxge_tx_lb_policy = HXGE_TX_LB_TCPUDP; 643dec9fcdSqs 653dec9fcdSqs /* 663dec9fcdSqs * Tunables to manage the receive buffer blocks. 673dec9fcdSqs * 683dec9fcdSqs * hxge_rx_threshold_hi: copy all buffers. 693dec9fcdSqs * hxge_rx_bcopy_size_type: receive buffer block size type. 703dec9fcdSqs * hxge_rx_threshold_lo: copy only up to tunable block size type. 713dec9fcdSqs */ 72f043ebedSMichael Speer #if defined(__sparc) 73f043ebedSMichael Speer hxge_rxbuf_threshold_t hxge_rx_threshold_hi = HXGE_RX_COPY_6; 74f043ebedSMichael Speer hxge_rxbuf_threshold_t hxge_rx_threshold_lo = HXGE_RX_COPY_4; 75f043ebedSMichael Speer #else 7657c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_rxbuf_threshold_t hxge_rx_threshold_hi = HXGE_RX_COPY_NONE; 7757c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_rxbuf_threshold_t hxge_rx_threshold_lo = HXGE_RX_COPY_NONE; 78f043ebedSMichael Speer #endif 79f043ebedSMichael Speer hxge_rxbuf_type_t hxge_rx_buf_size_type = RCR_PKTBUFSZ_0; 803dec9fcdSqs 813dec9fcdSqs rtrace_t hpi_rtracebuf; 823dec9fcdSqs 833dec9fcdSqs /* 843dec9fcdSqs * Function Prototypes 853dec9fcdSqs */ 863dec9fcdSqs static int hxge_attach(dev_info_t *, ddi_attach_cmd_t); 873dec9fcdSqs static int hxge_detach(dev_info_t *, ddi_detach_cmd_t); 883dec9fcdSqs static void hxge_unattach(p_hxge_t); 893dec9fcdSqs 903dec9fcdSqs static hxge_status_t hxge_setup_system_dma_pages(p_hxge_t); 913dec9fcdSqs 923dec9fcdSqs static hxge_status_t hxge_setup_mutexes(p_hxge_t); 933dec9fcdSqs static void hxge_destroy_mutexes(p_hxge_t); 943dec9fcdSqs 953dec9fcdSqs static hxge_status_t hxge_map_regs(p_hxge_t hxgep); 963dec9fcdSqs static void hxge_unmap_regs(p_hxge_t hxgep); 973dec9fcdSqs 98f043ebedSMichael Speer static hxge_status_t hxge_add_intrs(p_hxge_t hxgep); 993dec9fcdSqs static void hxge_remove_intrs(p_hxge_t hxgep); 1003dec9fcdSqs static hxge_status_t hxge_add_intrs_adv(p_hxge_t hxgep); 1013dec9fcdSqs static hxge_status_t hxge_add_intrs_adv_type(p_hxge_t, uint32_t); 1023dec9fcdSqs static hxge_status_t hxge_add_intrs_adv_type_fix(p_hxge_t, uint32_t); 103f043ebedSMichael Speer static void hxge_intrs_enable(p_hxge_t hxgep); 1043dec9fcdSqs static void hxge_intrs_disable(p_hxge_t hxgep); 1053dec9fcdSqs static void hxge_suspend(p_hxge_t); 1063dec9fcdSqs static hxge_status_t hxge_resume(p_hxge_t); 107f043ebedSMichael Speer static hxge_status_t hxge_setup_dev(p_hxge_t); 1083dec9fcdSqs static void hxge_destroy_dev(p_hxge_t); 109f043ebedSMichael Speer static hxge_status_t hxge_alloc_mem_pool(p_hxge_t); 1103dec9fcdSqs static void hxge_free_mem_pool(p_hxge_t); 1113dec9fcdSqs static hxge_status_t hxge_alloc_rx_mem_pool(p_hxge_t); 1123dec9fcdSqs static void hxge_free_rx_mem_pool(p_hxge_t); 1133dec9fcdSqs static hxge_status_t hxge_alloc_tx_mem_pool(p_hxge_t); 1143dec9fcdSqs static void hxge_free_tx_mem_pool(p_hxge_t); 1153dec9fcdSqs static hxge_status_t hxge_dma_mem_alloc(p_hxge_t, dma_method_t, 1163dec9fcdSqs struct ddi_dma_attr *, size_t, ddi_device_acc_attr_t *, uint_t, 1173dec9fcdSqs p_hxge_dma_common_t); 1183dec9fcdSqs static void hxge_dma_mem_free(p_hxge_dma_common_t); 1193dec9fcdSqs static hxge_status_t hxge_alloc_rx_buf_dma(p_hxge_t, uint16_t, 1203dec9fcdSqs p_hxge_dma_common_t *, size_t, size_t, uint32_t *); 1213dec9fcdSqs static void hxge_free_rx_buf_dma(p_hxge_t, p_hxge_dma_common_t, uint32_t); 1223dec9fcdSqs static hxge_status_t hxge_alloc_rx_cntl_dma(p_hxge_t, uint16_t, 1238ad8db65SMichael Speer p_hxge_dma_common_t *, struct ddi_dma_attr *, size_t); 1243dec9fcdSqs static void hxge_free_rx_cntl_dma(p_hxge_t, p_hxge_dma_common_t); 1253dec9fcdSqs static hxge_status_t hxge_alloc_tx_buf_dma(p_hxge_t, uint16_t, 1263dec9fcdSqs p_hxge_dma_common_t *, size_t, size_t, uint32_t *); 1273dec9fcdSqs static void hxge_free_tx_buf_dma(p_hxge_t, p_hxge_dma_common_t, uint32_t); 1283dec9fcdSqs static hxge_status_t hxge_alloc_tx_cntl_dma(p_hxge_t, uint16_t, 1293dec9fcdSqs p_hxge_dma_common_t *, size_t); 1303dec9fcdSqs static void hxge_free_tx_cntl_dma(p_hxge_t, p_hxge_dma_common_t); 1313dec9fcdSqs static int hxge_init_common_dev(p_hxge_t); 1323dec9fcdSqs static void hxge_uninit_common_dev(p_hxge_t); 1333dec9fcdSqs 1343dec9fcdSqs /* 1353dec9fcdSqs * The next declarations are for the GLDv3 interface. 1363dec9fcdSqs */ 1373dec9fcdSqs static int hxge_m_start(void *); 1383dec9fcdSqs static void hxge_m_stop(void *); 1393dec9fcdSqs static int hxge_m_multicst(void *, boolean_t, const uint8_t *); 1403dec9fcdSqs static int hxge_m_promisc(void *, boolean_t); 1413dec9fcdSqs static void hxge_m_ioctl(void *, queue_t *, mblk_t *); 1423dec9fcdSqs static hxge_status_t hxge_mac_register(p_hxge_t hxgep); 1433dec9fcdSqs 1443dec9fcdSqs static boolean_t hxge_m_getcapab(void *, mac_capab_t, void *); 145a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static boolean_t hxge_param_locked(mac_prop_id_t pr_num); 146a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 147a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val); 148a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 149a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, void *pr_val); 150*0dc2366fSVenugopal Iyer static void hxge_m_propinfo(void *barg, const char *pr_name, 151*0dc2366fSVenugopal Iyer mac_prop_id_t pr_num, mac_prop_info_handle_t mph); 152a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_set_priv_prop(p_hxge_t hxgep, const char *pr_name, 153a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val); 154a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int hxge_get_priv_prop(p_hxge_t hxgep, const char *pr_name, 155*0dc2366fSVenugopal Iyer uint_t pr_valsize, void *pr_val); 156a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_link_poll(void *arg); 157e5d97391SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_link_update(p_hxge_t hxge, link_state_t state); 1581c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States static void hxge_msix_init(p_hxge_t hxgep); 159a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 160*0dc2366fSVenugopal Iyer char *hxge_priv_props[] = { 161*0dc2366fSVenugopal Iyer "_rxdma_intr_time", 162*0dc2366fSVenugopal Iyer "_rxdma_intr_pkts", 163*0dc2366fSVenugopal Iyer "_class_opt_ipv4_tcp", 164*0dc2366fSVenugopal Iyer "_class_opt_ipv4_udp", 165*0dc2366fSVenugopal Iyer "_class_opt_ipv4_ah", 166*0dc2366fSVenugopal Iyer "_class_opt_ipv4_sctp", 167*0dc2366fSVenugopal Iyer "_class_opt_ipv6_tcp", 168*0dc2366fSVenugopal Iyer "_class_opt_ipv6_udp", 169*0dc2366fSVenugopal Iyer "_class_opt_ipv6_ah", 170*0dc2366fSVenugopal Iyer "_class_opt_ipv6_sctp", 171*0dc2366fSVenugopal Iyer NULL 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 \ 181*0dc2366fSVenugopal Iyer (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO) 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, 194*0dc2366fSVenugopal Iyer NULL, 1953dec9fcdSqs hxge_m_ioctl, 196a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_getcapab, 197a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States NULL, 198a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States NULL, 199a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_setprop, 200*0dc2366fSVenugopal Iyer hxge_m_getprop, 201*0dc2366fSVenugopal Iyer hxge_m_propinfo 2023dec9fcdSqs }; 2033dec9fcdSqs 20457c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* PSARC/2007/453 MSI-X interrupt limit override. */ 20557c5371aSQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_REQUEST_10G 8 20657c5371aSQiyan Sun - Sun Microsystems - San Diego United States static int hxge_create_msi_property(p_hxge_t); 20757c5371aSQiyan Sun - Sun Microsystems - San Diego United States 2083dec9fcdSqs /* Enable debug messages as necessary. */ 209a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint64_t hxge_debug_level = 0; 2103dec9fcdSqs 2113dec9fcdSqs /* 2123dec9fcdSqs * This list contains the instance structures for the Hydra 2133dec9fcdSqs * devices present in the system. The lock exists to guarantee 2143dec9fcdSqs * mutually exclusive access to the list. 2153dec9fcdSqs */ 2163dec9fcdSqs void *hxge_list = NULL; 2173dec9fcdSqs void *hxge_hw_list = NULL; 2183dec9fcdSqs hxge_os_mutex_t hxge_common_lock; 2193dec9fcdSqs 2203dec9fcdSqs extern uint64_t hpi_debug_level; 2213dec9fcdSqs 2223dec9fcdSqs extern hxge_status_t hxge_ldgv_init(); 2233dec9fcdSqs extern hxge_status_t hxge_ldgv_uninit(); 2243dec9fcdSqs extern hxge_status_t hxge_intr_ldgv_init(); 2253dec9fcdSqs extern void hxge_fm_init(p_hxge_t hxgep, ddi_device_acc_attr_t *reg_attr, 226f043ebedSMichael Speer ddi_device_acc_attr_t *desc_attr, ddi_dma_attr_t *dma_attr); 2273dec9fcdSqs extern void hxge_fm_fini(p_hxge_t hxgep); 2283dec9fcdSqs 2293dec9fcdSqs /* 2303dec9fcdSqs * Count used to maintain the number of buffers being used 2313dec9fcdSqs * by Hydra instances and loaned up to the upper layers. 2323dec9fcdSqs */ 2333dec9fcdSqs uint32_t hxge_mblks_pending = 0; 2343dec9fcdSqs 2353dec9fcdSqs /* 2363dec9fcdSqs * Device register access attributes for PIO. 2373dec9fcdSqs */ 2383dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_reg_acc_attr = { 239f043ebedSMichael Speer DDI_DEVICE_ATTR_V0, 2403dec9fcdSqs DDI_STRUCTURE_LE_ACC, 2413dec9fcdSqs DDI_STRICTORDER_ACC, 2423dec9fcdSqs }; 2433dec9fcdSqs 2443dec9fcdSqs /* 2453dec9fcdSqs * Device descriptor access attributes for DMA. 2463dec9fcdSqs */ 2473dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_desc_dma_acc_attr = { 2483dec9fcdSqs DDI_DEVICE_ATTR_V0, 2493dec9fcdSqs DDI_STRUCTURE_LE_ACC, 2503dec9fcdSqs DDI_STRICTORDER_ACC 2513dec9fcdSqs }; 2523dec9fcdSqs 2533dec9fcdSqs /* 2543dec9fcdSqs * Device buffer access attributes for DMA. 2553dec9fcdSqs */ 2563dec9fcdSqs static ddi_device_acc_attr_t hxge_dev_buf_dma_acc_attr = { 2573dec9fcdSqs DDI_DEVICE_ATTR_V0, 2583dec9fcdSqs DDI_STRUCTURE_BE_ACC, 2593dec9fcdSqs DDI_STRICTORDER_ACC 2603dec9fcdSqs }; 2613dec9fcdSqs 2628ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_rcr_desc_dma_attr = { 2638ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 2648ad8db65SMichael Speer 0, /* low address */ 2658ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 2668ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 2678ad8db65SMichael Speer 0x80000, /* alignment */ 2688ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 2698ad8db65SMichael Speer 0x1, /* minimum transfer size */ 2708ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 2718ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 2728ad8db65SMichael Speer 1, /* scatter/gather list length */ 2738ad8db65SMichael Speer (unsigned int)1, /* granularity */ 2748ad8db65SMichael Speer 0 /* attribute flags */ 2758ad8db65SMichael Speer }; 2768ad8db65SMichael Speer 2778ad8db65SMichael Speer ddi_dma_attr_t hxge_tx_desc_dma_attr = { 2783dec9fcdSqs DMA_ATTR_V0, /* version number. */ 2793dec9fcdSqs 0, /* low address */ 2803dec9fcdSqs 0xffffffffffffffff, /* high address */ 2813dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 2823dec9fcdSqs 0x100000, /* alignment */ 2833dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 2843dec9fcdSqs 0x1, /* minimum transfer size */ 2853dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 2863dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 2873dec9fcdSqs 1, /* scatter/gather list length */ 2883dec9fcdSqs (unsigned int)1, /* granularity */ 2893dec9fcdSqs 0 /* attribute flags */ 2903dec9fcdSqs }; 2913dec9fcdSqs 2928ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_rbr_desc_dma_attr = { 2938ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 2948ad8db65SMichael Speer 0, /* low address */ 2958ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 2968ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 2978ad8db65SMichael Speer 0x40000, /* alignment */ 2988ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 2998ad8db65SMichael Speer 0x1, /* minimum transfer size */ 3008ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 3018ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 3028ad8db65SMichael Speer 1, /* scatter/gather list length */ 3038ad8db65SMichael Speer (unsigned int)1, /* granularity */ 3048ad8db65SMichael Speer 0 /* attribute flags */ 3058ad8db65SMichael Speer }; 3068ad8db65SMichael Speer 3078ad8db65SMichael Speer ddi_dma_attr_t hxge_rx_mbox_dma_attr = { 3088ad8db65SMichael Speer DMA_ATTR_V0, /* version number. */ 3098ad8db65SMichael Speer 0, /* low address */ 3108ad8db65SMichael Speer 0xffffffffffffffff, /* high address */ 3118ad8db65SMichael Speer 0xffffffffffffffff, /* address counter max */ 3128ad8db65SMichael Speer #if defined(_BIG_ENDIAN) 3138ad8db65SMichael Speer 0x2000, /* alignment */ 3148ad8db65SMichael Speer #else 3158ad8db65SMichael Speer 0x1000, /* alignment */ 3168ad8db65SMichael Speer #endif 3178ad8db65SMichael Speer 0xfc00fc, /* dlim_burstsizes */ 3188ad8db65SMichael Speer 0x1, /* minimum transfer size */ 3198ad8db65SMichael Speer 0xffffffffffffffff, /* maximum transfer size */ 3208ad8db65SMichael Speer 0xffffffffffffffff, /* maximum segment size */ 3218ad8db65SMichael Speer 5, /* scatter/gather list length */ 3228ad8db65SMichael Speer (unsigned int)1, /* granularity */ 3238ad8db65SMichael Speer 0 /* attribute flags */ 3248ad8db65SMichael Speer }; 3258ad8db65SMichael Speer 3263dec9fcdSqs ddi_dma_attr_t hxge_tx_dma_attr = { 3273dec9fcdSqs DMA_ATTR_V0, /* version number. */ 3283dec9fcdSqs 0, /* low address */ 3293dec9fcdSqs 0xffffffffffffffff, /* high address */ 3303dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 3313dec9fcdSqs #if defined(_BIG_ENDIAN) 3323dec9fcdSqs 0x2000, /* alignment */ 3333dec9fcdSqs #else 3343dec9fcdSqs 0x1000, /* alignment */ 3353dec9fcdSqs #endif 3363dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 3373dec9fcdSqs 0x1, /* minimum transfer size */ 3383dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 3393dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 3403dec9fcdSqs 5, /* scatter/gather list length */ 3413dec9fcdSqs (unsigned int)1, /* granularity */ 3423dec9fcdSqs 0 /* attribute flags */ 3433dec9fcdSqs }; 3443dec9fcdSqs 3453dec9fcdSqs ddi_dma_attr_t hxge_rx_dma_attr = { 3463dec9fcdSqs DMA_ATTR_V0, /* version number. */ 3473dec9fcdSqs 0, /* low address */ 3483dec9fcdSqs 0xffffffffffffffff, /* high address */ 3493dec9fcdSqs 0xffffffffffffffff, /* address counter max */ 3503dec9fcdSqs 0x10000, /* alignment */ 3513dec9fcdSqs 0xfc00fc, /* dlim_burstsizes */ 3523dec9fcdSqs 0x1, /* minimum transfer size */ 3533dec9fcdSqs 0xffffffffffffffff, /* maximum transfer size */ 3543dec9fcdSqs 0xffffffffffffffff, /* maximum segment size */ 3553dec9fcdSqs 1, /* scatter/gather list length */ 3563dec9fcdSqs (unsigned int)1, /* granularity */ 3573dec9fcdSqs DDI_DMA_RELAXED_ORDERING /* attribute flags */ 3583dec9fcdSqs }; 3593dec9fcdSqs 3603dec9fcdSqs ddi_dma_lim_t hxge_dma_limits = { 3613dec9fcdSqs (uint_t)0, /* dlim_addr_lo */ 3623dec9fcdSqs (uint_t)0xffffffff, /* dlim_addr_hi */ 3633dec9fcdSqs (uint_t)0xffffffff, /* dlim_cntr_max */ 3643dec9fcdSqs (uint_t)0xfc00fc, /* dlim_burstsizes for 32 and 64 bit xfers */ 3653dec9fcdSqs 0x1, /* dlim_minxfer */ 3663dec9fcdSqs 1024 /* dlim_speed */ 3673dec9fcdSqs }; 3683dec9fcdSqs 3693dec9fcdSqs dma_method_t hxge_force_dma = DVMA; 3703dec9fcdSqs 3713dec9fcdSqs /* 3723dec9fcdSqs * dma chunk sizes. 3733dec9fcdSqs * 3743dec9fcdSqs * Try to allocate the largest possible size 3753dec9fcdSqs * so that fewer number of dma chunks would be managed 3763dec9fcdSqs */ 3773dec9fcdSqs size_t alloc_sizes[] = { 3783dec9fcdSqs 0x1000, 0x2000, 0x4000, 0x8000, 3793dec9fcdSqs 0x10000, 0x20000, 0x40000, 0x80000, 3803dec9fcdSqs 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000 3813dec9fcdSqs }; 3823dec9fcdSqs 3833dec9fcdSqs /* 3843dec9fcdSqs * Translate "dev_t" to a pointer to the associated "dev_info_t". 3853dec9fcdSqs */ 3863dec9fcdSqs static int 3873dec9fcdSqs hxge_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 3883dec9fcdSqs { 3893dec9fcdSqs p_hxge_t hxgep = NULL; 3903dec9fcdSqs int instance; 3913dec9fcdSqs int status = DDI_SUCCESS; 3921ed83081SMichael Speer int i; 3933dec9fcdSqs 3943dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_attach")); 3953dec9fcdSqs 3963dec9fcdSqs /* 3973dec9fcdSqs * Get the device instance since we'll need to setup or retrieve a soft 3983dec9fcdSqs * state for this instance. 3993dec9fcdSqs */ 4003dec9fcdSqs instance = ddi_get_instance(dip); 4013dec9fcdSqs 4023dec9fcdSqs switch (cmd) { 4033dec9fcdSqs case DDI_ATTACH: 4043dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_ATTACH")); 4053dec9fcdSqs break; 4063dec9fcdSqs 4073dec9fcdSqs case DDI_RESUME: 4083dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_RESUME")); 4093dec9fcdSqs hxgep = (p_hxge_t)ddi_get_soft_state(hxge_list, instance); 4103dec9fcdSqs if (hxgep == NULL) { 4113dec9fcdSqs status = DDI_FAILURE; 4123dec9fcdSqs break; 4133dec9fcdSqs } 4143dec9fcdSqs if (hxgep->dip != dip) { 4153dec9fcdSqs status = DDI_FAILURE; 4163dec9fcdSqs break; 4173dec9fcdSqs } 4183dec9fcdSqs if (hxgep->suspended == DDI_PM_SUSPEND) { 4193dec9fcdSqs status = ddi_dev_is_needed(hxgep->dip, 0, 1); 4203dec9fcdSqs } else { 4213dec9fcdSqs (void) hxge_resume(hxgep); 4223dec9fcdSqs } 4233dec9fcdSqs goto hxge_attach_exit; 4243dec9fcdSqs 4253dec9fcdSqs case DDI_PM_RESUME: 4263dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_PM_RESUME")); 4273dec9fcdSqs hxgep = (p_hxge_t)ddi_get_soft_state(hxge_list, instance); 4283dec9fcdSqs if (hxgep == NULL) { 4293dec9fcdSqs status = DDI_FAILURE; 4303dec9fcdSqs break; 4313dec9fcdSqs } 4323dec9fcdSqs if (hxgep->dip != dip) { 4333dec9fcdSqs status = DDI_FAILURE; 4343dec9fcdSqs break; 4353dec9fcdSqs } 4363dec9fcdSqs (void) hxge_resume(hxgep); 4373dec9fcdSqs goto hxge_attach_exit; 4383dec9fcdSqs 4393dec9fcdSqs default: 4403dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing unknown")); 4413dec9fcdSqs status = DDI_FAILURE; 4423dec9fcdSqs goto hxge_attach_exit; 4433dec9fcdSqs } 4443dec9fcdSqs 4453dec9fcdSqs if (ddi_soft_state_zalloc(hxge_list, instance) == DDI_FAILURE) { 4463dec9fcdSqs status = DDI_FAILURE; 4473dec9fcdSqs HXGE_ERROR_MSG((hxgep, DDI_CTL, 4483dec9fcdSqs "ddi_soft_state_zalloc failed")); 4493dec9fcdSqs goto hxge_attach_exit; 4503dec9fcdSqs } 4513dec9fcdSqs 4523dec9fcdSqs hxgep = ddi_get_soft_state(hxge_list, instance); 4533dec9fcdSqs if (hxgep == NULL) { 4543dec9fcdSqs status = HXGE_ERROR; 4553dec9fcdSqs HXGE_ERROR_MSG((hxgep, DDI_CTL, 4563dec9fcdSqs "ddi_get_soft_state failed")); 4573dec9fcdSqs goto hxge_attach_fail2; 4583dec9fcdSqs } 4593dec9fcdSqs 4603dec9fcdSqs hxgep->drv_state = 0; 4613dec9fcdSqs hxgep->dip = dip; 4623dec9fcdSqs hxgep->instance = instance; 4633dec9fcdSqs hxgep->p_dip = ddi_get_parent(dip); 4643dec9fcdSqs hxgep->hxge_debug_level = hxge_debug_level; 4653dec9fcdSqs hpi_debug_level = hxge_debug_level; 4663dec9fcdSqs 4671ed83081SMichael Speer /* 4681ed83081SMichael Speer * Initialize MMAC struture. 4691ed83081SMichael Speer */ 4701ed83081SMichael Speer (void) hxge_pfc_num_macs_get(hxgep, &hxgep->mmac.total); 4711ed83081SMichael Speer hxgep->mmac.available = hxgep->mmac.total; 4721ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 4731ed83081SMichael Speer hxgep->mmac.addrs[i].set = B_FALSE; 4741ed83081SMichael Speer hxgep->mmac.addrs[i].primary = B_FALSE; 4751ed83081SMichael Speer } 4761ed83081SMichael Speer 477f043ebedSMichael Speer hxge_fm_init(hxgep, &hxge_dev_reg_acc_attr, &hxge_dev_desc_dma_acc_attr, 478f043ebedSMichael Speer &hxge_rx_dma_attr); 4793dec9fcdSqs 4803dec9fcdSqs status = hxge_map_regs(hxgep); 4813dec9fcdSqs if (status != HXGE_OK) { 4823dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "hxge_map_regs failed")); 4833dec9fcdSqs goto hxge_attach_fail3; 4843dec9fcdSqs } 4853dec9fcdSqs 4863dec9fcdSqs status = hxge_init_common_dev(hxgep); 4873dec9fcdSqs if (status != HXGE_OK) { 4883dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 4893dec9fcdSqs "hxge_init_common_dev failed")); 4903dec9fcdSqs goto hxge_attach_fail4; 4913dec9fcdSqs } 4923dec9fcdSqs 4933dec9fcdSqs /* 4943dec9fcdSqs * Setup the Ndd parameters for this instance. 4953dec9fcdSqs */ 4963dec9fcdSqs hxge_init_param(hxgep); 4973dec9fcdSqs 4983dec9fcdSqs /* 4993dec9fcdSqs * Setup Register Tracing Buffer. 5003dec9fcdSqs */ 5013dec9fcdSqs hpi_rtrace_buf_init((rtrace_t *)&hpi_rtracebuf); 5023dec9fcdSqs 5033dec9fcdSqs /* init stats ptr */ 5043dec9fcdSqs hxge_init_statsp(hxgep); 5053dec9fcdSqs 506a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States status = hxge_setup_mutexes(hxgep); 507a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (status != HXGE_OK) { 508a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DDI_CTL, "set mutex failed")); 509a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States goto hxge_attach_fail; 510a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 511a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 51223b519b2SMichael Speer /* Scrub the MSI-X memory */ 51323b519b2SMichael Speer hxge_msix_init(hxgep); 51423b519b2SMichael Speer 5153dec9fcdSqs status = hxge_get_config_properties(hxgep); 5163dec9fcdSqs if (status != HXGE_OK) { 5173dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "get_hw create failed")); 5183dec9fcdSqs goto hxge_attach_fail; 5193dec9fcdSqs } 5203dec9fcdSqs 5213dec9fcdSqs /* 5223dec9fcdSqs * Setup the Kstats for the driver. 5233dec9fcdSqs */ 5243dec9fcdSqs hxge_setup_kstats(hxgep); 5253dec9fcdSqs hxge_setup_param(hxgep); 5263dec9fcdSqs 5273dec9fcdSqs status = hxge_setup_system_dma_pages(hxgep); 5283dec9fcdSqs if (status != HXGE_OK) { 5293dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "set dma page failed")); 5303dec9fcdSqs goto hxge_attach_fail; 5313dec9fcdSqs } 5323dec9fcdSqs 5333dec9fcdSqs hxge_hw_id_init(hxgep); 5343dec9fcdSqs hxge_hw_init_niu_common(hxgep); 5353dec9fcdSqs 5363dec9fcdSqs status = hxge_setup_dev(hxgep); 5373dec9fcdSqs if (status != DDI_SUCCESS) { 5383dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "set dev failed")); 5393dec9fcdSqs goto hxge_attach_fail; 5403dec9fcdSqs } 5413dec9fcdSqs 5423dec9fcdSqs status = hxge_add_intrs(hxgep); 5433dec9fcdSqs if (status != DDI_SUCCESS) { 5443dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "add_intr failed")); 5453dec9fcdSqs goto hxge_attach_fail; 5463dec9fcdSqs } 5473dec9fcdSqs 5483dec9fcdSqs /* 5493dec9fcdSqs * Enable interrupts. 5503dec9fcdSqs */ 5513dec9fcdSqs hxge_intrs_enable(hxgep); 5523dec9fcdSqs 5533dec9fcdSqs if ((status = hxge_mac_register(hxgep)) != HXGE_OK) { 5543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 5553dec9fcdSqs "unable to register to mac layer (%d)", status)); 5563dec9fcdSqs goto hxge_attach_fail; 5573dec9fcdSqs } 558a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States mac_link_update(hxgep->mach, LINK_STATE_UNKNOWN); 5593dec9fcdSqs 5603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "registered to mac (instance %d)", 5613dec9fcdSqs instance)); 5623dec9fcdSqs 5633dec9fcdSqs goto hxge_attach_exit; 5643dec9fcdSqs 5653dec9fcdSqs hxge_attach_fail: 5663dec9fcdSqs hxge_unattach(hxgep); 5673dec9fcdSqs goto hxge_attach_fail1; 5683dec9fcdSqs 5693dec9fcdSqs hxge_attach_fail5: 5703dec9fcdSqs /* 5713dec9fcdSqs * Tear down the ndd parameters setup. 5723dec9fcdSqs */ 5733dec9fcdSqs hxge_destroy_param(hxgep); 5743dec9fcdSqs 5753dec9fcdSqs /* 5763dec9fcdSqs * Tear down the kstat setup. 5773dec9fcdSqs */ 5783dec9fcdSqs hxge_destroy_kstats(hxgep); 5793dec9fcdSqs 5803dec9fcdSqs hxge_attach_fail4: 5813dec9fcdSqs if (hxgep->hxge_hw_p) { 5823dec9fcdSqs hxge_uninit_common_dev(hxgep); 5833dec9fcdSqs hxgep->hxge_hw_p = NULL; 5843dec9fcdSqs } 5853dec9fcdSqs hxge_attach_fail3: 5863dec9fcdSqs /* 5873dec9fcdSqs * Unmap the register setup. 5883dec9fcdSqs */ 5893dec9fcdSqs hxge_unmap_regs(hxgep); 5903dec9fcdSqs 5913dec9fcdSqs hxge_fm_fini(hxgep); 5923dec9fcdSqs 5933dec9fcdSqs hxge_attach_fail2: 5943dec9fcdSqs ddi_soft_state_free(hxge_list, hxgep->instance); 5953dec9fcdSqs 5963dec9fcdSqs hxge_attach_fail1: 5973dec9fcdSqs if (status != HXGE_OK) 5983dec9fcdSqs status = (HXGE_ERROR | HXGE_DDI_FAILED); 5993dec9fcdSqs hxgep = NULL; 6003dec9fcdSqs 6013dec9fcdSqs hxge_attach_exit: 6023dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_attach status = 0x%08x", 6033dec9fcdSqs status)); 6043dec9fcdSqs 6053dec9fcdSqs return (status); 6063dec9fcdSqs } 6073dec9fcdSqs 6083dec9fcdSqs static int 6093dec9fcdSqs hxge_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 6103dec9fcdSqs { 6113dec9fcdSqs int status = DDI_SUCCESS; 6123dec9fcdSqs int instance; 6133dec9fcdSqs p_hxge_t hxgep = NULL; 6143dec9fcdSqs 6153dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_detach")); 6163dec9fcdSqs instance = ddi_get_instance(dip); 6173dec9fcdSqs hxgep = ddi_get_soft_state(hxge_list, instance); 6183dec9fcdSqs if (hxgep == NULL) { 6193dec9fcdSqs status = DDI_FAILURE; 6203dec9fcdSqs goto hxge_detach_exit; 6213dec9fcdSqs } 6223dec9fcdSqs 6233dec9fcdSqs switch (cmd) { 6243dec9fcdSqs case DDI_DETACH: 6253dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_DETACH")); 6263dec9fcdSqs break; 6273dec9fcdSqs 6283dec9fcdSqs case DDI_PM_SUSPEND: 6293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_PM_SUSPEND")); 6303dec9fcdSqs hxgep->suspended = DDI_PM_SUSPEND; 6313dec9fcdSqs hxge_suspend(hxgep); 6323dec9fcdSqs break; 6333dec9fcdSqs 6343dec9fcdSqs case DDI_SUSPEND: 6353dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "doing DDI_SUSPEND")); 6363dec9fcdSqs if (hxgep->suspended != DDI_PM_SUSPEND) { 6373dec9fcdSqs hxgep->suspended = DDI_SUSPEND; 6383dec9fcdSqs hxge_suspend(hxgep); 6393dec9fcdSqs } 6403dec9fcdSqs break; 6413dec9fcdSqs 6423dec9fcdSqs default: 6433dec9fcdSqs status = DDI_FAILURE; 6443dec9fcdSqs break; 6453dec9fcdSqs } 6463dec9fcdSqs 6473dec9fcdSqs if (cmd != DDI_DETACH) 6483dec9fcdSqs goto hxge_detach_exit; 6493dec9fcdSqs 6503dec9fcdSqs /* 6513dec9fcdSqs * Stop the xcvr polling. 6523dec9fcdSqs */ 6533dec9fcdSqs hxgep->suspended = cmd; 6543dec9fcdSqs 6553dec9fcdSqs if (hxgep->mach && (status = mac_unregister(hxgep->mach)) != 0) { 6563dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 6573dec9fcdSqs "<== hxge_detach status = 0x%08X", status)); 6583dec9fcdSqs return (DDI_FAILURE); 6593dec9fcdSqs } 6603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 6613dec9fcdSqs "<== hxge_detach (mac_unregister) status = 0x%08X", status)); 6623dec9fcdSqs 6633dec9fcdSqs hxge_unattach(hxgep); 6643dec9fcdSqs hxgep = NULL; 6653dec9fcdSqs 6663dec9fcdSqs hxge_detach_exit: 6673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_detach status = 0x%08X", 6683dec9fcdSqs status)); 6693dec9fcdSqs 6703dec9fcdSqs return (status); 6713dec9fcdSqs } 6723dec9fcdSqs 6733dec9fcdSqs static void 6743dec9fcdSqs hxge_unattach(p_hxge_t hxgep) 6753dec9fcdSqs { 6763dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_unattach")); 6773dec9fcdSqs 6783dec9fcdSqs if (hxgep == NULL || hxgep->dev_regs == NULL) { 6793dec9fcdSqs return; 6803dec9fcdSqs } 6813dec9fcdSqs 6823dec9fcdSqs if (hxgep->hxge_hw_p) { 6833dec9fcdSqs hxge_uninit_common_dev(hxgep); 6843dec9fcdSqs hxgep->hxge_hw_p = NULL; 6853dec9fcdSqs } 6863dec9fcdSqs 6873dec9fcdSqs if (hxgep->hxge_timerid) { 6883dec9fcdSqs hxge_stop_timer(hxgep, hxgep->hxge_timerid); 6893dec9fcdSqs hxgep->hxge_timerid = 0; 6903dec9fcdSqs } 6913dec9fcdSqs 692f043ebedSMichael Speer /* Stop interrupts. */ 693f043ebedSMichael Speer hxge_intrs_disable(hxgep); 694f043ebedSMichael Speer 6953dec9fcdSqs /* Stop any further interrupts. */ 6963dec9fcdSqs hxge_remove_intrs(hxgep); 6973dec9fcdSqs 6983dec9fcdSqs /* Stop the device and free resources. */ 6993dec9fcdSqs hxge_destroy_dev(hxgep); 7003dec9fcdSqs 7013dec9fcdSqs /* Tear down the ndd parameters setup. */ 7023dec9fcdSqs hxge_destroy_param(hxgep); 7033dec9fcdSqs 7043dec9fcdSqs /* Tear down the kstat setup. */ 7053dec9fcdSqs hxge_destroy_kstats(hxgep); 7063dec9fcdSqs 7073dec9fcdSqs /* 7083dec9fcdSqs * Remove the list of ndd parameters which were setup during attach. 7093dec9fcdSqs */ 7103dec9fcdSqs if (hxgep->dip) { 7113dec9fcdSqs HXGE_DEBUG_MSG((hxgep, OBP_CTL, 7123dec9fcdSqs " hxge_unattach: remove all properties")); 7133dec9fcdSqs (void) ddi_prop_remove_all(hxgep->dip); 7143dec9fcdSqs } 7153dec9fcdSqs 716fe930412Sqs /* 717fe930412Sqs * Reset RDC, TDC, PFC, and VMAC blocks from PEU to clear any 718fe930412Sqs * previous state before unmapping the registers. 719fe930412Sqs */ 720fe930412Sqs HXGE_REG_WR32(hxgep->hpi_handle, BLOCK_RESET, 0x0000001E); 721fe930412Sqs HXGE_DELAY(1000); 722fe930412Sqs 7233dec9fcdSqs /* 7243dec9fcdSqs * Unmap the register setup. 7253dec9fcdSqs */ 7263dec9fcdSqs hxge_unmap_regs(hxgep); 7273dec9fcdSqs 7283dec9fcdSqs hxge_fm_fini(hxgep); 7293dec9fcdSqs 730a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Destroy all mutexes. */ 731a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_destroy_mutexes(hxgep); 732a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 7333dec9fcdSqs /* 7343dec9fcdSqs * Free the soft state data structures allocated with this instance. 7353dec9fcdSqs */ 7363dec9fcdSqs ddi_soft_state_free(hxge_list, hxgep->instance); 7373dec9fcdSqs 7383dec9fcdSqs HXGE_DEBUG_MSG((NULL, DDI_CTL, "<== hxge_unattach")); 7393dec9fcdSqs } 7403dec9fcdSqs 7413dec9fcdSqs static hxge_status_t 7423dec9fcdSqs hxge_map_regs(p_hxge_t hxgep) 7433dec9fcdSqs { 7443dec9fcdSqs int ddi_status = DDI_SUCCESS; 7453dec9fcdSqs p_dev_regs_t dev_regs; 7463dec9fcdSqs 7473dec9fcdSqs #ifdef HXGE_DEBUG 7483dec9fcdSqs char *sysname; 7493dec9fcdSqs #endif 7503dec9fcdSqs 7513dec9fcdSqs off_t regsize; 7523dec9fcdSqs hxge_status_t status = HXGE_OK; 7533dec9fcdSqs int nregs; 7543dec9fcdSqs 7553dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_map_regs")); 7563dec9fcdSqs 7573dec9fcdSqs if (ddi_dev_nregs(hxgep->dip, &nregs) != DDI_SUCCESS) 7583dec9fcdSqs return (HXGE_ERROR); 7593dec9fcdSqs 7603dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "hxge_map_regs: nregs: %d", nregs)); 7613dec9fcdSqs 7623dec9fcdSqs hxgep->dev_regs = NULL; 7633dec9fcdSqs dev_regs = KMEM_ZALLOC(sizeof (dev_regs_t), KM_SLEEP); 7643dec9fcdSqs dev_regs->hxge_regh = NULL; 7653dec9fcdSqs dev_regs->hxge_pciregh = NULL; 7663dec9fcdSqs dev_regs->hxge_msix_regh = NULL; 7673dec9fcdSqs 7683dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 0, ®size); 7693dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7703dec9fcdSqs "hxge_map_regs: pci config size 0x%x", regsize)); 7713dec9fcdSqs 7723dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 0, 7733dec9fcdSqs (caddr_t *)&(dev_regs->hxge_pciregp), 0, 0, 7743dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_pciregh); 7753dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 7763dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 7773dec9fcdSqs "ddi_map_regs, hxge bus config regs failed")); 7783dec9fcdSqs goto hxge_map_regs_fail0; 7793dec9fcdSqs } 7803dec9fcdSqs 7813dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7823dec9fcdSqs "hxge_map_reg: PCI config addr 0x%0llx handle 0x%0llx", 7833dec9fcdSqs dev_regs->hxge_pciregp, 7843dec9fcdSqs dev_regs->hxge_pciregh)); 7853dec9fcdSqs 7863dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 1, ®size); 7873dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 7883dec9fcdSqs "hxge_map_regs: pio size 0x%x", regsize)); 7893dec9fcdSqs 7903dec9fcdSqs /* set up the device mapped register */ 7913dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 1, 7923dec9fcdSqs (caddr_t *)&(dev_regs->hxge_regp), 0, 0, 7933dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_regh); 7943dec9fcdSqs 7953dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 7963dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 7973dec9fcdSqs "ddi_map_regs for Hydra global reg failed")); 7983dec9fcdSqs goto hxge_map_regs_fail1; 7993dec9fcdSqs } 8003dec9fcdSqs 8013dec9fcdSqs /* set up the msi/msi-x mapped register */ 8023dec9fcdSqs (void) ddi_dev_regsize(hxgep->dip, 2, ®size); 8033dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8043dec9fcdSqs "hxge_map_regs: msix size 0x%x", regsize)); 8053dec9fcdSqs 8063dec9fcdSqs ddi_status = ddi_regs_map_setup(hxgep->dip, 2, 8073dec9fcdSqs (caddr_t *)&(dev_regs->hxge_msix_regp), 0, 0, 8083dec9fcdSqs &hxge_dev_reg_acc_attr, &dev_regs->hxge_msix_regh); 8093dec9fcdSqs 8103dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 8113dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 8123dec9fcdSqs "ddi_map_regs for msi reg failed")); 8133dec9fcdSqs goto hxge_map_regs_fail2; 8143dec9fcdSqs } 8153dec9fcdSqs 8163dec9fcdSqs hxgep->dev_regs = dev_regs; 8173dec9fcdSqs 8183dec9fcdSqs HPI_PCI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_pciregh); 8193dec9fcdSqs HPI_PCI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_pciregp); 8203dec9fcdSqs HPI_MSI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_msix_regh); 8213dec9fcdSqs HPI_MSI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_msix_regp); 8223dec9fcdSqs 8233dec9fcdSqs HPI_ACC_HANDLE_SET(hxgep, dev_regs->hxge_regh); 8243dec9fcdSqs HPI_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_regp); 8253dec9fcdSqs 8263dec9fcdSqs HPI_REG_ACC_HANDLE_SET(hxgep, dev_regs->hxge_regh); 8273dec9fcdSqs HPI_REG_ADD_HANDLE_SET(hxgep, (hpi_reg_ptr_t)dev_regs->hxge_regp); 8283dec9fcdSqs 8293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "hxge_map_reg: hardware addr 0x%0llx " 8303dec9fcdSqs " handle 0x%0llx", dev_regs->hxge_regp, dev_regs->hxge_regh)); 8313dec9fcdSqs 8323dec9fcdSqs goto hxge_map_regs_exit; 8333dec9fcdSqs 8343dec9fcdSqs hxge_map_regs_fail3: 8353dec9fcdSqs if (dev_regs->hxge_msix_regh) { 8363dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_msix_regh); 8373dec9fcdSqs } 8383dec9fcdSqs 8393dec9fcdSqs hxge_map_regs_fail2: 8403dec9fcdSqs if (dev_regs->hxge_regh) { 8413dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_regh); 8423dec9fcdSqs } 8433dec9fcdSqs 8443dec9fcdSqs hxge_map_regs_fail1: 8453dec9fcdSqs if (dev_regs->hxge_pciregh) { 8463dec9fcdSqs ddi_regs_map_free(&dev_regs->hxge_pciregh); 8473dec9fcdSqs } 8483dec9fcdSqs 8493dec9fcdSqs hxge_map_regs_fail0: 8503dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "Freeing register set memory")); 8513dec9fcdSqs kmem_free(dev_regs, sizeof (dev_regs_t)); 8523dec9fcdSqs 8533dec9fcdSqs hxge_map_regs_exit: 8543dec9fcdSqs if (ddi_status != DDI_SUCCESS) 8553dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 8563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_map_regs")); 8573dec9fcdSqs return (status); 8583dec9fcdSqs } 8593dec9fcdSqs 8603dec9fcdSqs static void 8613dec9fcdSqs hxge_unmap_regs(p_hxge_t hxgep) 8623dec9fcdSqs { 8633dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_unmap_regs")); 8643dec9fcdSqs if (hxgep->dev_regs) { 8653dec9fcdSqs if (hxgep->dev_regs->hxge_pciregh) { 8663dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8673dec9fcdSqs "==> hxge_unmap_regs: bus")); 8683dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_pciregh); 8693dec9fcdSqs hxgep->dev_regs->hxge_pciregh = NULL; 8703dec9fcdSqs } 8713dec9fcdSqs 8723dec9fcdSqs if (hxgep->dev_regs->hxge_regh) { 8733dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8743dec9fcdSqs "==> hxge_unmap_regs: device registers")); 8753dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_regh); 8763dec9fcdSqs hxgep->dev_regs->hxge_regh = NULL; 8773dec9fcdSqs } 8783dec9fcdSqs 8793dec9fcdSqs if (hxgep->dev_regs->hxge_msix_regh) { 8803dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 8813dec9fcdSqs "==> hxge_unmap_regs: device interrupts")); 8823dec9fcdSqs ddi_regs_map_free(&hxgep->dev_regs->hxge_msix_regh); 8833dec9fcdSqs hxgep->dev_regs->hxge_msix_regh = NULL; 8843dec9fcdSqs } 8853dec9fcdSqs kmem_free(hxgep->dev_regs, sizeof (dev_regs_t)); 8863dec9fcdSqs hxgep->dev_regs = NULL; 8873dec9fcdSqs } 8883dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_unmap_regs")); 8893dec9fcdSqs } 8903dec9fcdSqs 8913dec9fcdSqs static hxge_status_t 8923dec9fcdSqs hxge_setup_mutexes(p_hxge_t hxgep) 8933dec9fcdSqs { 8943dec9fcdSqs int ddi_status = DDI_SUCCESS; 8953dec9fcdSqs hxge_status_t status = HXGE_OK; 8963dec9fcdSqs 8973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_mutexes")); 8983dec9fcdSqs 8993dec9fcdSqs /* 9003dec9fcdSqs * Get the interrupt cookie so the mutexes can be Initialised. 9013dec9fcdSqs */ 9023dec9fcdSqs ddi_status = ddi_get_iblock_cookie(hxgep->dip, 0, 9033dec9fcdSqs &hxgep->interrupt_cookie); 9043dec9fcdSqs 9053dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 9063dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 9073dec9fcdSqs "<== hxge_setup_mutexes: failed 0x%x", ddi_status)); 9083dec9fcdSqs goto hxge_setup_mutexes_exit; 9093dec9fcdSqs } 9103dec9fcdSqs 9113dec9fcdSqs /* 9123dec9fcdSqs * Initialize mutex's for this device. 9133dec9fcdSqs */ 9143dec9fcdSqs MUTEX_INIT(hxgep->genlock, NULL, 9153dec9fcdSqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9166ffca240SMichael Speer MUTEX_INIT(&hxgep->vmac_lock, NULL, 9176ffca240SMichael Speer MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9183dec9fcdSqs MUTEX_INIT(&hxgep->ouraddr_lock, NULL, 9193dec9fcdSqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9203dec9fcdSqs RW_INIT(&hxgep->filter_lock, NULL, 9213dec9fcdSqs RW_DRIVER, (void *) hxgep->interrupt_cookie); 922fe930412Sqs MUTEX_INIT(&hxgep->pio_lock, NULL, 923fe930412Sqs MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 924a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_INIT(&hxgep->timeout.lock, NULL, 925a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_DRIVER, (void *) hxgep->interrupt_cookie); 9263dec9fcdSqs 9273dec9fcdSqs hxge_setup_mutexes_exit: 9283dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 9293dec9fcdSqs "<== hxge_setup_mutexes status = %x", status)); 9303dec9fcdSqs 9313dec9fcdSqs if (ddi_status != DDI_SUCCESS) 9323dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 9333dec9fcdSqs 9343dec9fcdSqs return (status); 9353dec9fcdSqs } 9363dec9fcdSqs 9373dec9fcdSqs static void 9383dec9fcdSqs hxge_destroy_mutexes(p_hxge_t hxgep) 9393dec9fcdSqs { 9403dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_mutexes")); 9413dec9fcdSqs RW_DESTROY(&hxgep->filter_lock); 9426ffca240SMichael Speer MUTEX_DESTROY(&hxgep->vmac_lock); 9433dec9fcdSqs MUTEX_DESTROY(&hxgep->ouraddr_lock); 9443dec9fcdSqs MUTEX_DESTROY(hxgep->genlock); 945fe930412Sqs MUTEX_DESTROY(&hxgep->pio_lock); 946a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_DESTROY(&hxgep->timeout.lock); 9473dec9fcdSqs 9483dec9fcdSqs if (hxge_debug_init == 1) { 9493dec9fcdSqs MUTEX_DESTROY(&hxgedebuglock); 9503dec9fcdSqs hxge_debug_init = 0; 9513dec9fcdSqs } 9523dec9fcdSqs 9533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_mutexes")); 9543dec9fcdSqs } 9553dec9fcdSqs 9563dec9fcdSqs hxge_status_t 9573dec9fcdSqs hxge_init(p_hxge_t hxgep) 9583dec9fcdSqs { 9593dec9fcdSqs hxge_status_t status = HXGE_OK; 9603dec9fcdSqs 9613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, STR_CTL, "==> hxge_init")); 9623dec9fcdSqs 9633dec9fcdSqs if (hxgep->drv_state & STATE_HW_INITIALIZED) { 9643dec9fcdSqs return (status); 9653dec9fcdSqs } 9663dec9fcdSqs 9673dec9fcdSqs /* 9683dec9fcdSqs * Allocate system memory for the receive/transmit buffer blocks and 9693dec9fcdSqs * receive/transmit descriptor rings. 9703dec9fcdSqs */ 9713dec9fcdSqs status = hxge_alloc_mem_pool(hxgep); 9723dec9fcdSqs if (status != HXGE_OK) { 9733dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "alloc mem failed\n")); 9743dec9fcdSqs goto hxge_init_fail1; 9753dec9fcdSqs } 9763dec9fcdSqs 9773dec9fcdSqs /* 9783dec9fcdSqs * Initialize and enable TXDMA channels. 9793dec9fcdSqs */ 9803dec9fcdSqs status = hxge_init_txdma_channels(hxgep); 9813dec9fcdSqs if (status != HXGE_OK) { 9823dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init txdma failed\n")); 9833dec9fcdSqs goto hxge_init_fail3; 9843dec9fcdSqs } 9853dec9fcdSqs 9863dec9fcdSqs /* 9873dec9fcdSqs * Initialize and enable RXDMA channels. 9883dec9fcdSqs */ 9893dec9fcdSqs status = hxge_init_rxdma_channels(hxgep); 9903dec9fcdSqs if (status != HXGE_OK) { 9913dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init rxdma failed\n")); 9923dec9fcdSqs goto hxge_init_fail4; 9933dec9fcdSqs } 9943dec9fcdSqs 9953dec9fcdSqs /* 9963dec9fcdSqs * Initialize TCAM 9973dec9fcdSqs */ 9983dec9fcdSqs status = hxge_classify_init(hxgep); 9993dec9fcdSqs if (status != HXGE_OK) { 10003dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init classify failed\n")); 10013dec9fcdSqs goto hxge_init_fail5; 10023dec9fcdSqs } 10033dec9fcdSqs 10043dec9fcdSqs /* 10053dec9fcdSqs * Initialize the VMAC block. 10063dec9fcdSqs */ 10073dec9fcdSqs status = hxge_vmac_init(hxgep); 10083dec9fcdSqs if (status != HXGE_OK) { 10093dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "init MAC failed\n")); 10103dec9fcdSqs goto hxge_init_fail5; 10113dec9fcdSqs } 10123dec9fcdSqs 10133dec9fcdSqs /* Bringup - this may be unnecessary when PXE and FCODE available */ 10143dec9fcdSqs status = hxge_pfc_set_default_mac_addr(hxgep); 10153dec9fcdSqs if (status != HXGE_OK) { 10163dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 10173dec9fcdSqs "Default Address Failure\n")); 10183dec9fcdSqs goto hxge_init_fail5; 10193dec9fcdSqs } 10203dec9fcdSqs 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 12403dec9fcdSqs hxgep->suspended = 0; 12413dec9fcdSqs 12421c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States /* 12431c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * Resume the link status timer after hxge_intrs_enable to avoid 12441c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States * accessing MSIX table simultaneously. 12451c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States */ 1246a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 1247a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = timeout(hxge_link_poll, (void *)hxgep, 1248a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks); 1249a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 1250a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 12513dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 12523dec9fcdSqs "<== hxge_resume status = 0x%x", status)); 12533dec9fcdSqs 12543dec9fcdSqs return (status); 12553dec9fcdSqs } 12563dec9fcdSqs 1257f043ebedSMichael Speer static hxge_status_t 12583dec9fcdSqs hxge_setup_dev(p_hxge_t hxgep) 12593dec9fcdSqs { 12603dec9fcdSqs hxge_status_t status = HXGE_OK; 12613dec9fcdSqs 12623dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_dev")); 12633dec9fcdSqs 12643dec9fcdSqs status = hxge_link_init(hxgep); 12653dec9fcdSqs if (fm_check_acc_handle(hxgep->dev_regs->hxge_regh) != DDI_FM_OK) { 12663dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 12673dec9fcdSqs "Bad register acc handle")); 12683dec9fcdSqs status = HXGE_ERROR; 12693dec9fcdSqs } 12703dec9fcdSqs 12713dec9fcdSqs if (status != HXGE_OK) { 12723dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, 12733dec9fcdSqs " hxge_setup_dev status (link init 0x%08x)", status)); 12743dec9fcdSqs goto hxge_setup_dev_exit; 12753dec9fcdSqs } 12763dec9fcdSqs 12773dec9fcdSqs hxge_setup_dev_exit: 12783dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 12793dec9fcdSqs "<== hxge_setup_dev status = 0x%08x", status)); 12803dec9fcdSqs 12813dec9fcdSqs return (status); 12823dec9fcdSqs } 12833dec9fcdSqs 12843dec9fcdSqs static void 12853dec9fcdSqs hxge_destroy_dev(p_hxge_t hxgep) 12863dec9fcdSqs { 12873dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_dev")); 12883dec9fcdSqs 12893dec9fcdSqs (void) hxge_hw_stop(hxgep); 12903dec9fcdSqs 12913dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_dev")); 12923dec9fcdSqs } 12933dec9fcdSqs 12943dec9fcdSqs static hxge_status_t 12953dec9fcdSqs hxge_setup_system_dma_pages(p_hxge_t hxgep) 12963dec9fcdSqs { 12973dec9fcdSqs int ddi_status = DDI_SUCCESS; 12983dec9fcdSqs uint_t count; 12993dec9fcdSqs ddi_dma_cookie_t cookie; 13003dec9fcdSqs uint_t iommu_pagesize; 13013dec9fcdSqs hxge_status_t status = HXGE_OK; 13023dec9fcdSqs 13033dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_setup_system_dma_pages")); 13043dec9fcdSqs 13053dec9fcdSqs hxgep->sys_page_sz = ddi_ptob(hxgep->dip, (ulong_t)1); 13063dec9fcdSqs iommu_pagesize = dvma_pagesize(hxgep->dip); 13073dec9fcdSqs 13083dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13093dec9fcdSqs " hxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 13103dec9fcdSqs " default_block_size %d iommu_pagesize %d", 13113dec9fcdSqs hxgep->sys_page_sz, ddi_ptob(hxgep->dip, (ulong_t)1), 13123dec9fcdSqs hxgep->rx_default_block_size, iommu_pagesize)); 13133dec9fcdSqs 13143dec9fcdSqs if (iommu_pagesize != 0) { 13153dec9fcdSqs if (hxgep->sys_page_sz == iommu_pagesize) { 13163dec9fcdSqs /* Hydra support up to 8K pages */ 13173dec9fcdSqs if (iommu_pagesize > 0x2000) 13183dec9fcdSqs hxgep->sys_page_sz = 0x2000; 13193dec9fcdSqs } else { 13203dec9fcdSqs if (hxgep->sys_page_sz > iommu_pagesize) 13213dec9fcdSqs hxgep->sys_page_sz = iommu_pagesize; 13223dec9fcdSqs } 13233dec9fcdSqs } 13243dec9fcdSqs 13253dec9fcdSqs hxgep->sys_page_mask = ~(hxgep->sys_page_sz - 1); 13263dec9fcdSqs 13273dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13283dec9fcdSqs "==> hxge_setup_system_dma_pages: page %d (ddi_ptob %d) " 13293dec9fcdSqs "default_block_size %d page mask %d", 13303dec9fcdSqs hxgep->sys_page_sz, ddi_ptob(hxgep->dip, (ulong_t)1), 13313dec9fcdSqs hxgep->rx_default_block_size, hxgep->sys_page_mask)); 13323dec9fcdSqs 13333dec9fcdSqs switch (hxgep->sys_page_sz) { 13343dec9fcdSqs default: 13353dec9fcdSqs hxgep->sys_page_sz = 0x1000; 13363dec9fcdSqs hxgep->sys_page_mask = ~(hxgep->sys_page_sz - 1); 13373dec9fcdSqs hxgep->rx_default_block_size = 0x1000; 13383dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_4K; 13393dec9fcdSqs break; 13403dec9fcdSqs case 0x1000: 13413dec9fcdSqs hxgep->rx_default_block_size = 0x1000; 13423dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_4K; 13433dec9fcdSqs break; 13443dec9fcdSqs case 0x2000: 13453dec9fcdSqs hxgep->rx_default_block_size = 0x2000; 13463dec9fcdSqs hxgep->rx_bksize_code = RBR_BKSIZE_8K; 13473dec9fcdSqs break; 13483dec9fcdSqs } 13493dec9fcdSqs 13503dec9fcdSqs hxge_rx_dma_attr.dma_attr_align = hxgep->sys_page_sz; 13513dec9fcdSqs hxge_tx_dma_attr.dma_attr_align = hxgep->sys_page_sz; 13523dec9fcdSqs 13533dec9fcdSqs /* 13543dec9fcdSqs * Get the system DMA burst size. 13553dec9fcdSqs */ 13563dec9fcdSqs ddi_status = ddi_dma_alloc_handle(hxgep->dip, &hxge_tx_dma_attr, 13573dec9fcdSqs DDI_DMA_DONTWAIT, 0, &hxgep->dmasparehandle); 13583dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 13593dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 13603dec9fcdSqs "ddi_dma_alloc_handle: failed status 0x%x", ddi_status)); 13613dec9fcdSqs goto hxge_get_soft_properties_exit; 13623dec9fcdSqs } 13633dec9fcdSqs 13643dec9fcdSqs ddi_status = ddi_dma_addr_bind_handle(hxgep->dmasparehandle, NULL, 13653dec9fcdSqs (caddr_t)hxgep->dmasparehandle, sizeof (hxgep->dmasparehandle), 13663dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, 13673dec9fcdSqs &cookie, &count); 13683dec9fcdSqs if (ddi_status != DDI_DMA_MAPPED) { 13693dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 13703dec9fcdSqs "Binding spare handle to find system burstsize failed.")); 13713dec9fcdSqs ddi_status = DDI_FAILURE; 13723dec9fcdSqs goto hxge_get_soft_properties_fail1; 13733dec9fcdSqs } 13743dec9fcdSqs 13753dec9fcdSqs hxgep->sys_burst_sz = ddi_dma_burstsizes(hxgep->dmasparehandle); 13763dec9fcdSqs (void) ddi_dma_unbind_handle(hxgep->dmasparehandle); 13773dec9fcdSqs 13783dec9fcdSqs hxge_get_soft_properties_fail1: 13793dec9fcdSqs ddi_dma_free_handle(&hxgep->dmasparehandle); 13803dec9fcdSqs 13813dec9fcdSqs hxge_get_soft_properties_exit: 13823dec9fcdSqs 13833dec9fcdSqs if (ddi_status != DDI_SUCCESS) 13843dec9fcdSqs status |= (HXGE_ERROR | HXGE_DDI_FAILED); 13853dec9fcdSqs 13863dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 13873dec9fcdSqs "<== hxge_setup_system_dma_pages status = 0x%08x", status)); 13883dec9fcdSqs 13893dec9fcdSqs return (status); 13903dec9fcdSqs } 13913dec9fcdSqs 1392f043ebedSMichael Speer static hxge_status_t 13933dec9fcdSqs hxge_alloc_mem_pool(p_hxge_t hxgep) 13943dec9fcdSqs { 13953dec9fcdSqs hxge_status_t status = HXGE_OK; 13963dec9fcdSqs 13973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_alloc_mem_pool")); 13983dec9fcdSqs 13993dec9fcdSqs status = hxge_alloc_rx_mem_pool(hxgep); 14003dec9fcdSqs if (status != HXGE_OK) { 14013dec9fcdSqs return (HXGE_ERROR); 14023dec9fcdSqs } 14033dec9fcdSqs 14043dec9fcdSqs status = hxge_alloc_tx_mem_pool(hxgep); 14053dec9fcdSqs if (status != HXGE_OK) { 14063dec9fcdSqs hxge_free_rx_mem_pool(hxgep); 14073dec9fcdSqs return (HXGE_ERROR); 14083dec9fcdSqs } 14093dec9fcdSqs 14103dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_alloc_mem_pool")); 14113dec9fcdSqs return (HXGE_OK); 14123dec9fcdSqs } 14133dec9fcdSqs 14143dec9fcdSqs static void 14153dec9fcdSqs hxge_free_mem_pool(p_hxge_t hxgep) 14163dec9fcdSqs { 14173dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_free_mem_pool")); 14183dec9fcdSqs 14193dec9fcdSqs hxge_free_rx_mem_pool(hxgep); 14203dec9fcdSqs hxge_free_tx_mem_pool(hxgep); 14213dec9fcdSqs 14223dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "<== hxge_free_mem_pool")); 14233dec9fcdSqs } 14243dec9fcdSqs 14253dec9fcdSqs static hxge_status_t 14263dec9fcdSqs hxge_alloc_rx_mem_pool(p_hxge_t hxgep) 14273dec9fcdSqs { 14283dec9fcdSqs int i, j; 14293dec9fcdSqs uint32_t ndmas, st_rdc; 14303dec9fcdSqs p_hxge_dma_pt_cfg_t p_all_cfgp; 14313dec9fcdSqs p_hxge_hw_pt_cfg_t p_cfgp; 14323dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 14333dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 14348ad8db65SMichael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp; 14358ad8db65SMichael Speer p_hxge_dma_common_t *dma_rbr_cntl_p; 14368ad8db65SMichael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp; 14378ad8db65SMichael Speer p_hxge_dma_common_t *dma_rcr_cntl_p; 14388ad8db65SMichael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp; 14398ad8db65SMichael Speer p_hxge_dma_common_t *dma_mbox_cntl_p; 14403dec9fcdSqs size_t rx_buf_alloc_size; 14418ad8db65SMichael Speer size_t rx_rbr_cntl_alloc_size; 14428ad8db65SMichael Speer size_t rx_rcr_cntl_alloc_size; 14438ad8db65SMichael Speer size_t rx_mbox_cntl_alloc_size; 14443dec9fcdSqs uint32_t *num_chunks; /* per dma */ 14453dec9fcdSqs hxge_status_t status = HXGE_OK; 14463dec9fcdSqs 14473dec9fcdSqs uint32_t hxge_port_rbr_size; 14483dec9fcdSqs uint32_t hxge_port_rbr_spare_size; 14493dec9fcdSqs uint32_t hxge_port_rcr_size; 14503dec9fcdSqs 14513dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_mem_pool")); 14523dec9fcdSqs 14533dec9fcdSqs p_all_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 14543dec9fcdSqs p_cfgp = (p_hxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 14553dec9fcdSqs st_rdc = p_cfgp->start_rdc; 14563dec9fcdSqs ndmas = p_cfgp->max_rdcs; 14573dec9fcdSqs 14583dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 14593dec9fcdSqs " hxge_alloc_rx_mem_pool st_rdc %d ndmas %d", st_rdc, ndmas)); 14603dec9fcdSqs 14613dec9fcdSqs /* 14623dec9fcdSqs * Allocate memory for each receive DMA channel. 14633dec9fcdSqs */ 14643dec9fcdSqs dma_poolp = (p_hxge_dma_pool_t)KMEM_ZALLOC(sizeof (hxge_dma_pool_t), 14653dec9fcdSqs KM_SLEEP); 14663dec9fcdSqs dma_buf_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14673dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14683dec9fcdSqs 14698ad8db65SMichael Speer dma_rbr_cntl_poolp = (p_hxge_dma_pool_t) 14703dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14718ad8db65SMichael Speer dma_rbr_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14728ad8db65SMichael Speer sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14738ad8db65SMichael Speer dma_rcr_cntl_poolp = (p_hxge_dma_pool_t) 14748ad8db65SMichael Speer KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14758ad8db65SMichael Speer dma_rcr_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14768ad8db65SMichael Speer sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14778ad8db65SMichael Speer dma_mbox_cntl_poolp = (p_hxge_dma_pool_t) 14788ad8db65SMichael Speer KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 14798ad8db65SMichael Speer dma_mbox_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 14803dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 14813dec9fcdSqs 14823dec9fcdSqs num_chunks = (uint32_t *)KMEM_ZALLOC(sizeof (uint32_t) * ndmas, 14833dec9fcdSqs KM_SLEEP); 14843dec9fcdSqs 14853dec9fcdSqs /* 14863dec9fcdSqs * Assume that each DMA channel will be configured with default block 14873dec9fcdSqs * size. rbr block counts are mod of batch count (16). 14883dec9fcdSqs */ 14893dec9fcdSqs hxge_port_rbr_size = p_all_cfgp->rbr_size; 14903dec9fcdSqs hxge_port_rcr_size = p_all_cfgp->rcr_size; 14913dec9fcdSqs 14923dec9fcdSqs if (!hxge_port_rbr_size) { 14933dec9fcdSqs hxge_port_rbr_size = HXGE_RBR_RBB_DEFAULT; 14943dec9fcdSqs } 14953dec9fcdSqs 14963dec9fcdSqs if (hxge_port_rbr_size % HXGE_RXDMA_POST_BATCH) { 14973dec9fcdSqs hxge_port_rbr_size = (HXGE_RXDMA_POST_BATCH * 14983dec9fcdSqs (hxge_port_rbr_size / HXGE_RXDMA_POST_BATCH + 1)); 14993dec9fcdSqs } 15003dec9fcdSqs 15013dec9fcdSqs p_all_cfgp->rbr_size = hxge_port_rbr_size; 15023dec9fcdSqs hxge_port_rbr_spare_size = hxge_rbr_spare_size; 15033dec9fcdSqs 15043dec9fcdSqs if (hxge_port_rbr_spare_size % HXGE_RXDMA_POST_BATCH) { 15053dec9fcdSqs hxge_port_rbr_spare_size = (HXGE_RXDMA_POST_BATCH * 15063dec9fcdSqs (hxge_port_rbr_spare_size / HXGE_RXDMA_POST_BATCH + 1)); 15073dec9fcdSqs } 15083dec9fcdSqs 15093dec9fcdSqs rx_buf_alloc_size = (hxgep->rx_default_block_size * 15103dec9fcdSqs (hxge_port_rbr_size + hxge_port_rbr_spare_size)); 15113dec9fcdSqs 15123dec9fcdSqs /* 15133dec9fcdSqs * Addresses of receive block ring, receive completion ring and the 15143dec9fcdSqs * mailbox must be all cache-aligned (64 bytes). 15153dec9fcdSqs */ 15168ad8db65SMichael Speer rx_rbr_cntl_alloc_size = hxge_port_rbr_size + hxge_port_rbr_spare_size; 15178ad8db65SMichael Speer rx_rbr_cntl_alloc_size *= sizeof (rx_desc_t); 15188ad8db65SMichael Speer rx_rcr_cntl_alloc_size = sizeof (rcr_entry_t) * hxge_port_rcr_size; 15198ad8db65SMichael Speer rx_mbox_cntl_alloc_size = sizeof (rxdma_mailbox_t); 15203dec9fcdSqs 15213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_alloc_rx_mem_pool: " 15223dec9fcdSqs "hxge_port_rbr_size = %d hxge_port_rbr_spare_size = %d " 15233dec9fcdSqs "hxge_port_rcr_size = %d rx_cntl_alloc_size = %d", 15243dec9fcdSqs hxge_port_rbr_size, hxge_port_rbr_spare_size, 15253dec9fcdSqs hxge_port_rcr_size, rx_cntl_alloc_size)); 15263dec9fcdSqs 15273dec9fcdSqs hxgep->hxge_port_rbr_size = hxge_port_rbr_size; 15283dec9fcdSqs hxgep->hxge_port_rcr_size = hxge_port_rcr_size; 15293dec9fcdSqs 15303dec9fcdSqs /* 15313dec9fcdSqs * Allocate memory for receive buffers and descriptor rings. Replace 15323dec9fcdSqs * allocation functions with interface functions provided by the 15333dec9fcdSqs * partition manager when it is available. 15343dec9fcdSqs */ 15353dec9fcdSqs /* 15363dec9fcdSqs * Allocate memory for the receive buffer blocks. 15373dec9fcdSqs */ 15383dec9fcdSqs for (i = 0; i < ndmas; i++) { 15393dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 15403dec9fcdSqs " hxge_alloc_rx_mem_pool to alloc mem: " 15413dec9fcdSqs " dma %d dma_buf_p %llx &dma_buf_p %llx", 15423dec9fcdSqs i, dma_buf_p[i], &dma_buf_p[i])); 15433dec9fcdSqs 15443dec9fcdSqs num_chunks[i] = 0; 15453dec9fcdSqs 15463dec9fcdSqs status = hxge_alloc_rx_buf_dma(hxgep, st_rdc, &dma_buf_p[i], 15473dec9fcdSqs rx_buf_alloc_size, hxgep->rx_default_block_size, 15483dec9fcdSqs &num_chunks[i]); 15493dec9fcdSqs if (status != HXGE_OK) { 15503dec9fcdSqs break; 15513dec9fcdSqs } 15523dec9fcdSqs 15533dec9fcdSqs st_rdc++; 15543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 15553dec9fcdSqs " hxge_alloc_rx_mem_pool DONE alloc mem: " 15563dec9fcdSqs "dma %d dma_buf_p %llx &dma_buf_p %llx", i, 15573dec9fcdSqs dma_buf_p[i], &dma_buf_p[i])); 15583dec9fcdSqs } 15593dec9fcdSqs 15603dec9fcdSqs if (i < ndmas) { 15613dec9fcdSqs goto hxge_alloc_rx_mem_fail1; 15623dec9fcdSqs } 15633dec9fcdSqs 15643dec9fcdSqs /* 15653dec9fcdSqs * Allocate memory for descriptor rings and mailbox. 15663dec9fcdSqs */ 15673dec9fcdSqs st_rdc = p_cfgp->start_rdc; 15683dec9fcdSqs for (j = 0; j < ndmas; j++) { 15698ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15708ad8db65SMichael Speer &dma_rbr_cntl_p[j], &hxge_rx_rbr_desc_dma_attr, 15718ad8db65SMichael Speer rx_rbr_cntl_alloc_size)) != HXGE_OK) { 15728ad8db65SMichael Speer break; 15738ad8db65SMichael Speer } 15748ad8db65SMichael Speer 15758ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15768ad8db65SMichael Speer &dma_rcr_cntl_p[j], &hxge_rx_rcr_desc_dma_attr, 15778ad8db65SMichael Speer rx_rcr_cntl_alloc_size)) != HXGE_OK) { 15788ad8db65SMichael Speer break; 15798ad8db65SMichael Speer } 15808ad8db65SMichael Speer 15818ad8db65SMichael Speer if ((status = hxge_alloc_rx_cntl_dma(hxgep, st_rdc, 15828ad8db65SMichael Speer &dma_mbox_cntl_p[j], &hxge_rx_mbox_dma_attr, 15838ad8db65SMichael Speer rx_mbox_cntl_alloc_size)) != HXGE_OK) { 15843dec9fcdSqs break; 15853dec9fcdSqs } 15863dec9fcdSqs st_rdc++; 15873dec9fcdSqs } 15883dec9fcdSqs 15893dec9fcdSqs if (j < ndmas) { 15903dec9fcdSqs goto hxge_alloc_rx_mem_fail2; 15913dec9fcdSqs } 15923dec9fcdSqs 15933dec9fcdSqs dma_poolp->ndmas = ndmas; 15943dec9fcdSqs dma_poolp->num_chunks = num_chunks; 15953dec9fcdSqs dma_poolp->buf_allocated = B_TRUE; 15963dec9fcdSqs hxgep->rx_buf_pool_p = dma_poolp; 15973dec9fcdSqs dma_poolp->dma_buf_pool_p = dma_buf_p; 15983dec9fcdSqs 15998ad8db65SMichael Speer dma_rbr_cntl_poolp->ndmas = ndmas; 16008ad8db65SMichael Speer dma_rbr_cntl_poolp->buf_allocated = B_TRUE; 16018ad8db65SMichael Speer hxgep->rx_rbr_cntl_pool_p = dma_rbr_cntl_poolp; 16028ad8db65SMichael Speer dma_rbr_cntl_poolp->dma_buf_pool_p = dma_rbr_cntl_p; 16038ad8db65SMichael Speer 16048ad8db65SMichael Speer dma_rcr_cntl_poolp->ndmas = ndmas; 16058ad8db65SMichael Speer dma_rcr_cntl_poolp->buf_allocated = B_TRUE; 16068ad8db65SMichael Speer hxgep->rx_rcr_cntl_pool_p = dma_rcr_cntl_poolp; 16078ad8db65SMichael Speer dma_rcr_cntl_poolp->dma_buf_pool_p = dma_rcr_cntl_p; 16088ad8db65SMichael Speer 16098ad8db65SMichael Speer dma_mbox_cntl_poolp->ndmas = ndmas; 16108ad8db65SMichael Speer dma_mbox_cntl_poolp->buf_allocated = B_TRUE; 16118ad8db65SMichael Speer hxgep->rx_mbox_cntl_pool_p = dma_mbox_cntl_poolp; 16128ad8db65SMichael Speer dma_mbox_cntl_poolp->dma_buf_pool_p = dma_mbox_cntl_p; 16133dec9fcdSqs 16143dec9fcdSqs goto hxge_alloc_rx_mem_pool_exit; 16153dec9fcdSqs 16163dec9fcdSqs hxge_alloc_rx_mem_fail2: 16173dec9fcdSqs /* Free control buffers */ 16183dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16193dec9fcdSqs "==> hxge_alloc_rx_mem_pool: freeing control bufs (%d)", j)); 16203dec9fcdSqs for (; j >= 0; j--) { 16213dec9fcdSqs hxge_free_rx_cntl_dma(hxgep, 16228ad8db65SMichael Speer (p_hxge_dma_common_t)dma_rbr_cntl_p[j]); 16238ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, 16248ad8db65SMichael Speer (p_hxge_dma_common_t)dma_rcr_cntl_p[j]); 16258ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, 16268ad8db65SMichael Speer (p_hxge_dma_common_t)dma_mbox_cntl_p[j]); 16273dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16283dec9fcdSqs "==> hxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 16293dec9fcdSqs } 16303dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16313dec9fcdSqs "==> hxge_alloc_rx_mem_pool: control bufs freed (%d)", j)); 16323dec9fcdSqs 16333dec9fcdSqs hxge_alloc_rx_mem_fail1: 16343dec9fcdSqs /* Free data buffers */ 16353dec9fcdSqs i--; 16363dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16373dec9fcdSqs "==> hxge_alloc_rx_mem_pool: freeing data bufs (%d)", i)); 16383dec9fcdSqs for (; i >= 0; i--) { 16393dec9fcdSqs hxge_free_rx_buf_dma(hxgep, (p_hxge_dma_common_t)dma_buf_p[i], 16403dec9fcdSqs num_chunks[i]); 16413dec9fcdSqs } 16423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16433dec9fcdSqs "==> hxge_alloc_rx_mem_pool: data bufs freed (%d)", i)); 16443dec9fcdSqs 16453dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 16463dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 16473dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 16488ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_poolp, sizeof (hxge_dma_pool_t)); 16498ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16508ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_poolp, sizeof (hxge_dma_pool_t)); 16518ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16528ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_poolp, sizeof (hxge_dma_pool_t)); 16538ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 16543dec9fcdSqs 16553dec9fcdSqs hxge_alloc_rx_mem_pool_exit: 16563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 16573dec9fcdSqs "<== hxge_alloc_rx_mem_pool:status 0x%08x", status)); 16583dec9fcdSqs 16593dec9fcdSqs return (status); 16603dec9fcdSqs } 16613dec9fcdSqs 16623dec9fcdSqs static void 16633dec9fcdSqs hxge_free_rx_mem_pool(p_hxge_t hxgep) 16643dec9fcdSqs { 16653dec9fcdSqs uint32_t i, ndmas; 16663dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 16673dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 16688ad8db65SMichael Speer p_hxge_dma_pool_t dma_rbr_cntl_poolp; 16698ad8db65SMichael Speer p_hxge_dma_common_t *dma_rbr_cntl_p; 16708ad8db65SMichael Speer p_hxge_dma_pool_t dma_rcr_cntl_poolp; 16718ad8db65SMichael Speer p_hxge_dma_common_t *dma_rcr_cntl_p; 16728ad8db65SMichael Speer p_hxge_dma_pool_t dma_mbox_cntl_poolp; 16738ad8db65SMichael Speer p_hxge_dma_common_t *dma_mbox_cntl_p; 16743dec9fcdSqs uint32_t *num_chunks; 16753dec9fcdSqs 16763dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "==> hxge_free_rx_mem_pool")); 16773dec9fcdSqs 16783dec9fcdSqs dma_poolp = hxgep->rx_buf_pool_p; 16793dec9fcdSqs if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 16803dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_mem_pool " 16813dec9fcdSqs "(null rx buf pool or buf not allocated")); 16823dec9fcdSqs return; 16833dec9fcdSqs } 16843dec9fcdSqs 16858ad8db65SMichael Speer dma_rbr_cntl_poolp = hxgep->rx_rbr_cntl_pool_p; 16868ad8db65SMichael Speer if (dma_rbr_cntl_poolp == NULL || 16878ad8db65SMichael Speer (!dma_rbr_cntl_poolp->buf_allocated)) { 16888ad8db65SMichael Speer HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 16898ad8db65SMichael Speer "<== hxge_free_rx_mem_pool " 16908ad8db65SMichael Speer "(null rbr cntl buf pool or rbr cntl buf not allocated")); 16918ad8db65SMichael Speer return; 16928ad8db65SMichael Speer } 16938ad8db65SMichael Speer 16948ad8db65SMichael Speer dma_rcr_cntl_poolp = hxgep->rx_rcr_cntl_pool_p; 16958ad8db65SMichael Speer if (dma_rcr_cntl_poolp == NULL || 16968ad8db65SMichael Speer (!dma_rcr_cntl_poolp->buf_allocated)) { 16973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 16983dec9fcdSqs "<== hxge_free_rx_mem_pool " 16998ad8db65SMichael Speer "(null rcr cntl buf pool or rcr cntl buf not allocated")); 17008ad8db65SMichael Speer return; 17018ad8db65SMichael Speer } 17028ad8db65SMichael Speer 17038ad8db65SMichael Speer dma_mbox_cntl_poolp = hxgep->rx_mbox_cntl_pool_p; 17048ad8db65SMichael Speer if (dma_mbox_cntl_poolp == NULL || 17058ad8db65SMichael Speer (!dma_mbox_cntl_poolp->buf_allocated)) { 17068ad8db65SMichael Speer HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17078ad8db65SMichael Speer "<== hxge_free_rx_mem_pool " 17088ad8db65SMichael Speer "(null mbox cntl buf pool or mbox cntl buf not allocated")); 17093dec9fcdSqs return; 17103dec9fcdSqs } 17113dec9fcdSqs 17123dec9fcdSqs dma_buf_p = dma_poolp->dma_buf_pool_p; 17133dec9fcdSqs num_chunks = dma_poolp->num_chunks; 17143dec9fcdSqs 17158ad8db65SMichael Speer dma_rbr_cntl_p = dma_rbr_cntl_poolp->dma_buf_pool_p; 17168ad8db65SMichael Speer dma_rcr_cntl_p = dma_rcr_cntl_poolp->dma_buf_pool_p; 17178ad8db65SMichael Speer dma_mbox_cntl_p = dma_mbox_cntl_poolp->dma_buf_pool_p; 17188ad8db65SMichael Speer ndmas = dma_rbr_cntl_poolp->ndmas; 17193dec9fcdSqs 17203dec9fcdSqs for (i = 0; i < ndmas; i++) { 17213dec9fcdSqs hxge_free_rx_buf_dma(hxgep, dma_buf_p[i], num_chunks[i]); 17223dec9fcdSqs } 17233dec9fcdSqs 17243dec9fcdSqs for (i = 0; i < ndmas; i++) { 17258ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_rbr_cntl_p[i]); 17268ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_rcr_cntl_p[i]); 17278ad8db65SMichael Speer hxge_free_rx_cntl_dma(hxgep, dma_mbox_cntl_p[i]); 17283dec9fcdSqs } 17293dec9fcdSqs 17303dec9fcdSqs for (i = 0; i < ndmas; i++) { 17313dec9fcdSqs KMEM_FREE(dma_buf_p[i], 17323dec9fcdSqs sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 17338ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p[i], sizeof (hxge_dma_common_t)); 17348ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p[i], sizeof (hxge_dma_common_t)); 17358ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p[i], sizeof (hxge_dma_common_t)); 17363dec9fcdSqs } 17373dec9fcdSqs 17383dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 17398ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17408ad8db65SMichael Speer KMEM_FREE(dma_rbr_cntl_poolp, sizeof (hxge_dma_pool_t)); 17418ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17428ad8db65SMichael Speer KMEM_FREE(dma_rcr_cntl_poolp, sizeof (hxge_dma_pool_t)); 17438ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 17448ad8db65SMichael Speer KMEM_FREE(dma_mbox_cntl_poolp, sizeof (hxge_dma_pool_t)); 17453dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 17463dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 17473dec9fcdSqs 17483dec9fcdSqs hxgep->rx_buf_pool_p = NULL; 17498ad8db65SMichael Speer hxgep->rx_rbr_cntl_pool_p = NULL; 17508ad8db65SMichael Speer hxgep->rx_rcr_cntl_pool_p = NULL; 17518ad8db65SMichael Speer hxgep->rx_mbox_cntl_pool_p = NULL; 17523dec9fcdSqs 17533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_mem_pool")); 17543dec9fcdSqs } 17553dec9fcdSqs 17563dec9fcdSqs static hxge_status_t 17573dec9fcdSqs hxge_alloc_rx_buf_dma(p_hxge_t hxgep, uint16_t dma_channel, 17583dec9fcdSqs p_hxge_dma_common_t *dmap, 17593dec9fcdSqs size_t alloc_size, size_t block_size, uint32_t *num_chunks) 17603dec9fcdSqs { 17613dec9fcdSqs p_hxge_dma_common_t rx_dmap; 17623dec9fcdSqs hxge_status_t status = HXGE_OK; 17633dec9fcdSqs size_t total_alloc_size; 17643dec9fcdSqs size_t allocated = 0; 17653dec9fcdSqs int i, size_index, array_size; 17663dec9fcdSqs 17673dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_buf_dma")); 17683dec9fcdSqs 17693dec9fcdSqs rx_dmap = (p_hxge_dma_common_t) 17703dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK, KM_SLEEP); 17713dec9fcdSqs 17723dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17733dec9fcdSqs " alloc_rx_buf_dma rdc %d asize %x bsize %x bbuf %llx ", 17743dec9fcdSqs dma_channel, alloc_size, block_size, dmap)); 17753dec9fcdSqs 17763dec9fcdSqs total_alloc_size = alloc_size; 17773dec9fcdSqs 17783dec9fcdSqs i = 0; 17793dec9fcdSqs size_index = 0; 17803dec9fcdSqs array_size = sizeof (alloc_sizes) / sizeof (size_t); 1781b83cd2c3SMichael Speer while ((size_index < array_size) && 1782b83cd2c3SMichael Speer (alloc_sizes[size_index] < alloc_size)) 17833dec9fcdSqs size_index++; 17843dec9fcdSqs if (size_index >= array_size) { 17853dec9fcdSqs size_index = array_size - 1; 17863dec9fcdSqs } 17873dec9fcdSqs 17883dec9fcdSqs while ((allocated < total_alloc_size) && 17893dec9fcdSqs (size_index >= 0) && (i < HXGE_DMA_BLOCK)) { 17903dec9fcdSqs rx_dmap[i].dma_chunk_index = i; 17913dec9fcdSqs rx_dmap[i].block_size = block_size; 17923dec9fcdSqs rx_dmap[i].alength = alloc_sizes[size_index]; 17933dec9fcdSqs rx_dmap[i].orig_alength = rx_dmap[i].alength; 17943dec9fcdSqs rx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 17953dec9fcdSqs rx_dmap[i].dma_channel = dma_channel; 17963dec9fcdSqs rx_dmap[i].contig_alloc_type = B_FALSE; 17973dec9fcdSqs 17983dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 17993dec9fcdSqs "alloc_rx_buf_dma rdc %d chunk %d bufp %llx size %x " 18003dec9fcdSqs "i %d nblocks %d alength %d", 18013dec9fcdSqs dma_channel, i, &rx_dmap[i], block_size, 18023dec9fcdSqs i, rx_dmap[i].nblocks, rx_dmap[i].alength)); 18033dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 18043dec9fcdSqs &hxge_rx_dma_attr, rx_dmap[i].alength, 18053dec9fcdSqs &hxge_dev_buf_dma_acc_attr, 18063dec9fcdSqs DDI_DMA_READ | DDI_DMA_STREAMING, 18073dec9fcdSqs (p_hxge_dma_common_t)(&rx_dmap[i])); 18083dec9fcdSqs if (status != HXGE_OK) { 18093dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18103dec9fcdSqs " hxge_alloc_rx_buf_dma: Alloc Failed: " 18113dec9fcdSqs " for size: %d", alloc_sizes[size_index])); 18123dec9fcdSqs size_index--; 18133dec9fcdSqs } else { 18143dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18153dec9fcdSqs " alloc_rx_buf_dma allocated rdc %d " 18163dec9fcdSqs "chunk %d size %x dvma %x bufp %llx ", 18173dec9fcdSqs dma_channel, i, rx_dmap[i].alength, 18183dec9fcdSqs rx_dmap[i].ioaddr_pp, &rx_dmap[i])); 18193dec9fcdSqs i++; 18203dec9fcdSqs allocated += alloc_sizes[size_index]; 18213dec9fcdSqs } 18223dec9fcdSqs } 18233dec9fcdSqs 18243dec9fcdSqs if (allocated < total_alloc_size) { 18253dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 18263dec9fcdSqs " hxge_alloc_rx_buf_dma failed due to" 18273dec9fcdSqs " allocated(%d) < required(%d)", 18283dec9fcdSqs allocated, total_alloc_size)); 18293dec9fcdSqs goto hxge_alloc_rx_mem_fail1; 18303dec9fcdSqs } 18313dec9fcdSqs 18323dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18333dec9fcdSqs " alloc_rx_buf_dma rdc %d allocated %d chunks", dma_channel, i)); 18343dec9fcdSqs 18353dec9fcdSqs *num_chunks = i; 18363dec9fcdSqs *dmap = rx_dmap; 18373dec9fcdSqs 18383dec9fcdSqs goto hxge_alloc_rx_mem_exit; 18393dec9fcdSqs 18403dec9fcdSqs hxge_alloc_rx_mem_fail1: 18413dec9fcdSqs KMEM_FREE(rx_dmap, sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 18423dec9fcdSqs 18433dec9fcdSqs hxge_alloc_rx_mem_exit: 18443dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 18453dec9fcdSqs "<== hxge_alloc_rx_buf_dma status 0x%08x", status)); 18463dec9fcdSqs 18473dec9fcdSqs return (status); 18483dec9fcdSqs } 18493dec9fcdSqs 18503dec9fcdSqs /*ARGSUSED*/ 18513dec9fcdSqs static void 18523dec9fcdSqs hxge_free_rx_buf_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap, 18533dec9fcdSqs uint32_t num_chunks) 18543dec9fcdSqs { 18553dec9fcdSqs int i; 18563dec9fcdSqs 18573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 18583dec9fcdSqs "==> hxge_free_rx_buf_dma: # of chunks %d", num_chunks)); 18593dec9fcdSqs 18603dec9fcdSqs for (i = 0; i < num_chunks; i++) { 18613dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, 18623dec9fcdSqs "==> hxge_free_rx_buf_dma: chunk %d dmap 0x%llx", i, dmap)); 18633dec9fcdSqs hxge_dma_mem_free(dmap++); 18643dec9fcdSqs } 18653dec9fcdSqs 18663dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM2_CTL, "<== hxge_free_rx_buf_dma")); 18673dec9fcdSqs } 18683dec9fcdSqs 18693dec9fcdSqs /*ARGSUSED*/ 18703dec9fcdSqs static hxge_status_t 18713dec9fcdSqs hxge_alloc_rx_cntl_dma(p_hxge_t hxgep, uint16_t dma_channel, 18728ad8db65SMichael Speer p_hxge_dma_common_t *dmap, struct ddi_dma_attr *attr, size_t size) 18733dec9fcdSqs { 18743dec9fcdSqs p_hxge_dma_common_t rx_dmap; 18753dec9fcdSqs hxge_status_t status = HXGE_OK; 18763dec9fcdSqs 18773dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_rx_cntl_dma")); 18783dec9fcdSqs 18793dec9fcdSqs rx_dmap = (p_hxge_dma_common_t) 18803dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t), KM_SLEEP); 18813dec9fcdSqs 18823dec9fcdSqs rx_dmap->contig_alloc_type = B_FALSE; 18833dec9fcdSqs 18843dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 18858ad8db65SMichael Speer attr, size, &hxge_dev_desc_dma_acc_attr, 18863dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, rx_dmap); 18873dec9fcdSqs if (status != HXGE_OK) { 18883dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 18893dec9fcdSqs " hxge_alloc_rx_cntl_dma: Alloc Failed: " 18903dec9fcdSqs " for size: %d", size)); 18913dec9fcdSqs goto hxge_alloc_rx_cntl_dma_fail1; 18923dec9fcdSqs } 18933dec9fcdSqs 18943dec9fcdSqs *dmap = rx_dmap; 18953dec9fcdSqs 18963dec9fcdSqs goto hxge_alloc_rx_cntl_dma_exit; 18973dec9fcdSqs 18983dec9fcdSqs hxge_alloc_rx_cntl_dma_fail1: 18993dec9fcdSqs KMEM_FREE(rx_dmap, sizeof (hxge_dma_common_t)); 19003dec9fcdSqs 19013dec9fcdSqs hxge_alloc_rx_cntl_dma_exit: 19023dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 19033dec9fcdSqs "<== hxge_alloc_rx_cntl_dma status 0x%08x", status)); 19043dec9fcdSqs 19053dec9fcdSqs return (status); 19063dec9fcdSqs } 19073dec9fcdSqs 19083dec9fcdSqs /*ARGSUSED*/ 19093dec9fcdSqs static void 19103dec9fcdSqs hxge_free_rx_cntl_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap) 19113dec9fcdSqs { 19123dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_free_rx_cntl_dma")); 19133dec9fcdSqs 19143dec9fcdSqs hxge_dma_mem_free(dmap); 19153dec9fcdSqs 19163dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_free_rx_cntl_dma")); 19173dec9fcdSqs } 19183dec9fcdSqs 19193dec9fcdSqs static hxge_status_t 19203dec9fcdSqs hxge_alloc_tx_mem_pool(p_hxge_t hxgep) 19213dec9fcdSqs { 19223dec9fcdSqs hxge_status_t status = HXGE_OK; 19233dec9fcdSqs int i, j; 19243dec9fcdSqs uint32_t ndmas, st_tdc; 19253dec9fcdSqs p_hxge_dma_pt_cfg_t p_all_cfgp; 19263dec9fcdSqs p_hxge_hw_pt_cfg_t p_cfgp; 19273dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 19283dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 19293dec9fcdSqs p_hxge_dma_pool_t dma_cntl_poolp; 19303dec9fcdSqs p_hxge_dma_common_t *dma_cntl_p; 19313dec9fcdSqs size_t tx_buf_alloc_size; 19323dec9fcdSqs size_t tx_cntl_alloc_size; 19333dec9fcdSqs uint32_t *num_chunks; /* per dma */ 19343dec9fcdSqs 19353dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_alloc_tx_mem_pool")); 19363dec9fcdSqs 19373dec9fcdSqs p_all_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 19383dec9fcdSqs p_cfgp = (p_hxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 19393dec9fcdSqs st_tdc = p_cfgp->start_tdc; 19403dec9fcdSqs ndmas = p_cfgp->max_tdcs; 19413dec9fcdSqs 19423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_alloc_tx_mem_pool: " 19433dec9fcdSqs "p_cfgp 0x%016llx start_tdc %d ndmas %d hxgep->max_tdcs %d", 19443dec9fcdSqs p_cfgp, p_cfgp->start_tdc, p_cfgp->max_tdcs, hxgep->max_tdcs)); 19453dec9fcdSqs /* 19463dec9fcdSqs * Allocate memory for each transmit DMA channel. 19473dec9fcdSqs */ 19483dec9fcdSqs dma_poolp = (p_hxge_dma_pool_t)KMEM_ZALLOC(sizeof (hxge_dma_pool_t), 19493dec9fcdSqs KM_SLEEP); 19503dec9fcdSqs dma_buf_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 19513dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 19523dec9fcdSqs 19533dec9fcdSqs dma_cntl_poolp = (p_hxge_dma_pool_t) 19543dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_pool_t), KM_SLEEP); 19553dec9fcdSqs dma_cntl_p = (p_hxge_dma_common_t *)KMEM_ZALLOC( 19563dec9fcdSqs sizeof (p_hxge_dma_common_t) * ndmas, KM_SLEEP); 19573dec9fcdSqs 19583dec9fcdSqs hxgep->hxge_port_tx_ring_size = hxge_tx_ring_size; 19593dec9fcdSqs 19603dec9fcdSqs /* 19613dec9fcdSqs * Assume that each DMA channel will be configured with default 19623dec9fcdSqs * transmit bufer size for copying transmit data. (For packet payload 19633dec9fcdSqs * over this limit, packets will not be copied.) 19643dec9fcdSqs */ 19653dec9fcdSqs tx_buf_alloc_size = (hxge_bcopy_thresh * hxge_tx_ring_size); 19663dec9fcdSqs 19673dec9fcdSqs /* 19683dec9fcdSqs * Addresses of transmit descriptor ring and the mailbox must be all 19693dec9fcdSqs * cache-aligned (64 bytes). 19703dec9fcdSqs */ 19713dec9fcdSqs tx_cntl_alloc_size = hxge_tx_ring_size; 19723dec9fcdSqs tx_cntl_alloc_size *= (sizeof (tx_desc_t)); 19733dec9fcdSqs tx_cntl_alloc_size += sizeof (txdma_mailbox_t); 19743dec9fcdSqs 19753dec9fcdSqs num_chunks = (uint32_t *)KMEM_ZALLOC(sizeof (uint32_t) * ndmas, 19763dec9fcdSqs KM_SLEEP); 19773dec9fcdSqs 19783dec9fcdSqs /* 19793dec9fcdSqs * Allocate memory for transmit buffers and descriptor rings. Replace 19803dec9fcdSqs * allocation functions with interface functions provided by the 19813dec9fcdSqs * partition manager when it is available. 19823dec9fcdSqs * 19833dec9fcdSqs * Allocate memory for the transmit buffer pool. 19843dec9fcdSqs */ 19853dec9fcdSqs for (i = 0; i < ndmas; i++) { 19863dec9fcdSqs num_chunks[i] = 0; 19873dec9fcdSqs status = hxge_alloc_tx_buf_dma(hxgep, st_tdc, &dma_buf_p[i], 19883dec9fcdSqs tx_buf_alloc_size, hxge_bcopy_thresh, &num_chunks[i]); 19893dec9fcdSqs if (status != HXGE_OK) { 19903dec9fcdSqs break; 19913dec9fcdSqs } 19923dec9fcdSqs st_tdc++; 19933dec9fcdSqs } 19943dec9fcdSqs 19953dec9fcdSqs if (i < ndmas) { 19963dec9fcdSqs goto hxge_alloc_tx_mem_pool_fail1; 19973dec9fcdSqs } 19983dec9fcdSqs 19993dec9fcdSqs st_tdc = p_cfgp->start_tdc; 20003dec9fcdSqs 20013dec9fcdSqs /* 20023dec9fcdSqs * Allocate memory for descriptor rings and mailbox. 20033dec9fcdSqs */ 20043dec9fcdSqs for (j = 0; j < ndmas; j++) { 20053dec9fcdSqs status = hxge_alloc_tx_cntl_dma(hxgep, st_tdc, &dma_cntl_p[j], 20063dec9fcdSqs tx_cntl_alloc_size); 20073dec9fcdSqs if (status != HXGE_OK) { 20083dec9fcdSqs break; 20093dec9fcdSqs } 20103dec9fcdSqs st_tdc++; 20113dec9fcdSqs } 20123dec9fcdSqs 20133dec9fcdSqs if (j < ndmas) { 20143dec9fcdSqs goto hxge_alloc_tx_mem_pool_fail2; 20153dec9fcdSqs } 20163dec9fcdSqs 20173dec9fcdSqs dma_poolp->ndmas = ndmas; 20183dec9fcdSqs dma_poolp->num_chunks = num_chunks; 20193dec9fcdSqs dma_poolp->buf_allocated = B_TRUE; 20203dec9fcdSqs dma_poolp->dma_buf_pool_p = dma_buf_p; 20213dec9fcdSqs hxgep->tx_buf_pool_p = dma_poolp; 20223dec9fcdSqs 20233dec9fcdSqs dma_cntl_poolp->ndmas = ndmas; 20243dec9fcdSqs dma_cntl_poolp->buf_allocated = B_TRUE; 20253dec9fcdSqs dma_cntl_poolp->dma_buf_pool_p = dma_cntl_p; 20263dec9fcdSqs hxgep->tx_cntl_pool_p = dma_cntl_poolp; 20273dec9fcdSqs 20283dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, 20293dec9fcdSqs "==> hxge_alloc_tx_mem_pool: start_tdc %d " 20303dec9fcdSqs "ndmas %d poolp->ndmas %d", st_tdc, ndmas, dma_poolp->ndmas)); 20313dec9fcdSqs 20323dec9fcdSqs goto hxge_alloc_tx_mem_pool_exit; 20333dec9fcdSqs 20343dec9fcdSqs hxge_alloc_tx_mem_pool_fail2: 20353dec9fcdSqs /* Free control buffers */ 20363dec9fcdSqs j--; 20373dec9fcdSqs for (; j >= 0; j--) { 20383dec9fcdSqs hxge_free_tx_cntl_dma(hxgep, 20393dec9fcdSqs (p_hxge_dma_common_t)dma_cntl_p[j]); 20403dec9fcdSqs } 20413dec9fcdSqs 20423dec9fcdSqs hxge_alloc_tx_mem_pool_fail1: 20433dec9fcdSqs /* Free data buffers */ 20443dec9fcdSqs i--; 20453dec9fcdSqs for (; i >= 0; i--) { 20463dec9fcdSqs hxge_free_tx_buf_dma(hxgep, (p_hxge_dma_common_t)dma_buf_p[i], 20473dec9fcdSqs num_chunks[i]); 20483dec9fcdSqs } 20493dec9fcdSqs 20503dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 20513dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 20523dec9fcdSqs KMEM_FREE(dma_cntl_poolp, sizeof (hxge_dma_pool_t)); 20533dec9fcdSqs KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 20543dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 20553dec9fcdSqs 20563dec9fcdSqs hxge_alloc_tx_mem_pool_exit: 20573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, 20583dec9fcdSqs "<== hxge_alloc_tx_mem_pool:status 0x%08x", status)); 20593dec9fcdSqs 20603dec9fcdSqs return (status); 20613dec9fcdSqs } 20623dec9fcdSqs 20633dec9fcdSqs static hxge_status_t 20643dec9fcdSqs hxge_alloc_tx_buf_dma(p_hxge_t hxgep, uint16_t dma_channel, 20653dec9fcdSqs p_hxge_dma_common_t *dmap, size_t alloc_size, 20663dec9fcdSqs size_t block_size, uint32_t *num_chunks) 20673dec9fcdSqs { 20683dec9fcdSqs p_hxge_dma_common_t tx_dmap; 20693dec9fcdSqs hxge_status_t status = HXGE_OK; 20703dec9fcdSqs size_t total_alloc_size; 20713dec9fcdSqs size_t allocated = 0; 20723dec9fcdSqs int i, size_index, array_size; 20733dec9fcdSqs 20743dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_tx_buf_dma")); 20753dec9fcdSqs 20763dec9fcdSqs tx_dmap = (p_hxge_dma_common_t) 20773dec9fcdSqs KMEM_ZALLOC(sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK, KM_SLEEP); 20783dec9fcdSqs 20793dec9fcdSqs total_alloc_size = alloc_size; 20803dec9fcdSqs i = 0; 20813dec9fcdSqs size_index = 0; 20823dec9fcdSqs array_size = sizeof (alloc_sizes) / sizeof (size_t); 2083b83cd2c3SMichael Speer while ((size_index < array_size) && 2084b83cd2c3SMichael Speer (alloc_sizes[size_index] < alloc_size)) 20853dec9fcdSqs size_index++; 20863dec9fcdSqs if (size_index >= array_size) { 20873dec9fcdSqs size_index = array_size - 1; 20883dec9fcdSqs } 20893dec9fcdSqs 20903dec9fcdSqs while ((allocated < total_alloc_size) && 20913dec9fcdSqs (size_index >= 0) && (i < HXGE_DMA_BLOCK)) { 20923dec9fcdSqs tx_dmap[i].dma_chunk_index = i; 20933dec9fcdSqs tx_dmap[i].block_size = block_size; 20943dec9fcdSqs tx_dmap[i].alength = alloc_sizes[size_index]; 20953dec9fcdSqs tx_dmap[i].orig_alength = tx_dmap[i].alength; 20963dec9fcdSqs tx_dmap[i].nblocks = alloc_sizes[size_index] / block_size; 20973dec9fcdSqs tx_dmap[i].dma_channel = dma_channel; 20983dec9fcdSqs tx_dmap[i].contig_alloc_type = B_FALSE; 20993dec9fcdSqs 21003dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 21013dec9fcdSqs &hxge_tx_dma_attr, tx_dmap[i].alength, 21023dec9fcdSqs &hxge_dev_buf_dma_acc_attr, 21033dec9fcdSqs DDI_DMA_WRITE | DDI_DMA_STREAMING, 21043dec9fcdSqs (p_hxge_dma_common_t)(&tx_dmap[i])); 21053dec9fcdSqs if (status != HXGE_OK) { 21063dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21073dec9fcdSqs " hxge_alloc_tx_buf_dma: Alloc Failed: " 21083dec9fcdSqs " for size: %d", alloc_sizes[size_index])); 21093dec9fcdSqs size_index--; 21103dec9fcdSqs } else { 21113dec9fcdSqs i++; 21123dec9fcdSqs allocated += alloc_sizes[size_index]; 21133dec9fcdSqs } 21143dec9fcdSqs } 21153dec9fcdSqs 21163dec9fcdSqs if (allocated < total_alloc_size) { 21173dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 21183dec9fcdSqs " hxge_alloc_tx_buf_dma: failed due to" 21193dec9fcdSqs " allocated(%d) < required(%d)", 21203dec9fcdSqs allocated, total_alloc_size)); 21213dec9fcdSqs goto hxge_alloc_tx_mem_fail1; 21223dec9fcdSqs } 21233dec9fcdSqs 21243dec9fcdSqs *num_chunks = i; 21253dec9fcdSqs *dmap = tx_dmap; 21263dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21273dec9fcdSqs "==> hxge_alloc_tx_buf_dma dmap 0x%016llx num chunks %d", 21283dec9fcdSqs *dmap, i)); 21293dec9fcdSqs goto hxge_alloc_tx_mem_exit; 21303dec9fcdSqs 21313dec9fcdSqs hxge_alloc_tx_mem_fail1: 21323dec9fcdSqs KMEM_FREE(tx_dmap, sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 21333dec9fcdSqs 21343dec9fcdSqs hxge_alloc_tx_mem_exit: 21353dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21363dec9fcdSqs "<== hxge_alloc_tx_buf_dma status 0x%08x", status)); 21373dec9fcdSqs 21383dec9fcdSqs return (status); 21393dec9fcdSqs } 21403dec9fcdSqs 21413dec9fcdSqs /*ARGSUSED*/ 21423dec9fcdSqs static void 21433dec9fcdSqs hxge_free_tx_buf_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap, 21443dec9fcdSqs uint32_t num_chunks) 21453dec9fcdSqs { 21463dec9fcdSqs int i; 21473dec9fcdSqs 21483dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "==> hxge_free_tx_buf_dma")); 21493dec9fcdSqs 21503dec9fcdSqs for (i = 0; i < num_chunks; i++) { 21513dec9fcdSqs hxge_dma_mem_free(dmap++); 21523dec9fcdSqs } 21533dec9fcdSqs 21543dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM_CTL, "<== hxge_free_tx_buf_dma")); 21553dec9fcdSqs } 21563dec9fcdSqs 21573dec9fcdSqs /*ARGSUSED*/ 21583dec9fcdSqs static hxge_status_t 21593dec9fcdSqs hxge_alloc_tx_cntl_dma(p_hxge_t hxgep, uint16_t dma_channel, 21603dec9fcdSqs p_hxge_dma_common_t *dmap, size_t size) 21613dec9fcdSqs { 21623dec9fcdSqs p_hxge_dma_common_t tx_dmap; 21633dec9fcdSqs hxge_status_t status = HXGE_OK; 21643dec9fcdSqs 21653dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_alloc_tx_cntl_dma")); 21663dec9fcdSqs 21673dec9fcdSqs tx_dmap = (p_hxge_dma_common_t)KMEM_ZALLOC(sizeof (hxge_dma_common_t), 21683dec9fcdSqs KM_SLEEP); 21693dec9fcdSqs 21703dec9fcdSqs tx_dmap->contig_alloc_type = B_FALSE; 21713dec9fcdSqs 21723dec9fcdSqs status = hxge_dma_mem_alloc(hxgep, hxge_force_dma, 21738ad8db65SMichael Speer &hxge_tx_desc_dma_attr, size, &hxge_dev_desc_dma_acc_attr, 21743dec9fcdSqs DDI_DMA_RDWR | DDI_DMA_CONSISTENT, tx_dmap); 21753dec9fcdSqs if (status != HXGE_OK) { 21763dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 21773dec9fcdSqs " hxge_alloc_tx_cntl_dma: Alloc Failed: " 21783dec9fcdSqs " for size: %d", size)); 21793dec9fcdSqs goto hxge_alloc_tx_cntl_dma_fail1; 21803dec9fcdSqs } 21813dec9fcdSqs 21823dec9fcdSqs *dmap = tx_dmap; 21833dec9fcdSqs 21843dec9fcdSqs goto hxge_alloc_tx_cntl_dma_exit; 21853dec9fcdSqs 21863dec9fcdSqs hxge_alloc_tx_cntl_dma_fail1: 21873dec9fcdSqs KMEM_FREE(tx_dmap, sizeof (hxge_dma_common_t)); 21883dec9fcdSqs 21893dec9fcdSqs hxge_alloc_tx_cntl_dma_exit: 21903dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 21913dec9fcdSqs "<== hxge_alloc_tx_cntl_dma status 0x%08x", status)); 21923dec9fcdSqs 21933dec9fcdSqs return (status); 21943dec9fcdSqs } 21953dec9fcdSqs 21963dec9fcdSqs /*ARGSUSED*/ 21973dec9fcdSqs static void 21983dec9fcdSqs hxge_free_tx_cntl_dma(p_hxge_t hxgep, p_hxge_dma_common_t dmap) 21993dec9fcdSqs { 22003dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_free_tx_cntl_dma")); 22013dec9fcdSqs 22023dec9fcdSqs hxge_dma_mem_free(dmap); 22033dec9fcdSqs 22043dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_free_tx_cntl_dma")); 22053dec9fcdSqs } 22063dec9fcdSqs 22073dec9fcdSqs static void 22083dec9fcdSqs hxge_free_tx_mem_pool(p_hxge_t hxgep) 22093dec9fcdSqs { 22103dec9fcdSqs uint32_t i, ndmas; 22113dec9fcdSqs p_hxge_dma_pool_t dma_poolp; 22123dec9fcdSqs p_hxge_dma_common_t *dma_buf_p; 22133dec9fcdSqs p_hxge_dma_pool_t dma_cntl_poolp; 22143dec9fcdSqs p_hxge_dma_common_t *dma_cntl_p; 22153dec9fcdSqs uint32_t *num_chunks; 22163dec9fcdSqs 22173dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, "==> hxge_free_tx_mem_pool")); 22183dec9fcdSqs 22193dec9fcdSqs dma_poolp = hxgep->tx_buf_pool_p; 22203dec9fcdSqs if (dma_poolp == NULL || (!dma_poolp->buf_allocated)) { 22213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, 22223dec9fcdSqs "<== hxge_free_tx_mem_pool " 22233dec9fcdSqs "(null rx buf pool or buf not allocated")); 22243dec9fcdSqs return; 22253dec9fcdSqs } 22263dec9fcdSqs 22273dec9fcdSqs dma_cntl_poolp = hxgep->tx_cntl_pool_p; 22283dec9fcdSqs if (dma_cntl_poolp == NULL || (!dma_cntl_poolp->buf_allocated)) { 22293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, 22303dec9fcdSqs "<== hxge_free_tx_mem_pool " 22313dec9fcdSqs "(null tx cntl buf pool or cntl buf not allocated")); 22323dec9fcdSqs return; 22333dec9fcdSqs } 22343dec9fcdSqs 22353dec9fcdSqs dma_buf_p = dma_poolp->dma_buf_pool_p; 22363dec9fcdSqs num_chunks = dma_poolp->num_chunks; 22373dec9fcdSqs 22383dec9fcdSqs dma_cntl_p = dma_cntl_poolp->dma_buf_pool_p; 22393dec9fcdSqs ndmas = dma_cntl_poolp->ndmas; 22403dec9fcdSqs 22413dec9fcdSqs for (i = 0; i < ndmas; i++) { 22423dec9fcdSqs hxge_free_tx_buf_dma(hxgep, dma_buf_p[i], num_chunks[i]); 22433dec9fcdSqs } 22443dec9fcdSqs 22453dec9fcdSqs for (i = 0; i < ndmas; i++) { 22463dec9fcdSqs hxge_free_tx_cntl_dma(hxgep, dma_cntl_p[i]); 22473dec9fcdSqs } 22483dec9fcdSqs 22493dec9fcdSqs for (i = 0; i < ndmas; i++) { 22503dec9fcdSqs KMEM_FREE(dma_buf_p[i], 22513dec9fcdSqs sizeof (hxge_dma_common_t) * HXGE_DMA_BLOCK); 22523dec9fcdSqs KMEM_FREE(dma_cntl_p[i], sizeof (hxge_dma_common_t)); 22533dec9fcdSqs } 22543dec9fcdSqs 22553dec9fcdSqs KMEM_FREE(num_chunks, sizeof (uint32_t) * ndmas); 22563dec9fcdSqs KMEM_FREE(dma_cntl_p, ndmas * sizeof (p_hxge_dma_common_t)); 22573dec9fcdSqs KMEM_FREE(dma_cntl_poolp, sizeof (hxge_dma_pool_t)); 22583dec9fcdSqs KMEM_FREE(dma_buf_p, ndmas * sizeof (p_hxge_dma_common_t)); 22593dec9fcdSqs KMEM_FREE(dma_poolp, sizeof (hxge_dma_pool_t)); 22603dec9fcdSqs 22613dec9fcdSqs hxgep->tx_buf_pool_p = NULL; 22623dec9fcdSqs hxgep->tx_cntl_pool_p = NULL; 22633dec9fcdSqs 22643dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MEM3_CTL, "<== hxge_free_tx_mem_pool")); 22653dec9fcdSqs } 22663dec9fcdSqs 22673dec9fcdSqs /*ARGSUSED*/ 22683dec9fcdSqs static hxge_status_t 22693dec9fcdSqs hxge_dma_mem_alloc(p_hxge_t hxgep, dma_method_t method, 22703dec9fcdSqs struct ddi_dma_attr *dma_attrp, 22713dec9fcdSqs size_t length, ddi_device_acc_attr_t *acc_attr_p, uint_t xfer_flags, 22723dec9fcdSqs p_hxge_dma_common_t dma_p) 22733dec9fcdSqs { 22743dec9fcdSqs caddr_t kaddrp; 22753dec9fcdSqs int ddi_status = DDI_SUCCESS; 22763dec9fcdSqs 22773dec9fcdSqs dma_p->dma_handle = NULL; 22783dec9fcdSqs dma_p->acc_handle = NULL; 22793dec9fcdSqs dma_p->kaddrp = NULL; 22803dec9fcdSqs 22813dec9fcdSqs ddi_status = ddi_dma_alloc_handle(hxgep->dip, dma_attrp, 22823dec9fcdSqs DDI_DMA_DONTWAIT, NULL, &dma_p->dma_handle); 22833dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 22843dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 22853dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_alloc_handle failed.")); 22863dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 22873dec9fcdSqs } 22883dec9fcdSqs 22893dec9fcdSqs ddi_status = ddi_dma_mem_alloc(dma_p->dma_handle, length, acc_attr_p, 22903dec9fcdSqs xfer_flags, DDI_DMA_DONTWAIT, 0, &kaddrp, &dma_p->alength, 22913dec9fcdSqs &dma_p->acc_handle); 22923dec9fcdSqs if (ddi_status != DDI_SUCCESS) { 22933dec9fcdSqs /* The caller will decide whether it is fatal */ 22943dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 22953dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_mem_alloc failed")); 22963dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 22973dec9fcdSqs dma_p->dma_handle = NULL; 22983dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 22993dec9fcdSqs } 23003dec9fcdSqs 23013dec9fcdSqs if (dma_p->alength < length) { 23023dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 23033dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_mem_alloc < length.")); 23043dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23053dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23063dec9fcdSqs dma_p->acc_handle = NULL; 23073dec9fcdSqs dma_p->dma_handle = NULL; 23083dec9fcdSqs return (HXGE_ERROR); 23093dec9fcdSqs } 23103dec9fcdSqs 23113dec9fcdSqs ddi_status = ddi_dma_addr_bind_handle(dma_p->dma_handle, NULL, 23123dec9fcdSqs kaddrp, dma_p->alength, xfer_flags, DDI_DMA_DONTWAIT, 0, 23133dec9fcdSqs &dma_p->dma_cookie, &dma_p->ncookies); 23143dec9fcdSqs if (ddi_status != DDI_DMA_MAPPED) { 23153dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 23163dec9fcdSqs "hxge_dma_mem_alloc:di_dma_addr_bind failed " 23173dec9fcdSqs "(staus 0x%x ncookies %d.)", ddi_status, dma_p->ncookies)); 23183dec9fcdSqs if (dma_p->acc_handle) { 23193dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23203dec9fcdSqs dma_p->acc_handle = NULL; 23213dec9fcdSqs } 23223dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23233dec9fcdSqs dma_p->dma_handle = NULL; 23243dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 23253dec9fcdSqs } 23263dec9fcdSqs 23273dec9fcdSqs if (dma_p->ncookies != 1) { 23283dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, 23293dec9fcdSqs "hxge_dma_mem_alloc:ddi_dma_addr_bind > 1 cookie" 23303dec9fcdSqs "(staus 0x%x ncookies %d.)", ddi_status, dma_p->ncookies)); 23313dec9fcdSqs if (dma_p->acc_handle) { 23323dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23333dec9fcdSqs dma_p->acc_handle = NULL; 23343dec9fcdSqs } 23353dec9fcdSqs (void) ddi_dma_unbind_handle(dma_p->dma_handle); 23363dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23373dec9fcdSqs dma_p->dma_handle = NULL; 23383dec9fcdSqs return (HXGE_ERROR); 23393dec9fcdSqs } 23403dec9fcdSqs 23413dec9fcdSqs dma_p->kaddrp = kaddrp; 23423dec9fcdSqs #if defined(__i386) 23433dec9fcdSqs dma_p->ioaddr_pp = 23443dec9fcdSqs (unsigned char *)(uint32_t)dma_p->dma_cookie.dmac_laddress; 23453dec9fcdSqs #else 23463dec9fcdSqs dma_p->ioaddr_pp = (unsigned char *) dma_p->dma_cookie.dmac_laddress; 23473dec9fcdSqs #endif 23483dec9fcdSqs 23493dec9fcdSqs HPI_DMA_ACC_HANDLE_SET(dma_p, dma_p->acc_handle); 23503dec9fcdSqs 23513dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_dma_mem_alloc: " 23523dec9fcdSqs "dma buffer allocated: dma_p $%p " 23533dec9fcdSqs "return dmac_ladress from cookie $%p dmac_size %d " 23543dec9fcdSqs "dma_p->ioaddr_p $%p " 23553dec9fcdSqs "dma_p->orig_ioaddr_p $%p " 23563dec9fcdSqs "orig_vatopa $%p " 23573dec9fcdSqs "alength %d (0x%x) " 23583dec9fcdSqs "kaddrp $%p " 23593dec9fcdSqs "length %d (0x%x)", 23603dec9fcdSqs dma_p, 23613dec9fcdSqs dma_p->dma_cookie.dmac_laddress, 23623dec9fcdSqs dma_p->dma_cookie.dmac_size, 23633dec9fcdSqs dma_p->ioaddr_pp, 23643dec9fcdSqs dma_p->orig_ioaddr_pp, 23653dec9fcdSqs dma_p->orig_vatopa, 23663dec9fcdSqs dma_p->alength, dma_p->alength, 23673dec9fcdSqs kaddrp, 23683dec9fcdSqs length, length)); 23693dec9fcdSqs 23703dec9fcdSqs return (HXGE_OK); 23713dec9fcdSqs } 23723dec9fcdSqs 23733dec9fcdSqs static void 23743dec9fcdSqs hxge_dma_mem_free(p_hxge_dma_common_t dma_p) 23753dec9fcdSqs { 23768ad8db65SMichael Speer if (dma_p == NULL) 23778ad8db65SMichael Speer return; 23788ad8db65SMichael Speer 23793dec9fcdSqs if (dma_p->dma_handle != NULL) { 23803dec9fcdSqs if (dma_p->ncookies) { 23813dec9fcdSqs (void) ddi_dma_unbind_handle(dma_p->dma_handle); 23823dec9fcdSqs dma_p->ncookies = 0; 23833dec9fcdSqs } 23843dec9fcdSqs ddi_dma_free_handle(&dma_p->dma_handle); 23853dec9fcdSqs dma_p->dma_handle = NULL; 23863dec9fcdSqs } 23878ad8db65SMichael Speer 23883dec9fcdSqs if (dma_p->acc_handle != NULL) { 23893dec9fcdSqs ddi_dma_mem_free(&dma_p->acc_handle); 23903dec9fcdSqs dma_p->acc_handle = NULL; 23913dec9fcdSqs HPI_DMA_ACC_HANDLE_SET(dma_p, NULL); 23923dec9fcdSqs } 23938ad8db65SMichael Speer 23943dec9fcdSqs dma_p->kaddrp = NULL; 23953dec9fcdSqs dma_p->alength = NULL; 23963dec9fcdSqs } 23973dec9fcdSqs 23983dec9fcdSqs /* 23993dec9fcdSqs * hxge_m_start() -- start transmitting and receiving. 24003dec9fcdSqs * 24013dec9fcdSqs * This function is called by the MAC layer when the first 24023dec9fcdSqs * stream is open to prepare the hardware ready for sending 24033dec9fcdSqs * and transmitting packets. 24043dec9fcdSqs */ 24053dec9fcdSqs static int 24063dec9fcdSqs hxge_m_start(void *arg) 24073dec9fcdSqs { 24083dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24093dec9fcdSqs 24103dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_start")); 24113dec9fcdSqs 24123dec9fcdSqs MUTEX_ENTER(hxgep->genlock); 24133dec9fcdSqs 24143dec9fcdSqs if (hxge_init(hxgep) != DDI_SUCCESS) { 24153dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 24163dec9fcdSqs "<== hxge_m_start: initialization failed")); 24173dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24183dec9fcdSqs return (EIO); 24193dec9fcdSqs } 24203dec9fcdSqs 24213dec9fcdSqs if (hxgep->hxge_mac_state != HXGE_MAC_STARTED) { 24223dec9fcdSqs /* 24233dec9fcdSqs * Start timer to check the system error and tx hangs 24243dec9fcdSqs */ 24253dec9fcdSqs hxgep->hxge_timerid = hxge_start_timer(hxgep, 24263dec9fcdSqs hxge_check_hw_state, HXGE_CHECK_TIMER); 24273dec9fcdSqs 24283dec9fcdSqs hxgep->hxge_mac_state = HXGE_MAC_STARTED; 2429e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 2430e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.link_status = 0; 2431e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.report_link_status = B_TRUE; 2432e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks = drv_usectohz(2 * 1000000); 2433e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 2434e5d97391SQiyan Sun - Sun Microsystems - San Diego United States /* Start the link status timer to check the link status */ 2435e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 2436e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = timeout(hxge_link_poll, (void *)hxgep, 2437e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.ticks); 2438e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 24393dec9fcdSqs } 24403dec9fcdSqs 24413dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24423dec9fcdSqs 24433dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_start")); 24443dec9fcdSqs 24453dec9fcdSqs return (0); 24463dec9fcdSqs } 24473dec9fcdSqs 24483dec9fcdSqs /* 24493dec9fcdSqs * hxge_m_stop(): stop transmitting and receiving. 24503dec9fcdSqs */ 24513dec9fcdSqs static void 24523dec9fcdSqs hxge_m_stop(void *arg) 24533dec9fcdSqs { 24543dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24553dec9fcdSqs 24563dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_stop")); 24573dec9fcdSqs 24583dec9fcdSqs if (hxgep->hxge_timerid) { 24593dec9fcdSqs hxge_stop_timer(hxgep, hxgep->hxge_timerid); 24603dec9fcdSqs hxgep->hxge_timerid = 0; 24613dec9fcdSqs } 24623dec9fcdSqs 2463e5d97391SQiyan Sun - Sun Microsystems - San Diego United States /* Stop the link status timer before unregistering */ 2464e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&hxgep->timeout.lock); 2465e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->timeout.id) { 2466e5d97391SQiyan Sun - Sun Microsystems - San Diego United States (void) untimeout(hxgep->timeout.id); 2467e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxgep->timeout.id = 0; 2468e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 2469e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_DOWN); 2470e5d97391SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&hxgep->timeout.lock); 2471e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 24723dec9fcdSqs MUTEX_ENTER(hxgep->genlock); 24733dec9fcdSqs 24743dec9fcdSqs hxge_uninit(hxgep); 24753dec9fcdSqs 24763dec9fcdSqs hxgep->hxge_mac_state = HXGE_MAC_STOPPED; 24773dec9fcdSqs 24783dec9fcdSqs MUTEX_EXIT(hxgep->genlock); 24793dec9fcdSqs 24803dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_stop")); 24813dec9fcdSqs } 24823dec9fcdSqs 24833dec9fcdSqs static int 24843dec9fcdSqs hxge_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 24853dec9fcdSqs { 24863dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 24873dec9fcdSqs struct ether_addr addrp; 24883dec9fcdSqs 24893dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_m_multicst: add %d", add)); 24903dec9fcdSqs 24913dec9fcdSqs bcopy(mca, (uint8_t *)&addrp, ETHERADDRL); 24923dec9fcdSqs 24933dec9fcdSqs if (add) { 24943dec9fcdSqs if (hxge_add_mcast_addr(hxgep, &addrp)) { 24953dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 24963dec9fcdSqs "<== hxge_m_multicst: add multicast failed")); 24973dec9fcdSqs return (EINVAL); 24983dec9fcdSqs } 24993dec9fcdSqs } else { 25003dec9fcdSqs if (hxge_del_mcast_addr(hxgep, &addrp)) { 25013dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25023dec9fcdSqs "<== hxge_m_multicst: del multicast failed")); 25033dec9fcdSqs return (EINVAL); 25043dec9fcdSqs } 25053dec9fcdSqs } 25063dec9fcdSqs 25073dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_m_multicst")); 25083dec9fcdSqs 25093dec9fcdSqs return (0); 25103dec9fcdSqs } 25113dec9fcdSqs 25123dec9fcdSqs static int 25133dec9fcdSqs hxge_m_promisc(void *arg, boolean_t on) 25143dec9fcdSqs { 25153dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 25163dec9fcdSqs 25173dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "==> hxge_m_promisc: on %d", on)); 25183dec9fcdSqs 25193dec9fcdSqs if (hxge_set_promisc(hxgep, on)) { 25203dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25213dec9fcdSqs "<== hxge_m_promisc: set promisc failed")); 25223dec9fcdSqs return (EINVAL); 25233dec9fcdSqs } 25243dec9fcdSqs 25253dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MAC_CTL, "<== hxge_m_promisc: on %d", on)); 25263dec9fcdSqs 25273dec9fcdSqs return (0); 25283dec9fcdSqs } 25293dec9fcdSqs 25303dec9fcdSqs static void 25313dec9fcdSqs hxge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 25323dec9fcdSqs { 25333dec9fcdSqs p_hxge_t hxgep = (p_hxge_t)arg; 25343dec9fcdSqs struct iocblk *iocp = (struct iocblk *)mp->b_rptr; 25353dec9fcdSqs boolean_t need_privilege; 25363dec9fcdSqs int err; 25373dec9fcdSqs int cmd; 25383dec9fcdSqs 25393dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_ioctl")); 25403dec9fcdSqs 25413dec9fcdSqs iocp = (struct iocblk *)mp->b_rptr; 25423dec9fcdSqs iocp->ioc_error = 0; 25433dec9fcdSqs need_privilege = B_TRUE; 25443dec9fcdSqs cmd = iocp->ioc_cmd; 25453dec9fcdSqs 25463dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "==> hxge_m_ioctl: cmd 0x%08x", cmd)); 25473dec9fcdSqs switch (cmd) { 25483dec9fcdSqs default: 25493dec9fcdSqs miocnak(wq, mp, 0, EINVAL); 25503dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_ioctl: invalid")); 25513dec9fcdSqs return; 25523dec9fcdSqs 25533dec9fcdSqs case LB_GET_INFO_SIZE: 25543dec9fcdSqs case LB_GET_INFO: 25553dec9fcdSqs case LB_GET_MODE: 25563dec9fcdSqs need_privilege = B_FALSE; 25573dec9fcdSqs break; 25583dec9fcdSqs 25593dec9fcdSqs case LB_SET_MODE: 25603dec9fcdSqs break; 25613dec9fcdSqs 25623dec9fcdSqs case ND_GET: 25633dec9fcdSqs need_privilege = B_FALSE; 25643dec9fcdSqs break; 25653dec9fcdSqs case ND_SET: 25663dec9fcdSqs break; 25673dec9fcdSqs 25683dec9fcdSqs case HXGE_GET_TX_RING_SZ: 25693dec9fcdSqs case HXGE_GET_TX_DESC: 25703dec9fcdSqs case HXGE_TX_SIDE_RESET: 25713dec9fcdSqs case HXGE_RX_SIDE_RESET: 25723dec9fcdSqs case HXGE_GLOBAL_RESET: 25733dec9fcdSqs case HXGE_RESET_MAC: 25743dec9fcdSqs case HXGE_PUT_TCAM: 25753dec9fcdSqs case HXGE_GET_TCAM: 25763dec9fcdSqs case HXGE_RTRACE: 25773dec9fcdSqs 25783dec9fcdSqs need_privilege = B_FALSE; 25793dec9fcdSqs break; 25803dec9fcdSqs } 25813dec9fcdSqs 25823dec9fcdSqs if (need_privilege) { 25833dec9fcdSqs err = secpolicy_net_config(iocp->ioc_cr, B_FALSE); 25843dec9fcdSqs if (err != 0) { 25853dec9fcdSqs miocnak(wq, mp, 0, err); 25863dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 25873dec9fcdSqs "<== hxge_m_ioctl: no priv")); 25883dec9fcdSqs return; 25893dec9fcdSqs } 25903dec9fcdSqs } 25913dec9fcdSqs 25923dec9fcdSqs switch (cmd) { 25933dec9fcdSqs case ND_GET: 25943dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "ND_GET command")); 25953dec9fcdSqs case ND_SET: 25963dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "ND_SET command")); 25973dec9fcdSqs hxge_param_ioctl(hxgep, wq, mp, iocp); 25983dec9fcdSqs break; 25993dec9fcdSqs 26003dec9fcdSqs case LB_GET_MODE: 26013dec9fcdSqs case LB_SET_MODE: 26023dec9fcdSqs case LB_GET_INFO_SIZE: 26033dec9fcdSqs case LB_GET_INFO: 26043dec9fcdSqs hxge_loopback_ioctl(hxgep, wq, mp, iocp); 26053dec9fcdSqs break; 26063dec9fcdSqs 26073dec9fcdSqs case HXGE_PUT_TCAM: 26083dec9fcdSqs case HXGE_GET_TCAM: 26093dec9fcdSqs case HXGE_GET_TX_RING_SZ: 26103dec9fcdSqs case HXGE_GET_TX_DESC: 26113dec9fcdSqs case HXGE_TX_SIDE_RESET: 26123dec9fcdSqs case HXGE_RX_SIDE_RESET: 26133dec9fcdSqs case HXGE_GLOBAL_RESET: 26143dec9fcdSqs case HXGE_RESET_MAC: 26153dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, 26163dec9fcdSqs "==> hxge_m_ioctl: cmd 0x%x", cmd)); 26173dec9fcdSqs hxge_hw_ioctl(hxgep, wq, mp, iocp); 26183dec9fcdSqs break; 26193dec9fcdSqs } 26203dec9fcdSqs 26213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, NEMO_CTL, "<== hxge_m_ioctl")); 26223dec9fcdSqs } 26233dec9fcdSqs 26241ed83081SMichael Speer /*ARGSUSED*/ 26251ed83081SMichael Speer static int 26261ed83081SMichael Speer hxge_tx_ring_start(mac_ring_driver_t rdriver, uint64_t mr_gen_num) 26271ed83081SMichael Speer { 26281ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26291ed83081SMichael Speer p_hxge_t hxgep; 26301ed83081SMichael Speer p_tx_ring_t ring; 26311ed83081SMichael Speer 26321ed83081SMichael Speer ASSERT(rhp != NULL); 26331ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26341ed83081SMichael Speer 26351ed83081SMichael Speer hxgep = rhp->hxgep; 26361ed83081SMichael Speer 26371ed83081SMichael Speer /* 26381ed83081SMichael Speer * Get the ring pointer. 26391ed83081SMichael Speer */ 26401ed83081SMichael Speer ring = hxgep->tx_rings->rings[rhp->index]; 26411ed83081SMichael Speer 26421ed83081SMichael Speer /* 26431ed83081SMichael Speer * Fill in the handle for the transmit. 26441ed83081SMichael Speer */ 26451ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26466ffca240SMichael Speer rhp->started = B_TRUE; 26471ed83081SMichael Speer ring->ring_handle = rhp->ring_handle; 26481ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26491ed83081SMichael Speer 26501ed83081SMichael Speer return (0); 26511ed83081SMichael Speer } 26521ed83081SMichael Speer 26531ed83081SMichael Speer static void 26541ed83081SMichael Speer hxge_tx_ring_stop(mac_ring_driver_t rdriver) 26551ed83081SMichael Speer { 26561ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26571ed83081SMichael Speer p_hxge_t hxgep; 26581ed83081SMichael Speer p_tx_ring_t ring; 26591ed83081SMichael Speer 26601ed83081SMichael Speer ASSERT(rhp != NULL); 26611ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26621ed83081SMichael Speer 26631ed83081SMichael Speer hxgep = rhp->hxgep; 26641ed83081SMichael Speer ring = hxgep->tx_rings->rings[rhp->index]; 26651ed83081SMichael Speer 26661ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26671ed83081SMichael Speer ring->ring_handle = (mac_ring_handle_t)NULL; 26686ffca240SMichael Speer rhp->started = B_FALSE; 26691ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26701ed83081SMichael Speer } 26711ed83081SMichael Speer 26721ed83081SMichael Speer static int 26731ed83081SMichael Speer hxge_rx_ring_start(mac_ring_driver_t rdriver, uint64_t mr_gen_num) 26741ed83081SMichael Speer { 26751ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 26761ed83081SMichael Speer p_hxge_t hxgep; 26771ed83081SMichael Speer p_rx_rcr_ring_t ring; 26781ed83081SMichael Speer int i; 26791ed83081SMichael Speer 26801ed83081SMichael Speer ASSERT(rhp != NULL); 26811ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 26821ed83081SMichael Speer 26831ed83081SMichael Speer hxgep = rhp->hxgep; 26841ed83081SMichael Speer 26851ed83081SMichael Speer /* 26861ed83081SMichael Speer * Get pointer to ring. 26871ed83081SMichael Speer */ 26881ed83081SMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index]; 26891ed83081SMichael Speer 26901ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 26911ed83081SMichael Speer 26921ed83081SMichael Speer if (rhp->started) { 26931ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 26941ed83081SMichael Speer return (0); 26951ed83081SMichael Speer } 26961ed83081SMichael Speer 26971ed83081SMichael Speer /* 26981ed83081SMichael Speer * Set the ldvp and ldgp pointers to enable/disable 26991ed83081SMichael Speer * polling. 27001ed83081SMichael Speer */ 27011ed83081SMichael Speer for (i = 0; i < hxgep->ldgvp->maxldvs; i++) { 27021ed83081SMichael Speer if ((hxgep->ldgvp->ldvp[i].is_rxdma == 1) && 27031ed83081SMichael Speer (hxgep->ldgvp->ldvp[i].channel == rhp->index)) { 27041ed83081SMichael Speer ring->ldvp = &hxgep->ldgvp->ldvp[i]; 27051ed83081SMichael Speer ring->ldgp = hxgep->ldgvp->ldvp[i].ldgp; 27061ed83081SMichael Speer break; 27071ed83081SMichael Speer } 27081ed83081SMichael Speer } 27091ed83081SMichael Speer 27101ed83081SMichael Speer rhp->started = B_TRUE; 27111ed83081SMichael Speer ring->rcr_mac_handle = rhp->ring_handle; 27121ed83081SMichael Speer ring->rcr_gen_num = mr_gen_num; 27131ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 27141ed83081SMichael Speer 27151ed83081SMichael Speer return (0); 27161ed83081SMichael Speer } 27171ed83081SMichael Speer 27181ed83081SMichael Speer static void 27191ed83081SMichael Speer hxge_rx_ring_stop(mac_ring_driver_t rdriver) 27201ed83081SMichael Speer { 27211ed83081SMichael Speer p_hxge_ring_handle_t rhp = (p_hxge_ring_handle_t)rdriver; 27221ed83081SMichael Speer p_hxge_t hxgep; 27231ed83081SMichael Speer p_rx_rcr_ring_t ring; 27241ed83081SMichael Speer 27251ed83081SMichael Speer ASSERT(rhp != NULL); 27261ed83081SMichael Speer ASSERT((rhp->index >= 0) && (rhp->index < HXGE_MAX_TDCS)); 27271ed83081SMichael Speer 27281ed83081SMichael Speer hxgep = rhp->hxgep; 27291ed83081SMichael Speer ring = hxgep->rx_rcr_rings->rcr_rings[rhp->index]; 27301ed83081SMichael Speer 27311ed83081SMichael Speer MUTEX_ENTER(&ring->lock); 27321ed83081SMichael Speer rhp->started = B_TRUE; 27331ed83081SMichael Speer ring->rcr_mac_handle = NULL; 27341ed83081SMichael Speer ring->ldvp = NULL; 27351ed83081SMichael Speer ring->ldgp = NULL; 27361ed83081SMichael Speer MUTEX_EXIT(&ring->lock); 27371ed83081SMichael Speer } 27381ed83081SMichael Speer 27391ed83081SMichael Speer static int 27401ed83081SMichael Speer hxge_rx_group_start(mac_group_driver_t gdriver) 27411ed83081SMichael Speer { 27421ed83081SMichael Speer hxge_ring_group_t *group = (hxge_ring_group_t *)gdriver; 27431ed83081SMichael Speer 27441ed83081SMichael Speer ASSERT(group->hxgep != NULL); 27451ed83081SMichael Speer ASSERT(group->hxgep->hxge_mac_state == HXGE_MAC_STARTED); 27461ed83081SMichael Speer 27471ed83081SMichael Speer MUTEX_ENTER(group->hxgep->genlock); 27481ed83081SMichael Speer group->started = B_TRUE; 27491ed83081SMichael Speer MUTEX_EXIT(group->hxgep->genlock); 27501ed83081SMichael Speer 27511ed83081SMichael Speer return (0); 27521ed83081SMichael Speer } 27531ed83081SMichael Speer 27541ed83081SMichael Speer static void 27551ed83081SMichael Speer hxge_rx_group_stop(mac_group_driver_t gdriver) 27561ed83081SMichael Speer { 27571ed83081SMichael Speer hxge_ring_group_t *group = (hxge_ring_group_t *)gdriver; 27581ed83081SMichael Speer 27591ed83081SMichael Speer ASSERT(group->hxgep != NULL); 27601ed83081SMichael Speer ASSERT(group->hxgep->hxge_mac_state == HXGE_MAC_STARTED); 27611ed83081SMichael Speer ASSERT(group->started == B_TRUE); 27621ed83081SMichael Speer 27631ed83081SMichael Speer MUTEX_ENTER(group->hxgep->genlock); 27641ed83081SMichael Speer group->started = B_FALSE; 27651ed83081SMichael Speer MUTEX_EXIT(group->hxgep->genlock); 27661ed83081SMichael Speer } 27671ed83081SMichael Speer 27681ed83081SMichael Speer static int 27691ed83081SMichael Speer hxge_mmac_get_slot(p_hxge_t hxgep, int *slot) 27701ed83081SMichael Speer { 27711ed83081SMichael Speer int i; 27721ed83081SMichael Speer 27731ed83081SMichael Speer /* 27741ed83081SMichael Speer * Find an open slot. 27751ed83081SMichael Speer */ 27761ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 27771ed83081SMichael Speer if (!hxgep->mmac.addrs[i].set) { 27781ed83081SMichael Speer *slot = i; 27791ed83081SMichael Speer return (0); 27801ed83081SMichael Speer } 27811ed83081SMichael Speer } 27821ed83081SMichael Speer 27831ed83081SMichael Speer return (ENXIO); 27841ed83081SMichael Speer } 27851ed83081SMichael Speer 27861ed83081SMichael Speer static int 27871ed83081SMichael Speer hxge_mmac_set_addr(p_hxge_t hxgep, int slot, const uint8_t *addr) 27881ed83081SMichael Speer { 27891ed83081SMichael Speer struct ether_addr eaddr; 27901ed83081SMichael Speer hxge_status_t status = HXGE_OK; 27911ed83081SMichael Speer 27921ed83081SMichael Speer bcopy(addr, (uint8_t *)&eaddr, ETHERADDRL); 27931ed83081SMichael Speer 27941ed83081SMichael Speer /* 27951ed83081SMichael Speer * Set new interface local address and re-init device. 27961ed83081SMichael Speer * This is destructive to any other streams attached 27971ed83081SMichael Speer * to this device. 27981ed83081SMichael Speer */ 27991ed83081SMichael Speer RW_ENTER_WRITER(&hxgep->filter_lock); 28001ed83081SMichael Speer status = hxge_pfc_set_mac_address(hxgep, slot, &eaddr); 28011ed83081SMichael Speer RW_EXIT(&hxgep->filter_lock); 28021ed83081SMichael Speer if (status != HXGE_OK) 28031ed83081SMichael Speer return (status); 28041ed83081SMichael Speer 28051ed83081SMichael Speer hxgep->mmac.addrs[slot].set = B_TRUE; 28061ed83081SMichael Speer bcopy(addr, hxgep->mmac.addrs[slot].addr, ETHERADDRL); 28071ed83081SMichael Speer hxgep->mmac.available--; 28081ed83081SMichael Speer if (slot == HXGE_MAC_DEFAULT_ADDR_SLOT) 28091ed83081SMichael Speer hxgep->mmac.addrs[slot].primary = B_TRUE; 28101ed83081SMichael Speer 28111ed83081SMichael Speer return (0); 28121ed83081SMichael Speer } 28131ed83081SMichael Speer 28141ed83081SMichael Speer static int 28151ed83081SMichael Speer hxge_mmac_find_addr(p_hxge_t hxgep, const uint8_t *addr, int *slot) 28161ed83081SMichael Speer { 28171ed83081SMichael Speer int i, result; 28181ed83081SMichael Speer 28191ed83081SMichael Speer for (i = 0; i < hxgep->mmac.total; i++) { 28201ed83081SMichael Speer if (hxgep->mmac.addrs[i].set) { 28211ed83081SMichael Speer result = memcmp(hxgep->mmac.addrs[i].addr, 28221ed83081SMichael Speer addr, ETHERADDRL); 28231ed83081SMichael Speer if (result == 0) { 28241ed83081SMichael Speer *slot = i; 28251ed83081SMichael Speer return (0); 28261ed83081SMichael Speer } 28271ed83081SMichael Speer } 28281ed83081SMichael Speer } 28291ed83081SMichael Speer 28301ed83081SMichael Speer return (EINVAL); 28311ed83081SMichael Speer } 28321ed83081SMichael Speer 28331ed83081SMichael Speer static int 28341ed83081SMichael Speer hxge_mmac_unset_addr(p_hxge_t hxgep, int slot) 28351ed83081SMichael Speer { 28361ed83081SMichael Speer hxge_status_t status; 28371ed83081SMichael Speer int i; 28381ed83081SMichael Speer 28391ed83081SMichael Speer status = hxge_pfc_clear_mac_address(hxgep, slot); 28401ed83081SMichael Speer if (status != HXGE_OK) 28411ed83081SMichael Speer return (status); 28421ed83081SMichael Speer 28431ed83081SMichael Speer for (i = 0; i < ETHERADDRL; i++) 28441ed83081SMichael Speer hxgep->mmac.addrs[slot].addr[i] = 0; 28451ed83081SMichael Speer 28461ed83081SMichael Speer hxgep->mmac.addrs[slot].set = B_FALSE; 28471ed83081SMichael Speer if (slot == HXGE_MAC_DEFAULT_ADDR_SLOT) 28481ed83081SMichael Speer hxgep->mmac.addrs[slot].primary = B_FALSE; 28491ed83081SMichael Speer hxgep->mmac.available++; 28501ed83081SMichael Speer 28511ed83081SMichael Speer return (0); 28521ed83081SMichael Speer } 28531ed83081SMichael Speer 28541ed83081SMichael Speer static int 28551ed83081SMichael Speer hxge_rx_group_add_mac(void *arg, const uint8_t *mac_addr) 28561ed83081SMichael Speer { 28571ed83081SMichael Speer hxge_ring_group_t *group = arg; 28581ed83081SMichael Speer p_hxge_t hxgep = group->hxgep; 28591ed83081SMichael Speer int slot = 0; 28601ed83081SMichael Speer 28611ed83081SMichael Speer ASSERT(group->type == MAC_RING_TYPE_RX); 28621ed83081SMichael Speer 28631ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 28641ed83081SMichael Speer 28651ed83081SMichael Speer /* 28661ed83081SMichael Speer * Find a slot for the address. 28671ed83081SMichael Speer */ 28681ed83081SMichael Speer if (hxge_mmac_get_slot(hxgep, &slot) != 0) { 28691ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28701ed83081SMichael Speer return (ENOSPC); 28711ed83081SMichael Speer } 28721ed83081SMichael Speer 28731ed83081SMichael Speer /* 28741ed83081SMichael Speer * Program the MAC address. 28751ed83081SMichael Speer */ 28761ed83081SMichael Speer if (hxge_mmac_set_addr(hxgep, slot, mac_addr) != 0) { 28771ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28781ed83081SMichael Speer return (ENOSPC); 28791ed83081SMichael Speer } 28801ed83081SMichael Speer 28811ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28821ed83081SMichael Speer return (0); 28831ed83081SMichael Speer } 28841ed83081SMichael Speer 28851ed83081SMichael Speer static int 28861ed83081SMichael Speer hxge_rx_group_rem_mac(void *arg, const uint8_t *mac_addr) 28871ed83081SMichael Speer { 28881ed83081SMichael Speer hxge_ring_group_t *group = arg; 28891ed83081SMichael Speer p_hxge_t hxgep = group->hxgep; 28901ed83081SMichael Speer int rv, slot; 28911ed83081SMichael Speer 28921ed83081SMichael Speer ASSERT(group->type == MAC_RING_TYPE_RX); 28931ed83081SMichael Speer 28941ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 28951ed83081SMichael Speer 28961ed83081SMichael Speer if ((rv = hxge_mmac_find_addr(hxgep, mac_addr, &slot)) != 0) { 28971ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 28981ed83081SMichael Speer return (rv); 28991ed83081SMichael Speer } 29001ed83081SMichael Speer 29011ed83081SMichael Speer if ((rv = hxge_mmac_unset_addr(hxgep, slot)) != 0) { 29021ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 29031ed83081SMichael Speer return (rv); 29041ed83081SMichael Speer } 29051ed83081SMichael Speer 29061ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 29071ed83081SMichael Speer return (0); 29081ed83081SMichael Speer } 29091ed83081SMichael Speer 29101ed83081SMichael Speer static void 29111ed83081SMichael Speer hxge_group_get(void *arg, mac_ring_type_t type, int groupid, 29121ed83081SMichael Speer mac_group_info_t *infop, mac_group_handle_t gh) 29131ed83081SMichael Speer { 29141ed83081SMichael Speer p_hxge_t hxgep = arg; 29151ed83081SMichael Speer hxge_ring_group_t *group; 29161ed83081SMichael Speer 29171ed83081SMichael Speer ASSERT(type == MAC_RING_TYPE_RX); 29181ed83081SMichael Speer 29191ed83081SMichael Speer switch (type) { 29201ed83081SMichael Speer case MAC_RING_TYPE_RX: 29211ed83081SMichael Speer group = &hxgep->rx_groups[groupid]; 29221ed83081SMichael Speer group->hxgep = hxgep; 29231ed83081SMichael Speer group->ghandle = gh; 29241ed83081SMichael Speer group->index = groupid; 29251ed83081SMichael Speer group->type = type; 29261ed83081SMichael Speer 29271ed83081SMichael Speer infop->mgi_driver = (mac_group_driver_t)group; 29281ed83081SMichael Speer infop->mgi_start = hxge_rx_group_start; 29291ed83081SMichael Speer infop->mgi_stop = hxge_rx_group_stop; 29301ed83081SMichael Speer infop->mgi_addmac = hxge_rx_group_add_mac; 29311ed83081SMichael Speer infop->mgi_remmac = hxge_rx_group_rem_mac; 29321ed83081SMichael Speer infop->mgi_count = HXGE_MAX_RDCS; 29331ed83081SMichael Speer break; 29341ed83081SMichael Speer 29351ed83081SMichael Speer case MAC_RING_TYPE_TX: 29361ed83081SMichael Speer default: 29371ed83081SMichael Speer break; 29381ed83081SMichael Speer } 29391ed83081SMichael Speer } 29401ed83081SMichael Speer 2941*0dc2366fSVenugopal Iyer static int 2942*0dc2366fSVenugopal Iyer hxge_ring_get_htable_idx(p_hxge_t hxgep, mac_ring_type_t type, uint32_t channel) 2943*0dc2366fSVenugopal Iyer { 2944*0dc2366fSVenugopal Iyer int i; 2945*0dc2366fSVenugopal Iyer 2946*0dc2366fSVenugopal Iyer ASSERT(hxgep->ldgvp != NULL); 2947*0dc2366fSVenugopal Iyer 2948*0dc2366fSVenugopal Iyer switch (type) { 2949*0dc2366fSVenugopal Iyer case MAC_RING_TYPE_RX: 2950*0dc2366fSVenugopal Iyer for (i = 0; i < hxgep->ldgvp->maxldvs; i++) { 2951*0dc2366fSVenugopal Iyer if ((hxgep->ldgvp->ldvp[i].is_rxdma) && 2952*0dc2366fSVenugopal Iyer (hxgep->ldgvp->ldvp[i].channel == channel)) { 2953*0dc2366fSVenugopal Iyer return ((int) 2954*0dc2366fSVenugopal Iyer hxgep->ldgvp->ldvp[i].ldgp->htable_idx); 2955*0dc2366fSVenugopal Iyer } 2956*0dc2366fSVenugopal Iyer } 2957*0dc2366fSVenugopal Iyer break; 2958*0dc2366fSVenugopal Iyer 2959*0dc2366fSVenugopal Iyer case MAC_RING_TYPE_TX: 2960*0dc2366fSVenugopal Iyer for (i = 0; i < hxgep->ldgvp->maxldvs; i++) { 2961*0dc2366fSVenugopal Iyer if ((hxgep->ldgvp->ldvp[i].is_txdma) && 2962*0dc2366fSVenugopal Iyer (hxgep->ldgvp->ldvp[i].channel == channel)) { 2963*0dc2366fSVenugopal Iyer return ((int) 2964*0dc2366fSVenugopal Iyer hxgep->ldgvp->ldvp[i].ldgp->htable_idx); 2965*0dc2366fSVenugopal Iyer } 2966*0dc2366fSVenugopal Iyer } 2967*0dc2366fSVenugopal Iyer break; 2968*0dc2366fSVenugopal Iyer 2969*0dc2366fSVenugopal Iyer default: 2970*0dc2366fSVenugopal Iyer break; 2971*0dc2366fSVenugopal Iyer } 2972*0dc2366fSVenugopal Iyer 2973*0dc2366fSVenugopal Iyer return (-1); 2974*0dc2366fSVenugopal Iyer } 2975*0dc2366fSVenugopal Iyer 29761ed83081SMichael Speer /* 29771ed83081SMichael Speer * Callback function for the GLDv3 layer to register all rings. 29781ed83081SMichael Speer */ 29791ed83081SMichael Speer /*ARGSUSED*/ 29801ed83081SMichael Speer static void 29811ed83081SMichael Speer hxge_fill_ring(void *arg, mac_ring_type_t type, const int rg_index, 29821ed83081SMichael Speer const int index, mac_ring_info_t *infop, mac_ring_handle_t rh) 29831ed83081SMichael Speer { 29841ed83081SMichael Speer p_hxge_t hxgep = arg; 29851ed83081SMichael Speer 2986*0dc2366fSVenugopal Iyer ASSERT(hxgep != NULL); 2987*0dc2366fSVenugopal Iyer ASSERT(infop != NULL); 2988*0dc2366fSVenugopal Iyer 29891ed83081SMichael Speer switch (type) { 29901ed83081SMichael Speer case MAC_RING_TYPE_TX: { 29911ed83081SMichael Speer p_hxge_ring_handle_t rhp; 2992*0dc2366fSVenugopal Iyer mac_intr_t *mintr = &infop->mri_intr; 2993*0dc2366fSVenugopal Iyer p_hxge_intr_t intrp; 2994*0dc2366fSVenugopal Iyer int htable_idx; 29951ed83081SMichael Speer 29961ed83081SMichael Speer ASSERT((index >= 0) && (index < HXGE_MAX_TDCS)); 29971ed83081SMichael Speer rhp = &hxgep->tx_ring_handles[index]; 29981ed83081SMichael Speer rhp->hxgep = hxgep; 29991ed83081SMichael Speer rhp->index = index; 30001ed83081SMichael Speer rhp->ring_handle = rh; 30011ed83081SMichael Speer infop->mri_driver = (mac_ring_driver_t)rhp; 30021ed83081SMichael Speer infop->mri_start = hxge_tx_ring_start; 30031ed83081SMichael Speer infop->mri_stop = hxge_tx_ring_stop; 30041ed83081SMichael Speer infop->mri_tx = hxge_tx_ring_send; 3005*0dc2366fSVenugopal Iyer infop->mri_stat = hxge_tx_ring_stat; 3006*0dc2366fSVenugopal Iyer 3007*0dc2366fSVenugopal Iyer intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 3008*0dc2366fSVenugopal Iyer htable_idx = hxge_ring_get_htable_idx(hxgep, type, index); 3009*0dc2366fSVenugopal Iyer if (htable_idx >= 0) 3010*0dc2366fSVenugopal Iyer mintr->mi_ddi_handle = intrp->htable[htable_idx]; 3011*0dc2366fSVenugopal Iyer else 3012*0dc2366fSVenugopal Iyer mintr->mi_ddi_handle = NULL; 30131ed83081SMichael Speer break; 30141ed83081SMichael Speer } 3015*0dc2366fSVenugopal Iyer 30161ed83081SMichael Speer case MAC_RING_TYPE_RX: { 30171ed83081SMichael Speer p_hxge_ring_handle_t rhp; 30181ed83081SMichael Speer mac_intr_t hxge_mac_intr; 3019*0dc2366fSVenugopal Iyer p_hxge_intr_t intrp; 3020*0dc2366fSVenugopal Iyer int htable_idx; 30211ed83081SMichael Speer 30221ed83081SMichael Speer ASSERT((index >= 0) && (index < HXGE_MAX_RDCS)); 30231ed83081SMichael Speer rhp = &hxgep->rx_ring_handles[index]; 30241ed83081SMichael Speer rhp->hxgep = hxgep; 30251ed83081SMichael Speer rhp->index = index; 30261ed83081SMichael Speer rhp->ring_handle = rh; 30271ed83081SMichael Speer 30281ed83081SMichael Speer /* 30291ed83081SMichael Speer * Entrypoint to enable interrupt (disable poll) and 30301ed83081SMichael Speer * disable interrupt (enable poll). 30311ed83081SMichael Speer */ 30321ed83081SMichael Speer hxge_mac_intr.mi_handle = (mac_intr_handle_t)rhp; 3033*0dc2366fSVenugopal Iyer hxge_mac_intr.mi_enable = (mac_intr_enable_t)hxge_disable_poll; 3034*0dc2366fSVenugopal Iyer hxge_mac_intr.mi_disable = (mac_intr_disable_t)hxge_enable_poll; 3035*0dc2366fSVenugopal Iyer 3036*0dc2366fSVenugopal Iyer intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 3037*0dc2366fSVenugopal Iyer htable_idx = hxge_ring_get_htable_idx(hxgep, type, index); 3038*0dc2366fSVenugopal Iyer if (htable_idx >= 0) 3039*0dc2366fSVenugopal Iyer hxge_mac_intr.mi_ddi_handle = intrp->htable[htable_idx]; 3040*0dc2366fSVenugopal Iyer else 3041*0dc2366fSVenugopal Iyer hxge_mac_intr.mi_ddi_handle = NULL; 3042*0dc2366fSVenugopal Iyer 30431ed83081SMichael Speer infop->mri_driver = (mac_ring_driver_t)rhp; 30441ed83081SMichael Speer infop->mri_start = hxge_rx_ring_start; 30451ed83081SMichael Speer infop->mri_stop = hxge_rx_ring_stop; 30461ed83081SMichael Speer infop->mri_intr = hxge_mac_intr; 30471ed83081SMichael Speer infop->mri_poll = hxge_rx_poll; 3048*0dc2366fSVenugopal Iyer infop->mri_stat = hxge_rx_ring_stat; 30491ed83081SMichael Speer break; 30501ed83081SMichael Speer } 3051*0dc2366fSVenugopal Iyer 30521ed83081SMichael Speer default: 30531ed83081SMichael Speer break; 30541ed83081SMichael Speer } 30551ed83081SMichael Speer } 30561ed83081SMichael Speer 30573dec9fcdSqs /*ARGSUSED*/ 30583dec9fcdSqs boolean_t 30593dec9fcdSqs hxge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 30603dec9fcdSqs { 30611ed83081SMichael Speer p_hxge_t hxgep = arg; 30623dec9fcdSqs 30633dec9fcdSqs switch (cap) { 30641ed83081SMichael Speer case MAC_CAPAB_HCKSUM: { 30651ed83081SMichael Speer uint32_t *txflags = cap_data; 30661ed83081SMichael Speer 30673dec9fcdSqs *txflags = HCKSUM_INET_PARTIAL; 30683dec9fcdSqs break; 30691ed83081SMichael Speer } 30701ed83081SMichael Speer 30711ed83081SMichael Speer case MAC_CAPAB_RINGS: { 30721ed83081SMichael Speer mac_capab_rings_t *cap_rings = cap_data; 30731ed83081SMichael Speer 30741ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 30751ed83081SMichael Speer if (cap_rings->mr_type == MAC_RING_TYPE_RX) { 30761ed83081SMichael Speer cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 30771ed83081SMichael Speer cap_rings->mr_rnum = HXGE_MAX_RDCS; 30781ed83081SMichael Speer cap_rings->mr_rget = hxge_fill_ring; 30791ed83081SMichael Speer cap_rings->mr_gnum = HXGE_MAX_RX_GROUPS; 30801ed83081SMichael Speer cap_rings->mr_gget = hxge_group_get; 30811ed83081SMichael Speer cap_rings->mr_gaddring = NULL; 30821ed83081SMichael Speer cap_rings->mr_gremring = NULL; 30831ed83081SMichael Speer } else { 30841ed83081SMichael Speer cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 30851ed83081SMichael Speer cap_rings->mr_rnum = HXGE_MAX_TDCS; 30861ed83081SMichael Speer cap_rings->mr_rget = hxge_fill_ring; 30871ed83081SMichael Speer cap_rings->mr_gnum = 0; 30881ed83081SMichael Speer cap_rings->mr_gget = NULL; 30891ed83081SMichael Speer cap_rings->mr_gaddring = NULL; 30901ed83081SMichael Speer cap_rings->mr_gremring = NULL; 30911ed83081SMichael Speer } 30921ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 30931ed83081SMichael Speer break; 30941ed83081SMichael Speer } 30953dec9fcdSqs 30963dec9fcdSqs default: 30973dec9fcdSqs return (B_FALSE); 30983dec9fcdSqs } 30993dec9fcdSqs return (B_TRUE); 31003dec9fcdSqs } 31013dec9fcdSqs 3102a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static boolean_t 3103a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_param_locked(mac_prop_id_t pr_num) 3104a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3105a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3106a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * All adv_* parameters are locked (read-only) while 3107a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * the device is in any sort of loopback mode ... 3108a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3109a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3110a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3111a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3112a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3113a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3114a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3115a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3116a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3117a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3118a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3119a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3120a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3121a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3122a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3123a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3124a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (B_TRUE); 3125a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3126a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (B_FALSE); 3127a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3128a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3129a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3130a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * callback functions for set/get of properties 3131a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3132a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3133a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 3134a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t pr_valsize, const void *pr_val) 3135a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3136a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_t *hxgep = barg; 3137a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp; 3138a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3139a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint32_t new_mtu, old_framesize, new_framesize; 3140a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3141a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, "==> hxge_m_setprop")); 3142a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3143a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States statsp = hxgep->statsp; 31441ed83081SMichael Speer MUTEX_ENTER(hxgep->genlock); 3145a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (statsp->port_stats.lb_mode != hxge_lb_normal && 3146a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_param_locked(pr_num)) { 3147a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3148a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * All adv_* parameters are locked (read-only) 3149a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * while the device is in any sort of loopback mode. 3150a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3151a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3152a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: loopback mode: read only")); 31531ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 3154a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EBUSY); 3155a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3156a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3157a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3158a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3159a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * These properties are either not exist or read only 3160a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3161a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3162a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3163a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3164a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3165a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3166a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3167a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3168a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3169a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3170a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3171a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3172a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3173a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_STATUS: 3174a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_SPEED: 3175a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_DUPLEX: 3176a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3177a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3178a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * Flow control is handled in the shared domain and 3179a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * it is readonly here. 3180a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3181a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3182a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3183a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3184a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: read only property %d", 3185a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States pr_num)); 3186a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3187a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3188a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_MTU: 3189a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 3190a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3191a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: set MTU: %d", new_mtu)); 3192a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3193a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_framesize = new_mtu + MTU_TO_FRAME_SIZE; 3194a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (new_framesize == hxgep->vmac.maxframesize) { 3195a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = 0; 3196a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3197a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3198a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3199afdda45fSVasumathi Sundaram - Sun Microsystems if (hxgep->hxge_mac_state == HXGE_MAC_STARTED) { 3200afdda45fSVasumathi Sundaram - Sun Microsystems err = EBUSY; 3201afdda45fSVasumathi Sundaram - Sun Microsystems break; 3202afdda45fSVasumathi Sundaram - Sun Microsystems } 3203afdda45fSVasumathi Sundaram - Sun Microsystems 3204a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (new_framesize < MIN_FRAME_SIZE || 3205a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_framesize > MAX_FRAME_SIZE) { 3206a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3207a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3208a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3209a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3210a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States old_framesize = hxgep->vmac.maxframesize; 3211a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = (uint16_t)new_framesize; 3212a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3213a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (hxge_vmac_set_framesize(hxgep)) { 3214a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = 3215a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (uint16_t)old_framesize; 3216a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3217a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3218a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3219a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3220a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = mac_maxsdu_update(hxgep->mach, new_mtu); 3221a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (err) { 3222a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = 3223a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (uint16_t)old_framesize; 3224a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) hxge_vmac_set_framesize(hxgep); 3225a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3226a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3227a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3228a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: set MTU: %d maxframe %d", 3229a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States new_mtu, hxgep->vmac.maxframesize)); 3230a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3231a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3232a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_PRIVATE: 3233a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3234a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_setprop: private property")); 3235a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_set_priv_prop(hxgep, pr_name, pr_valsize, 3236a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States pr_val); 3237a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3238a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3239a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States default: 3240a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOTSUP; 3241a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3242a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3243a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 32441ed83081SMichael Speer MUTEX_EXIT(hxgep->genlock); 3245a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3246a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3247a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_m_setprop (return %d)", err)); 3248a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3249a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3250a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3251a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3252a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3253a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num, 3254*0dc2366fSVenugopal Iyer uint_t pr_valsize, void *pr_val) 3255a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3256a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_t *hxgep = barg; 3257a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp = hxgep->statsp; 3258a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3259a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States link_flowctrl_t fl; 3260a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint64_t tmp = 0; 3261a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States link_state_t ls; 3262a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3263a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3264a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_getprop: pr_num %d", pr_num)); 3265a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3266a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States switch (pr_num) { 3267a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_DUPLEX: 3268a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = statsp->mac_stats.link_duplex; 3269a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3270a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_m_getprop: duplex mode %d", 3271a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val)); 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_SPEED: 3275*0dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (uint64_t)); 3276a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States tmp = statsp->mac_stats.link_speed * 1000000ull; 3277a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&tmp, pr_val, sizeof (tmp)); 3278a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3279a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3280a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_STATUS: 3281*0dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (link_state_t)); 3282a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (!statsp->mac_stats.link_up) 3283a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States ls = LINK_STATE_DOWN; 3284a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States else 3285a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States ls = LINK_STATE_UP; 3286a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&ls, pr_val, sizeof (ls)); 3287a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3288a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3289a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_FLOWCTRL: 3290a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 3291a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * Flow control is supported by the shared domain and 3292a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * it is currently transmit only 3293a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States */ 3294*0dc2366fSVenugopal Iyer ASSERT(pr_valsize < sizeof (link_flowctrl_t)); 3295a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States fl = LINK_FLOWCTRL_TX; 3296a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States bcopy(&fl, pr_val, sizeof (fl)); 3297a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3298a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_AUTONEG: 3299a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* 10G link only and it is not negotiable */ 3300a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States *(uint8_t *)pr_val = 0; 3301a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3302a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000FDX_CAP: 3303a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100FDX_CAP: 3304a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10FDX_CAP: 3305a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_1000HDX_CAP: 3306a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_100HDX_CAP: 3307a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_ADV_10HDX_CAP: 3308a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000FDX_CAP: 3309a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100FDX_CAP: 3310a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10FDX_CAP: 3311a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_1000HDX_CAP: 3312a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_100HDX_CAP: 3313a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_EN_10HDX_CAP: 3314a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOTSUP; 3315a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3316a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3317a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States case MAC_PROP_PRIVATE: 3318*0dc2366fSVenugopal Iyer err = hxge_get_priv_prop(hxgep, pr_name, pr_valsize, 3319*0dc2366fSVenugopal Iyer pr_val); 3320f0f2c3a5SGirish Moodalbail break; 3321*0dc2366fSVenugopal Iyer 3322a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States default: 3323a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3324a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States break; 3325a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3326a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3327a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, "<== hxge_m_getprop")); 3328a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3329a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3330a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3331a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3332*0dc2366fSVenugopal Iyer static void 3333*0dc2366fSVenugopal Iyer hxge_m_propinfo(void *arg, const char *pr_name, 3334*0dc2366fSVenugopal Iyer mac_prop_id_t pr_num, mac_prop_info_handle_t prh) 3335*0dc2366fSVenugopal Iyer { 3336*0dc2366fSVenugopal Iyer _NOTE(ARGUNUSED(arg)); 3337*0dc2366fSVenugopal Iyer switch (pr_num) { 3338*0dc2366fSVenugopal Iyer case MAC_PROP_DUPLEX: 3339*0dc2366fSVenugopal Iyer case MAC_PROP_SPEED: 3340*0dc2366fSVenugopal Iyer case MAC_PROP_STATUS: 3341*0dc2366fSVenugopal Iyer case MAC_PROP_AUTONEG: 3342*0dc2366fSVenugopal Iyer case MAC_PROP_FLOWCTRL: 3343*0dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 3344*0dc2366fSVenugopal Iyer break; 3345*0dc2366fSVenugopal Iyer 3346*0dc2366fSVenugopal Iyer case MAC_PROP_MTU: 3347*0dc2366fSVenugopal Iyer mac_prop_info_set_range_uint32(prh, 3348*0dc2366fSVenugopal Iyer MIN_FRAME_SIZE - MTU_TO_FRAME_SIZE, 3349*0dc2366fSVenugopal Iyer MAX_FRAME_SIZE - MTU_TO_FRAME_SIZE); 3350*0dc2366fSVenugopal Iyer break; 3351*0dc2366fSVenugopal Iyer 3352*0dc2366fSVenugopal Iyer case MAC_PROP_PRIVATE: { 3353*0dc2366fSVenugopal Iyer char valstr[MAXNAMELEN]; 3354*0dc2366fSVenugopal Iyer 3355*0dc2366fSVenugopal Iyer bzero(valstr, sizeof (valstr)); 3356*0dc2366fSVenugopal Iyer 3357*0dc2366fSVenugopal Iyer /* Receive Interrupt Blanking Parameters */ 3358*0dc2366fSVenugopal Iyer if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3359*0dc2366fSVenugopal Iyer (void) snprintf(valstr, sizeof (valstr), "%d", 3360*0dc2366fSVenugopal Iyer RXDMA_RCR_TO_DEFAULT); 3361*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3362*0dc2366fSVenugopal Iyer (void) snprintf(valstr, sizeof (valstr), "%d", 3363*0dc2366fSVenugopal Iyer RXDMA_RCR_PTHRES_DEFAULT); 3364*0dc2366fSVenugopal Iyer 3365*0dc2366fSVenugopal Iyer /* Classification and Load Distribution Configuration */ 3366*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0 || 3367*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv4_udp") == 0 || 3368*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv4_ah") == 0 || 3369*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv4_sctp") == 0 || 3370*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv6_tcp") == 0 || 3371*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv6_udp") == 0 || 3372*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv6_ah") == 0 || 3373*0dc2366fSVenugopal Iyer strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3374*0dc2366fSVenugopal Iyer (void) snprintf(valstr, sizeof (valstr), "%d", 3375*0dc2366fSVenugopal Iyer HXGE_CLASS_TCAM_LOOKUP); 3376*0dc2366fSVenugopal Iyer } 3377*0dc2366fSVenugopal Iyer 3378*0dc2366fSVenugopal Iyer if (strlen(valstr) > 0) 3379*0dc2366fSVenugopal Iyer mac_prop_info_set_default_str(prh, valstr); 3380*0dc2366fSVenugopal Iyer break; 3381*0dc2366fSVenugopal Iyer } 3382*0dc2366fSVenugopal Iyer } 3383*0dc2366fSVenugopal Iyer } 3384*0dc2366fSVenugopal Iyer 3385*0dc2366fSVenugopal Iyer 3386a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* ARGSUSED */ 3387a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3388a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_set_priv_prop(p_hxge_t hxgep, const char *pr_name, uint_t pr_valsize, 3389a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States const void *pr_val) 3390a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3391a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_param_t param_arr = hxgep->param_arr; 3392a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3393a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3394a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3395a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_set_priv_prop: name %s (value %s)", pr_name, pr_val)); 3396a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3397a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_val == NULL) { 3398a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (EINVAL); 3399a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3400a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3401a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Blanking */ 3402a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3403a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_rx_intr_time(hxgep, NULL, NULL, 3404a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (char *)pr_val, (caddr_t)¶m_arr[param_rxdma_intr_time]); 3405a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3406a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_rx_intr_pkts(hxgep, NULL, NULL, 3407a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (char *)pr_val, (caddr_t)¶m_arr[param_rxdma_intr_pkts]); 3408a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3409a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Classification */ 3410a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0) { 3411a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3412a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_tcp]); 3413a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_udp") == 0) { 3414a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3415a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_udp]); 3416a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_ah") == 0) { 3417a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3418a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_ah]); 3419a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv4_sctp") == 0) { 3420a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3421a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv4_sctp]); 3422a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_tcp") == 0) { 3423a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3424a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_tcp]); 3425a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_udp") == 0) { 3426a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3427a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_udp]); 3428a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_ah") == 0) { 3429a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3430a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_ah]); 3431a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else if (strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3432a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = hxge_param_set_ip_opt(hxgep, NULL, NULL, (char *)pr_val, 3433a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (caddr_t)¶m_arr[param_class_opt_ipv6_sctp]); 3434a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3435a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = EINVAL; 3436a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3437a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3438a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3439a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_set_priv_prop: err %d", err)); 3440a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3441a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3442a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3443a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3444a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static int 3445*0dc2366fSVenugopal Iyer hxge_get_priv_prop(p_hxge_t hxgep, const char *pr_name, uint_t pr_valsize, 3446*0dc2366fSVenugopal Iyer void *pr_val) 3447a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 3448a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_param_t param_arr = hxgep->param_arr; 3449a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States char valstr[MAXNAMELEN]; 3450a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int err = 0; 3451a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States uint_t strsize; 3452a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int value = 0; 3453a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3454a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3455a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_get_priv_prop: property %s", pr_name)); 3456a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3457*0dc2366fSVenugopal Iyer /* Receive Interrupt Blanking Parameters */ 3458*0dc2366fSVenugopal Iyer if (strcmp(pr_name, "_rxdma_intr_time") == 0) { 3459*0dc2366fSVenugopal Iyer value = hxgep->intr_timeout; 3460*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rxdma_intr_pkts") == 0) { 3461*0dc2366fSVenugopal Iyer value = hxgep->intr_threshold; 3462a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3463*0dc2366fSVenugopal Iyer /* Classification and Load Distribution Configuration */ 3464*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv4_tcp") == 0) { 3465*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3466*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv4_tcp]); 3467a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3468*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv4_tcp].value; 3469*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv4_udp") == 0) { 3470*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3471*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv4_udp]); 3472*0dc2366fSVenugopal Iyer 3473*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv4_udp].value; 3474*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv4_ah") == 0) { 3475*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3476*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv4_ah]); 3477*0dc2366fSVenugopal Iyer 3478*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv4_ah].value; 3479*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv4_sctp") == 0) { 3480*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3481*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv4_sctp]); 3482*0dc2366fSVenugopal Iyer 3483*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv4_sctp].value; 3484*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv6_tcp") == 0) { 3485*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3486*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv6_tcp]); 3487*0dc2366fSVenugopal Iyer 3488*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv6_tcp].value; 3489*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv6_udp") == 0) { 3490*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3491*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv6_udp]); 3492*0dc2366fSVenugopal Iyer 3493*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv6_udp].value; 3494*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv6_ah") == 0) { 3495*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3496*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv6_ah]); 3497*0dc2366fSVenugopal Iyer 3498*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv6_ah].value; 3499*0dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_class_opt_ipv6_sctp") == 0) { 3500*0dc2366fSVenugopal Iyer err = hxge_param_get_ip_opt(hxgep, NULL, NULL, 3501*0dc2366fSVenugopal Iyer (caddr_t)¶m_arr[param_class_opt_ipv6_sctp]); 3502*0dc2366fSVenugopal Iyer 3503*0dc2366fSVenugopal Iyer value = (int)param_arr[param_class_opt_ipv6_sctp].value; 3504*0dc2366fSVenugopal Iyer } else { 3505*0dc2366fSVenugopal Iyer err = EINVAL; 3506a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3507a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3508a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (err == 0) { 3509a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) snprintf(valstr, sizeof (valstr), "0x%x", value); 3510a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3511a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States strsize = (uint_t)strlen(valstr); 3512a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (pr_valsize < strsize) { 3513a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States err = ENOBUFS; 3514a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 3515a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States (void) strlcpy(pr_val, valstr, pr_valsize); 3516a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3517a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 3518a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3519a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, DLADM_CTL, 3520a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States "<== hxge_get_priv_prop: return %d", err)); 3521a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 3522a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (err); 3523a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 35243dec9fcdSqs /* 35253dec9fcdSqs * Module loading and removing entry points. 35263dec9fcdSqs */ 35273dec9fcdSqs DDI_DEFINE_STREAM_OPS(hxge_dev_ops, nulldev, nulldev, hxge_attach, hxge_detach, 35283a109ad9SQiyan Sun - Sun Microsystems - San Diego United States nodev, NULL, D_MP, NULL, NULL); 35293dec9fcdSqs 35303dec9fcdSqs extern struct mod_ops mod_driverops; 35313dec9fcdSqs 35323dec9fcdSqs #define HXGE_DESC_VER "HXGE 10Gb Ethernet Driver" 35333dec9fcdSqs 35343dec9fcdSqs /* 35353dec9fcdSqs * Module linkage information for the kernel. 35363dec9fcdSqs */ 35373dec9fcdSqs static struct modldrv hxge_modldrv = { 35383dec9fcdSqs &mod_driverops, 35393dec9fcdSqs HXGE_DESC_VER, 35403dec9fcdSqs &hxge_dev_ops 35413dec9fcdSqs }; 35423dec9fcdSqs 35433dec9fcdSqs static struct modlinkage modlinkage = { 35443dec9fcdSqs MODREV_1, (void *) &hxge_modldrv, NULL 35453dec9fcdSqs }; 35463dec9fcdSqs 35473dec9fcdSqs int 35483dec9fcdSqs _init(void) 35493dec9fcdSqs { 35503dec9fcdSqs int status; 35513dec9fcdSqs 35523dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _init")); 35533dec9fcdSqs mac_init_ops(&hxge_dev_ops, "hxge"); 35543dec9fcdSqs status = ddi_soft_state_init(&hxge_list, sizeof (hxge_t), 0); 35553dec9fcdSqs if (status != 0) { 35563dec9fcdSqs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, 35573dec9fcdSqs "failed to init device soft state")); 35583dec9fcdSqs mac_fini_ops(&hxge_dev_ops); 35593dec9fcdSqs goto _init_exit; 35603dec9fcdSqs } 35613dec9fcdSqs 35623dec9fcdSqs status = mod_install(&modlinkage); 35633dec9fcdSqs if (status != 0) { 35643dec9fcdSqs ddi_soft_state_fini(&hxge_list); 35653dec9fcdSqs HXGE_ERROR_MSG((NULL, HXGE_ERR_CTL, "Mod install failed")); 35663dec9fcdSqs goto _init_exit; 35673dec9fcdSqs } 35683dec9fcdSqs 35693dec9fcdSqs MUTEX_INIT(&hxge_common_lock, NULL, MUTEX_DRIVER, NULL); 35703dec9fcdSqs 35713dec9fcdSqs _init_exit: 35723dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "_init status = 0x%X", status)); 35733dec9fcdSqs 35743dec9fcdSqs return (status); 35753dec9fcdSqs } 35763dec9fcdSqs 35773dec9fcdSqs int 35783dec9fcdSqs _fini(void) 35793dec9fcdSqs { 35803dec9fcdSqs int status; 35813dec9fcdSqs 35823dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini")); 35833dec9fcdSqs 35843dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _fini: mod_remove")); 35853dec9fcdSqs 35863dec9fcdSqs if (hxge_mblks_pending) 35873dec9fcdSqs return (EBUSY); 35883dec9fcdSqs 35893dec9fcdSqs status = mod_remove(&modlinkage); 35903dec9fcdSqs if (status != DDI_SUCCESS) { 35913dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, 35923dec9fcdSqs "Module removal failed 0x%08x", status)); 35933dec9fcdSqs goto _fini_exit; 35943dec9fcdSqs } 35953dec9fcdSqs 35963dec9fcdSqs mac_fini_ops(&hxge_dev_ops); 35973dec9fcdSqs 35983dec9fcdSqs ddi_soft_state_fini(&hxge_list); 35993dec9fcdSqs 36003dec9fcdSqs MUTEX_DESTROY(&hxge_common_lock); 36013dec9fcdSqs 36023dec9fcdSqs _fini_exit: 36033dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "_fini status = 0x%08x", status)); 36043dec9fcdSqs 36053dec9fcdSqs return (status); 36063dec9fcdSqs } 36073dec9fcdSqs 36083dec9fcdSqs int 36093dec9fcdSqs _info(struct modinfo *modinfop) 36103dec9fcdSqs { 36113dec9fcdSqs int status; 36123dec9fcdSqs 36133dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, "==> _info")); 36143dec9fcdSqs status = mod_info(&modlinkage, modinfop); 36153dec9fcdSqs HXGE_DEBUG_MSG((NULL, MOD_CTL, " _info status = 0x%X", status)); 36163dec9fcdSqs 36173dec9fcdSqs return (status); 36183dec9fcdSqs } 36193dec9fcdSqs 36203dec9fcdSqs /*ARGSUSED*/ 3621f043ebedSMichael Speer static hxge_status_t 36223dec9fcdSqs hxge_add_intrs(p_hxge_t hxgep) 36233dec9fcdSqs { 36243dec9fcdSqs int intr_types; 36253dec9fcdSqs int type = 0; 36263dec9fcdSqs int ddi_status = DDI_SUCCESS; 36273dec9fcdSqs hxge_status_t status = HXGE_OK; 36283dec9fcdSqs 36293dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs")); 36303dec9fcdSqs 36313dec9fcdSqs hxgep->hxge_intr_type.intr_registered = B_FALSE; 36323dec9fcdSqs hxgep->hxge_intr_type.intr_enabled = B_FALSE; 36333dec9fcdSqs hxgep->hxge_intr_type.msi_intx_cnt = 0; 36343dec9fcdSqs hxgep->hxge_intr_type.intr_added = 0; 36353dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable = B_FALSE; 36363dec9fcdSqs hxgep->hxge_intr_type.intr_type = 0; 36373dec9fcdSqs 36383dec9fcdSqs if (hxge_msi_enable) { 36393dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable = B_TRUE; 36403dec9fcdSqs } 36413dec9fcdSqs 36423dec9fcdSqs /* Get the supported interrupt types */ 36433dec9fcdSqs if ((ddi_status = ddi_intr_get_supported_types(hxgep->dip, &intr_types)) 36443dec9fcdSqs != DDI_SUCCESS) { 36453dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "<== hxge_add_intrs: " 36463dec9fcdSqs "ddi_intr_get_supported_types failed: status 0x%08x", 36473dec9fcdSqs ddi_status)); 36483dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 36493dec9fcdSqs } 36503dec9fcdSqs 36513dec9fcdSqs hxgep->hxge_intr_type.intr_types = intr_types; 36523dec9fcdSqs 36533dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36543dec9fcdSqs "ddi_intr_get_supported_types: 0x%08x", intr_types)); 36553dec9fcdSqs 36563dec9fcdSqs /* 36573dec9fcdSqs * Pick the interrupt type to use MSIX, MSI, INTX hxge_msi_enable: 36583dec9fcdSqs * (1): 1 - MSI 36593dec9fcdSqs * (2): 2 - MSI-X 36603dec9fcdSqs * others - FIXED 36613dec9fcdSqs */ 36623dec9fcdSqs switch (hxge_msi_enable) { 36633dec9fcdSqs default: 36643dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 36653dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36663dec9fcdSqs "use fixed (intx emulation) type %08x", type)); 36673dec9fcdSqs break; 36683dec9fcdSqs 36693dec9fcdSqs case 2: 36703dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36713dec9fcdSqs "ddi_intr_get_supported_types: 0x%08x", intr_types)); 36723dec9fcdSqs if (intr_types & DDI_INTR_TYPE_MSIX) { 36733dec9fcdSqs type = DDI_INTR_TYPE_MSIX; 36743dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36753dec9fcdSqs "==> hxge_add_intrs: " 36763dec9fcdSqs "ddi_intr_get_supported_types: MSIX 0x%08x", type)); 36773dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_MSI) { 36783dec9fcdSqs type = DDI_INTR_TYPE_MSI; 36793dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36803dec9fcdSqs "==> hxge_add_intrs: " 36813dec9fcdSqs "ddi_intr_get_supported_types: MSI 0x%08x", type)); 36823dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_FIXED) { 36833dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 36843dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs: " 36853dec9fcdSqs "ddi_intr_get_supported_types: MSXED0x%08x", type)); 36863dec9fcdSqs } 36873dec9fcdSqs break; 36883dec9fcdSqs 36893dec9fcdSqs case 1: 36903dec9fcdSqs if (intr_types & DDI_INTR_TYPE_MSI) { 36913dec9fcdSqs type = DDI_INTR_TYPE_MSI; 36923dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36933dec9fcdSqs "==> hxge_add_intrs: " 36943dec9fcdSqs "ddi_intr_get_supported_types: MSI 0x%08x", type)); 36953dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_MSIX) { 36963dec9fcdSqs type = DDI_INTR_TYPE_MSIX; 36973dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 36983dec9fcdSqs "==> hxge_add_intrs: " 36993dec9fcdSqs "ddi_intr_get_supported_types: MSIX 0x%08x", type)); 37003dec9fcdSqs } else if (intr_types & DDI_INTR_TYPE_FIXED) { 37013dec9fcdSqs type = DDI_INTR_TYPE_FIXED; 37023dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 37033dec9fcdSqs "==> hxge_add_intrs: " 37043dec9fcdSqs "ddi_intr_get_supported_types: MSXED0x%08x", type)); 37053dec9fcdSqs } 37063dec9fcdSqs } 37073dec9fcdSqs 37083dec9fcdSqs hxgep->hxge_intr_type.intr_type = type; 37093dec9fcdSqs if ((type == DDI_INTR_TYPE_MSIX || type == DDI_INTR_TYPE_MSI || 37103dec9fcdSqs type == DDI_INTR_TYPE_FIXED) && 37113dec9fcdSqs hxgep->hxge_intr_type.niu_msi_enable) { 37123dec9fcdSqs if ((status = hxge_add_intrs_adv(hxgep)) != DDI_SUCCESS) { 37133dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 37143dec9fcdSqs " hxge_add_intrs: " 37153dec9fcdSqs " hxge_add_intrs_adv failed: status 0x%08x", 37163dec9fcdSqs status)); 37173dec9fcdSqs return (status); 37183dec9fcdSqs } else { 37193dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_add_intrs: " 37203dec9fcdSqs "interrupts registered : type %d", type)); 37213dec9fcdSqs hxgep->hxge_intr_type.intr_registered = B_TRUE; 37223dec9fcdSqs 37233dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 37243dec9fcdSqs "\nAdded advanced hxge add_intr_adv " 37253dec9fcdSqs "intr type 0x%x\n", type)); 37263dec9fcdSqs 37273dec9fcdSqs return (status); 37283dec9fcdSqs } 37293dec9fcdSqs } 37303dec9fcdSqs 37313dec9fcdSqs if (!hxgep->hxge_intr_type.intr_registered) { 37323dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 37333dec9fcdSqs "==> hxge_add_intrs: failed to register interrupts")); 37343dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 37353dec9fcdSqs } 37363dec9fcdSqs 37373dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs")); 37383dec9fcdSqs 37393dec9fcdSqs return (status); 37403dec9fcdSqs } 37413dec9fcdSqs 37423dec9fcdSqs /*ARGSUSED*/ 37433dec9fcdSqs static hxge_status_t 37443dec9fcdSqs hxge_add_intrs_adv(p_hxge_t hxgep) 37453dec9fcdSqs { 37463dec9fcdSqs int intr_type; 37473dec9fcdSqs p_hxge_intr_t intrp; 37483dec9fcdSqs hxge_status_t status; 37493dec9fcdSqs 37503dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv")); 37513dec9fcdSqs 37523dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 37533dec9fcdSqs intr_type = intrp->intr_type; 37543dec9fcdSqs 37553dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv: type 0x%x", 37563dec9fcdSqs intr_type)); 37573dec9fcdSqs 37583dec9fcdSqs switch (intr_type) { 37593dec9fcdSqs case DDI_INTR_TYPE_MSI: /* 0x2 */ 37603dec9fcdSqs case DDI_INTR_TYPE_MSIX: /* 0x4 */ 37613dec9fcdSqs status = hxge_add_intrs_adv_type(hxgep, intr_type); 37623dec9fcdSqs break; 37633dec9fcdSqs 37643dec9fcdSqs case DDI_INTR_TYPE_FIXED: /* 0x1 */ 37653dec9fcdSqs status = hxge_add_intrs_adv_type_fix(hxgep, intr_type); 37663dec9fcdSqs break; 37673dec9fcdSqs 37683dec9fcdSqs default: 37693dec9fcdSqs status = HXGE_ERROR; 37703dec9fcdSqs break; 37713dec9fcdSqs } 37723dec9fcdSqs 37733dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv")); 37743dec9fcdSqs 37753dec9fcdSqs return (status); 37763dec9fcdSqs } 37773dec9fcdSqs 37783dec9fcdSqs /*ARGSUSED*/ 37793dec9fcdSqs static hxge_status_t 37803dec9fcdSqs hxge_add_intrs_adv_type(p_hxge_t hxgep, uint32_t int_type) 37813dec9fcdSqs { 37823dec9fcdSqs dev_info_t *dip = hxgep->dip; 37833dec9fcdSqs p_hxge_ldg_t ldgp; 37843dec9fcdSqs p_hxge_intr_t intrp; 37853dec9fcdSqs uint_t *inthandler; 37863dec9fcdSqs void *arg1, *arg2; 37873dec9fcdSqs int behavior; 37883dec9fcdSqs int nintrs, navail; 378957c5371aSQiyan Sun - Sun Microsystems - San Diego United States int nactual, nrequired, nrequest; 37903dec9fcdSqs int inum = 0; 37913dec9fcdSqs int loop = 0; 37923dec9fcdSqs int x, y; 37933dec9fcdSqs int ddi_status = DDI_SUCCESS; 37943dec9fcdSqs hxge_status_t status = HXGE_OK; 37953dec9fcdSqs 37963dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv_type")); 37973dec9fcdSqs 37983dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 37993dec9fcdSqs 38003dec9fcdSqs ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 38013dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 38023dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38033dec9fcdSqs "ddi_intr_get_nintrs() failed, status: 0x%x%, " 38043dec9fcdSqs "nintrs: %d", ddi_status, nintrs)); 38053dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38063dec9fcdSqs } 38073dec9fcdSqs 38083dec9fcdSqs ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 38093dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 38103dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38113dec9fcdSqs "ddi_intr_get_navail() failed, status: 0x%x%, " 38123dec9fcdSqs "nintrs: %d", ddi_status, navail)); 38133dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38143dec9fcdSqs } 38153dec9fcdSqs 38163dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38173dec9fcdSqs "ddi_intr_get_navail() returned: intr type %d nintrs %d, navail %d", 38183dec9fcdSqs int_type, nintrs, navail)); 38193dec9fcdSqs 382057c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* PSARC/2007/453 MSI-X interrupt limit override */ 382157c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (int_type == DDI_INTR_TYPE_MSIX) { 382257c5371aSQiyan Sun - Sun Microsystems - San Diego United States nrequest = hxge_create_msi_property(hxgep); 382357c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (nrequest < navail) { 382457c5371aSQiyan Sun - Sun Microsystems - San Diego United States navail = nrequest; 382557c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, INT_CTL, 382657c5371aSQiyan Sun - Sun Microsystems - San Diego United States "hxge_add_intrs_adv_type: nintrs %d " 382757c5371aSQiyan Sun - Sun Microsystems - San Diego United States "navail %d (nrequest %d)", 382857c5371aSQiyan Sun - Sun Microsystems - San Diego United States nintrs, navail, nrequest)); 382957c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 383057c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 383157c5371aSQiyan Sun - Sun Microsystems - San Diego United States 38323dec9fcdSqs if (int_type == DDI_INTR_TYPE_MSI && !ISP2(navail)) { 38333dec9fcdSqs /* MSI must be power of 2 */ 38343dec9fcdSqs if ((navail & 16) == 16) { 38353dec9fcdSqs navail = 16; 38363dec9fcdSqs } else if ((navail & 8) == 8) { 38373dec9fcdSqs navail = 8; 38383dec9fcdSqs } else if ((navail & 4) == 4) { 38393dec9fcdSqs navail = 4; 38403dec9fcdSqs } else if ((navail & 2) == 2) { 38413dec9fcdSqs navail = 2; 38423dec9fcdSqs } else { 38433dec9fcdSqs navail = 1; 38443dec9fcdSqs } 38453dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38463dec9fcdSqs "ddi_intr_get_navail(): (msi power of 2) nintrs %d, " 38473dec9fcdSqs "navail %d", nintrs, navail)); 38483dec9fcdSqs } 38493dec9fcdSqs 38503dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38513dec9fcdSqs "requesting: intr type %d nintrs %d, navail %d", 38523dec9fcdSqs int_type, nintrs, navail)); 38533dec9fcdSqs 38543dec9fcdSqs behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 38553dec9fcdSqs DDI_INTR_ALLOC_NORMAL); 38563dec9fcdSqs intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 38573dec9fcdSqs intrp->htable = kmem_zalloc(intrp->intr_size, KM_SLEEP); 38583dec9fcdSqs 38593dec9fcdSqs ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 38603dec9fcdSqs navail, &nactual, behavior); 38613dec9fcdSqs if (ddi_status != DDI_SUCCESS || nactual == 0) { 38623dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38633dec9fcdSqs " ddi_intr_alloc() failed: %d", ddi_status)); 38643dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38653dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38663dec9fcdSqs } 38673dec9fcdSqs 38683dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 38693dec9fcdSqs "ddi_intr_alloc() returned: navail %d nactual %d", 38703dec9fcdSqs navail, nactual)); 38713dec9fcdSqs 38723dec9fcdSqs if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 38733dec9fcdSqs (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 38743dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38753dec9fcdSqs " ddi_intr_get_pri() failed: %d", ddi_status)); 38763dec9fcdSqs /* Free already allocated interrupts */ 38773dec9fcdSqs for (y = 0; y < nactual; y++) { 38783dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 38793dec9fcdSqs } 38803dec9fcdSqs 38813dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38823dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 38833dec9fcdSqs } 38843dec9fcdSqs 38853dec9fcdSqs nrequired = 0; 38863dec9fcdSqs status = hxge_ldgv_init(hxgep, &nactual, &nrequired); 38873dec9fcdSqs if (status != HXGE_OK) { 38883dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 38893dec9fcdSqs "hxge_add_intrs_adv_typ:hxge_ldgv_init " 38903dec9fcdSqs "failed: 0x%x", status)); 38913dec9fcdSqs /* Free already allocated interrupts */ 38923dec9fcdSqs for (y = 0; y < nactual; y++) { 38933dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 38943dec9fcdSqs } 38953dec9fcdSqs 38963dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 38973dec9fcdSqs return (status); 38983dec9fcdSqs } 38993dec9fcdSqs 39003dec9fcdSqs ldgp = hxgep->ldgvp->ldgp; 39013dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39023dec9fcdSqs "After hxge_ldgv_init(): nreq %d nactual %d", nrequired, nactual)); 39033dec9fcdSqs 39043dec9fcdSqs if (nactual < nrequired) 39053dec9fcdSqs loop = nactual; 39063dec9fcdSqs else 39073dec9fcdSqs loop = nrequired; 39083dec9fcdSqs 39093dec9fcdSqs for (x = 0; x < loop; x++, ldgp++) { 39103dec9fcdSqs ldgp->vector = (uint8_t)x; 39113dec9fcdSqs arg1 = ldgp->ldvp; 39123dec9fcdSqs arg2 = hxgep; 39133dec9fcdSqs if (ldgp->nldvs == 1) { 39143dec9fcdSqs inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 39153dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39163dec9fcdSqs "hxge_add_intrs_adv_type: arg1 0x%x arg2 0x%x: " 39173dec9fcdSqs "1-1 int handler (entry %d)\n", 39183dec9fcdSqs arg1, arg2, x)); 39193dec9fcdSqs } else if (ldgp->nldvs > 1) { 39203dec9fcdSqs inthandler = (uint_t *)ldgp->sys_intr_handler; 39213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39223dec9fcdSqs "hxge_add_intrs_adv_type: arg1 0x%x arg2 0x%x: " 39233dec9fcdSqs "nldevs %d int handler (entry %d)\n", 39243dec9fcdSqs arg1, arg2, ldgp->nldvs, x)); 39253dec9fcdSqs } 39263dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39273dec9fcdSqs "==> hxge_add_intrs_adv_type: ddi_add_intr(inum) #%d " 39283dec9fcdSqs "htable 0x%llx", x, intrp->htable[x])); 39293dec9fcdSqs 39303dec9fcdSqs if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 39313dec9fcdSqs (ddi_intr_handler_t *)inthandler, arg1, arg2)) != 39323dec9fcdSqs DDI_SUCCESS) { 39333dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 39343dec9fcdSqs "==> hxge_add_intrs_adv_type: failed #%d " 39353dec9fcdSqs "status 0x%x", x, ddi_status)); 39363dec9fcdSqs for (y = 0; y < intrp->intr_added; y++) { 39373dec9fcdSqs (void) ddi_intr_remove_handler( 39383dec9fcdSqs intrp->htable[y]); 39393dec9fcdSqs } 39403dec9fcdSqs 39413dec9fcdSqs /* Free already allocated intr */ 39423dec9fcdSqs for (y = 0; y < nactual; y++) { 39433dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 39443dec9fcdSqs } 39453dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 39463dec9fcdSqs 39473dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 39483dec9fcdSqs 39493dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39503dec9fcdSqs } 39513dec9fcdSqs 3952*0dc2366fSVenugopal Iyer ldgp->htable_idx = x; 39533dec9fcdSqs intrp->intr_added++; 39543dec9fcdSqs } 39553dec9fcdSqs intrp->msi_intx_cnt = nactual; 39563dec9fcdSqs 39573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39583dec9fcdSqs "Requested: %d, Allowed: %d msi_intx_cnt %d intr_added %d", 39593dec9fcdSqs navail, nactual, intrp->msi_intx_cnt, intrp->intr_added)); 39603dec9fcdSqs 39613dec9fcdSqs (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 39623dec9fcdSqs (void) hxge_intr_ldgv_init(hxgep); 39633dec9fcdSqs 39643dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv_type")); 39653dec9fcdSqs 39663dec9fcdSqs return (status); 39673dec9fcdSqs } 39683dec9fcdSqs 39693dec9fcdSqs /*ARGSUSED*/ 39703dec9fcdSqs static hxge_status_t 39713dec9fcdSqs hxge_add_intrs_adv_type_fix(p_hxge_t hxgep, uint32_t int_type) 39723dec9fcdSqs { 39733dec9fcdSqs dev_info_t *dip = hxgep->dip; 39743dec9fcdSqs p_hxge_ldg_t ldgp; 39753dec9fcdSqs p_hxge_intr_t intrp; 39763dec9fcdSqs uint_t *inthandler; 39773dec9fcdSqs void *arg1, *arg2; 39783dec9fcdSqs int behavior; 39793dec9fcdSqs int nintrs, navail; 39803dec9fcdSqs int nactual, nrequired; 39813dec9fcdSqs int inum = 0; 39823dec9fcdSqs int x, y; 39833dec9fcdSqs int ddi_status = DDI_SUCCESS; 39843dec9fcdSqs hxge_status_t status = HXGE_OK; 39853dec9fcdSqs 39863dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_add_intrs_adv_type_fix")); 39873dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 39883dec9fcdSqs 39893dec9fcdSqs ddi_status = ddi_intr_get_nintrs(dip, int_type, &nintrs); 39903dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (nintrs == 0)) { 39913dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 39923dec9fcdSqs "ddi_intr_get_nintrs() failed, status: 0x%x%, " 39933dec9fcdSqs "nintrs: %d", status, nintrs)); 39943dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 39953dec9fcdSqs } 39963dec9fcdSqs 39973dec9fcdSqs ddi_status = ddi_intr_get_navail(dip, int_type, &navail); 39983dec9fcdSqs if ((ddi_status != DDI_SUCCESS) || (navail == 0)) { 39993dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40003dec9fcdSqs "ddi_intr_get_navail() failed, status: 0x%x%, " 40013dec9fcdSqs "nintrs: %d", ddi_status, navail)); 40023dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 40033dec9fcdSqs } 40043dec9fcdSqs 40053dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40063dec9fcdSqs "ddi_intr_get_navail() returned: nintrs %d, naavail %d", 40073dec9fcdSqs nintrs, navail)); 40083dec9fcdSqs 40093dec9fcdSqs behavior = ((int_type == DDI_INTR_TYPE_FIXED) ? DDI_INTR_ALLOC_STRICT : 40103dec9fcdSqs DDI_INTR_ALLOC_NORMAL); 40113dec9fcdSqs intrp->intr_size = navail * sizeof (ddi_intr_handle_t); 40123dec9fcdSqs intrp->htable = kmem_alloc(intrp->intr_size, KM_SLEEP); 40133dec9fcdSqs ddi_status = ddi_intr_alloc(dip, intrp->htable, int_type, inum, 40143dec9fcdSqs navail, &nactual, behavior); 40153dec9fcdSqs if (ddi_status != DDI_SUCCESS || nactual == 0) { 40163dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40173dec9fcdSqs " ddi_intr_alloc() failed: %d", ddi_status)); 40183dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40193dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 40203dec9fcdSqs } 40213dec9fcdSqs 40223dec9fcdSqs if ((ddi_status = ddi_intr_get_pri(intrp->htable[0], 40233dec9fcdSqs (uint_t *)&intrp->pri)) != DDI_SUCCESS) { 40243dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40253dec9fcdSqs " ddi_intr_get_pri() failed: %d", ddi_status)); 40263dec9fcdSqs /* Free already allocated interrupts */ 40273dec9fcdSqs for (y = 0; y < nactual; y++) { 40283dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 40293dec9fcdSqs } 40303dec9fcdSqs 40313dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40323dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 40333dec9fcdSqs } 40343dec9fcdSqs 40353dec9fcdSqs nrequired = 0; 40363dec9fcdSqs status = hxge_ldgv_init(hxgep, &nactual, &nrequired); 40373dec9fcdSqs if (status != HXGE_OK) { 40383dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40393dec9fcdSqs "hxge_add_intrs_adv_type_fix:hxge_ldgv_init " 40403dec9fcdSqs "failed: 0x%x", status)); 40413dec9fcdSqs /* Free already allocated interrupts */ 40423dec9fcdSqs for (y = 0; y < nactual; y++) { 40433dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 40443dec9fcdSqs } 40453dec9fcdSqs 40463dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40473dec9fcdSqs return (status); 40483dec9fcdSqs } 40493dec9fcdSqs 40503dec9fcdSqs ldgp = hxgep->ldgvp->ldgp; 40513dec9fcdSqs for (x = 0; x < nrequired; x++, ldgp++) { 40523dec9fcdSqs ldgp->vector = (uint8_t)x; 40533dec9fcdSqs arg1 = ldgp->ldvp; 40543dec9fcdSqs arg2 = hxgep; 40553dec9fcdSqs if (ldgp->nldvs == 1) { 40563dec9fcdSqs inthandler = (uint_t *)ldgp->ldvp->ldv_intr_handler; 40573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40583dec9fcdSqs "hxge_add_intrs_adv_type_fix: " 40593dec9fcdSqs "1-1 int handler(%d) ldg %d ldv %d " 40603dec9fcdSqs "arg1 $%p arg2 $%p\n", 40613dec9fcdSqs x, ldgp->ldg, ldgp->ldvp->ldv, arg1, arg2)); 40623dec9fcdSqs } else if (ldgp->nldvs > 1) { 40633dec9fcdSqs inthandler = (uint_t *)ldgp->sys_intr_handler; 40643dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 40653dec9fcdSqs "hxge_add_intrs_adv_type_fix: " 40663dec9fcdSqs "shared ldv %d int handler(%d) ldv %d ldg %d" 40673dec9fcdSqs "arg1 0x%016llx arg2 0x%016llx\n", 40683dec9fcdSqs x, ldgp->nldvs, ldgp->ldg, ldgp->ldvp->ldv, 40693dec9fcdSqs arg1, arg2)); 40703dec9fcdSqs } 40713dec9fcdSqs 40723dec9fcdSqs if ((ddi_status = ddi_intr_add_handler(intrp->htable[x], 40733dec9fcdSqs (ddi_intr_handler_t *)inthandler, arg1, arg2)) != 40743dec9fcdSqs DDI_SUCCESS) { 40753dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 40763dec9fcdSqs "==> hxge_add_intrs_adv_type_fix: failed #%d " 40773dec9fcdSqs "status 0x%x", x, ddi_status)); 40783dec9fcdSqs for (y = 0; y < intrp->intr_added; y++) { 40793dec9fcdSqs (void) ddi_intr_remove_handler( 40803dec9fcdSqs intrp->htable[y]); 40813dec9fcdSqs } 40823dec9fcdSqs for (y = 0; y < nactual; y++) { 40833dec9fcdSqs (void) ddi_intr_free(intrp->htable[y]); 40843dec9fcdSqs } 40853dec9fcdSqs /* Free already allocated intr */ 40863dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 40873dec9fcdSqs 40883dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 40893dec9fcdSqs 40903dec9fcdSqs return (HXGE_ERROR | HXGE_DDI_FAILED); 40913dec9fcdSqs } 40923dec9fcdSqs intrp->intr_added++; 40933dec9fcdSqs } 40943dec9fcdSqs 40953dec9fcdSqs intrp->msi_intx_cnt = nactual; 40963dec9fcdSqs 40973dec9fcdSqs (void) ddi_intr_get_cap(intrp->htable[0], &intrp->intr_cap); 40983dec9fcdSqs 40993dec9fcdSqs status = hxge_intr_ldgv_init(hxgep); 41003dec9fcdSqs 41013dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_add_intrs_adv_type_fix")); 41023dec9fcdSqs 41033dec9fcdSqs return (status); 41043dec9fcdSqs } 41053dec9fcdSqs 41063dec9fcdSqs /*ARGSUSED*/ 41073dec9fcdSqs static void 41083dec9fcdSqs hxge_remove_intrs(p_hxge_t hxgep) 41093dec9fcdSqs { 41103dec9fcdSqs int i, inum; 41113dec9fcdSqs p_hxge_intr_t intrp; 41123dec9fcdSqs 41133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_remove_intrs")); 41143dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 41153dec9fcdSqs if (!intrp->intr_registered) { 41163dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 41173dec9fcdSqs "<== hxge_remove_intrs: interrupts not registered")); 41183dec9fcdSqs return; 41193dec9fcdSqs } 41203dec9fcdSqs 41213dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_remove_intrs:advanced")); 41223dec9fcdSqs 41233dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 41243dec9fcdSqs (void) ddi_intr_block_disable(intrp->htable, 41253dec9fcdSqs intrp->intr_added); 41263dec9fcdSqs } else { 41273dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 41283dec9fcdSqs (void) ddi_intr_disable(intrp->htable[i]); 41293dec9fcdSqs } 41303dec9fcdSqs } 41313dec9fcdSqs 41323dec9fcdSqs for (inum = 0; inum < intrp->intr_added; inum++) { 41333dec9fcdSqs if (intrp->htable[inum]) { 41343dec9fcdSqs (void) ddi_intr_remove_handler(intrp->htable[inum]); 41353dec9fcdSqs } 41363dec9fcdSqs } 41373dec9fcdSqs 41383dec9fcdSqs for (inum = 0; inum < intrp->msi_intx_cnt; inum++) { 41393dec9fcdSqs if (intrp->htable[inum]) { 41403dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 41413dec9fcdSqs "hxge_remove_intrs: ddi_intr_free inum %d " 41423dec9fcdSqs "msi_intx_cnt %d intr_added %d", 41433dec9fcdSqs inum, intrp->msi_intx_cnt, intrp->intr_added)); 41443dec9fcdSqs 41453dec9fcdSqs (void) ddi_intr_free(intrp->htable[inum]); 41463dec9fcdSqs } 41473dec9fcdSqs } 41483dec9fcdSqs 41493dec9fcdSqs kmem_free(intrp->htable, intrp->intr_size); 41503dec9fcdSqs intrp->intr_registered = B_FALSE; 41513dec9fcdSqs intrp->intr_enabled = B_FALSE; 41523dec9fcdSqs intrp->msi_intx_cnt = 0; 41533dec9fcdSqs intrp->intr_added = 0; 41543dec9fcdSqs 41553dec9fcdSqs (void) hxge_ldgv_uninit(hxgep); 41563dec9fcdSqs 41573dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_remove_intrs")); 41583dec9fcdSqs } 41593dec9fcdSqs 41603dec9fcdSqs /*ARGSUSED*/ 4161f043ebedSMichael Speer static void 41623dec9fcdSqs hxge_intrs_enable(p_hxge_t hxgep) 41633dec9fcdSqs { 41643dec9fcdSqs p_hxge_intr_t intrp; 41653dec9fcdSqs int i; 41663dec9fcdSqs int status; 41673dec9fcdSqs 41683dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable")); 41693dec9fcdSqs 41703dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 41713dec9fcdSqs 41723dec9fcdSqs if (!intrp->intr_registered) { 41733dec9fcdSqs HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "<== hxge_intrs_enable: " 41743dec9fcdSqs "interrupts are not registered")); 41753dec9fcdSqs return; 41763dec9fcdSqs } 41773dec9fcdSqs 41783dec9fcdSqs if (intrp->intr_enabled) { 41793dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, 41803dec9fcdSqs "<== hxge_intrs_enable: already enabled")); 41813dec9fcdSqs return; 41823dec9fcdSqs } 41833dec9fcdSqs 41843dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 41853dec9fcdSqs status = ddi_intr_block_enable(intrp->htable, 41863dec9fcdSqs intrp->intr_added); 41873dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable " 41883dec9fcdSqs "block enable - status 0x%x total inums #%d\n", 41893dec9fcdSqs status, intrp->intr_added)); 41903dec9fcdSqs } else { 41913dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 41923dec9fcdSqs status = ddi_intr_enable(intrp->htable[i]); 41933dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_enable " 41943dec9fcdSqs "ddi_intr_enable:enable - status 0x%x " 41953dec9fcdSqs "total inums %d enable inum #%d\n", 41963dec9fcdSqs status, intrp->intr_added, i)); 41973dec9fcdSqs if (status == DDI_SUCCESS) { 41983dec9fcdSqs intrp->intr_enabled = B_TRUE; 41993dec9fcdSqs } 42003dec9fcdSqs } 42013dec9fcdSqs } 42023dec9fcdSqs 42033dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_enable")); 42043dec9fcdSqs } 42053dec9fcdSqs 42063dec9fcdSqs /*ARGSUSED*/ 42073dec9fcdSqs static void 42083dec9fcdSqs hxge_intrs_disable(p_hxge_t hxgep) 42093dec9fcdSqs { 42103dec9fcdSqs p_hxge_intr_t intrp; 42113dec9fcdSqs int i; 42123dec9fcdSqs 42133dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intrs_disable")); 42143dec9fcdSqs 42153dec9fcdSqs intrp = (p_hxge_intr_t)&hxgep->hxge_intr_type; 42163dec9fcdSqs 42173dec9fcdSqs if (!intrp->intr_registered) { 42183dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_disable: " 42193dec9fcdSqs "interrupts are not registered")); 42203dec9fcdSqs return; 42213dec9fcdSqs } 42223dec9fcdSqs 42233dec9fcdSqs if (intrp->intr_cap & DDI_INTR_FLAG_BLOCK) { 42243dec9fcdSqs (void) ddi_intr_block_disable(intrp->htable, 42253dec9fcdSqs intrp->intr_added); 42263dec9fcdSqs } else { 42273dec9fcdSqs for (i = 0; i < intrp->intr_added; i++) { 42283dec9fcdSqs (void) ddi_intr_disable(intrp->htable[i]); 42293dec9fcdSqs } 42303dec9fcdSqs } 42313dec9fcdSqs 42323dec9fcdSqs intrp->intr_enabled = B_FALSE; 42333dec9fcdSqs HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intrs_disable")); 42343dec9fcdSqs } 42353dec9fcdSqs 42363dec9fcdSqs static hxge_status_t 42373dec9fcdSqs hxge_mac_register(p_hxge_t hxgep) 42383dec9fcdSqs { 42393dec9fcdSqs mac_register_t *macp; 42403dec9fcdSqs int status; 42413dec9fcdSqs 42423dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_mac_register")); 42433dec9fcdSqs 42443dec9fcdSqs if ((macp = mac_alloc(MAC_VERSION)) == NULL) 42453dec9fcdSqs return (HXGE_ERROR); 42463dec9fcdSqs 42473dec9fcdSqs macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER; 42483dec9fcdSqs macp->m_driver = hxgep; 42493dec9fcdSqs macp->m_dip = hxgep->dip; 42503dec9fcdSqs macp->m_src_addr = hxgep->ouraddr.ether_addr_octet; 42511ed83081SMichael Speer macp->m_callbacks = &hxge_m_callbacks; 42521ed83081SMichael Speer macp->m_min_sdu = 0; 42531ed83081SMichael Speer macp->m_max_sdu = hxgep->vmac.maxframesize - MTU_TO_FRAME_SIZE; 42541ed83081SMichael Speer macp->m_margin = VLAN_TAGSZ; 42551ed83081SMichael Speer macp->m_priv_props = hxge_priv_props; 42561ed83081SMichael Speer macp->m_v12n = MAC_VIRT_LEVEL1; 42573dec9fcdSqs 42583dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, 42593dec9fcdSqs "hxge_mac_register: ether addr is %x:%x:%x:%x:%x:%x", 42603dec9fcdSqs macp->m_src_addr[0], 42613dec9fcdSqs macp->m_src_addr[1], 42623dec9fcdSqs macp->m_src_addr[2], 42633dec9fcdSqs macp->m_src_addr[3], 42643dec9fcdSqs macp->m_src_addr[4], 42653dec9fcdSqs macp->m_src_addr[5])); 42663dec9fcdSqs 42673dec9fcdSqs status = mac_register(macp, &hxgep->mach); 42683dec9fcdSqs mac_free(macp); 42693dec9fcdSqs 42703dec9fcdSqs if (status != 0) { 42713dec9fcdSqs cmn_err(CE_WARN, 42723dec9fcdSqs "hxge_mac_register failed (status %d instance %d)", 42733dec9fcdSqs status, hxgep->instance); 42743dec9fcdSqs return (HXGE_ERROR); 42753dec9fcdSqs } 42763dec9fcdSqs 42773dec9fcdSqs HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_mac_register success " 42783dec9fcdSqs "(instance %d)", hxgep->instance)); 42793dec9fcdSqs 42803dec9fcdSqs return (HXGE_OK); 42813dec9fcdSqs } 42823dec9fcdSqs 42833dec9fcdSqs static int 42843dec9fcdSqs hxge_init_common_dev(p_hxge_t hxgep) 42853dec9fcdSqs { 42863dec9fcdSqs p_hxge_hw_list_t hw_p; 42873dec9fcdSqs dev_info_t *p_dip; 42883dec9fcdSqs 42893dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==> hxge_init_common_dev")); 42903dec9fcdSqs 42913dec9fcdSqs p_dip = hxgep->p_dip; 42923dec9fcdSqs MUTEX_ENTER(&hxge_common_lock); 42933dec9fcdSqs 42943dec9fcdSqs /* 42953dec9fcdSqs * Loop through existing per Hydra hardware list. 42963dec9fcdSqs */ 42973dec9fcdSqs for (hw_p = hxge_hw_list; hw_p; hw_p = hw_p->next) { 42983dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 42993dec9fcdSqs "==> hxge_init_common_dev: hw_p $%p parent dip $%p", 43003dec9fcdSqs hw_p, p_dip)); 43013dec9fcdSqs if (hw_p->parent_devp == p_dip) { 43023dec9fcdSqs hxgep->hxge_hw_p = hw_p; 43033dec9fcdSqs hw_p->ndevs++; 43043dec9fcdSqs hw_p->hxge_p = hxgep; 43053dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43063dec9fcdSqs "==> hxge_init_common_device: " 43073dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (found)", 43083dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43093dec9fcdSqs break; 43103dec9fcdSqs } 43113dec9fcdSqs } 43123dec9fcdSqs 43133dec9fcdSqs if (hw_p == NULL) { 43143dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43153dec9fcdSqs "==> hxge_init_common_dev: parent dip $%p (new)", p_dip)); 43163dec9fcdSqs hw_p = kmem_zalloc(sizeof (hxge_hw_list_t), KM_SLEEP); 43173dec9fcdSqs hw_p->parent_devp = p_dip; 43183dec9fcdSqs hw_p->magic = HXGE_MAGIC; 43193dec9fcdSqs hxgep->hxge_hw_p = hw_p; 43203dec9fcdSqs hw_p->ndevs++; 43213dec9fcdSqs hw_p->hxge_p = hxgep; 43223dec9fcdSqs hw_p->next = hxge_hw_list; 43233dec9fcdSqs 43243dec9fcdSqs MUTEX_INIT(&hw_p->hxge_cfg_lock, NULL, MUTEX_DRIVER, NULL); 43253dec9fcdSqs MUTEX_INIT(&hw_p->hxge_tcam_lock, NULL, MUTEX_DRIVER, NULL); 43263dec9fcdSqs MUTEX_INIT(&hw_p->hxge_vlan_lock, NULL, MUTEX_DRIVER, NULL); 43273dec9fcdSqs 43283dec9fcdSqs hxge_hw_list = hw_p; 43293dec9fcdSqs } 43303dec9fcdSqs MUTEX_EXIT(&hxge_common_lock); 43313dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43323dec9fcdSqs "==> hxge_init_common_dev (hxge_hw_list) $%p", hxge_hw_list)); 43333dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<== hxge_init_common_dev")); 43343dec9fcdSqs 43353dec9fcdSqs return (HXGE_OK); 43363dec9fcdSqs } 43373dec9fcdSqs 43383dec9fcdSqs static void 43393dec9fcdSqs hxge_uninit_common_dev(p_hxge_t hxgep) 43403dec9fcdSqs { 43413dec9fcdSqs p_hxge_hw_list_t hw_p, h_hw_p; 43423dec9fcdSqs dev_info_t *p_dip; 43433dec9fcdSqs 43443dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==> hxge_uninit_common_dev")); 43453dec9fcdSqs if (hxgep->hxge_hw_p == NULL) { 43463dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43473dec9fcdSqs "<== hxge_uninit_common_dev (no common)")); 43483dec9fcdSqs return; 43493dec9fcdSqs } 43503dec9fcdSqs 43513dec9fcdSqs MUTEX_ENTER(&hxge_common_lock); 43523dec9fcdSqs h_hw_p = hxge_hw_list; 43533dec9fcdSqs for (hw_p = hxge_hw_list; hw_p; hw_p = hw_p->next) { 43543dec9fcdSqs p_dip = hw_p->parent_devp; 43553dec9fcdSqs if (hxgep->hxge_hw_p == hw_p && p_dip == hxgep->p_dip && 43563dec9fcdSqs hxgep->hxge_hw_p->magic == HXGE_MAGIC && 43573dec9fcdSqs hw_p->magic == HXGE_MAGIC) { 43583dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43593dec9fcdSqs "==> hxge_uninit_common_dev: " 43603dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (found)", 43613dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43623dec9fcdSqs 43633dec9fcdSqs hxgep->hxge_hw_p = NULL; 43643dec9fcdSqs if (hw_p->ndevs) { 43653dec9fcdSqs hw_p->ndevs--; 43663dec9fcdSqs } 43673dec9fcdSqs hw_p->hxge_p = NULL; 43683dec9fcdSqs if (!hw_p->ndevs) { 43693dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_vlan_lock); 43703dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_tcam_lock); 43713dec9fcdSqs MUTEX_DESTROY(&hw_p->hxge_cfg_lock); 43723dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43733dec9fcdSqs "==> hxge_uninit_common_dev: " 43743dec9fcdSqs "hw_p $%p parent dip $%p ndevs %d (last)", 43753dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43763dec9fcdSqs 43773dec9fcdSqs if (hw_p == hxge_hw_list) { 43783dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43793dec9fcdSqs "==> hxge_uninit_common_dev:" 43803dec9fcdSqs "remove head " 43813dec9fcdSqs "hw_p $%p parent dip $%p " 43823dec9fcdSqs "ndevs %d (head)", 43833dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43843dec9fcdSqs hxge_hw_list = hw_p->next; 43853dec9fcdSqs } else { 43863dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 43873dec9fcdSqs "==> hxge_uninit_common_dev:" 43883dec9fcdSqs "remove middle " 43893dec9fcdSqs "hw_p $%p parent dip $%p " 43903dec9fcdSqs "ndevs %d (middle)", 43913dec9fcdSqs hw_p, p_dip, hw_p->ndevs)); 43923dec9fcdSqs h_hw_p->next = hw_p->next; 43933dec9fcdSqs } 43943dec9fcdSqs 43953dec9fcdSqs KMEM_FREE(hw_p, sizeof (hxge_hw_list_t)); 43963dec9fcdSqs } 43973dec9fcdSqs break; 43983dec9fcdSqs } else { 43993dec9fcdSqs h_hw_p = hw_p; 44003dec9fcdSqs } 44013dec9fcdSqs } 44023dec9fcdSqs 44033dec9fcdSqs MUTEX_EXIT(&hxge_common_lock); 44043dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, 44053dec9fcdSqs "==> hxge_uninit_common_dev (hxge_hw_list) $%p", hxge_hw_list)); 44063dec9fcdSqs 44073dec9fcdSqs HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<= hxge_uninit_common_dev")); 44083dec9fcdSqs } 4409a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 44101c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_ENTRIES 32 44111c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_WAIT_COUNT 10 44121c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States #define HXGE_MSIX_PARITY_CHECK_COUNT 30 44131c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 4414a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States static void 4415a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_poll(void *arg) 4416a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States { 4417a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_t hxgep = (p_hxge_t)arg; 4418a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hpi_handle_t handle; 4419a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States cip_link_stat_t link_stat; 4420a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxge_timeout *to = &hxgep->timeout; 4421a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4422a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States handle = HXGE_DEV_HPI_HANDLE(hxgep); 4423a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(handle, CIP_LINK_STAT, &link_stat.value); 4424a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4425e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (to->report_link_status || 4426e5d97391SQiyan Sun - Sun Microsystems - San Diego United States (to->link_status != link_stat.bits.xpcs0_link_up)) { 4427a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States to->link_status = link_stat.bits.xpcs0_link_up; 4428e5d97391SQiyan Sun - Sun Microsystems - San Diego United States to->report_link_status = B_FALSE; 4429a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4430a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (link_stat.bits.xpcs0_link_up) { 4431e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_UP); 4432a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } else { 4433e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(hxgep, LINK_STATE_DOWN); 4434a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4435a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4436a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 4437a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States /* Restart the link status timer to check the link status */ 4438a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_ENTER(&to->lock); 4439a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States to->id = timeout(hxge_link_poll, arg, to->ticks); 4440a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States MUTEX_EXIT(&to->lock); 4441a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States } 4442e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 4443e5d97391SQiyan Sun - Sun Microsystems - San Diego United States static void 4444e5d97391SQiyan Sun - Sun Microsystems - San Diego United States hxge_link_update(p_hxge_t hxgep, link_state_t state) 4445e5d97391SQiyan Sun - Sun Microsystems - San Diego United States { 4446e5d97391SQiyan Sun - Sun Microsystems - San Diego United States p_hxge_stats_t statsp = (p_hxge_stats_t)hxgep->statsp; 4447e5d97391SQiyan Sun - Sun Microsystems - San Diego United States 4448e5d97391SQiyan Sun - Sun Microsystems - San Diego United States mac_link_update(hxgep->mach, state); 4449e5d97391SQiyan Sun - Sun Microsystems - San Diego United States if (state == LINK_STATE_UP) { 4450e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_speed = 10000; 4451e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_duplex = 2; 4452e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_up = 1; 4453e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } else { 4454e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_speed = 0; 4455e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_duplex = 0; 4456e5d97391SQiyan Sun - Sun Microsystems - San Diego United States statsp->mac_stats.link_up = 0; 4457e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 4458e5d97391SQiyan Sun - Sun Microsystems - San Diego United States } 44591c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 44601c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States static void 44611c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States hxge_msix_init(p_hxge_t hxgep) 44621c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States { 446357c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data0; 446457c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data1; 446557c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t data2; 44661c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States int i; 446757c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry0; 446857c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry1; 446957c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry2; 447057c5371aSQiyan Sun - Sun Microsystems - San Diego United States uint32_t msix_entry3; 44711c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 447257c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Change to use MSIx bar instead of indirect access */ 44731c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States for (i = 0; i < HXGE_MSIX_ENTRIES; i++) { 447457c5371aSQiyan Sun - Sun Microsystems - San Diego United States data0 = 0xffffffff - i; 447557c5371aSQiyan Sun - Sun Microsystems - San Diego United States data1 = 0xffffffff - i - 1; 447657c5371aSQiyan Sun - Sun Microsystems - San Diego United States data2 = 0xffffffff - i - 2; 447757c5371aSQiyan Sun - Sun Microsystems - San Diego United States 447857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16, data0); 447957c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16 + 4, data1); 448057c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16 + 8, data2); 4481f043ebedSMichael Speer HXGE_REG_WR32(hxgep->hpi_msi_handle, i * 16 + 12, 0); 44821c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 44831c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 448457c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* Initialize ram data out buffer. */ 44851c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States for (i = 0; i < HXGE_MSIX_ENTRIES; i++) { 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); 448957c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(hxgep->hpi_msi_handle, i * 16 + 12, &msix_entry3); 449057c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 449157c5371aSQiyan Sun - Sun Microsystems - San Diego United States } 44921c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 449357c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* 449457c5371aSQiyan Sun - Sun Microsystems - San Diego United States * The following function is to support 449557c5371aSQiyan Sun - Sun Microsystems - San Diego United States * PSARC/2007/453 MSI-X interrupt limit override. 449657c5371aSQiyan Sun - Sun Microsystems - San Diego United States */ 449757c5371aSQiyan Sun - Sun Microsystems - San Diego United States static int 449857c5371aSQiyan Sun - Sun Microsystems - San Diego United States hxge_create_msi_property(p_hxge_t hxgep) 44991c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States { 450057c5371aSQiyan Sun - Sun Microsystems - San Diego United States int nmsi; 450157c5371aSQiyan Sun - Sun Microsystems - San Diego United States extern int ncpus; 450257c5371aSQiyan Sun - Sun Microsystems - San Diego United States 450357c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, "==>hxge_create_msi_property")); 450457c5371aSQiyan Sun - Sun Microsystems - San Diego United States 450557c5371aSQiyan Sun - Sun Microsystems - San Diego United States (void) ddi_prop_create(DDI_DEV_T_NONE, hxgep->dip, 450657c5371aSQiyan Sun - Sun Microsystems - San Diego United States DDI_PROP_CANSLEEP, "#msix-request", NULL, 0); 450757c5371aSQiyan Sun - Sun Microsystems - San Diego United States /* 450857c5371aSQiyan Sun - Sun Microsystems - San Diego United States * The maximum MSI-X requested will be 8. 450957c5371aSQiyan Sun - Sun Microsystems - San Diego United States * If the # of CPUs is less than 8, we will reqeust 451057c5371aSQiyan Sun - Sun Microsystems - San Diego United States * # MSI-X based on the # of CPUs. 451157c5371aSQiyan Sun - Sun Microsystems - San Diego United States */ 451257c5371aSQiyan Sun - Sun Microsystems - San Diego United States if (ncpus >= HXGE_MSIX_REQUEST_10G) { 451357c5371aSQiyan Sun - Sun Microsystems - San Diego United States nmsi = HXGE_MSIX_REQUEST_10G; 451457c5371aSQiyan Sun - Sun Microsystems - San Diego United States } else { 451557c5371aSQiyan Sun - Sun Microsystems - San Diego United States nmsi = ncpus; 45161c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 45171c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States 451857c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, 451957c5371aSQiyan Sun - Sun Microsystems - San Diego United States "==>hxge_create_msi_property(10G): exists 0x%x (nmsi %d)", 452057c5371aSQiyan Sun - Sun Microsystems - San Diego United States ddi_prop_exists(DDI_DEV_T_NONE, hxgep->dip, 452157c5371aSQiyan Sun - Sun Microsystems - San Diego United States DDI_PROP_CANSLEEP, "#msix-request"), nmsi)); 452257c5371aSQiyan Sun - Sun Microsystems - San Diego United States 452357c5371aSQiyan Sun - Sun Microsystems - San Diego United States HXGE_DEBUG_MSG((hxgep, MOD_CTL, "<==hxge_create_msi_property")); 452457c5371aSQiyan Sun - Sun Microsystems - San Diego United States return (nmsi); 45251c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States } 4526