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