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 /* 223dec9fcdSqs148142 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 233dec9fcdSqs148142 * Use is subject to license terms. 243dec9fcdSqs148142 */ 253dec9fcdSqs148142 263dec9fcdSqs148142 #include <hxge_impl.h> 273dec9fcdSqs148142 #include <inet/common.h> 283dec9fcdSqs148142 #include <inet/mi.h> 293dec9fcdSqs148142 #include <inet/nd.h> 303dec9fcdSqs148142 313dec9fcdSqs148142 extern uint64_t hpi_debug_level; 323dec9fcdSqs148142 333dec9fcdSqs148142 #define HXGE_PARAM_MAC_RW \ 343dec9fcdSqs148142 HXGE_PARAM_RW | HXGE_PARAM_MAC | \ 353dec9fcdSqs148142 HXGE_PARAM_NDD_WR_OK | HXGE_PARAM_READ_PROP 363dec9fcdSqs148142 373dec9fcdSqs148142 #define HXGE_PARAM_RXDMA_RW HXGE_PARAM_RWP | HXGE_PARAM_RXDMA | \ 383dec9fcdSqs148142 HXGE_PARAM_NDD_WR_OK | HXGE_PARAM_READ_PROP 393dec9fcdSqs148142 403dec9fcdSqs148142 #define HXGE_PARAM_L2CLASS_CFG \ 413dec9fcdSqs148142 HXGE_PARAM_RW | HXGE_PARAM_PROP_ARR32 | \ 423dec9fcdSqs148142 HXGE_PARAM_READ_PROP | HXGE_PARAM_NDD_WR_OK 433dec9fcdSqs148142 443dec9fcdSqs148142 #define HXGE_PARAM_CLASS_RWS \ 453dec9fcdSqs148142 HXGE_PARAM_RWS | HXGE_PARAM_READ_PROP 463dec9fcdSqs148142 473dec9fcdSqs148142 #define HXGE_PARAM_ARRAY_INIT_SIZE 0x20ULL 483dec9fcdSqs148142 493dec9fcdSqs148142 #define BASE_ANY 0 503dec9fcdSqs148142 #define BASE_BINARY 2 513dec9fcdSqs148142 #define BASE_HEX 16 523dec9fcdSqs148142 #define BASE_DECIMAL 10 533dec9fcdSqs148142 #define ALL_FF_64 0xFFFFFFFFFFFFFFFFULL 543dec9fcdSqs148142 #define ALL_FF_32 0xFFFFFFFFUL 553dec9fcdSqs148142 563dec9fcdSqs148142 #define HXGE_NDD_INFODUMP_BUFF_SIZE 2048 /* is 2k enough? */ 573dec9fcdSqs148142 #define HXGE_NDD_INFODUMP_BUFF_8K 8192 583dec9fcdSqs148142 #define HXGE_NDD_INFODUMP_BUFF_16K 0x2000 593dec9fcdSqs148142 #define HXGE_NDD_INFODUMP_BUFF_64K 0x8000 603dec9fcdSqs148142 613dec9fcdSqs148142 #define PARAM_OUTOF_RANGE(vptr, eptr, rval, pa) \ 623dec9fcdSqs148142 ((vptr == eptr) || (rval < pa->minimum) || (rval > pa->maximum)) 633dec9fcdSqs148142 643dec9fcdSqs148142 #define ADVANCE_PRINT_BUFFER(pmp, plen, rlen) { \ 653dec9fcdSqs148142 ((mblk_t *)pmp)->b_wptr += plen; \ 663dec9fcdSqs148142 rlen -= plen; \ 673dec9fcdSqs148142 } 683dec9fcdSqs148142 69a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int hxge_param_rx_intr_pkts(p_hxge_t hxgep, queue_t *, 703dec9fcdSqs148142 mblk_t *, char *, caddr_t); 71a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int hxge_param_rx_intr_time(p_hxge_t hxgep, queue_t *, 723dec9fcdSqs148142 mblk_t *, char *, caddr_t); 733dec9fcdSqs148142 static int hxge_param_set_mac(p_hxge_t, queue_t *, 743dec9fcdSqs148142 mblk_t *, char *, caddr_t); 753dec9fcdSqs148142 static int hxge_param_set_ether_usr(p_hxge_t hxgep, queue_t *, mblk_t *, 763dec9fcdSqs148142 char *, caddr_t); 77a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int hxge_param_set_ip_opt(p_hxge_t hxgep, 783dec9fcdSqs148142 queue_t *, mblk_t *, char *, caddr_t); 793dec9fcdSqs148142 static int hxge_param_pfc_hash_init(p_hxge_t hxgep, 803dec9fcdSqs148142 queue_t *, mblk_t *, char *, caddr_t); 813dec9fcdSqs148142 static int hxge_param_tcam_enable(p_hxge_t hxgep, queue_t *, 823dec9fcdSqs148142 mblk_t *, char *, caddr_t); 833dec9fcdSqs148142 static int hxge_param_get_rxdma_info(p_hxge_t hxgep, queue_t *q, 843dec9fcdSqs148142 p_mblk_t mp, caddr_t cp); 853dec9fcdSqs148142 static int hxge_param_set_vlan_ids(p_hxge_t hxgep, queue_t *q, 863dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp); 873dec9fcdSqs148142 static int hxge_param_get_vlan_ids(p_hxge_t hxgep, queue_t *q, 883dec9fcdSqs148142 p_mblk_t mp, caddr_t cp); 89a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int hxge_param_get_ip_opt(p_hxge_t hxgep, 903dec9fcdSqs148142 queue_t *, mblk_t *, caddr_t); 913dec9fcdSqs148142 static int hxge_param_get_mac(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, 923dec9fcdSqs148142 caddr_t cp); 933dec9fcdSqs148142 static int hxge_param_get_debug_flag(p_hxge_t hxgep, queue_t *q, 943dec9fcdSqs148142 p_mblk_t mp, caddr_t cp); 953dec9fcdSqs148142 static int hxge_param_set_hxge_debug_flag(p_hxge_t hxgep, 963dec9fcdSqs148142 queue_t *, mblk_t *, char *, caddr_t); 973dec9fcdSqs148142 static int hxge_param_set_hpi_debug_flag(p_hxge_t hxgep, 983dec9fcdSqs148142 queue_t *, mblk_t *, char *, caddr_t); 993dec9fcdSqs148142 static int hxge_param_dump_ptrs(p_hxge_t hxgep, queue_t *q, 1003dec9fcdSqs148142 p_mblk_t mp, caddr_t cp); 1013dec9fcdSqs148142 1023dec9fcdSqs148142 /* 1033dec9fcdSqs148142 * Global array of Hydra changable parameters. 1043dec9fcdSqs148142 * This array is initialized to correspond to the default 1053dec9fcdSqs148142 * Hydra configuration. This array would be copied 1063dec9fcdSqs148142 * into the parameter structure and modifed per 1073dec9fcdSqs148142 * fcode and hxge.conf configuration. Later, the parameters are 1083dec9fcdSqs148142 * exported to ndd to display and run-time configuration (at least 1093dec9fcdSqs148142 * some of them). 1103dec9fcdSqs148142 */ 1113dec9fcdSqs148142 1123dec9fcdSqs148142 static hxge_param_t hxge_param_arr[] = { 1133dec9fcdSqs148142 /* min max value old hw-name conf-name */ 1143dec9fcdSqs148142 {hxge_param_get_generic, NULL, HXGE_PARAM_READ, 1153dec9fcdSqs148142 0, 999, 1000, 0, "instance", "instance"}, 1163dec9fcdSqs148142 1173dec9fcdSqs148142 /* MTU cannot be propagated to the stack from here, so don't show it */ 1183dec9fcdSqs148142 {hxge_param_get_mac, hxge_param_set_mac, 1193dec9fcdSqs148142 HXGE_PARAM_MAC_RW | HXGE_PARAM_DONT_SHOW, 1203dec9fcdSqs148142 0, 1, 0, 0, "accept-jumbo", "accept_jumbo"}, 1213dec9fcdSqs148142 1223dec9fcdSqs148142 {hxge_param_get_rxdma_info, NULL, 1233dec9fcdSqs148142 HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW, 1243dec9fcdSqs148142 HXGE_RBR_RBB_MIN, HXGE_RBR_RBB_MAX, HXGE_RBR_RBB_DEFAULT, 0, 1253dec9fcdSqs148142 "rx-rbr-size", "rx_rbr_size"}, 1263dec9fcdSqs148142 1273dec9fcdSqs148142 {hxge_param_get_rxdma_info, NULL, 1283dec9fcdSqs148142 HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW, 1293dec9fcdSqs148142 HXGE_RCR_MIN, HXGE_RCR_MAX, HXGE_RCR_DEFAULT, 0, 1303dec9fcdSqs148142 "rx-rcr-size", "rx_rcr_size"}, 1313dec9fcdSqs148142 1323dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_rx_intr_time, 1333dec9fcdSqs148142 HXGE_PARAM_RXDMA_RW, 1343dec9fcdSqs148142 HXGE_RDC_RCR_TIMEOUT_MIN, HXGE_RDC_RCR_TIMEOUT_MAX, 1353dec9fcdSqs148142 RXDMA_RCR_TO_DEFAULT, 0, "rxdma-intr-time", "rxdma_intr_time"}, 1363dec9fcdSqs148142 1373dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_rx_intr_pkts, 1383dec9fcdSqs148142 HXGE_PARAM_RXDMA_RW, 1393dec9fcdSqs148142 HXGE_RDC_RCR_THRESHOLD_MIN, HXGE_RDC_RCR_THRESHOLD_MAX, 1403dec9fcdSqs148142 RXDMA_RCR_PTHRES_DEFAULT, 0, 1413dec9fcdSqs148142 "rxdma-intr-pkts", "rxdma_intr_pkts"}, 1423dec9fcdSqs148142 1433dec9fcdSqs148142 /* Hardware VLAN is not used currently, so don't show it */ 1443dec9fcdSqs148142 {hxge_param_get_vlan_ids, hxge_param_set_vlan_ids, 1453dec9fcdSqs148142 HXGE_PARAM_L2CLASS_CFG | HXGE_PARAM_DONT_SHOW, 1463dec9fcdSqs148142 VLAN_ID_MIN, VLAN_ID_MAX, 0, 0, "vlan-ids", "vlan_ids"}, 1473dec9fcdSqs148142 1483dec9fcdSqs148142 /* Hardware VLAN is not used currently, so don't show it */ 1493dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_set_generic, 1503dec9fcdSqs148142 HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW, 1513dec9fcdSqs148142 VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_IMPLICIT, VLAN_ID_IMPLICIT, 1523dec9fcdSqs148142 "implicit-vlan-id", "implicit_vlan_id"}, 1533dec9fcdSqs148142 1543dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_tcam_enable, 1553dec9fcdSqs148142 HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW, 1563dec9fcdSqs148142 0, 0x1, 0x0, 0, "tcam-enable", "tcam_enable"}, 1573dec9fcdSqs148142 1583dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_pfc_hash_init, 1593dec9fcdSqs148142 HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW, 1603dec9fcdSqs148142 0, ALL_FF_32, ALL_FF_32, 0, 1613dec9fcdSqs148142 "hash-init-value", "hash_init_value"}, 1623dec9fcdSqs148142 1633dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_set_ether_usr, 1643dec9fcdSqs148142 HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW, 1653dec9fcdSqs148142 0, ALL_FF_32, 0x0, 0, 1663dec9fcdSqs148142 "class-cfg-ether-usr1", "class_cfg_ether_usr1"}, 1673dec9fcdSqs148142 1683dec9fcdSqs148142 {hxge_param_get_generic, hxge_param_set_ether_usr, 1693dec9fcdSqs148142 HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW, 1703dec9fcdSqs148142 0, ALL_FF_32, 0x0, 0, 1713dec9fcdSqs148142 "class-cfg-ether-usr2", "class_cfg_ether_usr2"}, 1723dec9fcdSqs148142 1733dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1743dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1753dec9fcdSqs148142 "class-opt-ipv4-tcp", "class_opt_ipv4_tcp"}, 1763dec9fcdSqs148142 1773dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1783dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1793dec9fcdSqs148142 "class-opt-ipv4-udp", "class_opt_ipv4_udp"}, 1803dec9fcdSqs148142 1813dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1823dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1833dec9fcdSqs148142 "class-opt-ipv4-ah", "class_opt_ipv4_ah"}, 1843dec9fcdSqs148142 1853dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1863dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1873dec9fcdSqs148142 "class-opt-ipv4-sctp", "class_opt_ipv4_sctp"}, 1883dec9fcdSqs148142 1893dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1903dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1913dec9fcdSqs148142 "class-opt-ipv6-tcp", "class_opt_ipv6_tcp"}, 1923dec9fcdSqs148142 1933dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1943dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1953dec9fcdSqs148142 "class-opt-ipv6-udp", "class_opt_ipv6_udp"}, 1963dec9fcdSqs148142 1973dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 1983dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 1993dec9fcdSqs148142 "class-opt-ipv6-ah", "class_opt_ipv6_ah"}, 2003dec9fcdSqs148142 2013dec9fcdSqs148142 {hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS, 2023dec9fcdSqs148142 0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0, 2033dec9fcdSqs148142 "class-opt-ipv6-sctp", "class_opt_ipv6_sctp"}, 2043dec9fcdSqs148142 2053dec9fcdSqs148142 {hxge_param_get_debug_flag, hxge_param_set_hxge_debug_flag, 2063dec9fcdSqs148142 HXGE_PARAM_RW | HXGE_PARAM_DONT_SHOW, 2073dec9fcdSqs148142 0ULL, ALL_FF_64, 0ULL, 0ULL, 2083dec9fcdSqs148142 "hxge-debug-flag", "hxge_debug_flag"}, 2093dec9fcdSqs148142 2103dec9fcdSqs148142 {hxge_param_get_debug_flag, hxge_param_set_hpi_debug_flag, 2113dec9fcdSqs148142 HXGE_PARAM_RW | HXGE_PARAM_DONT_SHOW, 2123dec9fcdSqs148142 0ULL, ALL_FF_64, 0ULL, 0ULL, 2133dec9fcdSqs148142 "hpi-debug-flag", "hpi_debug_flag"}, 2143dec9fcdSqs148142 2153dec9fcdSqs148142 {hxge_param_dump_ptrs, NULL, HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW, 2163dec9fcdSqs148142 0, 0x0fffffff, 0x0fffffff, 0, "dump-ptrs", "dump_ptrs"}, 2173dec9fcdSqs148142 2183dec9fcdSqs148142 {NULL, NULL, HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW, 2193dec9fcdSqs148142 0, 0x0fffffff, 0x0fffffff, 0, "end", "end"}, 2203dec9fcdSqs148142 }; 2213dec9fcdSqs148142 2223dec9fcdSqs148142 extern void *hxge_list; 2233dec9fcdSqs148142 2243dec9fcdSqs148142 /* 2253dec9fcdSqs148142 * Update the NDD array from the soft properties. 2263dec9fcdSqs148142 */ 2273dec9fcdSqs148142 void 2283dec9fcdSqs148142 hxge_get_param_soft_properties(p_hxge_t hxgep) 2293dec9fcdSqs148142 { 2303dec9fcdSqs148142 p_hxge_param_t param_arr; 2313dec9fcdSqs148142 uint_t prop_len; 2323dec9fcdSqs148142 int i, j; 2333dec9fcdSqs148142 uint32_t param_count; 2343dec9fcdSqs148142 uint32_t *int_prop_val; 2353dec9fcdSqs148142 2363dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, " ==> hxge_get_param_soft_properties")); 2373dec9fcdSqs148142 2383dec9fcdSqs148142 param_arr = hxgep->param_arr; 2393dec9fcdSqs148142 param_count = hxgep->param_count; 2403dec9fcdSqs148142 for (i = 0; i < param_count; i++) { 2413dec9fcdSqs148142 2423dec9fcdSqs148142 if ((param_arr[i].type & HXGE_PARAM_READ_PROP) == 0) 2433dec9fcdSqs148142 continue; 2443dec9fcdSqs148142 2453dec9fcdSqs148142 if ((param_arr[i].type & HXGE_PARAM_PROP_STR)) 2463dec9fcdSqs148142 continue; 2473dec9fcdSqs148142 2483dec9fcdSqs148142 if ((param_arr[i].type & HXGE_PARAM_PROP_ARR32) || 2493dec9fcdSqs148142 (param_arr[i].type & HXGE_PARAM_PROP_ARR64)) { 2503dec9fcdSqs148142 2513dec9fcdSqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, 2523dec9fcdSqs148142 hxgep->dip, 0, param_arr[i].fcode_name, 2533dec9fcdSqs148142 (int **)&int_prop_val, (uint_t *)&prop_len) == 2543dec9fcdSqs148142 DDI_PROP_SUCCESS) { 2553dec9fcdSqs148142 uint64_t *cfg_value; 2563dec9fcdSqs148142 uint64_t prop_count; 2573dec9fcdSqs148142 2583dec9fcdSqs148142 if (prop_len > HXGE_PARAM_ARRAY_INIT_SIZE) 2593dec9fcdSqs148142 prop_len = HXGE_PARAM_ARRAY_INIT_SIZE; 2603dec9fcdSqs148142 #if defined(__i386) 2613dec9fcdSqs148142 cfg_value = 2623dec9fcdSqs148142 (uint64_t *)(int32_t)param_arr[i].value; 2633dec9fcdSqs148142 #else 2643dec9fcdSqs148142 cfg_value = (uint64_t *)param_arr[i].value; 2653dec9fcdSqs148142 #endif 2663dec9fcdSqs148142 for (j = 0; j < prop_len; j++) { 2673dec9fcdSqs148142 cfg_value[j] = int_prop_val[j]; 2683dec9fcdSqs148142 } 2693dec9fcdSqs148142 prop_count = prop_len; 2703dec9fcdSqs148142 param_arr[i].type |= 2713dec9fcdSqs148142 (prop_count << HXGE_PARAM_ARRAY_CNT_SHIFT); 2723dec9fcdSqs148142 2733dec9fcdSqs148142 ddi_prop_free(int_prop_val); 2743dec9fcdSqs148142 } 2753dec9fcdSqs148142 continue; 2763dec9fcdSqs148142 } 2773dec9fcdSqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, 2783dec9fcdSqs148142 param_arr[i].fcode_name, (int **)&int_prop_val, 2793dec9fcdSqs148142 &prop_len) == DDI_PROP_SUCCESS) { 2803dec9fcdSqs148142 if ((*int_prop_val >= param_arr[i].minimum) && 2813dec9fcdSqs148142 (*int_prop_val <= param_arr[i].maximum)) 2823dec9fcdSqs148142 param_arr[i].value = *int_prop_val; 2833dec9fcdSqs148142 ddi_prop_free(int_prop_val); 2843dec9fcdSqs148142 } 2853dec9fcdSqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, 2863dec9fcdSqs148142 param_arr[i].name, (int **)&int_prop_val, &prop_len) == 2873dec9fcdSqs148142 DDI_PROP_SUCCESS) { 2883dec9fcdSqs148142 if ((*int_prop_val >= param_arr[i].minimum) && 2893dec9fcdSqs148142 (*int_prop_val <= param_arr[i].maximum)) 2903dec9fcdSqs148142 param_arr[i].value = *int_prop_val; 2913dec9fcdSqs148142 ddi_prop_free(int_prop_val); 2923dec9fcdSqs148142 } 2933dec9fcdSqs148142 } 2943dec9fcdSqs148142 } 2953dec9fcdSqs148142 2963dec9fcdSqs148142 static int 2973dec9fcdSqs148142 hxge_private_param_register(p_hxge_t hxgep, p_hxge_param_t param_arr) 2983dec9fcdSqs148142 { 2993dec9fcdSqs148142 int status = B_TRUE; 3003dec9fcdSqs148142 int channel; 3013dec9fcdSqs148142 char *prop_name; 3023dec9fcdSqs148142 char *end; 3033dec9fcdSqs148142 uint32_t name_chars; 3043dec9fcdSqs148142 3053dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD2_CTL, " hxge_private_param_register %s", 3063dec9fcdSqs148142 param_arr->name)); 3073dec9fcdSqs148142 3083dec9fcdSqs148142 if ((param_arr->type & HXGE_PARAM_PRIV) != HXGE_PARAM_PRIV) 3093dec9fcdSqs148142 return (B_TRUE); 3103dec9fcdSqs148142 prop_name = param_arr->name; 3113dec9fcdSqs148142 if (param_arr->type & HXGE_PARAM_RXDMA) { 3123dec9fcdSqs148142 if (strncmp("rxdma_intr", prop_name, 10) == 0) 3133dec9fcdSqs148142 return (B_TRUE); 3143dec9fcdSqs148142 else 3153dec9fcdSqs148142 return (B_FALSE); 3163dec9fcdSqs148142 } 3173dec9fcdSqs148142 3183dec9fcdSqs148142 if (param_arr->type & HXGE_PARAM_TXDMA) { 3193dec9fcdSqs148142 name_chars = strlen("txdma"); 3203dec9fcdSqs148142 if (strncmp("txdma", prop_name, name_chars) == 0) { 3213dec9fcdSqs148142 prop_name += name_chars; 3223dec9fcdSqs148142 channel = mi_strtol(prop_name, &end, 10); 3233dec9fcdSqs148142 /* now check if this rdc is in config */ 3243dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD2_CTL, 3253dec9fcdSqs148142 " hxge_private_param_register: %d", channel)); 3263dec9fcdSqs148142 return (hxge_check_txdma_port_member(hxgep, channel)); 3273dec9fcdSqs148142 } 3283dec9fcdSqs148142 return (B_FALSE); 3293dec9fcdSqs148142 } 3303dec9fcdSqs148142 3313dec9fcdSqs148142 status = B_FALSE; 3323dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD2_CTL, "<== hxge_private_param_register")); 3333dec9fcdSqs148142 3343dec9fcdSqs148142 return (status); 3353dec9fcdSqs148142 } 3363dec9fcdSqs148142 3373dec9fcdSqs148142 void 3383dec9fcdSqs148142 hxge_setup_param(p_hxge_t hxgep) 3393dec9fcdSqs148142 { 3403dec9fcdSqs148142 p_hxge_param_t param_arr; 3413dec9fcdSqs148142 int i; 3423dec9fcdSqs148142 pfi_t set_pfi; 3433dec9fcdSqs148142 3443dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_setup_param")); 3453dec9fcdSqs148142 /* 3463dec9fcdSqs148142 * Make sure the param_instance is set to a valid device instance. 3473dec9fcdSqs148142 */ 3483dec9fcdSqs148142 if (hxge_param_arr[param_instance].value == 1000) 3493dec9fcdSqs148142 hxge_param_arr[param_instance].value = hxgep->instance; 3503dec9fcdSqs148142 3513dec9fcdSqs148142 param_arr = hxgep->param_arr; 3523dec9fcdSqs148142 param_arr[param_instance].value = hxgep->instance; 3533dec9fcdSqs148142 3543dec9fcdSqs148142 for (i = 0; i < hxgep->param_count; i++) { 3553dec9fcdSqs148142 if ((param_arr[i].type & HXGE_PARAM_PRIV) && 3563dec9fcdSqs148142 (hxge_private_param_register(hxgep, ¶m_arr[i]) == 3573dec9fcdSqs148142 B_FALSE)) { 3583dec9fcdSqs148142 param_arr[i].setf = NULL; 3593dec9fcdSqs148142 param_arr[i].getf = NULL; 3603dec9fcdSqs148142 } 3613dec9fcdSqs148142 if (param_arr[i].type & HXGE_PARAM_CMPLX) 3623dec9fcdSqs148142 param_arr[i].setf = NULL; 3633dec9fcdSqs148142 3643dec9fcdSqs148142 if (param_arr[i].type & HXGE_PARAM_DONT_SHOW) { 3653dec9fcdSqs148142 param_arr[i].setf = NULL; 3663dec9fcdSqs148142 param_arr[i].getf = NULL; 3673dec9fcdSqs148142 } 3683dec9fcdSqs148142 set_pfi = (pfi_t)param_arr[i].setf; 3693dec9fcdSqs148142 3703dec9fcdSqs148142 if ((set_pfi) && (param_arr[i].type & HXGE_PARAM_INIT_ONLY)) { 3713dec9fcdSqs148142 set_pfi = NULL; 3723dec9fcdSqs148142 } 3733dec9fcdSqs148142 if (!hxge_nd_load(&hxgep->param_list, param_arr[i].name, 3743dec9fcdSqs148142 (pfi_t)param_arr[i].getf, set_pfi, 3753dec9fcdSqs148142 (caddr_t)¶m_arr[i])) { 3763dec9fcdSqs148142 (void) hxge_nd_free(&hxgep->param_list); 3773dec9fcdSqs148142 break; 3783dec9fcdSqs148142 } 3793dec9fcdSqs148142 } 3803dec9fcdSqs148142 3813dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_setup_param")); 3823dec9fcdSqs148142 } 3833dec9fcdSqs148142 3843dec9fcdSqs148142 /* 3853dec9fcdSqs148142 * Called from the attached function, it allocates memory for 3863dec9fcdSqs148142 * the parameter array and some members. 3873dec9fcdSqs148142 */ 3883dec9fcdSqs148142 void 3893dec9fcdSqs148142 hxge_init_param(p_hxge_t hxgep) 3903dec9fcdSqs148142 { 3913dec9fcdSqs148142 p_hxge_param_t param_arr; 3923dec9fcdSqs148142 int i, alloc_size; 3933dec9fcdSqs148142 uint64_t alloc_count; 3943dec9fcdSqs148142 3953dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_init_param")); 3963dec9fcdSqs148142 /* 3973dec9fcdSqs148142 * Make sure the param_instance is set to a valid device instance. 3983dec9fcdSqs148142 */ 3993dec9fcdSqs148142 if (hxge_param_arr[param_instance].value == 1000) 4003dec9fcdSqs148142 hxge_param_arr[param_instance].value = hxgep->instance; 4013dec9fcdSqs148142 4023dec9fcdSqs148142 param_arr = hxgep->param_arr; 4033dec9fcdSqs148142 if (param_arr == NULL) { 4043dec9fcdSqs148142 param_arr = (p_hxge_param_t)KMEM_ZALLOC( 4053dec9fcdSqs148142 sizeof (hxge_param_arr), KM_SLEEP); 4063dec9fcdSqs148142 } 4073dec9fcdSqs148142 for (i = 0; i < sizeof (hxge_param_arr) / sizeof (hxge_param_t); i++) { 4083dec9fcdSqs148142 param_arr[i] = hxge_param_arr[i]; 4093dec9fcdSqs148142 if ((param_arr[i].type & HXGE_PARAM_PROP_ARR32) || 4103dec9fcdSqs148142 (param_arr[i].type & HXGE_PARAM_PROP_ARR64)) { 4113dec9fcdSqs148142 alloc_count = HXGE_PARAM_ARRAY_INIT_SIZE; 4123dec9fcdSqs148142 alloc_size = alloc_count * sizeof (uint64_t); 4133dec9fcdSqs148142 #if defined(__i386) 4143dec9fcdSqs148142 param_arr[i].value = 4153dec9fcdSqs148142 (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size, 4163dec9fcdSqs148142 KM_SLEEP); 4173dec9fcdSqs148142 param_arr[i].old_value = 4183dec9fcdSqs148142 (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size, 4193dec9fcdSqs148142 KM_SLEEP); 4203dec9fcdSqs148142 #else 4213dec9fcdSqs148142 param_arr[i].value = 4223dec9fcdSqs148142 (uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP); 4233dec9fcdSqs148142 param_arr[i].old_value = 4243dec9fcdSqs148142 (uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP); 4253dec9fcdSqs148142 #endif 4263dec9fcdSqs148142 param_arr[i].type |= 4273dec9fcdSqs148142 (alloc_count << HXGE_PARAM_ARRAY_ALLOC_SHIFT); 4283dec9fcdSqs148142 } 4293dec9fcdSqs148142 } 4303dec9fcdSqs148142 4313dec9fcdSqs148142 hxgep->param_arr = param_arr; 4323dec9fcdSqs148142 hxgep->param_count = sizeof (hxge_param_arr) / sizeof (hxge_param_t); 4333dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_init_param: count %d", 4343dec9fcdSqs148142 hxgep->param_count)); 4353dec9fcdSqs148142 } 4363dec9fcdSqs148142 4373dec9fcdSqs148142 /* 4383dec9fcdSqs148142 * Called from the attached functions, it frees memory for the parameter array 4393dec9fcdSqs148142 */ 4403dec9fcdSqs148142 void 4413dec9fcdSqs148142 hxge_destroy_param(p_hxge_t hxgep) 4423dec9fcdSqs148142 { 4433dec9fcdSqs148142 int i; 4443dec9fcdSqs148142 uint64_t free_size, free_count; 4453dec9fcdSqs148142 4463dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_param")); 4473dec9fcdSqs148142 /* 4483dec9fcdSqs148142 * Make sure the param_instance is set to a valid device instance. 4493dec9fcdSqs148142 */ 4503dec9fcdSqs148142 if (hxge_param_arr[param_instance].value == hxgep->instance) { 4513dec9fcdSqs148142 for (i = 0; i <= hxge_param_arr[param_instance].maximum; i++) { 4523dec9fcdSqs148142 if ((ddi_get_soft_state(hxge_list, i) != NULL) && 4533dec9fcdSqs148142 (i != hxgep->instance)) 4543dec9fcdSqs148142 break; 4553dec9fcdSqs148142 } 4563dec9fcdSqs148142 hxge_param_arr[param_instance].value = i; 4573dec9fcdSqs148142 } 4583dec9fcdSqs148142 if (hxgep->param_list) 4593dec9fcdSqs148142 hxge_nd_free(&hxgep->param_list); 4603dec9fcdSqs148142 for (i = 0; i < hxgep->param_count; i++) { 4613dec9fcdSqs148142 if ((hxgep->param_arr[i].type & HXGE_PARAM_PROP_ARR32) || 4623dec9fcdSqs148142 (hxgep->param_arr[i].type & HXGE_PARAM_PROP_ARR64)) { 4633dec9fcdSqs148142 free_count = ((hxgep->param_arr[i].type & 4643dec9fcdSqs148142 HXGE_PARAM_ARRAY_ALLOC_MASK) >> 4653dec9fcdSqs148142 HXGE_PARAM_ARRAY_ALLOC_SHIFT); 4663dec9fcdSqs148142 free_count = HXGE_PARAM_ARRAY_INIT_SIZE; 4673dec9fcdSqs148142 free_size = sizeof (uint64_t) * free_count; 4683dec9fcdSqs148142 #if defined(__i386) 4693dec9fcdSqs148142 KMEM_FREE((void *)(uint32_t) 4703dec9fcdSqs148142 hxgep->param_arr[i].value, free_size); 4713dec9fcdSqs148142 KMEM_FREE((void *)(uint32_t) 4723dec9fcdSqs148142 hxgep->param_arr[i].old_value, free_size); 4733dec9fcdSqs148142 #else 4743dec9fcdSqs148142 KMEM_FREE((void *) hxgep->param_arr[i].value, 4753dec9fcdSqs148142 free_size); 4763dec9fcdSqs148142 KMEM_FREE((void *) hxgep->param_arr[i].old_value, 4773dec9fcdSqs148142 free_size); 4783dec9fcdSqs148142 #endif 4793dec9fcdSqs148142 } 4803dec9fcdSqs148142 } 4813dec9fcdSqs148142 4823dec9fcdSqs148142 KMEM_FREE(hxgep->param_arr, sizeof (hxge_param_arr)); 4833dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_param")); 4843dec9fcdSqs148142 } 4853dec9fcdSqs148142 4863dec9fcdSqs148142 /* 4873dec9fcdSqs148142 * Extracts the value from the 'hxge' parameter array and prints the 4883dec9fcdSqs148142 * parameter value. cp points to the required parameter. 4893dec9fcdSqs148142 */ 4903dec9fcdSqs148142 /* ARGSUSED */ 4913dec9fcdSqs148142 int 4923dec9fcdSqs148142 hxge_param_get_generic(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp) 4933dec9fcdSqs148142 { 4943dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 4953dec9fcdSqs148142 4963dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, " ==> hxge_param_get_generic name %s ", 4973dec9fcdSqs148142 pa->name)); 4983dec9fcdSqs148142 4993dec9fcdSqs148142 if (pa->value > 0xffffffff) 5003dec9fcdSqs148142 (void) mi_mpprintf(mp, "%x%x", (int)(pa->value >> 32), 5013dec9fcdSqs148142 (int)(pa->value & 0xffffffff)); 5023dec9fcdSqs148142 else 5033dec9fcdSqs148142 (void) mi_mpprintf(mp, "%x", (int)pa->value); 5043dec9fcdSqs148142 5053dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_generic")); 5063dec9fcdSqs148142 return (0); 5073dec9fcdSqs148142 } 5083dec9fcdSqs148142 5093dec9fcdSqs148142 /* ARGSUSED */ 5103dec9fcdSqs148142 static int 5113dec9fcdSqs148142 hxge_param_get_mac(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp) 5123dec9fcdSqs148142 { 5133dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 5143dec9fcdSqs148142 5153dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_mac")); 5163dec9fcdSqs148142 5173dec9fcdSqs148142 (void) mi_mpprintf(mp, "%d", (uint32_t)pa->value); 5183dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_mac")); 5193dec9fcdSqs148142 return (0); 5203dec9fcdSqs148142 } 5213dec9fcdSqs148142 5223dec9fcdSqs148142 /* ARGSUSED */ 5233dec9fcdSqs148142 int 5243dec9fcdSqs148142 hxge_param_get_rxdma_info(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp) 5253dec9fcdSqs148142 { 5263dec9fcdSqs148142 uint_t print_len, buf_len; 5273dec9fcdSqs148142 p_mblk_t np; 5283dec9fcdSqs148142 int rdc; 5293dec9fcdSqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp; 5303dec9fcdSqs148142 p_hxge_hw_pt_cfg_t p_cfgp; 5313dec9fcdSqs148142 int buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_SIZE; 5323dec9fcdSqs148142 5333dec9fcdSqs148142 p_rx_rcr_rings_t rx_rcr_rings; 5343dec9fcdSqs148142 p_rx_rcr_ring_t *rcr_rings; 5353dec9fcdSqs148142 p_rx_rbr_rings_t rx_rbr_rings; 5363dec9fcdSqs148142 p_rx_rbr_ring_t *rbr_rings; 5373dec9fcdSqs148142 5383dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_rxdma_info")); 5393dec9fcdSqs148142 5403dec9fcdSqs148142 (void) mi_mpprintf(mp, "RXDMA Information\n"); 5413dec9fcdSqs148142 5423dec9fcdSqs148142 if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) { 5433dec9fcdSqs148142 /* The following may work even if we cannot get a large buf. */ 5443dec9fcdSqs148142 (void) mi_mpprintf(mp, "%s\n", "out of buffer"); 5453dec9fcdSqs148142 return (0); 5463dec9fcdSqs148142 } 5473dec9fcdSqs148142 buf_len = buff_alloc_size; 5483dec9fcdSqs148142 5493dec9fcdSqs148142 mp->b_cont = np; 5503dec9fcdSqs148142 5513dec9fcdSqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 5523dec9fcdSqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 5533dec9fcdSqs148142 5543dec9fcdSqs148142 rx_rcr_rings = hxgep->rx_rcr_rings; 5553dec9fcdSqs148142 rcr_rings = rx_rcr_rings->rcr_rings; 5563dec9fcdSqs148142 rx_rbr_rings = hxgep->rx_rbr_rings; 5573dec9fcdSqs148142 rbr_rings = rx_rbr_rings->rbr_rings; 5583dec9fcdSqs148142 5593dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 5603dec9fcdSqs148142 "Total RDCs\t %d\n", p_cfgp->max_rdcs); 5613dec9fcdSqs148142 ((mblk_t *)np)->b_wptr += print_len; 5623dec9fcdSqs148142 buf_len -= print_len; 5633dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 5643dec9fcdSqs148142 "RDC\t HW RDC\t Timeout\t Packets RBR ptr \t" 5653dec9fcdSqs148142 "chunks\t RCR ptr\n"); 5663dec9fcdSqs148142 ((mblk_t *)np)->b_wptr += print_len; 5673dec9fcdSqs148142 buf_len -= print_len; 5683dec9fcdSqs148142 for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) { 5693dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 5703dec9fcdSqs148142 " %d\t %d\t $%p\t 0x%x\t $%p\n", 571*1667122dSMichael Speer rdc, hxgep->rdc[rdc], (void *)rbr_rings[rdc], 572*1667122dSMichael Speer rbr_rings[rdc]->num_blocks, (void *)rcr_rings[rdc]); 5733dec9fcdSqs148142 ((mblk_t *)np)->b_wptr += print_len; 5743dec9fcdSqs148142 buf_len -= print_len; 5753dec9fcdSqs148142 } 5763dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_rxdma_info")); 5773dec9fcdSqs148142 return (0); 5783dec9fcdSqs148142 } 5793dec9fcdSqs148142 5803dec9fcdSqs148142 int 5813dec9fcdSqs148142 hxge_mk_mblk_tail_space(p_mblk_t mp, p_mblk_t *nmp, size_t size) 5823dec9fcdSqs148142 { 5833dec9fcdSqs148142 p_mblk_t tmp; 5843dec9fcdSqs148142 5853dec9fcdSqs148142 tmp = mp; 5863dec9fcdSqs148142 while (tmp->b_cont) 5873dec9fcdSqs148142 tmp = tmp->b_cont; 5883dec9fcdSqs148142 if ((tmp->b_wptr + size) >= tmp->b_datap->db_lim) { 5893dec9fcdSqs148142 tmp->b_cont = allocb(1024, BPRI_HI); 5903dec9fcdSqs148142 tmp = tmp->b_cont; 5913dec9fcdSqs148142 if (!tmp) 5923dec9fcdSqs148142 return (ENOMEM); 5933dec9fcdSqs148142 } 5943dec9fcdSqs148142 *nmp = tmp; 5953dec9fcdSqs148142 return (0); 5963dec9fcdSqs148142 } 5973dec9fcdSqs148142 5983dec9fcdSqs148142 /* 5993dec9fcdSqs148142 * Sets the ge parameter to the value in the hxge_param_register using 6003dec9fcdSqs148142 * hxge_nd_load(). 6013dec9fcdSqs148142 */ 6023dec9fcdSqs148142 /* ARGSUSED */ 6033dec9fcdSqs148142 int 6043dec9fcdSqs148142 hxge_param_set_generic(p_hxge_t hxgep, queue_t *q, mblk_t *mp, 6053dec9fcdSqs148142 char *value, caddr_t cp) 6063dec9fcdSqs148142 { 6073dec9fcdSqs148142 char *end; 6083dec9fcdSqs148142 uint32_t new_value; 6093dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 6103dec9fcdSqs148142 6113dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, " ==> hxge_param_set_generic")); 6123dec9fcdSqs148142 new_value = (uint32_t)mi_strtol(value, &end, 10); 6133dec9fcdSqs148142 if (end == value || new_value < pa->minimum || 6143dec9fcdSqs148142 new_value > pa->maximum) { 6153dec9fcdSqs148142 return (EINVAL); 6163dec9fcdSqs148142 } 6173dec9fcdSqs148142 pa->value = new_value; 6183dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, " <== hxge_param_set_generic")); 6193dec9fcdSqs148142 return (0); 6203dec9fcdSqs148142 } 6213dec9fcdSqs148142 6223dec9fcdSqs148142 /* ARGSUSED */ 6233dec9fcdSqs148142 int 6243dec9fcdSqs148142 hxge_param_set_mac(p_hxge_t hxgep, queue_t *q, mblk_t *mp, 6253dec9fcdSqs148142 char *value, caddr_t cp) 6263dec9fcdSqs148142 { 6273dec9fcdSqs148142 char *end; 6283dec9fcdSqs148142 uint32_t new_value; 6293dec9fcdSqs148142 int status = 0; 6303dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 6313dec9fcdSqs148142 6323dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_mac")); 6333dec9fcdSqs148142 new_value = (uint32_t)mi_strtol(value, &end, BASE_DECIMAL); 6343dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, new_value, pa)) { 6353dec9fcdSqs148142 return (EINVAL); 6363dec9fcdSqs148142 } 6373dec9fcdSqs148142 6383dec9fcdSqs148142 if (pa->value != new_value) { 6393dec9fcdSqs148142 pa->old_value = pa->value; 6403dec9fcdSqs148142 pa->value = new_value; 6413dec9fcdSqs148142 } 6423dec9fcdSqs148142 6433dec9fcdSqs148142 if (pa->value != pa->old_value) { 6443dec9fcdSqs148142 RW_ENTER_WRITER(&hxgep->filter_lock); 6453dec9fcdSqs148142 (void) hxge_rx_vmac_disable(hxgep); 6463dec9fcdSqs148142 (void) hxge_tx_vmac_disable(hxgep); 6473dec9fcdSqs148142 6483dec9fcdSqs148142 /* 6493dec9fcdSqs148142 * Apply the new jumbo parameter here. 6503dec9fcdSqs148142 * The order of the following two calls is important. 6513dec9fcdSqs148142 */ 6523dec9fcdSqs148142 (void) hxge_tx_vmac_enable(hxgep); 6533dec9fcdSqs148142 (void) hxge_rx_vmac_enable(hxgep); 6543dec9fcdSqs148142 RW_EXIT(&hxgep->filter_lock); 6553dec9fcdSqs148142 } 6563dec9fcdSqs148142 6573dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_mac")); 6583dec9fcdSqs148142 return (status); 6593dec9fcdSqs148142 } 6603dec9fcdSqs148142 6613dec9fcdSqs148142 /* ARGSUSED */ 662a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int 6633dec9fcdSqs148142 hxge_param_rx_intr_pkts(p_hxge_t hxgep, queue_t *q, 6643dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 6653dec9fcdSqs148142 { 6663dec9fcdSqs148142 char *end; 6673dec9fcdSqs148142 uint32_t cfg_value; 6683dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 6693dec9fcdSqs148142 6703dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_rx_intr_pkts")); 6713dec9fcdSqs148142 672a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 673a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 674a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 675a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 6763dec9fcdSqs148142 6773dec9fcdSqs148142 if ((cfg_value > HXGE_RDC_RCR_THRESHOLD_MAX) || 6783dec9fcdSqs148142 (cfg_value < HXGE_RDC_RCR_THRESHOLD_MIN)) { 6793dec9fcdSqs148142 return (EINVAL); 6803dec9fcdSqs148142 } 6813dec9fcdSqs148142 6823dec9fcdSqs148142 if ((pa->value != cfg_value)) { 6833dec9fcdSqs148142 pa->old_value = pa->value; 6843dec9fcdSqs148142 pa->value = cfg_value; 6853dec9fcdSqs148142 hxgep->intr_threshold = pa->value; 6863dec9fcdSqs148142 } 6873dec9fcdSqs148142 6883dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_rx_intr_pkts")); 6893dec9fcdSqs148142 return (0); 6903dec9fcdSqs148142 } 6913dec9fcdSqs148142 6923dec9fcdSqs148142 /* ARGSUSED */ 693a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int 6943dec9fcdSqs148142 hxge_param_rx_intr_time(p_hxge_t hxgep, queue_t *q, 6953dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 6963dec9fcdSqs148142 { 6973dec9fcdSqs148142 char *end; 6983dec9fcdSqs148142 uint32_t cfg_value; 6993dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 7003dec9fcdSqs148142 7013dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_rx_intr_time")); 7023dec9fcdSqs148142 703a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 704a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 705a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 706a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 7073dec9fcdSqs148142 7083dec9fcdSqs148142 if ((cfg_value > HXGE_RDC_RCR_TIMEOUT_MAX) || 7093dec9fcdSqs148142 (cfg_value < HXGE_RDC_RCR_TIMEOUT_MIN)) { 7103dec9fcdSqs148142 return (EINVAL); 7113dec9fcdSqs148142 } 7123dec9fcdSqs148142 7133dec9fcdSqs148142 if ((pa->value != cfg_value)) { 7143dec9fcdSqs148142 pa->old_value = pa->value; 7153dec9fcdSqs148142 pa->value = cfg_value; 7163dec9fcdSqs148142 hxgep->intr_timeout = pa->value; 7173dec9fcdSqs148142 } 7183dec9fcdSqs148142 7193dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_rx_intr_time")); 7203dec9fcdSqs148142 return (0); 7213dec9fcdSqs148142 } 7223dec9fcdSqs148142 7233dec9fcdSqs148142 /* ARGSUSED */ 7243dec9fcdSqs148142 static int 7253dec9fcdSqs148142 hxge_param_set_vlan_ids(p_hxge_t hxgep, queue_t *q, mblk_t *mp, char *value, 7263dec9fcdSqs148142 caddr_t cp) 7273dec9fcdSqs148142 { 7283dec9fcdSqs148142 char *end; 7293dec9fcdSqs148142 uint32_t status = 0, cfg_value; 7303dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 7313dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 7323dec9fcdSqs148142 uint32_t *val_ptr, *old_val_ptr; 7333dec9fcdSqs148142 hxge_param_map_t *vmap, *old_map; 7343dec9fcdSqs148142 p_hxge_class_pt_cfg_t p_class_cfgp; 7353dec9fcdSqs148142 uint64_t cfgd_vlans; 7363dec9fcdSqs148142 int i, inc = 0, cfg_position; 7373dec9fcdSqs148142 hxge_mv_cfg_t *vlan_tbl; 7383dec9fcdSqs148142 hpi_handle_t handle; 7393dec9fcdSqs148142 7403dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_vlan_ids ")); 7413dec9fcdSqs148142 7423dec9fcdSqs148142 p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config; 7433dec9fcdSqs148142 vlan_tbl = (hxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0]; 7443dec9fcdSqs148142 handle = hxgep->hpi_reg_handle; 7453dec9fcdSqs148142 746a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 747a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 748a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 7493dec9fcdSqs148142 cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 7503dec9fcdSqs148142 7513dec9fcdSqs148142 /* now do decoding */ 7523dec9fcdSqs148142 cfgd_vlans = ((pa->type & HXGE_PARAM_ARRAY_CNT_MASK) >> 7533dec9fcdSqs148142 HXGE_PARAM_ARRAY_CNT_SHIFT); 7543dec9fcdSqs148142 7553dec9fcdSqs148142 if (cfgd_vlans >= HXGE_PARAM_ARRAY_INIT_SIZE) { 7563dec9fcdSqs148142 /* 7573dec9fcdSqs148142 * for now, we process only upto HXGE_PARAM_ARRAY_INIT_SIZE 7583dec9fcdSqs148142 * parameters In the future, we may want to expand 7593dec9fcdSqs148142 * the storage array and continue 7603dec9fcdSqs148142 */ 7613dec9fcdSqs148142 return (EINVAL); 7623dec9fcdSqs148142 } 7633dec9fcdSqs148142 7643dec9fcdSqs148142 vmap = (hxge_param_map_t *)&cfg_value; 7653dec9fcdSqs148142 if ((vmap->param_id == 0) || (vmap->param_id > VLAN_ID_MAX)) { 7663dec9fcdSqs148142 return (EINVAL); 7673dec9fcdSqs148142 } 7683dec9fcdSqs148142 7693dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, " hxge_param_set_vlan_ids id %d", 7703dec9fcdSqs148142 vmap->param_id)); 7713dec9fcdSqs148142 #if defined(__i386) 7723dec9fcdSqs148142 val_ptr = (uint32_t *)(uint32_t)pa->value; 7733dec9fcdSqs148142 old_val_ptr = (uint32_t *)(uint32_t)pa->old_value; 7743dec9fcdSqs148142 #else 7753dec9fcdSqs148142 val_ptr = (uint32_t *)pa->value; 7763dec9fcdSqs148142 old_val_ptr = (uint32_t *)pa->old_value; 7773dec9fcdSqs148142 #endif 7783dec9fcdSqs148142 7793dec9fcdSqs148142 /* Search to see if this vlan id is already configured */ 7803dec9fcdSqs148142 for (i = 0; i < cfgd_vlans; i++) { 7813dec9fcdSqs148142 old_map = (hxge_param_map_t *)&val_ptr[i]; 7823dec9fcdSqs148142 if ((old_map->param_id == 0) || 7833dec9fcdSqs148142 (vmap->param_id == old_map->param_id) || 7843dec9fcdSqs148142 (vlan_tbl[vmap->param_id].flag)) { 7853dec9fcdSqs148142 cfg_position = i; 7863dec9fcdSqs148142 break; 7873dec9fcdSqs148142 } 7883dec9fcdSqs148142 } 7893dec9fcdSqs148142 7903dec9fcdSqs148142 if (cfgd_vlans == 0) { 7913dec9fcdSqs148142 cfg_position = 0; 7923dec9fcdSqs148142 inc++; 7933dec9fcdSqs148142 } 7943dec9fcdSqs148142 7953dec9fcdSqs148142 if (i == cfgd_vlans) { 7963dec9fcdSqs148142 cfg_position = i; 7973dec9fcdSqs148142 inc++; 7983dec9fcdSqs148142 } 7993dec9fcdSqs148142 8003dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD2_CTL, 8013dec9fcdSqs148142 " set_vlan_ids mapping i %d cfgd_vlans %llx position %d ", 8023dec9fcdSqs148142 i, cfgd_vlans, cfg_position)); 8033dec9fcdSqs148142 8043dec9fcdSqs148142 if (val_ptr[cfg_position] != cfg_value) { 8053dec9fcdSqs148142 old_val_ptr[cfg_position] = val_ptr[cfg_position]; 8063dec9fcdSqs148142 val_ptr[cfg_position] = cfg_value; 8073dec9fcdSqs148142 vlan_tbl[vmap->param_id].flag = 1; 8083dec9fcdSqs148142 cfg_it = B_TRUE; 8093dec9fcdSqs148142 if (inc) { 8103dec9fcdSqs148142 cfgd_vlans++; 8113dec9fcdSqs148142 pa->type &= ~HXGE_PARAM_ARRAY_CNT_MASK; 8123dec9fcdSqs148142 pa->type |= (cfgd_vlans << HXGE_PARAM_ARRAY_CNT_SHIFT); 8133dec9fcdSqs148142 8143dec9fcdSqs148142 } 8153dec9fcdSqs148142 8163dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD2_CTL, 8173dec9fcdSqs148142 " after: param_set_vlan_ids cfg_vlans %llx position %d \n", 8183dec9fcdSqs148142 cfgd_vlans, cfg_position)); 8193dec9fcdSqs148142 } 8203dec9fcdSqs148142 8213dec9fcdSqs148142 if (cfg_it == B_TRUE) { 8223dec9fcdSqs148142 status = hpi_pfc_cfg_vlan_table_entry_set(handle, 8233dec9fcdSqs148142 (vlan_id_t)vmap->param_id); 8243dec9fcdSqs148142 if (status != HPI_SUCCESS) 8253dec9fcdSqs148142 return (EINVAL); 8263dec9fcdSqs148142 } 8273dec9fcdSqs148142 8283dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_vlan_ids")); 8293dec9fcdSqs148142 8303dec9fcdSqs148142 return (0); 8313dec9fcdSqs148142 } 8323dec9fcdSqs148142 8333dec9fcdSqs148142 8343dec9fcdSqs148142 /* ARGSUSED */ 8353dec9fcdSqs148142 static int 8363dec9fcdSqs148142 hxge_param_get_vlan_ids(p_hxge_t hxgep, queue_t *q, mblk_t *mp, caddr_t cp) 8373dec9fcdSqs148142 { 8383dec9fcdSqs148142 uint_t print_len, buf_len; 8393dec9fcdSqs148142 p_mblk_t np; 8403dec9fcdSqs148142 int i; 8413dec9fcdSqs148142 uint32_t *val_ptr; 8423dec9fcdSqs148142 hxge_param_map_t *vmap; 8433dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 8443dec9fcdSqs148142 p_hxge_class_pt_cfg_t p_class_cfgp; 8453dec9fcdSqs148142 uint64_t cfgd_vlans = 0; 8463dec9fcdSqs148142 int buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_SIZE * 32; 8473dec9fcdSqs148142 8483dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_vlan_ids ")); 8493dec9fcdSqs148142 (void) mi_mpprintf(mp, "VLAN Information\n"); 8503dec9fcdSqs148142 8513dec9fcdSqs148142 if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) { 8523dec9fcdSqs148142 (void) mi_mpprintf(mp, "%s\n", "out of buffer"); 8533dec9fcdSqs148142 return (0); 8543dec9fcdSqs148142 } 8553dec9fcdSqs148142 8563dec9fcdSqs148142 buf_len = buff_alloc_size; 8573dec9fcdSqs148142 mp->b_cont = np; 8583dec9fcdSqs148142 cfgd_vlans = (pa->type & HXGE_PARAM_ARRAY_CNT_MASK) >> 8593dec9fcdSqs148142 HXGE_PARAM_ARRAY_CNT_SHIFT; 8603dec9fcdSqs148142 8613dec9fcdSqs148142 i = (int)cfgd_vlans; 8623dec9fcdSqs148142 p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config; 8633dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 8643dec9fcdSqs148142 "Configured VLANs %d\n VLAN ID\n", i); 8653dec9fcdSqs148142 ((mblk_t *)np)->b_wptr += print_len; 8663dec9fcdSqs148142 buf_len -= print_len; 8673dec9fcdSqs148142 8683dec9fcdSqs148142 #if defined(__i386) 8693dec9fcdSqs148142 val_ptr = (uint32_t *)(uint32_t)pa->value; 8703dec9fcdSqs148142 #else 8713dec9fcdSqs148142 val_ptr = (uint32_t *)pa->value; 8723dec9fcdSqs148142 #endif 8733dec9fcdSqs148142 8743dec9fcdSqs148142 for (i = 0; i < cfgd_vlans; i++) { 8753dec9fcdSqs148142 vmap = (hxge_param_map_t *)&val_ptr[i]; 8763dec9fcdSqs148142 if (p_class_cfgp->vlan_tbl[vmap->param_id].flag) { 8773dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, 8783dec9fcdSqs148142 buf_len, " %d\n", vmap->param_id); 8793dec9fcdSqs148142 ((mblk_t *)np)->b_wptr += print_len; 8803dec9fcdSqs148142 buf_len -= print_len; 8813dec9fcdSqs148142 } 8823dec9fcdSqs148142 } 8833dec9fcdSqs148142 8843dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_vlan_ids")); 8853dec9fcdSqs148142 8863dec9fcdSqs148142 return (0); 8873dec9fcdSqs148142 } 8883dec9fcdSqs148142 8893dec9fcdSqs148142 /* ARGSUSED */ 8903dec9fcdSqs148142 static int 8913dec9fcdSqs148142 hxge_param_tcam_enable(p_hxge_t hxgep, queue_t *q, 8923dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 8933dec9fcdSqs148142 { 8943dec9fcdSqs148142 uint32_t status = 0, cfg_value; 8953dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 8963dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 8973dec9fcdSqs148142 char *end; 8983dec9fcdSqs148142 8993dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_tcam_enable")); 9003dec9fcdSqs148142 9013dec9fcdSqs148142 cfg_value = (uint32_t)mi_strtol(value, &end, BASE_BINARY); 9023dec9fcdSqs148142 if (pa->value != cfg_value) { 9033dec9fcdSqs148142 pa->old_value = pa->value; 9043dec9fcdSqs148142 pa->value = cfg_value; 9053dec9fcdSqs148142 cfg_it = B_TRUE; 9063dec9fcdSqs148142 } 9073dec9fcdSqs148142 if (cfg_it == B_TRUE) { 9083dec9fcdSqs148142 if (pa->value) 9093dec9fcdSqs148142 status = hxge_pfc_config_tcam_enable(hxgep); 9103dec9fcdSqs148142 else 9113dec9fcdSqs148142 status = hxge_pfc_config_tcam_disable(hxgep); 9123dec9fcdSqs148142 if (status != HXGE_OK) 9133dec9fcdSqs148142 return (EINVAL); 9143dec9fcdSqs148142 } 9153dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, " <== hxge_param_tcam_enable")); 9163dec9fcdSqs148142 return (0); 9173dec9fcdSqs148142 } 9183dec9fcdSqs148142 9193dec9fcdSqs148142 /* ARGSUSED */ 9203dec9fcdSqs148142 static int 9213dec9fcdSqs148142 hxge_param_set_ether_usr(p_hxge_t hxgep, queue_t *q, 9223dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 9233dec9fcdSqs148142 { 9243dec9fcdSqs148142 char *end; 9253dec9fcdSqs148142 uint32_t status = 0, cfg_value; 9263dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 9273dec9fcdSqs148142 9283dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_ether_usr")); 9293dec9fcdSqs148142 930a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 931a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 932a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 9333dec9fcdSqs148142 cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 9343dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) { 9353dec9fcdSqs148142 return (EINVAL); 9363dec9fcdSqs148142 } 9373dec9fcdSqs148142 if (pa->value != cfg_value) { 9383dec9fcdSqs148142 pa->old_value = pa->value; 9393dec9fcdSqs148142 pa->value = cfg_value; 9403dec9fcdSqs148142 } 9413dec9fcdSqs148142 9423dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_ether_usr")); 9433dec9fcdSqs148142 return (status); 9443dec9fcdSqs148142 } 9453dec9fcdSqs148142 9463dec9fcdSqs148142 static int 9473dec9fcdSqs148142 hxge_class_name_2value(p_hxge_t hxgep, char *name) 9483dec9fcdSqs148142 { 9493dec9fcdSqs148142 int i; 9503dec9fcdSqs148142 int class_instance = param_class_opt_ipv4_tcp; 9513dec9fcdSqs148142 p_hxge_param_t param_arr; 9523dec9fcdSqs148142 9533dec9fcdSqs148142 param_arr = hxgep->param_arr; 9543dec9fcdSqs148142 for (i = TCAM_CLASS_TCP_IPV4; i <= TCAM_CLASS_SCTP_IPV6; i++) { 9553dec9fcdSqs148142 if (strcmp(param_arr[class_instance].name, name) == 0) 9563dec9fcdSqs148142 return (i); 9573dec9fcdSqs148142 class_instance++; 9583dec9fcdSqs148142 } 9593dec9fcdSqs148142 return (-1); 9603dec9fcdSqs148142 } 9613dec9fcdSqs148142 9623dec9fcdSqs148142 /* ARGSUSED */ 963a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int 9643dec9fcdSqs148142 hxge_param_set_ip_opt(p_hxge_t hxgep, queue_t *q, 9653dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 9663dec9fcdSqs148142 { 9673dec9fcdSqs148142 char *end; 9683dec9fcdSqs148142 uint32_t status, cfg_value; 9693dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 9703dec9fcdSqs148142 tcam_class_t class; 9713dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 9723dec9fcdSqs148142 9733dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_ip_opt")); 9743dec9fcdSqs148142 975a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 976a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 977a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 9783dec9fcdSqs148142 cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 9793dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) { 9803dec9fcdSqs148142 return (EINVAL); 9813dec9fcdSqs148142 } 9823dec9fcdSqs148142 if (pa->value != cfg_value) { 9833dec9fcdSqs148142 pa->old_value = pa->value; 9843dec9fcdSqs148142 pa->value = cfg_value; 9853dec9fcdSqs148142 cfg_it = B_TRUE; 9863dec9fcdSqs148142 } 9873dec9fcdSqs148142 if (cfg_it == B_TRUE) { 9883dec9fcdSqs148142 /* do the actual hw setup */ 9893dec9fcdSqs148142 class = hxge_class_name_2value(hxgep, pa->name); 9903dec9fcdSqs148142 if (class == -1) 9913dec9fcdSqs148142 return (EINVAL); 9923dec9fcdSqs148142 9933dec9fcdSqs148142 status = hxge_pfc_ip_class_config(hxgep, class, pa->value); 9943dec9fcdSqs148142 if (status != HXGE_OK) 9953dec9fcdSqs148142 return (EINVAL); 9963dec9fcdSqs148142 } 9973dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_ip_opt")); 9983dec9fcdSqs148142 return (0); 9993dec9fcdSqs148142 } 10003dec9fcdSqs148142 10013dec9fcdSqs148142 /* ARGSUSED */ 1002a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States int 10033dec9fcdSqs148142 hxge_param_get_ip_opt(p_hxge_t hxgep, queue_t *q, mblk_t *mp, caddr_t cp) 10043dec9fcdSqs148142 { 10053dec9fcdSqs148142 uint32_t status, cfg_value; 10063dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 10073dec9fcdSqs148142 tcam_class_t class; 10083dec9fcdSqs148142 10093dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_ip_opt")); 10103dec9fcdSqs148142 10113dec9fcdSqs148142 /* do the actual hw setup */ 10123dec9fcdSqs148142 class = hxge_class_name_2value(hxgep, pa->name); 10133dec9fcdSqs148142 if (class == -1) 10143dec9fcdSqs148142 return (EINVAL); 10153dec9fcdSqs148142 cfg_value = 0; 10163dec9fcdSqs148142 status = hxge_pfc_ip_class_config_get(hxgep, class, &cfg_value); 10173dec9fcdSqs148142 if (status != HXGE_OK) 10183dec9fcdSqs148142 return (EINVAL); 10193dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, 10203dec9fcdSqs148142 "hxge_param_get_ip_opt_get %x ", cfg_value)); 10213dec9fcdSqs148142 pa->value = cfg_value; 10223dec9fcdSqs148142 1023a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (mp != NULL) 10243dec9fcdSqs148142 (void) mi_mpprintf(mp, "%x", cfg_value); 1025a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 10263dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_ip_opt status ")); 10273dec9fcdSqs148142 return (0); 10283dec9fcdSqs148142 } 10293dec9fcdSqs148142 10303dec9fcdSqs148142 /* ARGSUSED */ 10313dec9fcdSqs148142 static int 10323dec9fcdSqs148142 hxge_param_pfc_hash_init(p_hxge_t hxgep, queue_t *q, mblk_t *mp, 10333dec9fcdSqs148142 char *value, caddr_t cp) 10343dec9fcdSqs148142 { 10353dec9fcdSqs148142 char *end; 10363dec9fcdSqs148142 uint32_t status, cfg_value; 10373dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 10383dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 10393dec9fcdSqs148142 10403dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_pfc_hash_init")); 10413dec9fcdSqs148142 1042a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 1043a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 1044a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 10453dec9fcdSqs148142 cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX); 10463dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) { 10473dec9fcdSqs148142 return (EINVAL); 10483dec9fcdSqs148142 } 10493dec9fcdSqs148142 10503dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, 10513dec9fcdSqs148142 " hxge_param_pfc_hash_init value %x", cfg_value)); 10523dec9fcdSqs148142 if (pa->value != cfg_value) { 10533dec9fcdSqs148142 pa->old_value = pa->value; 10543dec9fcdSqs148142 pa->value = cfg_value; 10553dec9fcdSqs148142 cfg_it = B_TRUE; 10563dec9fcdSqs148142 } 10573dec9fcdSqs148142 10583dec9fcdSqs148142 if (cfg_it == B_TRUE) { 10593dec9fcdSqs148142 status = hxge_pfc_set_hash(hxgep, (uint32_t)pa->value); 10603dec9fcdSqs148142 if (status != HXGE_OK) 10613dec9fcdSqs148142 return (EINVAL); 10623dec9fcdSqs148142 } 10633dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, " <== hxge_param_pfc_hash_init")); 10643dec9fcdSqs148142 return (0); 10653dec9fcdSqs148142 } 10663dec9fcdSqs148142 10673dec9fcdSqs148142 /* ARGSUSED */ 10683dec9fcdSqs148142 static int 10693dec9fcdSqs148142 hxge_param_set_hxge_debug_flag(p_hxge_t hxgep, queue_t *q, 10703dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 10713dec9fcdSqs148142 { 10723dec9fcdSqs148142 char *end; 10733dec9fcdSqs148142 uint32_t status = 0; 10743dec9fcdSqs148142 uint64_t cfg_value = 0; 10753dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 10763dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 10773dec9fcdSqs148142 10783dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_hxge_debug_flag")); 1079a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 1080a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 1081a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 1082a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 10833dec9fcdSqs148142 cfg_value = mi_strtol(value, &end, BASE_HEX); 10843dec9fcdSqs148142 10853dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) { 10863dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, 10873dec9fcdSqs148142 " hxge_param_set_hxge_debug_flag" 10883dec9fcdSqs148142 " outof range %llx", cfg_value)); 10893dec9fcdSqs148142 return (EINVAL); 10903dec9fcdSqs148142 } 10913dec9fcdSqs148142 if (pa->value != cfg_value) { 10923dec9fcdSqs148142 pa->old_value = pa->value; 10933dec9fcdSqs148142 pa->value = cfg_value; 10943dec9fcdSqs148142 cfg_it = B_TRUE; 10953dec9fcdSqs148142 } 10963dec9fcdSqs148142 if (cfg_it == B_TRUE) 10973dec9fcdSqs148142 hxgep->hxge_debug_level = pa->value; 10983dec9fcdSqs148142 10993dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_hxge_debug_flag")); 11003dec9fcdSqs148142 return (status); 11013dec9fcdSqs148142 } 11023dec9fcdSqs148142 11033dec9fcdSqs148142 /* ARGSUSED */ 11043dec9fcdSqs148142 static int 11053dec9fcdSqs148142 hxge_param_get_debug_flag(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp) 11063dec9fcdSqs148142 { 11073dec9fcdSqs148142 int status = 0; 11083dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 11093dec9fcdSqs148142 11103dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_debug_flag")); 11113dec9fcdSqs148142 11123dec9fcdSqs148142 if (pa->value > 0xffffffff) 11133dec9fcdSqs148142 (void) mi_mpprintf(mp, "%x%x", (int)(pa->value >> 32), 11143dec9fcdSqs148142 (int)(pa->value & 0xffffffff)); 11153dec9fcdSqs148142 else 11163dec9fcdSqs148142 (void) mi_mpprintf(mp, "%x", (int)pa->value); 11173dec9fcdSqs148142 11183dec9fcdSqs148142 11193dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_debug_flag")); 11203dec9fcdSqs148142 return (status); 11213dec9fcdSqs148142 } 11223dec9fcdSqs148142 11233dec9fcdSqs148142 /* ARGSUSED */ 11243dec9fcdSqs148142 static int 11253dec9fcdSqs148142 hxge_param_set_hpi_debug_flag(p_hxge_t hxgep, queue_t *q, 11263dec9fcdSqs148142 mblk_t *mp, char *value, caddr_t cp) 11273dec9fcdSqs148142 { 11283dec9fcdSqs148142 char *end; 11293dec9fcdSqs148142 uint32_t status = 0; 11303dec9fcdSqs148142 uint64_t cfg_value = 0; 11313dec9fcdSqs148142 p_hxge_param_t pa = (p_hxge_param_t)cp; 11323dec9fcdSqs148142 uint32_t cfg_it = B_FALSE; 11333dec9fcdSqs148142 11343dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_hpi_debug_flag")); 1135a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 1136a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (strncasecmp(value, "0x", 2) == 0) 1137a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States value += 2; 1138a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 11393dec9fcdSqs148142 cfg_value = mi_strtol(value, &end, BASE_HEX); 11403dec9fcdSqs148142 11413dec9fcdSqs148142 if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) { 11423dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, " hxge_param_set_hpi_debug_flag" 11433dec9fcdSqs148142 " outof range %llx", cfg_value)); 11443dec9fcdSqs148142 return (EINVAL); 11453dec9fcdSqs148142 } 11463dec9fcdSqs148142 if (pa->value != cfg_value) { 11473dec9fcdSqs148142 pa->old_value = pa->value; 11483dec9fcdSqs148142 pa->value = cfg_value; 11493dec9fcdSqs148142 cfg_it = B_TRUE; 11503dec9fcdSqs148142 } 11513dec9fcdSqs148142 if (cfg_it == B_TRUE) { 11523dec9fcdSqs148142 hpi_debug_level = pa->value; 11533dec9fcdSqs148142 } 11543dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_debug_flag")); 11553dec9fcdSqs148142 return (status); 11563dec9fcdSqs148142 } 11573dec9fcdSqs148142 11583dec9fcdSqs148142 typedef struct block_info { 11593dec9fcdSqs148142 char *name; 11603dec9fcdSqs148142 uint32_t offset; 11613dec9fcdSqs148142 } block_info_t; 11623dec9fcdSqs148142 11633dec9fcdSqs148142 block_info_t reg_block[] = { 11643dec9fcdSqs148142 {"PIO", PIO_BASE_ADDR}, 11653dec9fcdSqs148142 {"PIO_LDSV", PIO_LDSV_BASE_ADDR}, 11663dec9fcdSqs148142 {"PIO_LDMASK", PIO_LDMASK_BASE_ADDR}, 11673dec9fcdSqs148142 {"PFC", PFC_BASE_ADDR}, 11683dec9fcdSqs148142 {"RDC", RDC_BASE_ADDR}, 11693dec9fcdSqs148142 {"TDC", TDC_BASE_ADDR}, 11703dec9fcdSqs148142 {"VMAC", VMAC_BASE_ADDR}, 11713dec9fcdSqs148142 {"END", ALL_FF_32}, 11723dec9fcdSqs148142 }; 11733dec9fcdSqs148142 11743dec9fcdSqs148142 /* ARGSUSED */ 11753dec9fcdSqs148142 static int 11763dec9fcdSqs148142 hxge_param_dump_ptrs(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp) 11773dec9fcdSqs148142 { 11783dec9fcdSqs148142 uint_t print_len, buf_len; 11793dec9fcdSqs148142 p_mblk_t np; 11803dec9fcdSqs148142 int rdc, tdc, block; 11813dec9fcdSqs148142 uint64_t base; 11823dec9fcdSqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp; 11833dec9fcdSqs148142 p_hxge_hw_pt_cfg_t p_cfgp; 11843dec9fcdSqs148142 int buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_8K; 11853dec9fcdSqs148142 p_tx_ring_t *tx_rings; 11863dec9fcdSqs148142 p_rx_rcr_rings_t rx_rcr_rings; 11873dec9fcdSqs148142 p_rx_rcr_ring_t *rcr_rings; 11883dec9fcdSqs148142 p_rx_rbr_rings_t rx_rbr_rings; 11893dec9fcdSqs148142 p_rx_rbr_ring_t *rbr_rings; 11903dec9fcdSqs148142 11913dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "==> hxge_param_dump_ptrs")); 11923dec9fcdSqs148142 11933dec9fcdSqs148142 (void) mi_mpprintf(mp, "ptr information\n"); 11943dec9fcdSqs148142 11953dec9fcdSqs148142 if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) { 11963dec9fcdSqs148142 /* The following may work even if we cannot get a large buf. */ 11973dec9fcdSqs148142 (void) mi_mpprintf(mp, "%s\n", "out of buffer"); 11983dec9fcdSqs148142 return (0); 11993dec9fcdSqs148142 } 12003dec9fcdSqs148142 buf_len = buff_alloc_size; 12013dec9fcdSqs148142 12023dec9fcdSqs148142 mp->b_cont = np; 12033dec9fcdSqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config; 12043dec9fcdSqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 12053dec9fcdSqs148142 12063dec9fcdSqs148142 rx_rcr_rings = hxgep->rx_rcr_rings; 12073dec9fcdSqs148142 rcr_rings = rx_rcr_rings->rcr_rings; 12083dec9fcdSqs148142 rx_rbr_rings = hxgep->rx_rbr_rings; 12093dec9fcdSqs148142 rbr_rings = rx_rbr_rings->rbr_rings; 12103dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12113dec9fcdSqs148142 "hxgep (hxge_t) $%p\n dev_regs (dev_regs_t) $%p\n", 1212*1667122dSMichael Speer (void *)hxgep, (void *)hxgep->dev_regs); 12133dec9fcdSqs148142 12143dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12153dec9fcdSqs148142 /* do register pointers */ 12163dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12173dec9fcdSqs148142 "reg base (hpi_reg_ptr_t) $%p\t pci reg (hpi_reg_ptr_t) $%p\n", 1218*1667122dSMichael Speer (void *)hxgep->dev_regs->hxge_regp, 1219*1667122dSMichael Speer (void *)hxgep->dev_regs->hxge_pciregp); 12203dec9fcdSqs148142 12213dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12223dec9fcdSqs148142 12233dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12243dec9fcdSqs148142 "\nBlock \t Offset \n"); 12253dec9fcdSqs148142 12263dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12273dec9fcdSqs148142 block = 0; 12283dec9fcdSqs148142 #if defined(__i386) 12293dec9fcdSqs148142 base = (uint64_t)(uint32_t)hxgep->dev_regs->hxge_regp; 12303dec9fcdSqs148142 #else 12313dec9fcdSqs148142 base = (uint64_t)hxgep->dev_regs->hxge_regp; 12323dec9fcdSqs148142 #endif 12333dec9fcdSqs148142 while (reg_block[block].offset != ALL_FF_32) { 12343dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12353dec9fcdSqs148142 "%9s\t 0x%llx\n", reg_block[block].name, 12363dec9fcdSqs148142 (unsigned long long) (reg_block[block].offset + base)); 12373dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12383dec9fcdSqs148142 block++; 12393dec9fcdSqs148142 } 12403dec9fcdSqs148142 12413dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12423dec9fcdSqs148142 "\nRDC\t rcrp (rx_rcr_ring_t)\t rbrp (rx_rbr_ring_t)\n"); 12433dec9fcdSqs148142 12443dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12453dec9fcdSqs148142 12463dec9fcdSqs148142 for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) { 12473dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12483dec9fcdSqs148142 " %d\t $%p\t\t $%p\n", 1249*1667122dSMichael Speer rdc, (void *)rcr_rings[rdc], (void *)rbr_rings[rdc]); 12503dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12513dec9fcdSqs148142 } 12523dec9fcdSqs148142 12533dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 12543dec9fcdSqs148142 "\nTDC\t tdcp (tx_ring_t)\n"); 12553dec9fcdSqs148142 12563dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12573dec9fcdSqs148142 tx_rings = hxgep->tx_rings->rings; 12583dec9fcdSqs148142 for (tdc = 0; tdc < p_cfgp->max_tdcs; tdc++) { 12593dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, 1260*1667122dSMichael Speer " %d\t $%p\n", tdc, (void *)tx_rings[tdc]); 12613dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12623dec9fcdSqs148142 } 12633dec9fcdSqs148142 12643dec9fcdSqs148142 print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, "\n\n"); 12653dec9fcdSqs148142 12663dec9fcdSqs148142 ADVANCE_PRINT_BUFFER(np, print_len, buf_len); 12673dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "<== hxge_param_dump_ptrs")); 12683dec9fcdSqs148142 return (0); 12693dec9fcdSqs148142 } 12703dec9fcdSqs148142 12713dec9fcdSqs148142 /* 12723dec9fcdSqs148142 * Load 'name' into the named dispatch table pointed to by 'ndp'. 12733dec9fcdSqs148142 * 'ndp' should be the address of a char pointer cell. If the table 12743dec9fcdSqs148142 * does not exist (*ndp == 0), a new table is allocated and 'ndp' 12753dec9fcdSqs148142 * is stuffed. If there is not enough space in the table for a new 12763dec9fcdSqs148142 * entry, more space is allocated. 12773dec9fcdSqs148142 */ 12783dec9fcdSqs148142 boolean_t 12793dec9fcdSqs148142 hxge_nd_load(caddr_t *pparam, char *name, 12803dec9fcdSqs148142 pfi_t get_pfi, pfi_t set_pfi, caddr_t data) 12813dec9fcdSqs148142 { 12823dec9fcdSqs148142 ND *nd; 12833dec9fcdSqs148142 NDE *nde; 12843dec9fcdSqs148142 12853dec9fcdSqs148142 HXGE_DEBUG_MSG((NULL, NDD2_CTL, " ==> hxge_nd_load: %s", name)); 12863dec9fcdSqs148142 if (!pparam) 12873dec9fcdSqs148142 return (B_FALSE); 12883dec9fcdSqs148142 if ((nd = (ND *) * pparam) == NULL) { 12893dec9fcdSqs148142 if ((nd = (ND *) KMEM_ZALLOC(sizeof (ND), KM_NOSLEEP)) == NULL) 12903dec9fcdSqs148142 return (B_FALSE); 12913dec9fcdSqs148142 *pparam = (caddr_t)nd; 12923dec9fcdSqs148142 } 12933dec9fcdSqs148142 if (nd->nd_tbl) { 12943dec9fcdSqs148142 for (nde = nd->nd_tbl; nde->nde_name; nde++) { 12953dec9fcdSqs148142 if (strcmp(name, nde->nde_name) == 0) 12963dec9fcdSqs148142 goto fill_it; 12973dec9fcdSqs148142 } 12983dec9fcdSqs148142 } 12993dec9fcdSqs148142 if (nd->nd_free_count <= 1) { 13003dec9fcdSqs148142 if ((nde = (NDE *) KMEM_ZALLOC(nd->nd_size + 13013dec9fcdSqs148142 NDE_ALLOC_SIZE, KM_NOSLEEP)) == NULL) 13023dec9fcdSqs148142 return (B_FALSE); 13033dec9fcdSqs148142 nd->nd_free_count += NDE_ALLOC_COUNT; 13043dec9fcdSqs148142 if (nd->nd_tbl) { 13053dec9fcdSqs148142 bcopy((char *)nd->nd_tbl, (char *)nde, nd->nd_size); 13063dec9fcdSqs148142 KMEM_FREE((char *)nd->nd_tbl, nd->nd_size); 13073dec9fcdSqs148142 } else { 13083dec9fcdSqs148142 nd->nd_free_count--; 13093dec9fcdSqs148142 nde->nde_name = "?"; 13103dec9fcdSqs148142 nde->nde_get_pfi = hxge_nd_get_names; 13113dec9fcdSqs148142 nde->nde_set_pfi = hxge_set_default; 13123dec9fcdSqs148142 } 13133dec9fcdSqs148142 nde->nde_data = (caddr_t)nd; 13143dec9fcdSqs148142 nd->nd_tbl = nde; 13153dec9fcdSqs148142 nd->nd_size += NDE_ALLOC_SIZE; 13163dec9fcdSqs148142 } 13173dec9fcdSqs148142 for (nde = nd->nd_tbl; nde->nde_name; nde++) 13183dec9fcdSqs148142 noop; 13193dec9fcdSqs148142 nd->nd_free_count--; 13203dec9fcdSqs148142 fill_it: 13213dec9fcdSqs148142 nde->nde_name = name; 13223dec9fcdSqs148142 nde->nde_get_pfi = get_pfi; 13233dec9fcdSqs148142 nde->nde_set_pfi = set_pfi; 13243dec9fcdSqs148142 nde->nde_data = data; 13253dec9fcdSqs148142 HXGE_DEBUG_MSG((NULL, NDD2_CTL, " <== hxge_nd_load")); 13263dec9fcdSqs148142 13273dec9fcdSqs148142 return (B_TRUE); 13283dec9fcdSqs148142 } 13293dec9fcdSqs148142 13303dec9fcdSqs148142 /* 13313dec9fcdSqs148142 * Free the table pointed to by 'pparam' 13323dec9fcdSqs148142 */ 13333dec9fcdSqs148142 void 13343dec9fcdSqs148142 hxge_nd_free(caddr_t *pparam) 13353dec9fcdSqs148142 { 13363dec9fcdSqs148142 ND *nd; 13373dec9fcdSqs148142 13383dec9fcdSqs148142 if ((nd = (ND *)*pparam) != NULL) { 13393dec9fcdSqs148142 if (nd->nd_tbl) 13403dec9fcdSqs148142 KMEM_FREE((char *)nd->nd_tbl, nd->nd_size); 13413dec9fcdSqs148142 KMEM_FREE((char *)nd, sizeof (ND)); 13423dec9fcdSqs148142 *pparam = nil(caddr_t); 13433dec9fcdSqs148142 } 13443dec9fcdSqs148142 } 13453dec9fcdSqs148142 13463dec9fcdSqs148142 int 13473dec9fcdSqs148142 hxge_nd_getset(p_hxge_t hxgep, queue_t *q, caddr_t param, p_mblk_t mp) 13483dec9fcdSqs148142 { 13493dec9fcdSqs148142 int err; 13503dec9fcdSqs148142 IOCP iocp; 13513dec9fcdSqs148142 p_mblk_t mp1, mp2; 13523dec9fcdSqs148142 ND *nd; 13533dec9fcdSqs148142 NDE *nde; 13543dec9fcdSqs148142 char *valp; 13553dec9fcdSqs148142 13563dec9fcdSqs148142 size_t avail; 13573dec9fcdSqs148142 13583dec9fcdSqs148142 if (!param) { 13593dec9fcdSqs148142 return (B_FALSE); 13603dec9fcdSqs148142 } 13613dec9fcdSqs148142 nd = (ND *) param; 13623dec9fcdSqs148142 iocp = (IOCP) mp->b_rptr; 13633dec9fcdSqs148142 if ((iocp->ioc_count == 0) || !(mp1 = mp->b_cont)) { 13643dec9fcdSqs148142 mp->b_datap->db_type = M_IOCACK; 13653dec9fcdSqs148142 iocp->ioc_count = 0; 13663dec9fcdSqs148142 iocp->ioc_error = EINVAL; 13673dec9fcdSqs148142 return (B_FALSE); 13683dec9fcdSqs148142 } 13693dec9fcdSqs148142 /* 13703dec9fcdSqs148142 * NOTE - logic throughout nd_xxx assumes single data block for ioctl. 13713dec9fcdSqs148142 * However, existing code sends in some big buffers. 13723dec9fcdSqs148142 */ 13733dec9fcdSqs148142 avail = iocp->ioc_count; 13743dec9fcdSqs148142 if (mp1->b_cont) { 13753dec9fcdSqs148142 freemsg(mp1->b_cont); 13763dec9fcdSqs148142 mp1->b_cont = NULL; 13773dec9fcdSqs148142 } 13783dec9fcdSqs148142 mp1->b_datap->db_lim[-1] = '\0'; /* Force null termination */ 13793dec9fcdSqs148142 for (valp = (char *)mp1->b_rptr; *valp != '\0'; valp++) { 13803dec9fcdSqs148142 if (*valp == '-') 13813dec9fcdSqs148142 *valp = '_'; 13823dec9fcdSqs148142 } 13833dec9fcdSqs148142 13843dec9fcdSqs148142 valp = (char *)mp1->b_rptr; 13853dec9fcdSqs148142 13863dec9fcdSqs148142 for (nde = nd->nd_tbl; /* */; nde++) { 13873dec9fcdSqs148142 if (!nde->nde_name) 13883dec9fcdSqs148142 return (B_FALSE); 13893dec9fcdSqs148142 if (strcmp(nde->nde_name, valp) == 0) 13903dec9fcdSqs148142 break; 13913dec9fcdSqs148142 } 13923dec9fcdSqs148142 err = EINVAL; 13933dec9fcdSqs148142 while (*valp++) 13943dec9fcdSqs148142 noop; 13953dec9fcdSqs148142 if (!*valp || valp >= (char *)mp1->b_wptr) 13963dec9fcdSqs148142 valp = nilp(char); 13973dec9fcdSqs148142 switch (iocp->ioc_cmd) { 13983dec9fcdSqs148142 case ND_GET: 1399a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (*nde->nde_get_pfi == NULL) 1400a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States return (B_FALSE); 1401a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 14023dec9fcdSqs148142 /* 14033dec9fcdSqs148142 * (temporary) hack: "*valp" is size of user buffer for 14043dec9fcdSqs148142 * copyout. If result of action routine is too big, free excess 14053dec9fcdSqs148142 * and return ioc_rval as buffer size needed. Return as many 14063dec9fcdSqs148142 * mblocks as will fit, free the rest. For backward 14073dec9fcdSqs148142 * compatibility, assume size of original ioctl buffer if 14083dec9fcdSqs148142 * "*valp" bad or not given. 14093dec9fcdSqs148142 */ 14103dec9fcdSqs148142 if (valp) 14113dec9fcdSqs148142 avail = mi_strtol(valp, (char **)0, 10); 14123dec9fcdSqs148142 /* 14133dec9fcdSqs148142 * We overwrite the name/value with the reply data 14143dec9fcdSqs148142 */ 14153dec9fcdSqs148142 mp2 = mp1; 14163dec9fcdSqs148142 while (mp2) { 14173dec9fcdSqs148142 mp2->b_wptr = mp2->b_rptr; 14183dec9fcdSqs148142 mp2 = mp2->b_cont; 14193dec9fcdSqs148142 } 14203dec9fcdSqs148142 14213dec9fcdSqs148142 err = (*nde->nde_get_pfi) (hxgep, q, mp1, nde->nde_data); 14223dec9fcdSqs148142 14233dec9fcdSqs148142 if (!err) { 14243dec9fcdSqs148142 size_t size_out = 0; 14253dec9fcdSqs148142 ssize_t excess; 14263dec9fcdSqs148142 14273dec9fcdSqs148142 iocp->ioc_rval = 0; 14283dec9fcdSqs148142 14293dec9fcdSqs148142 /* Tack on the null */ 14303dec9fcdSqs148142 err = hxge_mk_mblk_tail_space(mp1, &mp2, 1); 14313dec9fcdSqs148142 if (!err) { 14323dec9fcdSqs148142 *mp2->b_wptr++ = '\0'; 14333dec9fcdSqs148142 size_out = msgdsize(mp1); 14343dec9fcdSqs148142 excess = size_out - avail; 14353dec9fcdSqs148142 if (excess > 0) { 14363dec9fcdSqs148142 iocp->ioc_rval = (int)size_out; 14373dec9fcdSqs148142 size_out -= excess; 14383dec9fcdSqs148142 (void) adjmsg(mp1, -(excess + 1)); 14393dec9fcdSqs148142 err = hxge_mk_mblk_tail_space( 14403dec9fcdSqs148142 mp1, &mp2, 1); 14413dec9fcdSqs148142 if (!err) 14423dec9fcdSqs148142 *mp2->b_wptr++ = '\0'; 14433dec9fcdSqs148142 else 14443dec9fcdSqs148142 size_out = 0; 14453dec9fcdSqs148142 } 14463dec9fcdSqs148142 } else 14473dec9fcdSqs148142 size_out = 0; 14483dec9fcdSqs148142 iocp->ioc_count = size_out; 14493dec9fcdSqs148142 } 14503dec9fcdSqs148142 break; 14513dec9fcdSqs148142 14523dec9fcdSqs148142 case ND_SET: 14533dec9fcdSqs148142 if (valp) { 14543dec9fcdSqs148142 if (nde->nde_set_pfi) { 14553dec9fcdSqs148142 err = (*nde->nde_set_pfi) (hxgep, q, mp1, valp, 14563dec9fcdSqs148142 nde->nde_data); 14573dec9fcdSqs148142 iocp->ioc_count = 0; 14583dec9fcdSqs148142 freemsg(mp1); 14593dec9fcdSqs148142 mp->b_cont = NULL; 14603dec9fcdSqs148142 } 14613dec9fcdSqs148142 } 14623dec9fcdSqs148142 break; 14633dec9fcdSqs148142 14643dec9fcdSqs148142 default: 14653dec9fcdSqs148142 break; 14663dec9fcdSqs148142 } 14673dec9fcdSqs148142 iocp->ioc_error = err; 14683dec9fcdSqs148142 mp->b_datap->db_type = M_IOCACK; 14693dec9fcdSqs148142 return (B_TRUE); 14703dec9fcdSqs148142 } 14713dec9fcdSqs148142 14723dec9fcdSqs148142 /* ARGSUSED */ 14733dec9fcdSqs148142 int 14743dec9fcdSqs148142 hxge_nd_get_names(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t param) 14753dec9fcdSqs148142 { 14763dec9fcdSqs148142 ND *nd; 14773dec9fcdSqs148142 NDE *nde; 14783dec9fcdSqs148142 char *rwtag; 14793dec9fcdSqs148142 boolean_t get_ok, set_ok; 14803dec9fcdSqs148142 size_t param_len; 14813dec9fcdSqs148142 int status = 0; 14823dec9fcdSqs148142 14833dec9fcdSqs148142 nd = (ND *) param; 14843dec9fcdSqs148142 if (!nd) 14853dec9fcdSqs148142 return (ENOENT); 14863dec9fcdSqs148142 14873dec9fcdSqs148142 for (nde = nd->nd_tbl; nde->nde_name; nde++) { 14883dec9fcdSqs148142 get_ok = (nde->nde_get_pfi != hxge_get_default) && 14893dec9fcdSqs148142 (nde->nde_get_pfi != NULL); 14903dec9fcdSqs148142 set_ok = (nde->nde_set_pfi != hxge_set_default) && 14913dec9fcdSqs148142 (nde->nde_set_pfi != NULL); 14923dec9fcdSqs148142 if (get_ok) { 14933dec9fcdSqs148142 if (set_ok) 14943dec9fcdSqs148142 rwtag = "read and write"; 14953dec9fcdSqs148142 else 14963dec9fcdSqs148142 rwtag = "read only"; 14973dec9fcdSqs148142 } else if (set_ok) 14983dec9fcdSqs148142 rwtag = "write only"; 14993dec9fcdSqs148142 else { 15003dec9fcdSqs148142 continue; 15013dec9fcdSqs148142 } 15023dec9fcdSqs148142 param_len = strlen(rwtag); 15033dec9fcdSqs148142 param_len += strlen(nde->nde_name); 15043dec9fcdSqs148142 param_len += 4; 15053dec9fcdSqs148142 15063dec9fcdSqs148142 (void) mi_mpprintf(mp, "%s (%s)", nde->nde_name, rwtag); 15073dec9fcdSqs148142 } 15083dec9fcdSqs148142 return (status); 15093dec9fcdSqs148142 } 15103dec9fcdSqs148142 15113dec9fcdSqs148142 /* ARGSUSED */ 15123dec9fcdSqs148142 int 15133dec9fcdSqs148142 hxge_get_default(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t data) 15143dec9fcdSqs148142 { 15153dec9fcdSqs148142 return (EACCES); 15163dec9fcdSqs148142 } 15173dec9fcdSqs148142 15183dec9fcdSqs148142 /* ARGSUSED */ 15193dec9fcdSqs148142 int 15203dec9fcdSqs148142 hxge_set_default(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, char *value, 15213dec9fcdSqs148142 caddr_t data) 15223dec9fcdSqs148142 { 15233dec9fcdSqs148142 return (EACCES); 15243dec9fcdSqs148142 } 15253dec9fcdSqs148142 15263dec9fcdSqs148142 void 15273dec9fcdSqs148142 hxge_param_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp) 15283dec9fcdSqs148142 { 15293dec9fcdSqs148142 int cmd; 15303dec9fcdSqs148142 int status = B_FALSE; 15313dec9fcdSqs148142 15323dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "==> hxge_param_ioctl")); 15333dec9fcdSqs148142 cmd = iocp->ioc_cmd; 15343dec9fcdSqs148142 switch (cmd) { 15353dec9fcdSqs148142 default: 15363dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, 15373dec9fcdSqs148142 "hxge_param_ioctl: bad cmd 0x%0x", cmd)); 15383dec9fcdSqs148142 break; 15393dec9fcdSqs148142 15403dec9fcdSqs148142 case ND_GET: 15413dec9fcdSqs148142 case ND_SET: 15423dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, 15433dec9fcdSqs148142 "hxge_param_ioctl: cmd 0x%0x", cmd)); 15443dec9fcdSqs148142 if (!hxge_nd_getset(hxgep, wq, hxgep->param_list, mp)) { 15453dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, 15463dec9fcdSqs148142 "false ret from hxge_nd_getset")); 15473dec9fcdSqs148142 break; 15483dec9fcdSqs148142 } 15493dec9fcdSqs148142 status = B_TRUE; 15503dec9fcdSqs148142 break; 15513dec9fcdSqs148142 } 15523dec9fcdSqs148142 15533dec9fcdSqs148142 if (status) { 15543dec9fcdSqs148142 qreply(wq, mp); 15553dec9fcdSqs148142 } else { 15563dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 15573dec9fcdSqs148142 } 15583dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "<== hxge_param_ioctl")); 15593dec9fcdSqs148142 } 1560