16349Sqs148142 /*
26349Sqs148142 * CDDL HEADER START
36349Sqs148142 *
46349Sqs148142 * The contents of this file are subject to the terms of the
56349Sqs148142 * Common Development and Distribution License (the "License").
66349Sqs148142 * You may not use this file except in compliance with the License.
76349Sqs148142 *
86349Sqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96349Sqs148142 * or http://www.opensolaris.org/os/licensing.
106349Sqs148142 * See the License for the specific language governing permissions
116349Sqs148142 * and limitations under the License.
126349Sqs148142 *
136349Sqs148142 * When distributing Covered Code, include this CDDL HEADER in each
146349Sqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156349Sqs148142 * If applicable, add the following below this CDDL HEADER, with the
166349Sqs148142 * fields enclosed by brackets "[]" replaced with your own identifying
176349Sqs148142 * information: Portions Copyright [yyyy] [name of copyright owner]
186349Sqs148142 *
196349Sqs148142 * CDDL HEADER END
206349Sqs148142 */
216349Sqs148142 /*
226349Sqs148142 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
236349Sqs148142 * Use is subject to license terms.
246349Sqs148142 */
256349Sqs148142
266349Sqs148142 #include <hxge_impl.h>
276349Sqs148142 #include <hxge_vmac.h>
286349Sqs148142 #include <hxge_pfc.h>
296349Sqs148142 #include <hpi_pfc.h>
306349Sqs148142
316349Sqs148142 static hxge_status_t hxge_get_mac_addr_properties(p_hxge_t);
326349Sqs148142 static void hxge_use_cfg_hydra_properties(p_hxge_t);
336349Sqs148142 static void hxge_use_cfg_dma_config(p_hxge_t);
346349Sqs148142 static void hxge_use_cfg_class_config(p_hxge_t);
356349Sqs148142 static void hxge_set_hw_dma_config(p_hxge_t);
366349Sqs148142 static void hxge_set_hw_class_config(p_hxge_t);
376349Sqs148142 static void hxge_ldgv_setup(p_hxge_ldg_t *ldgp, p_hxge_ldv_t *ldvp, uint8_t ldv,
386349Sqs148142 uint8_t endldg, int *ngrps);
396349Sqs148142
406349Sqs148142 extern uint16_t hxge_rcr_timeout;
416349Sqs148142 extern uint16_t hxge_rcr_threshold;
426349Sqs148142
436349Sqs148142 extern uint32_t hxge_rbr_size;
446349Sqs148142 extern uint32_t hxge_rcr_size;
456349Sqs148142
466349Sqs148142 extern uint_t hxge_rx_intr();
476349Sqs148142 extern uint_t hxge_tx_intr();
486349Sqs148142 extern uint_t hxge_vmac_intr();
496349Sqs148142 extern uint_t hxge_syserr_intr();
506349Sqs148142 extern uint_t hxge_pfc_intr();
516349Sqs148142
526349Sqs148142 /*
536349Sqs148142 * Entry point to populate configuration parameters into the master hxge
546349Sqs148142 * data structure and to update the NDD parameter list.
556349Sqs148142 */
566349Sqs148142 hxge_status_t
hxge_get_config_properties(p_hxge_t hxgep)576349Sqs148142 hxge_get_config_properties(p_hxge_t hxgep)
586349Sqs148142 {
596349Sqs148142 hxge_status_t status = HXGE_OK;
606349Sqs148142
616349Sqs148142 HXGE_DEBUG_MSG((hxgep, VPD_CTL, " ==> hxge_get_config_properties"));
626349Sqs148142
636349Sqs148142 if (hxgep->hxge_hw_p == NULL) {
646349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
656349Sqs148142 " hxge_get_config_properties: common hardware not set"));
666349Sqs148142 return (HXGE_ERROR);
676349Sqs148142 }
686349Sqs148142
696349Sqs148142 hxgep->classifier.tcam_size = TCAM_HXGE_TCAM_MAX_ENTRY;
706349Sqs148142
716349Sqs148142 status = hxge_get_mac_addr_properties(hxgep);
726349Sqs148142 if (status != HXGE_OK) {
736349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
746349Sqs148142 " hxge_get_config_properties: mac addr properties failed"));
756349Sqs148142 return (status);
766349Sqs148142 }
776349Sqs148142
786349Sqs148142 HXGE_DEBUG_MSG((hxgep, VPD_CTL,
796349Sqs148142 " ==> hxge_get_config_properties: Hydra"));
806349Sqs148142
816349Sqs148142 hxge_use_cfg_hydra_properties(hxgep);
826349Sqs148142
836349Sqs148142 HXGE_DEBUG_MSG((hxgep, VPD_CTL, " <== hxge_get_config_properties"));
846349Sqs148142 return (HXGE_OK);
856349Sqs148142 }
866349Sqs148142
876349Sqs148142
886349Sqs148142 static void
hxge_set_hw_vlan_class_config(p_hxge_t hxgep)896349Sqs148142 hxge_set_hw_vlan_class_config(p_hxge_t hxgep)
906349Sqs148142 {
916349Sqs148142 int i;
926349Sqs148142 p_hxge_param_t param_arr;
936349Sqs148142 uint_t vlan_cnt;
946349Sqs148142 int *vlan_cfg_val;
956349Sqs148142 hxge_param_map_t *vmap;
966349Sqs148142 char *prop;
976349Sqs148142 p_hxge_class_pt_cfg_t p_class_cfgp;
986349Sqs148142 uint32_t good_cfg[32];
996349Sqs148142 int good_count = 0;
1006349Sqs148142 hxge_mv_cfg_t *vlan_tbl;
1016349Sqs148142
1026349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " ==> hxge_set_hw_vlan_config"));
1036349Sqs148142 p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config;
1046349Sqs148142
1056349Sqs148142 param_arr = hxgep->param_arr;
1066349Sqs148142 prop = param_arr[param_vlan_ids].fcode_name;
1076349Sqs148142
1086349Sqs148142 /*
1096349Sqs148142 * uint32_t array, each array entry specifying a VLAN id
1106349Sqs148142 */
1116349Sqs148142 for (i = 0; i <= VLAN_ID_MAX; i++) {
1126349Sqs148142 p_class_cfgp->vlan_tbl[i].flag = 0;
1136349Sqs148142 }
1146349Sqs148142
1156349Sqs148142 vlan_tbl = (hxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0];
1166349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, prop,
1176349Sqs148142 &vlan_cfg_val, &vlan_cnt) != DDI_PROP_SUCCESS) {
1186349Sqs148142 return;
1196349Sqs148142 }
1206349Sqs148142
1216349Sqs148142 for (i = 0; i < vlan_cnt; i++) {
1226349Sqs148142 vmap = (hxge_param_map_t *)&vlan_cfg_val[i];
1236349Sqs148142 if ((vmap->param_id) && (vmap->param_id <= VLAN_ID_MAX)) {
1246349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG2_CTL,
1256349Sqs148142 " hxge_vlan_config vlan id %d", vmap->param_id));
1266349Sqs148142
1276349Sqs148142 good_cfg[good_count] = vlan_cfg_val[i];
1286349Sqs148142 if (vlan_tbl[vmap->param_id].flag == 0)
1296349Sqs148142 good_count++;
1306349Sqs148142
1316349Sqs148142 vlan_tbl[vmap->param_id].flag = 1;
1326349Sqs148142 }
1336349Sqs148142 }
1346349Sqs148142
1356349Sqs148142 ddi_prop_free(vlan_cfg_val);
1366349Sqs148142 if (good_count != vlan_cnt) {
1376349Sqs148142 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
1386349Sqs148142 hxgep->dip, prop, (int *)good_cfg, good_count);
1396349Sqs148142 }
1406349Sqs148142
1416349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " <== hxge_set_hw_vlan_config"));
1426349Sqs148142 }
1436349Sqs148142
1446349Sqs148142
1456349Sqs148142 /*
1466349Sqs148142 * Read param_vlan_ids and param_implicit_vlan_id properties from either
1476349Sqs148142 * hxge.conf or OBP. Update the soft properties. Populate these
1486349Sqs148142 * properties into the hxge data structure.
1496349Sqs148142 */
1506349Sqs148142 static void
hxge_use_cfg_vlan_class_config(p_hxge_t hxgep)1516349Sqs148142 hxge_use_cfg_vlan_class_config(p_hxge_t hxgep)
1526349Sqs148142 {
1536349Sqs148142 uint_t vlan_cnt;
1546349Sqs148142 int *vlan_cfg_val;
1556349Sqs148142 int status;
1566349Sqs148142 p_hxge_param_t param_arr;
1576349Sqs148142 char *prop;
1586349Sqs148142 uint32_t implicit_vlan_id = 0;
1596349Sqs148142 int *int_prop_val;
1606349Sqs148142 uint_t prop_len;
1616349Sqs148142 p_hxge_param_t pa;
1626349Sqs148142
1636349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " ==> hxge_use_cfg_vlan_config"));
1646349Sqs148142 param_arr = hxgep->param_arr;
1656349Sqs148142 prop = param_arr[param_vlan_ids].fcode_name;
1666349Sqs148142
1676349Sqs148142 status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, prop,
1686349Sqs148142 &vlan_cfg_val, &vlan_cnt);
1696349Sqs148142 if (status == DDI_PROP_SUCCESS) {
1706349Sqs148142 status = ddi_prop_update_int_array(DDI_DEV_T_NONE,
1716349Sqs148142 hxgep->dip, prop, vlan_cfg_val, vlan_cnt);
1726349Sqs148142 ddi_prop_free(vlan_cfg_val);
1736349Sqs148142 }
1746349Sqs148142
1756349Sqs148142 pa = ¶m_arr[param_implicit_vlan_id];
1766349Sqs148142 prop = pa->fcode_name;
1776349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, prop,
1786349Sqs148142 &int_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
1796349Sqs148142 implicit_vlan_id = (uint32_t)*int_prop_val;
1806349Sqs148142 if ((implicit_vlan_id >= pa->minimum) ||
1816349Sqs148142 (implicit_vlan_id <= pa->maximum)) {
1826349Sqs148142 status = ddi_prop_update_int(DDI_DEV_T_NONE, hxgep->dip,
1836349Sqs148142 prop, (int)implicit_vlan_id);
1846349Sqs148142 }
1856349Sqs148142 ddi_prop_free(int_prop_val);
1866349Sqs148142 }
1876349Sqs148142
1886349Sqs148142 hxge_set_hw_vlan_class_config(hxgep);
1896349Sqs148142
1906349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " <== hxge_use_cfg_vlan_config"));
1916349Sqs148142 }
1926349Sqs148142
1936349Sqs148142 /*
1946349Sqs148142 * Read in the configuration parameters from either hxge.conf or OBP and
1956349Sqs148142 * populate the master data structure hxge.
1966349Sqs148142 * Use these parameters to update the soft properties and the ndd array.
1976349Sqs148142 */
1986349Sqs148142 static void
hxge_use_cfg_hydra_properties(p_hxge_t hxgep)1996349Sqs148142 hxge_use_cfg_hydra_properties(p_hxge_t hxgep)
2006349Sqs148142 {
2016349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " ==> hxge_use_cfg_hydra_properties"));
2026349Sqs148142
2036349Sqs148142 (void) hxge_use_cfg_dma_config(hxgep);
2046349Sqs148142 (void) hxge_use_cfg_vlan_class_config(hxgep);
2056349Sqs148142 (void) hxge_use_cfg_class_config(hxgep);
2066349Sqs148142
2076349Sqs148142 /*
2086349Sqs148142 * Read in the hardware (fcode) properties and use these properties
2096349Sqs148142 * to update the ndd array.
2106349Sqs148142 */
2116349Sqs148142 (void) hxge_get_param_soft_properties(hxgep);
2126349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " <== hxge_use_cfg_hydra_properties"));
2136349Sqs148142 }
2146349Sqs148142
2156349Sqs148142
2166349Sqs148142 /*
2176349Sqs148142 * Read param_accept_jumbo, param_rxdma_intr_time, and param_rxdma_intr_pkts
2186349Sqs148142 * from either hxge.conf or OBP.
2196349Sqs148142 * Update the soft properties.
2206349Sqs148142 * Populate these properties into the hxge data structure for latter use.
2216349Sqs148142 */
2226349Sqs148142 static void
hxge_use_cfg_dma_config(p_hxge_t hxgep)2236349Sqs148142 hxge_use_cfg_dma_config(p_hxge_t hxgep)
2246349Sqs148142 {
2256349Sqs148142 int tx_ndmas, rx_ndmas;
2266349Sqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp;
2276349Sqs148142 p_hxge_hw_pt_cfg_t p_cfgp;
2286349Sqs148142 dev_info_t *dip;
2296349Sqs148142 p_hxge_param_t param_arr;
2306349Sqs148142 char *prop;
2316349Sqs148142 int *prop_val;
2326349Sqs148142 uint_t prop_len;
2336349Sqs148142
2346349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " ==> hxge_use_cfg_dma_config"));
2356349Sqs148142 param_arr = hxgep->param_arr;
2366349Sqs148142
2376349Sqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
2386349Sqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2396349Sqs148142 dip = hxgep->dip;
2406349Sqs148142
2416349Sqs148142 tx_ndmas = 4;
2426349Sqs148142 p_cfgp->start_tdc = 0;
2436349Sqs148142 p_cfgp->max_tdcs = hxgep->max_tdcs = tx_ndmas;
2446349Sqs148142 hxgep->tdc_mask = (tx_ndmas - 1);
2456349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, "==> hxge_use_cfg_dma_config: "
2466349Sqs148142 "p_cfgp 0x%llx max_tdcs %d hxgep->max_tdcs %d",
2476349Sqs148142 p_cfgp, p_cfgp->max_tdcs, hxgep->max_tdcs));
2486349Sqs148142
2496349Sqs148142 rx_ndmas = 4;
2506349Sqs148142 p_cfgp->start_rdc = 0;
2516349Sqs148142 p_cfgp->max_rdcs = hxgep->max_rdcs = rx_ndmas;
2526349Sqs148142
2536349Sqs148142 p_cfgp->start_ldg = 0;
2546349Sqs148142 p_cfgp->max_ldgs = HXGE_INT_MAX_LDG;
2556349Sqs148142
2566349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, "==> hxge_use_default_dma_config: "
2576349Sqs148142 "p_cfgp 0x%llx max_rdcs %d hxgep->max_rdcs %d",
2586349Sqs148142 p_cfgp, p_cfgp->max_rdcs, hxgep->max_rdcs));
2596349Sqs148142
2606349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, "==> hxge_use_cfg_dma_config: "
2616349Sqs148142 "p_cfgp 0x%016llx start_ldg %d hxgep->max_ldgs %d ",
2626349Sqs148142 p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs));
2636349Sqs148142
2646349Sqs148142 /*
2656349Sqs148142 * add code for individual rdc properties
2666349Sqs148142 */
2676349Sqs148142 prop = param_arr[param_accept_jumbo].fcode_name;
2686349Sqs148142
2696349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
2706349Sqs148142 &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
2716349Sqs148142 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2726349Sqs148142 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
2736349Sqs148142 hxgep->dip, prop, prop_val, prop_len);
2746349Sqs148142 }
2756349Sqs148142 ddi_prop_free(prop_val);
2766349Sqs148142 }
2776349Sqs148142
2786349Sqs148142 prop = param_arr[param_rxdma_intr_time].fcode_name;
2796349Sqs148142
2806349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
2816349Sqs148142 &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
2826349Sqs148142 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2836349Sqs148142 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
2846349Sqs148142 hxgep->dip, prop, prop_val, prop_len);
2856349Sqs148142 }
2866349Sqs148142 ddi_prop_free(prop_val);
2876349Sqs148142 }
2886349Sqs148142
2896349Sqs148142 prop = param_arr[param_rxdma_intr_pkts].fcode_name;
2906349Sqs148142
2916349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
2926349Sqs148142 &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
2936349Sqs148142 if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2946349Sqs148142 (void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
2956349Sqs148142 hxgep->dip, prop, prop_val, prop_len);
2966349Sqs148142 }
2976349Sqs148142 ddi_prop_free(prop_val);
2986349Sqs148142 }
2996349Sqs148142
3006349Sqs148142 hxge_set_hw_dma_config(hxgep);
3016349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, "<== hxge_use_cfg_dma_config"));
3026349Sqs148142 }
3036349Sqs148142
3046349Sqs148142 static void
hxge_use_cfg_class_config(p_hxge_t hxgep)3056349Sqs148142 hxge_use_cfg_class_config(p_hxge_t hxgep)
3066349Sqs148142 {
3076349Sqs148142 hxge_set_hw_class_config(hxgep);
3086349Sqs148142 }
3096349Sqs148142
3106349Sqs148142 static void
hxge_set_hw_dma_config(p_hxge_t hxgep)3116349Sqs148142 hxge_set_hw_dma_config(p_hxge_t hxgep)
3126349Sqs148142 {
3136349Sqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp;
3146349Sqs148142 p_hxge_hw_pt_cfg_t p_cfgp;
3156349Sqs148142
3166349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, "==> hxge_set_hw_dma_config"));
3176349Sqs148142
3186349Sqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
3196349Sqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
3206349Sqs148142
3216349Sqs148142 /* Transmit DMA Channels */
3226349Sqs148142 hxgep->ntdc = p_cfgp->max_tdcs;
3236349Sqs148142
3246349Sqs148142 /* Receive DMA Channels */
3256349Sqs148142 hxgep->nrdc = p_cfgp->max_rdcs;
3266349Sqs148142
3276349Sqs148142 p_dma_cfgp->rbr_size = hxge_rbr_size;
3287618SMichael.Speer@Sun.COM if (hxge_rcr_size > HXGE_RCR_MAX)
3297618SMichael.Speer@Sun.COM hxge_rcr_size = HXGE_RCR_MAX;
3306349Sqs148142 p_dma_cfgp->rcr_size = hxge_rcr_size;
3316349Sqs148142
3326349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " <== hxge_set_hw_dma_config"));
3336349Sqs148142 }
3346349Sqs148142
3356349Sqs148142
3366349Sqs148142 boolean_t
hxge_check_rxdma_port_member(p_hxge_t hxgep,uint8_t rdc)3376349Sqs148142 hxge_check_rxdma_port_member(p_hxge_t hxgep, uint8_t rdc)
3386349Sqs148142 {
3396349Sqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp;
3406349Sqs148142 p_hxge_hw_pt_cfg_t p_cfgp;
3416349Sqs148142 int status = B_TRUE;
3426349Sqs148142
3436349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG2_CTL, "==> hxge_check_rxdma_port_member"));
3446349Sqs148142
3456349Sqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
3466349Sqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
3476349Sqs148142
3486349Sqs148142 /* Receive DMA Channels */
3496349Sqs148142 if (rdc < p_cfgp->max_rdcs)
3506349Sqs148142 status = B_TRUE;
3516349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG2_CTL, " <== hxge_check_rxdma_port_member"));
3526349Sqs148142
3536349Sqs148142 return (status);
3546349Sqs148142 }
3556349Sqs148142
3566349Sqs148142 boolean_t
hxge_check_txdma_port_member(p_hxge_t hxgep,uint8_t tdc)3576349Sqs148142 hxge_check_txdma_port_member(p_hxge_t hxgep, uint8_t tdc)
3586349Sqs148142 {
3596349Sqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp;
3606349Sqs148142 p_hxge_hw_pt_cfg_t p_cfgp;
3616349Sqs148142 int status = B_FALSE;
3626349Sqs148142
3636349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG2_CTL, "==> hxge_check_txdma_port_member"));
3646349Sqs148142
3656349Sqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
3666349Sqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
3676349Sqs148142
3686349Sqs148142 /* Receive DMA Channels */
3696349Sqs148142 if (tdc < p_cfgp->max_tdcs)
3706349Sqs148142 status = B_TRUE;
3716349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG2_CTL, " <== hxge_check_txdma_port_member"));
3726349Sqs148142
3736349Sqs148142 return (status);
3746349Sqs148142 }
3756349Sqs148142
3766349Sqs148142
3776349Sqs148142 /*
3786349Sqs148142 * Read the L2 classes, L3 classes, and initial hash from either hxge.conf
3796349Sqs148142 * or OBP. Populate these properties into the hxge data structure for latter
3806349Sqs148142 * use. Note that we are not updating these soft properties.
3816349Sqs148142 */
3826349Sqs148142 static void
hxge_set_hw_class_config(p_hxge_t hxgep)3836349Sqs148142 hxge_set_hw_class_config(p_hxge_t hxgep)
3846349Sqs148142 {
3856349Sqs148142 int i, j;
3866349Sqs148142 p_hxge_param_t param_arr;
3876349Sqs148142 int *int_prop_val;
3886349Sqs148142 uint32_t cfg_value;
3896349Sqs148142 char *prop;
3906349Sqs148142 p_hxge_class_pt_cfg_t p_class_cfgp;
3916349Sqs148142 int start_prop, end_prop;
3926349Sqs148142 uint_t prop_cnt;
3936349Sqs148142
3946349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " ==> hxge_set_hw_class_config"));
3956349Sqs148142
3966349Sqs148142 p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config;
3976349Sqs148142
3986349Sqs148142 param_arr = hxgep->param_arr;
3996349Sqs148142
4006349Sqs148142 /*
4016349Sqs148142 * L2 class configuration. User configurable ether types
4026349Sqs148142 */
4036349Sqs148142 start_prop = param_class_cfg_ether_usr1;
4046349Sqs148142 end_prop = param_class_cfg_ether_usr2;
4056349Sqs148142
4066349Sqs148142 for (i = start_prop; i <= end_prop; i++) {
4076349Sqs148142 prop = param_arr[i].fcode_name;
4086349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip,
4096349Sqs148142 0, prop, &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) {
4106349Sqs148142 cfg_value = (uint32_t)*int_prop_val;
4116349Sqs148142 ddi_prop_free(int_prop_val);
4126349Sqs148142 } else {
4136349Sqs148142 cfg_value = (uint32_t)param_arr[i].value;
4146349Sqs148142 }
4156349Sqs148142
4166349Sqs148142 j = (i - start_prop) + TCAM_CLASS_ETYPE_1;
4176349Sqs148142 p_class_cfgp->class_cfg[j] = cfg_value;
4186349Sqs148142 }
4196349Sqs148142
4206349Sqs148142 /*
4216349Sqs148142 * Use properties from either .conf or the NDD param array. Only bits
4226349Sqs148142 * 2 and 3 are significant
4236349Sqs148142 */
4246349Sqs148142 start_prop = param_class_opt_ipv4_tcp;
4256349Sqs148142 end_prop = param_class_opt_ipv6_sctp;
4266349Sqs148142
4276349Sqs148142 for (i = start_prop; i <= end_prop; i++) {
4286349Sqs148142 prop = param_arr[i].fcode_name;
4296349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip,
4306349Sqs148142 0, prop, &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) {
4316349Sqs148142 cfg_value = (uint32_t)*int_prop_val;
4326349Sqs148142 ddi_prop_free(int_prop_val);
4336349Sqs148142 } else {
4346349Sqs148142 cfg_value = (uint32_t)param_arr[i].value;
4356349Sqs148142 }
4366349Sqs148142
4376349Sqs148142 j = (i - start_prop) + TCAM_CLASS_TCP_IPV4;
4386349Sqs148142 p_class_cfgp->class_cfg[j] = cfg_value;
4396349Sqs148142 }
4406349Sqs148142
4416349Sqs148142 prop = param_arr[param_hash_init_value].fcode_name;
4426349Sqs148142
4436349Sqs148142 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0, prop,
4446349Sqs148142 &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) {
4456349Sqs148142 cfg_value = (uint32_t)*int_prop_val;
4466349Sqs148142 ddi_prop_free(int_prop_val);
4476349Sqs148142 } else {
4486349Sqs148142 cfg_value = (uint32_t)param_arr[param_hash_init_value].value;
4496349Sqs148142 }
4506349Sqs148142
4516349Sqs148142 p_class_cfgp->init_hash = (uint32_t)cfg_value;
4526349Sqs148142
4536349Sqs148142 HXGE_DEBUG_MSG((hxgep, CFG_CTL, " <== hxge_set_hw_class_config"));
4546349Sqs148142 }
4556349Sqs148142
4566349Sqs148142
4576349Sqs148142 /*
4586349Sqs148142 * Interrupts related interface functions.
4596349Sqs148142 */
4606349Sqs148142 hxge_status_t
hxge_ldgv_init(p_hxge_t hxgep,int * navail_p,int * nrequired_p)4616349Sqs148142 hxge_ldgv_init(p_hxge_t hxgep, int *navail_p, int *nrequired_p)
4626349Sqs148142 {
4636349Sqs148142 uint8_t ldv, i, maxldvs, maxldgs, start, end, nldvs;
4646349Sqs148142 int ldg, endldg, ngrps;
4656349Sqs148142 uint8_t channel;
4666349Sqs148142 p_hxge_dma_pt_cfg_t p_dma_cfgp;
4676349Sqs148142 p_hxge_hw_pt_cfg_t p_cfgp;
4686349Sqs148142 p_hxge_ldgv_t ldgvp;
4696349Sqs148142 p_hxge_ldg_t ldgp, ptr;
4706349Sqs148142 p_hxge_ldv_t ldvp;
4716349Sqs148142 hxge_status_t status = HXGE_OK;
472*7949SQiyan.Sun@Sun.COM peu_intr_mask_t parity_err_mask;
4736349Sqs148142
4746349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_ldgv_init"));
4756349Sqs148142 if (!*navail_p) {
4766349Sqs148142 *nrequired_p = 0;
4776349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
4786349Sqs148142 "<== hxge_ldgv_init:no avail"));
4796349Sqs148142 return (HXGE_ERROR);
4806349Sqs148142 }
4816349Sqs148142 p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
4826349Sqs148142 p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
4836349Sqs148142
4846349Sqs148142 /* each DMA channels */
4856349Sqs148142 nldvs = p_cfgp->max_tdcs + p_cfgp->max_rdcs;
4866349Sqs148142
4876349Sqs148142 /* vmac */
4886349Sqs148142 nldvs++;
4896349Sqs148142
4906349Sqs148142 /* pfc */
4916349Sqs148142 nldvs++;
4926349Sqs148142
4936349Sqs148142 /* system error interrupts. */
4946349Sqs148142 nldvs++;
4956349Sqs148142
4966349Sqs148142 maxldvs = nldvs;
4976349Sqs148142 maxldgs = p_cfgp->max_ldgs;
4986349Sqs148142
4996349Sqs148142 if (!maxldvs || !maxldgs) {
5006349Sqs148142 /* No devices configured. */
5016349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, "<== hxge_ldgv_init: "
5026349Sqs148142 "no logical devices or groups configured."));
5036349Sqs148142 return (HXGE_ERROR);
5046349Sqs148142 }
5056349Sqs148142 ldgvp = hxgep->ldgvp;
5066349Sqs148142 if (ldgvp == NULL) {
5076349Sqs148142 ldgvp = KMEM_ZALLOC(sizeof (hxge_ldgv_t), KM_SLEEP);
5086349Sqs148142 hxgep->ldgvp = ldgvp;
5096349Sqs148142 ldgvp->maxldgs = maxldgs;
5106349Sqs148142 ldgvp->maxldvs = maxldvs;
5116349Sqs148142 ldgp = ldgvp->ldgp =
5126349Sqs148142 KMEM_ZALLOC(sizeof (hxge_ldg_t) * maxldgs, KM_SLEEP);
5136349Sqs148142 ldvp = ldgvp->ldvp =
5146349Sqs148142 KMEM_ZALLOC(sizeof (hxge_ldv_t) * maxldvs, KM_SLEEP);
5156349Sqs148142 }
5166349Sqs148142
5176349Sqs148142 ldgvp->ndma_ldvs = p_cfgp->max_tdcs + p_cfgp->max_rdcs;
5186349Sqs148142 ldgvp->tmres = HXGE_TIMER_RESO;
5196349Sqs148142
5206349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
5216349Sqs148142 "==> hxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d",
5226349Sqs148142 maxldvs, maxldgs, nldvs));
5236349Sqs148142
5246349Sqs148142 ldg = p_cfgp->start_ldg;
5256349Sqs148142 ptr = ldgp;
5266349Sqs148142 for (i = 0; i < maxldgs; i++) {
5276349Sqs148142 ptr->arm = B_TRUE;
5286349Sqs148142 ptr->vldg_index = i;
5296349Sqs148142 ptr->ldg_timer = HXGE_TIMER_LDG;
5306349Sqs148142 ptr->ldg = ldg++;
5316349Sqs148142 ptr->sys_intr_handler = hxge_intr;
5326349Sqs148142 ptr->nldvs = 0;
5336349Sqs148142 ptr->hxgep = hxgep;
5346349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
5356349Sqs148142 "==> hxge_ldgv_init: maxldvs %d maxldgs %d ldg %d",
5366349Sqs148142 maxldvs, maxldgs, ptr->ldg));
5376349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
5386349Sqs148142 "==> hxge_ldv_init: timer %d", ptr->ldg_timer));
5396349Sqs148142 ptr++;
5406349Sqs148142 }
5416349Sqs148142
5426349Sqs148142 ldg = p_cfgp->start_ldg;
5436349Sqs148142 if (maxldgs > *navail_p) {
5446349Sqs148142 ngrps = *navail_p;
5456349Sqs148142 } else {
5466349Sqs148142 ngrps = maxldgs;
5476349Sqs148142 }
5486349Sqs148142 endldg = ldg + ngrps;
5496349Sqs148142
5506349Sqs148142 /*
5516349Sqs148142 * Receive DMA channels.
5526349Sqs148142 */
5536349Sqs148142 channel = p_cfgp->start_rdc;
5546349Sqs148142 start = p_cfgp->start_rdc + HXGE_RDMA_LD_START;
5556349Sqs148142 end = start + p_cfgp->max_rdcs;
5566349Sqs148142 nldvs = 0;
5576349Sqs148142 ldgvp->nldvs = 0;
5586349Sqs148142 ldgp->ldvp = NULL;
5596349Sqs148142 *nrequired_p = 0;
5606349Sqs148142 ptr = ldgp;
5616349Sqs148142
5626349Sqs148142 /*
5636349Sqs148142 * Start with RDC to configure logical devices for each group.
5646349Sqs148142 */
5656349Sqs148142 for (i = 0, ldv = start; ldv < end; i++, ldv++) {
5666349Sqs148142 ldvp->is_rxdma = B_TRUE;
5676349Sqs148142 ldvp->ldv = ldv;
5686349Sqs148142
5696349Sqs148142 /*
5706349Sqs148142 * If non-seq needs to change the following code
5716349Sqs148142 */
5726349Sqs148142 ldvp->channel = channel++;
5736349Sqs148142 ldvp->vdma_index = i;
5746349Sqs148142 ldvp->ldv_intr_handler = hxge_rx_intr;
5756349Sqs148142 ldvp->ldv_ldf_masks = 0;
5766349Sqs148142 ldvp->use_timer = B_FALSE;
5776349Sqs148142 ldvp->hxgep = hxgep;
5786349Sqs148142 hxge_ldgv_setup(&ptr, &ldvp, ldv, endldg, nrequired_p);
5796349Sqs148142 nldvs++;
5806349Sqs148142 }
5816349Sqs148142
5826349Sqs148142 /*
5836349Sqs148142 * Transmit DMA channels.
5846349Sqs148142 */
5856349Sqs148142 channel = p_cfgp->start_tdc;
5866349Sqs148142 start = p_cfgp->start_tdc + HXGE_TDMA_LD_START;
5876349Sqs148142 end = start + p_cfgp->max_tdcs;
5886349Sqs148142 for (i = 0, ldv = start; ldv < end; i++, ldv++) {
5896349Sqs148142 ldvp->is_txdma = B_TRUE;
5906349Sqs148142 ldvp->ldv = ldv;
5916349Sqs148142 ldvp->channel = channel++;
5926349Sqs148142 ldvp->vdma_index = i;
5936349Sqs148142 ldvp->ldv_intr_handler = hxge_tx_intr;
5946349Sqs148142 ldvp->ldv_ldf_masks = 0;
5956349Sqs148142 ldvp->use_timer = B_FALSE;
5966349Sqs148142 ldvp->hxgep = hxgep;
5976349Sqs148142 hxge_ldgv_setup(&ptr, &ldvp, ldv, endldg, nrequired_p);
5986349Sqs148142 nldvs++;
5996349Sqs148142 }
6006349Sqs148142
6016349Sqs148142 /*
6026349Sqs148142 * VMAC
6036349Sqs148142 */
6046349Sqs148142 ldvp->is_vmac = B_TRUE;
6056349Sqs148142 ldvp->ldv_intr_handler = hxge_vmac_intr;
6066349Sqs148142 ldvp->ldv_ldf_masks = 0;
6076349Sqs148142 ldv = HXGE_VMAC_LD;
6086349Sqs148142 ldvp->ldv = ldv;
6096349Sqs148142 ldvp->use_timer = B_FALSE;
6106349Sqs148142 ldvp->hxgep = hxgep;
6116349Sqs148142 hxge_ldgv_setup(&ptr, &ldvp, ldv, endldg, nrequired_p);
6126349Sqs148142 nldvs++;
6136349Sqs148142
6146349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
6156349Sqs148142 "==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
6166349Sqs148142 nldvs, *navail_p, *nrequired_p));
6176349Sqs148142
6186349Sqs148142 /*
6196349Sqs148142 * PFC
6206349Sqs148142 */
6216349Sqs148142 ldvp->is_pfc = B_TRUE;
6226349Sqs148142 ldvp->ldv_intr_handler = hxge_pfc_intr;
6236349Sqs148142 ldvp->ldv_ldf_masks = 0;
6246349Sqs148142 ldv = HXGE_PFC_LD;
6256349Sqs148142 ldvp->ldv = ldv;
6266349Sqs148142 ldvp->use_timer = B_FALSE;
6276349Sqs148142 ldvp->hxgep = hxgep;
6286349Sqs148142 hxge_ldgv_setup(&ptr, &ldvp, ldv, endldg, nrequired_p);
6296349Sqs148142 nldvs++;
6306349Sqs148142
6316349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
6326349Sqs148142 "==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
6336349Sqs148142 nldvs, *navail_p, *nrequired_p));
6346349Sqs148142
6356349Sqs148142 /*
6366349Sqs148142 * System error interrupts.
6376349Sqs148142 */
6386349Sqs148142 ldv = HXGE_SYS_ERROR_LD;
6396349Sqs148142 ldvp->ldv = ldv;
6406349Sqs148142 ldvp->is_syserr = B_TRUE;
6416349Sqs148142 ldvp->ldv_intr_handler = hxge_syserr_intr;
6426349Sqs148142 ldvp->ldv_ldf_masks = 0;
6436349Sqs148142 ldvp->hxgep = hxgep;
6446349Sqs148142 ldvp->use_timer = B_FALSE;
6456349Sqs148142 ldgvp->ldvp_syserr = ldvp;
6466349Sqs148142
6476349Sqs148142 /* Reset PEU error mask to allow PEU error interrupts */
648*7949SQiyan.Sun@Sun.COM /*
649*7949SQiyan.Sun@Sun.COM * Keep the msix parity error mask here and remove it
650*7949SQiyan.Sun@Sun.COM * after ddi_intr_enable call to avoid a msix par err
651*7949SQiyan.Sun@Sun.COM */
652*7949SQiyan.Sun@Sun.COM parity_err_mask.value = 0;
653*7949SQiyan.Sun@Sun.COM parity_err_mask.bits.eic_msix_parerr_mask = 1;
654*7949SQiyan.Sun@Sun.COM HXGE_REG_WR32(hxgep->hpi_handle, PEU_INTR_MASK, parity_err_mask.value);
6556349Sqs148142
6566349Sqs148142 /*
6576349Sqs148142 * Unmask the system interrupt states.
6586349Sqs148142 */
6596349Sqs148142 (void) hxge_fzc_sys_err_mask_set(hxgep, B_FALSE);
6606349Sqs148142 (void) hxge_ldgv_setup(&ptr, &ldvp, ldv, endldg, nrequired_p);
6616349Sqs148142 nldvs++;
6626349Sqs148142
6636349Sqs148142 ldgvp->ldg_intrs = *nrequired_p;
6646349Sqs148142
6656349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
6666349Sqs148142 "==> hxge_ldgv_init: nldvs %d navail %d nrequired %d",
6676349Sqs148142 nldvs, *navail_p, *nrequired_p));
6686349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_ldgv_init"));
6696349Sqs148142 return (status);
6706349Sqs148142 }
6716349Sqs148142
6726349Sqs148142 hxge_status_t
hxge_ldgv_uninit(p_hxge_t hxgep)6736349Sqs148142 hxge_ldgv_uninit(p_hxge_t hxgep)
6746349Sqs148142 {
6756349Sqs148142 p_hxge_ldgv_t ldgvp;
6766349Sqs148142
6776349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_ldgv_uninit"));
6786349Sqs148142 ldgvp = hxgep->ldgvp;
6796349Sqs148142 if (ldgvp == NULL) {
6806349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
6816349Sqs148142 "<== hxge_ldgv_uninit: no logical group configured."));
6826349Sqs148142 return (HXGE_OK);
6836349Sqs148142 }
6846349Sqs148142
6856349Sqs148142 if (ldgvp->ldgp) {
6866349Sqs148142 KMEM_FREE(ldgvp->ldgp, sizeof (hxge_ldg_t) * ldgvp->maxldgs);
6876349Sqs148142 }
6886349Sqs148142 if (ldgvp->ldvp) {
6896349Sqs148142 KMEM_FREE(ldgvp->ldvp, sizeof (hxge_ldv_t) * ldgvp->maxldvs);
6906349Sqs148142 }
6916349Sqs148142
6926349Sqs148142 KMEM_FREE(ldgvp, sizeof (hxge_ldgv_t));
6936349Sqs148142 hxgep->ldgvp = NULL;
6946349Sqs148142
6956349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_ldgv_uninit"));
6966349Sqs148142 return (HXGE_OK);
6976349Sqs148142 }
6986349Sqs148142
6996349Sqs148142 hxge_status_t
hxge_intr_ldgv_init(p_hxge_t hxgep)7006349Sqs148142 hxge_intr_ldgv_init(p_hxge_t hxgep)
7016349Sqs148142 {
7026349Sqs148142 hxge_status_t status = HXGE_OK;
7036349Sqs148142
7046349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_ldgv_init"));
7056349Sqs148142 /*
7066349Sqs148142 * Configure the logical device group numbers, state vectors
7076349Sqs148142 * and interrupt masks for each logical device.
7086349Sqs148142 */
7096349Sqs148142 status = hxge_fzc_intr_init(hxgep);
7106349Sqs148142
7116349Sqs148142 /*
7126349Sqs148142 * Configure logical device masks and timers.
7136349Sqs148142 */
7146349Sqs148142 status = hxge_intr_mask_mgmt(hxgep);
7156349Sqs148142
7166349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_ldgv_init"));
7176349Sqs148142 return (status);
7186349Sqs148142 }
7196349Sqs148142
7206349Sqs148142 hxge_status_t
hxge_intr_mask_mgmt(p_hxge_t hxgep)7216349Sqs148142 hxge_intr_mask_mgmt(p_hxge_t hxgep)
7226349Sqs148142 {
7236349Sqs148142 p_hxge_ldgv_t ldgvp;
7246349Sqs148142 p_hxge_ldg_t ldgp;
7256349Sqs148142 p_hxge_ldv_t ldvp;
7266349Sqs148142 hpi_handle_t handle;
7276349Sqs148142 int i, j;
7286349Sqs148142 hpi_status_t rs = HPI_SUCCESS;
7296349Sqs148142
7306349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_mask_mgmt"));
7316349Sqs148142
7326349Sqs148142 if ((ldgvp = hxgep->ldgvp) == NULL) {
7336349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
7346349Sqs148142 "<== hxge_intr_mask_mgmt: Null ldgvp"));
7356349Sqs148142 return (HXGE_ERROR);
7366349Sqs148142 }
7376349Sqs148142 handle = HXGE_DEV_HPI_HANDLE(hxgep);
7386349Sqs148142 ldgp = ldgvp->ldgp;
7396349Sqs148142 ldvp = ldgvp->ldvp;
7406349Sqs148142 if (ldgp == NULL || ldvp == NULL) {
7416349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
7426349Sqs148142 "<== hxge_intr_mask_mgmt: Null ldgp or ldvp"));
7436349Sqs148142 return (HXGE_ERROR);
7446349Sqs148142 }
7456349Sqs148142
7466349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7476349Sqs148142 "==> hxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs));
7486349Sqs148142 /* Initialize masks. */
7496349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7506349Sqs148142 "==> hxge_intr_mask_mgmt(Hydra): # intrs %d ", ldgvp->ldg_intrs));
7516349Sqs148142 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) {
7526349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7536349Sqs148142 "==> hxge_intr_mask_mgmt(Hydra): # ldv %d in group %d",
7546349Sqs148142 ldgp->nldvs, ldgp->ldg));
7556349Sqs148142 for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
7566349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7576349Sqs148142 "==> hxge_intr_mask_mgmt: set ldv # %d "
7586349Sqs148142 "for ldg %d", ldvp->ldv, ldgp->ldg));
7596349Sqs148142 rs = hpi_intr_mask_set(handle, ldvp->ldv,
7606349Sqs148142 ldvp->ldv_ldf_masks);
7616349Sqs148142 if (rs != HPI_SUCCESS) {
7626349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
7636349Sqs148142 "<== hxge_intr_mask_mgmt: set mask failed "
7646349Sqs148142 " rs 0x%x ldv %d mask 0x%x",
7656349Sqs148142 rs, ldvp->ldv, ldvp->ldv_ldf_masks));
7666349Sqs148142 return (HXGE_ERROR | rs);
7676349Sqs148142 }
7686349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7696349Sqs148142 "==> hxge_intr_mask_mgmt: set mask OK "
7706349Sqs148142 " rs 0x%x ldv %d mask 0x%x",
7716349Sqs148142 rs, ldvp->ldv, ldvp->ldv_ldf_masks));
7726349Sqs148142 }
7736349Sqs148142 }
7746349Sqs148142
7756349Sqs148142 ldgp = ldgvp->ldgp;
7766349Sqs148142 /* Configure timer and arm bit */
7776349Sqs148142 for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) {
7786349Sqs148142 rs = hpi_intr_ldg_mgmt_set(handle, ldgp->ldg,
7796349Sqs148142 ldgp->arm, ldgp->ldg_timer);
7806349Sqs148142 if (rs != HPI_SUCCESS) {
7816349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
7826349Sqs148142 "<== hxge_intr_mask_mgmt: set timer failed "
7836349Sqs148142 " rs 0x%x dg %d timer 0x%x",
7846349Sqs148142 rs, ldgp->ldg, ldgp->ldg_timer));
7856349Sqs148142 return (HXGE_ERROR | rs);
7866349Sqs148142 }
7876349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
7886349Sqs148142 "==> hxge_intr_mask_mgmt: set timer OK "
7896349Sqs148142 " rs 0x%x ldg %d timer 0x%x",
7906349Sqs148142 rs, ldgp->ldg, ldgp->ldg_timer));
7916349Sqs148142 }
7926349Sqs148142
7936349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_mask_mgmt"));
7946349Sqs148142 return (HXGE_OK);
7956349Sqs148142 }
7966349Sqs148142
7976349Sqs148142 hxge_status_t
hxge_intr_mask_mgmt_set(p_hxge_t hxgep,boolean_t on)7986349Sqs148142 hxge_intr_mask_mgmt_set(p_hxge_t hxgep, boolean_t on)
7996349Sqs148142 {
8006349Sqs148142 p_hxge_ldgv_t ldgvp;
8016349Sqs148142 p_hxge_ldg_t ldgp;
8026349Sqs148142 p_hxge_ldv_t ldvp;
8036349Sqs148142 hpi_handle_t handle;
8046349Sqs148142 int i, j;
8056349Sqs148142 hpi_status_t rs = HPI_SUCCESS;
8066349Sqs148142
8076349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8086349Sqs148142 "==> hxge_intr_mask_mgmt_set (%d)", on));
8096349Sqs148142
8106349Sqs148142 if ((ldgvp = hxgep->ldgvp) == NULL) {
8116349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
8126349Sqs148142 "==> hxge_intr_mask_mgmt_set: Null ldgvp"));
8136349Sqs148142 return (HXGE_ERROR);
8146349Sqs148142 }
8156349Sqs148142 handle = HXGE_DEV_HPI_HANDLE(hxgep);
8166349Sqs148142 ldgp = ldgvp->ldgp;
8176349Sqs148142 ldvp = ldgvp->ldvp;
8186349Sqs148142 if (ldgp == NULL || ldvp == NULL) {
8196349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
8206349Sqs148142 "<== hxge_intr_mask_mgmt_set: Null ldgp or ldvp"));
8216349Sqs148142 return (HXGE_ERROR);
8226349Sqs148142 }
8236349Sqs148142
8246349Sqs148142 /* set masks. */
8256349Sqs148142 for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) {
8266349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8276349Sqs148142 "==> hxge_intr_mask_mgmt_set: flag %d ldg %d"
8286349Sqs148142 "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs));
8296349Sqs148142 for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
8306349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8316349Sqs148142 "==> hxge_intr_mask_mgmt_set: "
8326349Sqs148142 "for %d %d flag %d", i, j, on));
8336349Sqs148142 if (on) {
8346349Sqs148142 ldvp->ldv_ldf_masks = 0;
8356349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8366349Sqs148142 "==> hxge_intr_mask_mgmt_set: "
8376349Sqs148142 "ON mask off"));
8386349Sqs148142 } else {
8396349Sqs148142 ldvp->ldv_ldf_masks = (uint8_t)LD_IM_MASK;
8406349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8416349Sqs148142 "==> hxge_intr_mask_mgmt_set:mask on"));
8426349Sqs148142 }
8436349Sqs148142
8446349Sqs148142 rs = hpi_intr_mask_set(handle, ldvp->ldv,
8456349Sqs148142 ldvp->ldv_ldf_masks);
8466349Sqs148142 if (rs != HPI_SUCCESS) {
8476349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
8486349Sqs148142 "==> hxge_intr_mask_mgmt_set: "
8496349Sqs148142 "set mask failed rs 0x%x ldv %d mask 0x%x",
8506349Sqs148142 rs, ldvp->ldv, ldvp->ldv_ldf_masks));
8516349Sqs148142 return (HXGE_ERROR | rs);
8526349Sqs148142 }
8536349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8546349Sqs148142 "==> hxge_intr_mask_mgmt_set: flag %d"
8556349Sqs148142 "set mask OK ldv %d mask 0x%x",
8566349Sqs148142 on, ldvp->ldv, ldvp->ldv_ldf_masks));
8576349Sqs148142 }
8586349Sqs148142 }
8596349Sqs148142
8606349Sqs148142 ldgp = ldgvp->ldgp;
8616349Sqs148142 /* set the arm bit */
8626349Sqs148142 for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) {
8636349Sqs148142 if (on && !ldgp->arm) {
8646349Sqs148142 ldgp->arm = B_TRUE;
8656349Sqs148142 } else if (!on && ldgp->arm) {
8666349Sqs148142 ldgp->arm = B_FALSE;
8676349Sqs148142 }
8686349Sqs148142 rs = hpi_intr_ldg_mgmt_set(handle, ldgp->ldg,
8696349Sqs148142 ldgp->arm, ldgp->ldg_timer);
8706349Sqs148142 if (rs != HPI_SUCCESS) {
8716349Sqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
8726349Sqs148142 "<== hxge_intr_mask_mgmt_set: "
8736349Sqs148142 "set timer failed rs 0x%x ldg %d timer 0x%x",
8746349Sqs148142 rs, ldgp->ldg, ldgp->ldg_timer));
8756349Sqs148142 return (HXGE_ERROR | rs);
8766349Sqs148142 }
8776349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL,
8786349Sqs148142 "==> hxge_intr_mask_mgmt_set: OK (flag %d) "
8796349Sqs148142 "set timer ldg %d timer 0x%x",
8806349Sqs148142 on, ldgp->ldg, ldgp->ldg_timer));
8816349Sqs148142 }
8826349Sqs148142
8836349Sqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_mask_mgmt_set"));
8846349Sqs148142 return (HXGE_OK);
8856349Sqs148142 }
8866349Sqs148142
8876349Sqs148142 /*
8886349Sqs148142 * For Big Endian systems, the mac address will be from OBP. For Little
8896349Sqs148142 * Endian (x64) systems, it will be retrieved from the card since it cannot
8906349Sqs148142 * be programmed into PXE.
8916349Sqs148142 * This function also populates the MMAC parameters.
8926349Sqs148142 */
8936349Sqs148142 static hxge_status_t
hxge_get_mac_addr_properties(p_hxge_t hxgep)8946349Sqs148142 hxge_get_mac_addr_properties(p_hxge_t hxgep)
8956349Sqs148142 {
8966349Sqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_get_mac_addr_properties "));
8976349Sqs148142
8986349Sqs148142 (void) hxge_pfc_mac_addrs_get(hxgep);
8996349Sqs148142 hxgep->ouraddr = hxgep->factaddr;
9006349Sqs148142
9016349Sqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_get_mac_addr_properties "));
9026349Sqs148142 return (HXGE_OK);
9036349Sqs148142 }
9046349Sqs148142
9056349Sqs148142 static void
hxge_ldgv_setup(p_hxge_ldg_t * ldgp,p_hxge_ldv_t * ldvp,uint8_t ldv,uint8_t endldg,int * ngrps)9066349Sqs148142 hxge_ldgv_setup(p_hxge_ldg_t *ldgp, p_hxge_ldv_t *ldvp, uint8_t ldv,
9076349Sqs148142 uint8_t endldg, int *ngrps)
9086349Sqs148142 {
9096349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL, "==> hxge_ldgv_setup"));
9106349Sqs148142 /* Assign the group number for each device. */
9116349Sqs148142 (*ldvp)->ldg_assigned = (*ldgp)->ldg;
9126349Sqs148142 (*ldvp)->ldgp = *ldgp;
9136349Sqs148142 (*ldvp)->ldv = ldv;
9146349Sqs148142
9156349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL,
9166349Sqs148142 "==> hxge_ldgv_setup: ldv %d endldg %d ldg %d, ldvp $%p",
9176349Sqs148142 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp));
9186349Sqs148142
9196349Sqs148142 (*ldgp)->nldvs++;
9206349Sqs148142 if ((*ldgp)->ldg == (endldg - 1)) {
9216349Sqs148142 if ((*ldgp)->ldvp == NULL) {
9226349Sqs148142 (*ldgp)->ldvp = *ldvp;
9236349Sqs148142 *ngrps += 1;
9246349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL,
9256349Sqs148142 "==> hxge_ldgv_setup: ngrps %d", *ngrps));
9266349Sqs148142 }
9276349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL,
9286349Sqs148142 "==> hxge_ldgv_setup: ldvp $%p ngrps %d",
9296349Sqs148142 *ldvp, *ngrps));
9306349Sqs148142 ++*ldvp;
9316349Sqs148142 } else {
9326349Sqs148142 (*ldgp)->ldvp = *ldvp;
9336349Sqs148142 *ngrps += 1;
9346349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL, "==> hxge_ldgv_setup(done): "
9356349Sqs148142 "ldv %d endldg %d ldg %d, ldvp $%p",
9366349Sqs148142 ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp));
9376349Sqs148142 (*ldvp) = ++*ldvp;
9386349Sqs148142 (*ldgp) = ++*ldgp;
9396349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL,
9406349Sqs148142 "==> hxge_ldgv_setup: new ngrps %d", *ngrps));
9416349Sqs148142 }
9426349Sqs148142
9436349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL, "==> hxge_ldgv_setup: "
9446349Sqs148142 "ldg %d nldvs %d ldv %d ldvp $%p endldg %d ngrps %d",
9456349Sqs148142 (*ldgp)->ldg, (*ldgp)->nldvs, ldv, ldvp, endldg, *ngrps));
9466349Sqs148142
9476349Sqs148142 HXGE_DEBUG_MSG((NULL, INT_CTL, "<== hxge_ldgv_setup"));
9486349Sqs148142 }
949