15779Sxy150489 /*
25779Sxy150489 * CDDL HEADER START
35779Sxy150489 *
45779Sxy150489 * The contents of this file are subject to the terms of the
55779Sxy150489 * Common Development and Distribution License (the "License").
65779Sxy150489 * You may not use this file except in compliance with the License.
75779Sxy150489 *
88275SEric Cheng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98275SEric Cheng * or http://www.opensolaris.org/os/licensing.
105779Sxy150489 * See the License for the specific language governing permissions
115779Sxy150489 * and limitations under the License.
125779Sxy150489 *
138275SEric Cheng * When distributing Covered Code, include this CDDL HEADER in each
148275SEric Cheng * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155779Sxy150489 * If applicable, add the following below this CDDL HEADER, with the
165779Sxy150489 * fields enclosed by brackets "[]" replaced with your own identifying
175779Sxy150489 * information: Portions Copyright [yyyy] [name of copyright owner]
185779Sxy150489 *
195779Sxy150489 * CDDL HEADER END
205779Sxy150489 */
215779Sxy150489
225779Sxy150489 /*
23*12980SGuoqing.Zhu@Sun.COM * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
245779Sxy150489 */
255779Sxy150489
268275SEric Cheng /*
27*12980SGuoqing.Zhu@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
288275SEric Cheng */
295779Sxy150489
305779Sxy150489 #include "igb_sw.h"
315779Sxy150489
325779Sxy150489 int
igb_m_stat(void * arg,uint_t stat,uint64_t * val)335779Sxy150489 igb_m_stat(void *arg, uint_t stat, uint64_t *val)
345779Sxy150489 {
355779Sxy150489 igb_t *igb = (igb_t *)arg;
365779Sxy150489 struct e1000_hw *hw = &igb->hw;
375779Sxy150489 igb_stat_t *igb_ks;
385779Sxy150489 uint32_t low_val, high_val;
395779Sxy150489
405779Sxy150489 igb_ks = (igb_stat_t *)igb->igb_ks->ks_data;
415779Sxy150489
425779Sxy150489 mutex_enter(&igb->gen_lock);
435779Sxy150489
445779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
455779Sxy150489 mutex_exit(&igb->gen_lock);
465779Sxy150489 return (ECANCELED);
475779Sxy150489 }
485779Sxy150489
495779Sxy150489 switch (stat) {
505779Sxy150489 case MAC_STAT_IFSPEED:
515779Sxy150489 *val = igb->link_speed * 1000000ull;
525779Sxy150489 break;
535779Sxy150489
545779Sxy150489 case MAC_STAT_MULTIRCV:
555779Sxy150489 igb_ks->mprc.value.ui64 +=
565779Sxy150489 E1000_READ_REG(hw, E1000_MPRC);
575779Sxy150489 *val = igb_ks->mprc.value.ui64;
585779Sxy150489 break;
595779Sxy150489
605779Sxy150489 case MAC_STAT_BRDCSTRCV:
615779Sxy150489 igb_ks->bprc.value.ui64 +=
625779Sxy150489 E1000_READ_REG(hw, E1000_BPRC);
635779Sxy150489 *val = igb_ks->bprc.value.ui64;
645779Sxy150489 break;
655779Sxy150489
665779Sxy150489 case MAC_STAT_MULTIXMT:
675779Sxy150489 igb_ks->mptc.value.ui64 +=
685779Sxy150489 E1000_READ_REG(hw, E1000_MPTC);
695779Sxy150489 *val = igb_ks->mptc.value.ui64;
705779Sxy150489 break;
715779Sxy150489
725779Sxy150489 case MAC_STAT_BRDCSTXMT:
735779Sxy150489 igb_ks->bptc.value.ui64 +=
745779Sxy150489 E1000_READ_REG(hw, E1000_BPTC);
755779Sxy150489 *val = igb_ks->bptc.value.ui64;
765779Sxy150489 break;
775779Sxy150489
785779Sxy150489 case MAC_STAT_NORCVBUF:
795779Sxy150489 igb_ks->rnbc.value.ui64 +=
805779Sxy150489 E1000_READ_REG(hw, E1000_RNBC);
815779Sxy150489 *val = igb_ks->rnbc.value.ui64;
825779Sxy150489 break;
835779Sxy150489
845779Sxy150489 case MAC_STAT_IERRORS:
855779Sxy150489 igb_ks->rxerrc.value.ui64 +=
865779Sxy150489 E1000_READ_REG(hw, E1000_RXERRC);
875779Sxy150489 igb_ks->algnerrc.value.ui64 +=
885779Sxy150489 E1000_READ_REG(hw, E1000_ALGNERRC);
895779Sxy150489 igb_ks->rlec.value.ui64 +=
905779Sxy150489 E1000_READ_REG(hw, E1000_RLEC);
915779Sxy150489 igb_ks->crcerrs.value.ui64 +=
925779Sxy150489 E1000_READ_REG(hw, E1000_CRCERRS);
935779Sxy150489 igb_ks->cexterr.value.ui64 +=
945779Sxy150489 E1000_READ_REG(hw, E1000_CEXTERR);
955779Sxy150489 *val = igb_ks->rxerrc.value.ui64 +
965779Sxy150489 igb_ks->algnerrc.value.ui64 +
975779Sxy150489 igb_ks->rlec.value.ui64 +
985779Sxy150489 igb_ks->crcerrs.value.ui64 +
995779Sxy150489 igb_ks->cexterr.value.ui64;
1005779Sxy150489 break;
1015779Sxy150489
1025779Sxy150489 case MAC_STAT_NOXMTBUF:
1035779Sxy150489 *val = 0;
1045779Sxy150489 break;
1055779Sxy150489
1065779Sxy150489 case MAC_STAT_OERRORS:
1075779Sxy150489 igb_ks->ecol.value.ui64 +=
1085779Sxy150489 E1000_READ_REG(hw, E1000_ECOL);
1095779Sxy150489 *val = igb_ks->ecol.value.ui64;
1105779Sxy150489 break;
1115779Sxy150489
1125779Sxy150489 case MAC_STAT_COLLISIONS:
1135779Sxy150489 igb_ks->colc.value.ui64 +=
1145779Sxy150489 E1000_READ_REG(hw, E1000_COLC);
1155779Sxy150489 *val = igb_ks->colc.value.ui64;
1165779Sxy150489 break;
1175779Sxy150489
1185779Sxy150489 case MAC_STAT_RBYTES:
1195779Sxy150489 /*
1205779Sxy150489 * The 64-bit register will reset whenever the upper
1215779Sxy150489 * 32 bits are read. So we need to read the lower
1225779Sxy150489 * 32 bits first, then read the upper 32 bits.
1235779Sxy150489 */
1245779Sxy150489 low_val = E1000_READ_REG(hw, E1000_TORL);
1255779Sxy150489 high_val = E1000_READ_REG(hw, E1000_TORH);
1265779Sxy150489 igb_ks->tor.value.ui64 +=
1275779Sxy150489 (uint64_t)high_val << 32 | (uint64_t)low_val;
1285779Sxy150489 *val = igb_ks->tor.value.ui64;
1295779Sxy150489 break;
1305779Sxy150489
1315779Sxy150489 case MAC_STAT_IPACKETS:
1325779Sxy150489 igb_ks->tpr.value.ui64 +=
1335779Sxy150489 E1000_READ_REG(hw, E1000_TPR);
1345779Sxy150489 *val = igb_ks->tpr.value.ui64;
1355779Sxy150489 break;
1365779Sxy150489
1375779Sxy150489 case MAC_STAT_OBYTES:
1385779Sxy150489 /*
1395779Sxy150489 * The 64-bit register will reset whenever the upper
1405779Sxy150489 * 32 bits are read. So we need to read the lower
1415779Sxy150489 * 32 bits first, then read the upper 32 bits.
1425779Sxy150489 */
1435779Sxy150489 low_val = E1000_READ_REG(hw, E1000_TOTL);
1445779Sxy150489 high_val = E1000_READ_REG(hw, E1000_TOTH);
1455779Sxy150489 igb_ks->tot.value.ui64 +=
1465779Sxy150489 (uint64_t)high_val << 32 | (uint64_t)low_val;
1475779Sxy150489 *val = igb_ks->tot.value.ui64;
1485779Sxy150489 break;
1495779Sxy150489
1505779Sxy150489 case MAC_STAT_OPACKETS:
1515779Sxy150489 igb_ks->tpt.value.ui64 +=
1525779Sxy150489 E1000_READ_REG(hw, E1000_TPT);
1535779Sxy150489 *val = igb_ks->tpt.value.ui64;
1545779Sxy150489 break;
1555779Sxy150489
1565779Sxy150489 /* RFC 1643 stats */
1575779Sxy150489 case ETHER_STAT_ALIGN_ERRORS:
1585779Sxy150489 igb_ks->algnerrc.value.ui64 +=
1595779Sxy150489 E1000_READ_REG(hw, E1000_ALGNERRC);
1605779Sxy150489 *val = igb_ks->algnerrc.value.ui64;
1615779Sxy150489 break;
1625779Sxy150489
1635779Sxy150489 case ETHER_STAT_FCS_ERRORS:
1645779Sxy150489 igb_ks->crcerrs.value.ui64 +=
1655779Sxy150489 E1000_READ_REG(hw, E1000_CRCERRS);
1665779Sxy150489 *val = igb_ks->crcerrs.value.ui64;
1675779Sxy150489 break;
1685779Sxy150489
1695779Sxy150489 case ETHER_STAT_FIRST_COLLISIONS:
1705779Sxy150489 igb_ks->scc.value.ui64 +=
1715779Sxy150489 E1000_READ_REG(hw, E1000_SCC);
1725779Sxy150489 *val = igb_ks->scc.value.ui64;
1735779Sxy150489 break;
1745779Sxy150489
1755779Sxy150489 case ETHER_STAT_MULTI_COLLISIONS:
1765779Sxy150489 igb_ks->mcc.value.ui64 +=
1775779Sxy150489 E1000_READ_REG(hw, E1000_MCC);
1785779Sxy150489 *val = igb_ks->mcc.value.ui64;
1795779Sxy150489 break;
1805779Sxy150489
1815779Sxy150489 case ETHER_STAT_SQE_ERRORS:
1825779Sxy150489 igb_ks->sec.value.ui64 +=
1835779Sxy150489 E1000_READ_REG(hw, E1000_SEC);
1845779Sxy150489 *val = igb_ks->sec.value.ui64;
1855779Sxy150489 break;
1865779Sxy150489
1875779Sxy150489 case ETHER_STAT_DEFER_XMTS:
1885779Sxy150489 igb_ks->dc.value.ui64 +=
1895779Sxy150489 E1000_READ_REG(hw, E1000_DC);
1905779Sxy150489 *val = igb_ks->dc.value.ui64;
1915779Sxy150489 break;
1925779Sxy150489
1935779Sxy150489 case ETHER_STAT_TX_LATE_COLLISIONS:
1945779Sxy150489 igb_ks->latecol.value.ui64 +=
1955779Sxy150489 E1000_READ_REG(hw, E1000_LATECOL);
1965779Sxy150489 *val = igb_ks->latecol.value.ui64;
1975779Sxy150489 break;
1985779Sxy150489
1995779Sxy150489 case ETHER_STAT_EX_COLLISIONS:
2005779Sxy150489 igb_ks->ecol.value.ui64 +=
2015779Sxy150489 E1000_READ_REG(hw, E1000_ECOL);
2025779Sxy150489 *val = igb_ks->ecol.value.ui64;
2035779Sxy150489 break;
2045779Sxy150489
2055779Sxy150489 case ETHER_STAT_MACXMT_ERRORS:
2065779Sxy150489 igb_ks->ecol.value.ui64 +=
2075779Sxy150489 E1000_READ_REG(hw, E1000_ECOL);
2085779Sxy150489 *val = igb_ks->ecol.value.ui64;
2095779Sxy150489 break;
2105779Sxy150489
2115779Sxy150489 case ETHER_STAT_CARRIER_ERRORS:
2125779Sxy150489 igb_ks->cexterr.value.ui64 +=
2135779Sxy150489 E1000_READ_REG(hw, E1000_CEXTERR);
2145779Sxy150489 *val = igb_ks->cexterr.value.ui64;
2155779Sxy150489 break;
2165779Sxy150489
2175779Sxy150489 case ETHER_STAT_TOOLONG_ERRORS:
2185779Sxy150489 igb_ks->roc.value.ui64 +=
2195779Sxy150489 E1000_READ_REG(hw, E1000_ROC);
2205779Sxy150489 *val = igb_ks->roc.value.ui64;
2215779Sxy150489 break;
2225779Sxy150489
2235779Sxy150489 case ETHER_STAT_MACRCV_ERRORS:
2245779Sxy150489 igb_ks->rxerrc.value.ui64 +=
2255779Sxy150489 E1000_READ_REG(hw, E1000_RXERRC);
2265779Sxy150489 *val = igb_ks->rxerrc.value.ui64;
2275779Sxy150489 break;
2285779Sxy150489
2295779Sxy150489 /* MII/GMII stats */
2305779Sxy150489 case ETHER_STAT_XCVR_ADDR:
2315779Sxy150489 /* The Internal PHY's MDI address for each MAC is 1 */
2325779Sxy150489 *val = 1;
2335779Sxy150489 break;
2345779Sxy150489
2355779Sxy150489 case ETHER_STAT_XCVR_ID:
2365779Sxy150489 *val = hw->phy.id | hw->phy.revision;
2375779Sxy150489 break;
2385779Sxy150489
2395779Sxy150489 case ETHER_STAT_XCVR_INUSE:
2405779Sxy150489 switch (igb->link_speed) {
2415779Sxy150489 case SPEED_1000:
2425779Sxy150489 *val =
2435779Sxy150489 (hw->phy.media_type == e1000_media_type_copper) ?
2445779Sxy150489 XCVR_1000T : XCVR_1000X;
2455779Sxy150489 break;
2465779Sxy150489 case SPEED_100:
2475779Sxy150489 *val =
2485779Sxy150489 (hw->phy.media_type == e1000_media_type_copper) ?
2495779Sxy150489 (igb->param_100t4_cap == 1) ?
2505779Sxy150489 XCVR_100T4 : XCVR_100T2 : XCVR_100X;
2515779Sxy150489 break;
2525779Sxy150489 case SPEED_10:
2535779Sxy150489 *val = XCVR_10;
2545779Sxy150489 break;
2555779Sxy150489 default:
2565779Sxy150489 *val = XCVR_NONE;
2575779Sxy150489 break;
2585779Sxy150489 }
2595779Sxy150489 break;
2605779Sxy150489
2615779Sxy150489 case ETHER_STAT_CAP_1000FDX:
2625779Sxy150489 *val = igb->param_1000fdx_cap;
2635779Sxy150489 break;
2645779Sxy150489
2655779Sxy150489 case ETHER_STAT_CAP_1000HDX:
2665779Sxy150489 *val = igb->param_1000hdx_cap;
2675779Sxy150489 break;
2685779Sxy150489
2695779Sxy150489 case ETHER_STAT_CAP_100FDX:
2705779Sxy150489 *val = igb->param_100fdx_cap;
2715779Sxy150489 break;
2725779Sxy150489
2735779Sxy150489 case ETHER_STAT_CAP_100HDX:
2745779Sxy150489 *val = igb->param_100hdx_cap;
2755779Sxy150489 break;
2765779Sxy150489
2775779Sxy150489 case ETHER_STAT_CAP_10FDX:
2785779Sxy150489 *val = igb->param_10fdx_cap;
2795779Sxy150489 break;
2805779Sxy150489
2815779Sxy150489 case ETHER_STAT_CAP_10HDX:
2825779Sxy150489 *val = igb->param_10hdx_cap;
2835779Sxy150489 break;
2845779Sxy150489
2855779Sxy150489 case ETHER_STAT_CAP_ASMPAUSE:
2865779Sxy150489 *val = igb->param_asym_pause_cap;
2875779Sxy150489 break;
2885779Sxy150489
2895779Sxy150489 case ETHER_STAT_CAP_PAUSE:
2905779Sxy150489 *val = igb->param_pause_cap;
2915779Sxy150489 break;
2925779Sxy150489
2935779Sxy150489 case ETHER_STAT_CAP_AUTONEG:
2945779Sxy150489 *val = igb->param_autoneg_cap;
2955779Sxy150489 break;
2965779Sxy150489
2975779Sxy150489 case ETHER_STAT_ADV_CAP_1000FDX:
2985779Sxy150489 *val = igb->param_adv_1000fdx_cap;
2995779Sxy150489 break;
3005779Sxy150489
3015779Sxy150489 case ETHER_STAT_ADV_CAP_1000HDX:
3025779Sxy150489 *val = igb->param_adv_1000hdx_cap;
3035779Sxy150489 break;
3045779Sxy150489
3055779Sxy150489 case ETHER_STAT_ADV_CAP_100FDX:
3065779Sxy150489 *val = igb->param_adv_100fdx_cap;
3075779Sxy150489 break;
3085779Sxy150489
3095779Sxy150489 case ETHER_STAT_ADV_CAP_100HDX:
3105779Sxy150489 *val = igb->param_adv_100hdx_cap;
3115779Sxy150489 break;
3125779Sxy150489
3135779Sxy150489 case ETHER_STAT_ADV_CAP_10FDX:
3145779Sxy150489 *val = igb->param_adv_10fdx_cap;
3155779Sxy150489 break;
3165779Sxy150489
3175779Sxy150489 case ETHER_STAT_ADV_CAP_10HDX:
3185779Sxy150489 *val = igb->param_adv_10hdx_cap;
3195779Sxy150489 break;
3205779Sxy150489
3215779Sxy150489 case ETHER_STAT_ADV_CAP_ASMPAUSE:
3225779Sxy150489 *val = igb->param_adv_asym_pause_cap;
3235779Sxy150489 break;
3245779Sxy150489
3255779Sxy150489 case ETHER_STAT_ADV_CAP_PAUSE:
3265779Sxy150489 *val = igb->param_adv_pause_cap;
3275779Sxy150489 break;
3285779Sxy150489
3295779Sxy150489 case ETHER_STAT_ADV_CAP_AUTONEG:
3305779Sxy150489 *val = hw->mac.autoneg;
3315779Sxy150489 break;
3325779Sxy150489
3335779Sxy150489 case ETHER_STAT_LP_CAP_1000FDX:
3345779Sxy150489 *val = igb->param_lp_1000fdx_cap;
3355779Sxy150489 break;
3365779Sxy150489
3375779Sxy150489 case ETHER_STAT_LP_CAP_1000HDX:
3385779Sxy150489 *val = igb->param_lp_1000hdx_cap;
3395779Sxy150489 break;
3405779Sxy150489
3415779Sxy150489 case ETHER_STAT_LP_CAP_100FDX:
3425779Sxy150489 *val = igb->param_lp_100fdx_cap;
3435779Sxy150489 break;
3445779Sxy150489
3455779Sxy150489 case ETHER_STAT_LP_CAP_100HDX:
3465779Sxy150489 *val = igb->param_lp_100hdx_cap;
3475779Sxy150489 break;
3485779Sxy150489
3495779Sxy150489 case ETHER_STAT_LP_CAP_10FDX:
3505779Sxy150489 *val = igb->param_lp_10fdx_cap;
3515779Sxy150489 break;
3525779Sxy150489
3535779Sxy150489 case ETHER_STAT_LP_CAP_10HDX:
3545779Sxy150489 *val = igb->param_lp_10hdx_cap;
3555779Sxy150489 break;
3565779Sxy150489
3575779Sxy150489 case ETHER_STAT_LP_CAP_ASMPAUSE:
3585779Sxy150489 *val = igb->param_lp_asym_pause_cap;
3595779Sxy150489 break;
3605779Sxy150489
3615779Sxy150489 case ETHER_STAT_LP_CAP_PAUSE:
3625779Sxy150489 *val = igb->param_lp_pause_cap;
3635779Sxy150489 break;
3645779Sxy150489
3655779Sxy150489 case ETHER_STAT_LP_CAP_AUTONEG:
3665779Sxy150489 *val = igb->param_lp_autoneg_cap;
3675779Sxy150489 break;
3685779Sxy150489
3695779Sxy150489 case ETHER_STAT_LINK_ASMPAUSE:
3705779Sxy150489 *val = igb->param_asym_pause_cap;
3715779Sxy150489 break;
3725779Sxy150489
3735779Sxy150489 case ETHER_STAT_LINK_PAUSE:
3745779Sxy150489 *val = igb->param_pause_cap;
3755779Sxy150489 break;
3765779Sxy150489
3775779Sxy150489 case ETHER_STAT_LINK_AUTONEG:
3785779Sxy150489 *val = hw->mac.autoneg;
3795779Sxy150489 break;
3805779Sxy150489
3815779Sxy150489 case ETHER_STAT_LINK_DUPLEX:
3825779Sxy150489 *val = (igb->link_duplex == FULL_DUPLEX) ?
3835779Sxy150489 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
3845779Sxy150489 break;
3855779Sxy150489
3865779Sxy150489 case ETHER_STAT_TOOSHORT_ERRORS:
3875779Sxy150489 igb_ks->ruc.value.ui64 +=
3885779Sxy150489 E1000_READ_REG(hw, E1000_RUC);
3895779Sxy150489 *val = igb_ks->ruc.value.ui64;
3905779Sxy150489 break;
3915779Sxy150489
3925779Sxy150489 case ETHER_STAT_CAP_REMFAULT:
3935779Sxy150489 *val = igb->param_rem_fault;
3945779Sxy150489 break;
3955779Sxy150489
3965779Sxy150489 case ETHER_STAT_ADV_REMFAULT:
3975779Sxy150489 *val = igb->param_adv_rem_fault;
3985779Sxy150489 break;
3995779Sxy150489
4005779Sxy150489 case ETHER_STAT_LP_REMFAULT:
4015779Sxy150489 *val = igb->param_lp_rem_fault;
4025779Sxy150489 break;
4035779Sxy150489
4045779Sxy150489 case ETHER_STAT_JABBER_ERRORS:
4055779Sxy150489 igb_ks->rjc.value.ui64 +=
4065779Sxy150489 E1000_READ_REG(hw, E1000_RJC);
4075779Sxy150489 *val = igb_ks->rjc.value.ui64;
4085779Sxy150489 break;
4095779Sxy150489
4105779Sxy150489 case ETHER_STAT_CAP_100T4:
4115779Sxy150489 *val = igb->param_100t4_cap;
4125779Sxy150489 break;
4135779Sxy150489
4145779Sxy150489 case ETHER_STAT_ADV_CAP_100T4:
4155779Sxy150489 *val = igb->param_adv_100t4_cap;
4165779Sxy150489 break;
4175779Sxy150489
4185779Sxy150489 case ETHER_STAT_LP_CAP_100T4:
4195779Sxy150489 *val = igb->param_lp_100t4_cap;
4205779Sxy150489 break;
4215779Sxy150489
4225779Sxy150489 default:
4235779Sxy150489 mutex_exit(&igb->gen_lock);
4245779Sxy150489 return (ENOTSUP);
4255779Sxy150489 }
4265779Sxy150489
4275779Sxy150489 mutex_exit(&igb->gen_lock);
4285779Sxy150489
42911367SJason.Xu@Sun.COM if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
43011367SJason.Xu@Sun.COM ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
43111367SJason.Xu@Sun.COM return (EIO);
43211367SJason.Xu@Sun.COM }
4336624Sgl147354
4345779Sxy150489 return (0);
4355779Sxy150489 }
4365779Sxy150489
4375779Sxy150489 /*
4385779Sxy150489 * Bring the device out of the reset/quiesced state that it
4395779Sxy150489 * was in when the interface was registered.
4405779Sxy150489 */
4415779Sxy150489 int
igb_m_start(void * arg)4425779Sxy150489 igb_m_start(void *arg)
4435779Sxy150489 {
4445779Sxy150489 igb_t *igb = (igb_t *)arg;
4455779Sxy150489
4465779Sxy150489 mutex_enter(&igb->gen_lock);
4475779Sxy150489
4485779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
4495779Sxy150489 mutex_exit(&igb->gen_lock);
4505779Sxy150489 return (ECANCELED);
4515779Sxy150489 }
4525779Sxy150489
45311502SChenlu.Chen@Sun.COM if (igb_start(igb, B_TRUE) != IGB_SUCCESS) {
4545779Sxy150489 mutex_exit(&igb->gen_lock);
4555779Sxy150489 return (EIO);
4565779Sxy150489 }
4575779Sxy150489
45811367SJason.Xu@Sun.COM atomic_or_32(&igb->igb_state, IGB_STARTED);
4595779Sxy150489
4605779Sxy150489 mutex_exit(&igb->gen_lock);
4615779Sxy150489
4625779Sxy150489 /*
4635779Sxy150489 * Enable and start the watchdog timer
4645779Sxy150489 */
4655779Sxy150489 igb_enable_watchdog_timer(igb);
4665779Sxy150489
4675779Sxy150489 return (0);
4685779Sxy150489 }
4695779Sxy150489
4705779Sxy150489 /*
4715779Sxy150489 * Stop the device and put it in a reset/quiesced state such
4725779Sxy150489 * that the interface can be unregistered.
4735779Sxy150489 */
4745779Sxy150489 void
igb_m_stop(void * arg)4755779Sxy150489 igb_m_stop(void *arg)
4765779Sxy150489 {
4775779Sxy150489 igb_t *igb = (igb_t *)arg;
4785779Sxy150489
4795779Sxy150489 mutex_enter(&igb->gen_lock);
4805779Sxy150489
4815779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
4825779Sxy150489 mutex_exit(&igb->gen_lock);
4835779Sxy150489 return;
4845779Sxy150489 }
4855779Sxy150489
48611367SJason.Xu@Sun.COM atomic_and_32(&igb->igb_state, ~IGB_STARTED);
4875779Sxy150489
48811502SChenlu.Chen@Sun.COM igb_stop(igb, B_TRUE);
4895779Sxy150489
4905779Sxy150489 mutex_exit(&igb->gen_lock);
4915779Sxy150489
4925779Sxy150489 /*
4935779Sxy150489 * Disable and stop the watchdog timer
4945779Sxy150489 */
4955779Sxy150489 igb_disable_watchdog_timer(igb);
4965779Sxy150489 }
4975779Sxy150489
4985779Sxy150489 /*
4995779Sxy150489 * Set the promiscuity of the device.
5005779Sxy150489 */
5015779Sxy150489 int
igb_m_promisc(void * arg,boolean_t on)5025779Sxy150489 igb_m_promisc(void *arg, boolean_t on)
5035779Sxy150489 {
5045779Sxy150489 igb_t *igb = (igb_t *)arg;
5055779Sxy150489 uint32_t reg_val;
5065779Sxy150489
5075779Sxy150489 mutex_enter(&igb->gen_lock);
5085779Sxy150489
5095779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
5105779Sxy150489 mutex_exit(&igb->gen_lock);
5115779Sxy150489 return (ECANCELED);
5125779Sxy150489 }
5135779Sxy150489
5145779Sxy150489 reg_val = E1000_READ_REG(&igb->hw, E1000_RCTL);
5155779Sxy150489
5165779Sxy150489 if (on)
5175779Sxy150489 reg_val |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
5185779Sxy150489 else
5195779Sxy150489 reg_val &= (~(E1000_RCTL_UPE | E1000_RCTL_MPE));
5205779Sxy150489
5215779Sxy150489 E1000_WRITE_REG(&igb->hw, E1000_RCTL, reg_val);
5225779Sxy150489
5235779Sxy150489 mutex_exit(&igb->gen_lock);
5245779Sxy150489
5256624Sgl147354 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
5266624Sgl147354 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
5276624Sgl147354 return (EIO);
5286624Sgl147354 }
5296624Sgl147354
5305779Sxy150489 return (0);
5315779Sxy150489 }
5325779Sxy150489
5335779Sxy150489 /*
5345779Sxy150489 * Add/remove the addresses to/from the set of multicast
5355779Sxy150489 * addresses for which the device will receive packets.
5365779Sxy150489 */
5375779Sxy150489 int
igb_m_multicst(void * arg,boolean_t add,const uint8_t * mcst_addr)5385779Sxy150489 igb_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
5395779Sxy150489 {
5405779Sxy150489 igb_t *igb = (igb_t *)arg;
5415779Sxy150489 int result;
5425779Sxy150489
5435779Sxy150489 mutex_enter(&igb->gen_lock);
5445779Sxy150489
5455779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
5465779Sxy150489 mutex_exit(&igb->gen_lock);
5475779Sxy150489 return (ECANCELED);
5485779Sxy150489 }
5495779Sxy150489
5505779Sxy150489 result = (add) ? igb_multicst_add(igb, mcst_addr)
5515779Sxy150489 : igb_multicst_remove(igb, mcst_addr);
5525779Sxy150489
5535779Sxy150489 mutex_exit(&igb->gen_lock);
5545779Sxy150489
5555779Sxy150489 return (result);
5565779Sxy150489 }
5575779Sxy150489
5585779Sxy150489 /*
5595779Sxy150489 * Pass on M_IOCTL messages passed to the DLD, and support
5605779Sxy150489 * private IOCTLs for debugging and ndd.
5615779Sxy150489 */
5625779Sxy150489 void
igb_m_ioctl(void * arg,queue_t * q,mblk_t * mp)5635779Sxy150489 igb_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
5645779Sxy150489 {
5655779Sxy150489 igb_t *igb = (igb_t *)arg;
5665779Sxy150489 struct iocblk *iocp;
5675779Sxy150489 enum ioc_reply status;
5685779Sxy150489
5695779Sxy150489 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
5705779Sxy150489 iocp->ioc_error = 0;
5715779Sxy150489
57211502SChenlu.Chen@Sun.COM mutex_enter(&igb->gen_lock);
57311502SChenlu.Chen@Sun.COM if (igb->igb_state & IGB_SUSPENDED) {
57411502SChenlu.Chen@Sun.COM mutex_exit(&igb->gen_lock);
57511502SChenlu.Chen@Sun.COM miocnak(q, mp, 0, EINVAL);
57611502SChenlu.Chen@Sun.COM return;
57711502SChenlu.Chen@Sun.COM }
57811502SChenlu.Chen@Sun.COM mutex_exit(&igb->gen_lock);
57911502SChenlu.Chen@Sun.COM
5805779Sxy150489 switch (iocp->ioc_cmd) {
5815779Sxy150489 case LB_GET_INFO_SIZE:
5825779Sxy150489 case LB_GET_INFO:
5835779Sxy150489 case LB_GET_MODE:
5845779Sxy150489 case LB_SET_MODE:
5855779Sxy150489 status = igb_loopback_ioctl(igb, iocp, mp);
5865779Sxy150489 break;
5875779Sxy150489
5885779Sxy150489 default:
5895779Sxy150489 status = IOC_INVAL;
5905779Sxy150489 break;
5915779Sxy150489 }
5925779Sxy150489
5935779Sxy150489 /*
5945779Sxy150489 * Decide how to reply
5955779Sxy150489 */
5965779Sxy150489 switch (status) {
5975779Sxy150489 default:
5985779Sxy150489 case IOC_INVAL:
5995779Sxy150489 /*
6005779Sxy150489 * Error, reply with a NAK and EINVAL or the specified error
6015779Sxy150489 */
6025779Sxy150489 miocnak(q, mp, 0, iocp->ioc_error == 0 ?
6035779Sxy150489 EINVAL : iocp->ioc_error);
6045779Sxy150489 break;
6055779Sxy150489
6065779Sxy150489 case IOC_DONE:
6075779Sxy150489 /*
6085779Sxy150489 * OK, reply already sent
6095779Sxy150489 */
6105779Sxy150489 break;
6115779Sxy150489
6125779Sxy150489 case IOC_ACK:
6135779Sxy150489 /*
6145779Sxy150489 * OK, reply with an ACK
6155779Sxy150489 */
6165779Sxy150489 miocack(q, mp, 0, 0);
6175779Sxy150489 break;
6185779Sxy150489
6195779Sxy150489 case IOC_REPLY:
6205779Sxy150489 /*
6215779Sxy150489 * OK, send prepared reply as ACK or NAK
6225779Sxy150489 */
6235779Sxy150489 mp->b_datap->db_type = iocp->ioc_error == 0 ?
6245779Sxy150489 M_IOCACK : M_IOCNAK;
6255779Sxy150489 qreply(q, mp);
6265779Sxy150489 break;
6275779Sxy150489 }
6285779Sxy150489 }
6295779Sxy150489
6305779Sxy150489 /*
6318275SEric Cheng * Add a MAC address to the target RX group.
6325779Sxy150489 */
6338275SEric Cheng static int
igb_addmac(void * arg,const uint8_t * mac_addr)6348275SEric Cheng igb_addmac(void *arg, const uint8_t *mac_addr)
6355779Sxy150489 {
6368275SEric Cheng igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
6378275SEric Cheng igb_t *igb = rx_group->igb;
6388275SEric Cheng struct e1000_hw *hw = &igb->hw;
6398275SEric Cheng int i, slot;
6405779Sxy150489
6415779Sxy150489 mutex_enter(&igb->gen_lock);
6425779Sxy150489
6435779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
6445779Sxy150489 mutex_exit(&igb->gen_lock);
6455779Sxy150489 return (ECANCELED);
6465779Sxy150489 }
6475779Sxy150489
6485779Sxy150489 if (igb->unicst_avail == 0) {
6495779Sxy150489 /* no slots available */
6505779Sxy150489 mutex_exit(&igb->gen_lock);
6515779Sxy150489 return (ENOSPC);
6525779Sxy150489 }
6535779Sxy150489
6545779Sxy150489 /*
6558275SEric Cheng * The slots from 0 to igb->num_rx_groups are reserved slots which
6568275SEric Cheng * are 1 to 1 mapped with group index directly. The other slots are
6578275SEric Cheng * shared between the all of groups. While adding a MAC address,
6588275SEric Cheng * it will try to set the reserved slots first, then the shared slots.
6595779Sxy150489 */
6608275SEric Cheng slot = -1;
6618275SEric Cheng if (igb->unicst_addr[rx_group->index].mac.set == 1) {
6628275SEric Cheng /*
6638275SEric Cheng * The reserved slot for current group is used, find the free
6648275SEric Cheng * slots in the shared slots.
6658275SEric Cheng */
6668275SEric Cheng for (i = igb->num_rx_groups; i < igb->unicst_total; i++) {
6678275SEric Cheng if (igb->unicst_addr[i].mac.set == 0) {
6688275SEric Cheng slot = i;
6698275SEric Cheng break;
6708275SEric Cheng }
6718275SEric Cheng }
6728275SEric Cheng } else
6738275SEric Cheng slot = rx_group->index;
6748275SEric Cheng
6758275SEric Cheng if (slot == -1) {
6768275SEric Cheng /* no slots available in the shared slots */
6778275SEric Cheng mutex_exit(&igb->gen_lock);
6788275SEric Cheng return (ENOSPC);
6795779Sxy150489 }
6805779Sxy150489
6818275SEric Cheng /* Set VMDq according to the mode supported by hardware. */
6828275SEric Cheng e1000_rar_set_vmdq(hw, mac_addr, slot, igb->vmdq_mode, rx_group->index);
6835779Sxy150489
6848275SEric Cheng bcopy(mac_addr, igb->unicst_addr[slot].mac.addr, ETHERADDRL);
6858275SEric Cheng igb->unicst_addr[slot].mac.group_index = rx_group->index;
6868275SEric Cheng igb->unicst_addr[slot].mac.set = 1;
6878275SEric Cheng igb->unicst_avail--;
6885779Sxy150489
6897072Sxy150489 mutex_exit(&igb->gen_lock);
6907072Sxy150489
6918275SEric Cheng return (0);
6925779Sxy150489 }
6935779Sxy150489
6945779Sxy150489 /*
6958275SEric Cheng * Remove a MAC address from the specified RX group.
6965779Sxy150489 */
6978275SEric Cheng static int
igb_remmac(void * arg,const uint8_t * mac_addr)6988275SEric Cheng igb_remmac(void *arg, const uint8_t *mac_addr)
6995779Sxy150489 {
7008275SEric Cheng igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
7018275SEric Cheng igb_t *igb = rx_group->igb;
7028275SEric Cheng struct e1000_hw *hw = &igb->hw;
7038275SEric Cheng int slot;
7045779Sxy150489
7055779Sxy150489 mutex_enter(&igb->gen_lock);
7065779Sxy150489
7075779Sxy150489 if (igb->igb_state & IGB_SUSPENDED) {
7085779Sxy150489 mutex_exit(&igb->gen_lock);
7095779Sxy150489 return (ECANCELED);
7105779Sxy150489 }
7115779Sxy150489
7128275SEric Cheng slot = igb_unicst_find(igb, mac_addr);
7138275SEric Cheng if (slot == -1) {
7145779Sxy150489 mutex_exit(&igb->gen_lock);
7155779Sxy150489 return (EINVAL);
7165779Sxy150489 }
7175779Sxy150489
7187072Sxy150489 if (igb->unicst_addr[slot].mac.set == 0) {
7197072Sxy150489 mutex_exit(&igb->gen_lock);
7207072Sxy150489 return (EINVAL);
7217072Sxy150489 }
7227072Sxy150489
7238275SEric Cheng /* Clear the MAC ddress in the slot */
7248275SEric Cheng e1000_rar_clear(hw, slot);
7258275SEric Cheng igb->unicst_addr[slot].mac.set = 0;
7268275SEric Cheng igb->unicst_avail++;
7275779Sxy150489
7285779Sxy150489 mutex_exit(&igb->gen_lock);
7295779Sxy150489
7308275SEric Cheng return (0);
7318275SEric Cheng }
7328275SEric Cheng
7338275SEric Cheng /*
7348275SEric Cheng * Enable interrupt on the specificed rx ring.
7358275SEric Cheng */
7368275SEric Cheng int
igb_rx_ring_intr_enable(mac_intr_handle_t intrh)7378275SEric Cheng igb_rx_ring_intr_enable(mac_intr_handle_t intrh)
7388275SEric Cheng {
7398275SEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
7408275SEric Cheng igb_t *igb = rx_ring->igb;
7418275SEric Cheng struct e1000_hw *hw = &igb->hw;
7428275SEric Cheng uint32_t index = rx_ring->index;
7438275SEric Cheng
7448275SEric Cheng if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
7458275SEric Cheng /* Interrupt enabling for MSI-X */
7468275SEric Cheng igb->eims_mask |= (E1000_EICR_RX_QUEUE0 << index);
7478275SEric Cheng E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask);
7488275SEric Cheng E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
7498275SEric Cheng } else {
7508275SEric Cheng ASSERT(index == 0);
7518275SEric Cheng /* Interrupt enabling for MSI and legacy */
7528275SEric Cheng igb->ims_mask |= E1000_IMS_RXT0;
7538275SEric Cheng E1000_WRITE_REG(hw, E1000_IMS, igb->ims_mask);
7548275SEric Cheng }
7558275SEric Cheng
7568275SEric Cheng E1000_WRITE_FLUSH(hw);
7578275SEric Cheng
7588275SEric Cheng return (0);
7598275SEric Cheng }
7608275SEric Cheng
7618275SEric Cheng /*
7628275SEric Cheng * Disable interrupt on the specificed rx ring.
7638275SEric Cheng */
7648275SEric Cheng int
igb_rx_ring_intr_disable(mac_intr_handle_t intrh)7658275SEric Cheng igb_rx_ring_intr_disable(mac_intr_handle_t intrh)
7668275SEric Cheng {
7678275SEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
7688275SEric Cheng igb_t *igb = rx_ring->igb;
7698275SEric Cheng struct e1000_hw *hw = &igb->hw;
7708275SEric Cheng uint32_t index = rx_ring->index;
7718275SEric Cheng
7728275SEric Cheng if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
7738275SEric Cheng /* Interrupt disabling for MSI-X */
7748275SEric Cheng igb->eims_mask &= ~(E1000_EICR_RX_QUEUE0 << index);
7758275SEric Cheng E1000_WRITE_REG(hw, E1000_EIMC,
7768275SEric Cheng (E1000_EICR_RX_QUEUE0 << index));
7778275SEric Cheng E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
7788275SEric Cheng } else {
7798275SEric Cheng ASSERT(index == 0);
7808275SEric Cheng /* Interrupt disabling for MSI and legacy */
7818275SEric Cheng igb->ims_mask &= ~E1000_IMS_RXT0;
7828275SEric Cheng E1000_WRITE_REG(hw, E1000_IMC, E1000_IMS_RXT0);
7838275SEric Cheng }
7848275SEric Cheng
7858275SEric Cheng E1000_WRITE_FLUSH(hw);
7868275SEric Cheng
7878275SEric Cheng return (0);
7885779Sxy150489 }
7895779Sxy150489
7905779Sxy150489 /*
7918275SEric Cheng * Get the global ring index by a ring index within a group.
7925779Sxy150489 */
7935779Sxy150489 int
igb_get_rx_ring_index(igb_t * igb,int gindex,int rindex)7948275SEric Cheng igb_get_rx_ring_index(igb_t *igb, int gindex, int rindex)
7955779Sxy150489 {
7968275SEric Cheng igb_rx_ring_t *rx_ring;
7978275SEric Cheng int i;
7985779Sxy150489
7998275SEric Cheng for (i = 0; i < igb->num_rx_rings; i++) {
8008275SEric Cheng rx_ring = &igb->rx_rings[i];
8018275SEric Cheng if (rx_ring->group_index == gindex)
8028275SEric Cheng rindex--;
8038275SEric Cheng if (rindex < 0)
8048275SEric Cheng return (i);
8055779Sxy150489 }
8065779Sxy150489
8078275SEric Cheng return (-1);
8088275SEric Cheng }
8095779Sxy150489
8108275SEric Cheng static int
igb_ring_start(mac_ring_driver_t rh,uint64_t mr_gen_num)8118275SEric Cheng igb_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num)
8128275SEric Cheng {
8138275SEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)rh;
8145779Sxy150489
8158275SEric Cheng mutex_enter(&rx_ring->rx_lock);
8168275SEric Cheng rx_ring->ring_gen_num = mr_gen_num;
8178275SEric Cheng mutex_exit(&rx_ring->rx_lock);
8188275SEric Cheng return (0);
8195779Sxy150489 }
8205779Sxy150489
8215779Sxy150489 /*
8228275SEric Cheng * Callback funtion for MAC layer to register all rings.
8235779Sxy150489 */
8248275SEric Cheng /* ARGSUSED */
8258275SEric Cheng void
igb_fill_ring(void * arg,mac_ring_type_t rtype,const int rg_index,const int index,mac_ring_info_t * infop,mac_ring_handle_t rh)8268275SEric Cheng igb_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index,
8278275SEric Cheng const int index, mac_ring_info_t *infop, mac_ring_handle_t rh)
8285779Sxy150489 {
8295779Sxy150489 igb_t *igb = (igb_t *)arg;
8308275SEric Cheng mac_intr_t *mintr = &infop->mri_intr;
8318275SEric Cheng
8328275SEric Cheng switch (rtype) {
8338275SEric Cheng case MAC_RING_TYPE_RX: {
8348275SEric Cheng igb_rx_ring_t *rx_ring;
8358275SEric Cheng int global_index;
8365779Sxy150489
8378275SEric Cheng /*
8388275SEric Cheng * 'index' is the ring index within the group.
8398275SEric Cheng * We need the global ring index by searching in group.
8408275SEric Cheng */
8418275SEric Cheng global_index = igb_get_rx_ring_index(igb, rg_index, index);
8428275SEric Cheng
8438275SEric Cheng ASSERT(global_index >= 0);
8445779Sxy150489
8458275SEric Cheng rx_ring = &igb->rx_rings[global_index];
8468275SEric Cheng rx_ring->ring_handle = rh;
8478275SEric Cheng
8488275SEric Cheng infop->mri_driver = (mac_ring_driver_t)rx_ring;
8498275SEric Cheng infop->mri_start = igb_ring_start;
8508275SEric Cheng infop->mri_stop = NULL;
8518275SEric Cheng infop->mri_poll = (mac_ring_poll_t)igb_rx_ring_poll;
85211878SVenu.Iyer@Sun.COM infop->mri_stat = igb_rx_ring_stat;
8538275SEric Cheng
8548275SEric Cheng mintr->mi_handle = (mac_intr_handle_t)rx_ring;
8558275SEric Cheng mintr->mi_enable = igb_rx_ring_intr_enable;
8568275SEric Cheng mintr->mi_disable = igb_rx_ring_intr_disable;
85711878SVenu.Iyer@Sun.COM if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
85811878SVenu.Iyer@Sun.COM mintr->mi_ddi_handle =
85911878SVenu.Iyer@Sun.COM igb->htable[rx_ring->intr_vector];
86011878SVenu.Iyer@Sun.COM }
8618275SEric Cheng break;
8625779Sxy150489 }
8638275SEric Cheng case MAC_RING_TYPE_TX: {
8648275SEric Cheng ASSERT(index < igb->num_tx_rings);
8655779Sxy150489
8668275SEric Cheng igb_tx_ring_t *tx_ring = &igb->tx_rings[index];
8678275SEric Cheng tx_ring->ring_handle = rh;
8685779Sxy150489
8698275SEric Cheng infop->mri_driver = (mac_ring_driver_t)tx_ring;
8708275SEric Cheng infop->mri_start = NULL;
8718275SEric Cheng infop->mri_stop = NULL;
8728275SEric Cheng infop->mri_tx = igb_tx_ring_send;
87311878SVenu.Iyer@Sun.COM infop->mri_stat = igb_tx_ring_stat;
87411878SVenu.Iyer@Sun.COM if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
87511878SVenu.Iyer@Sun.COM mintr->mi_ddi_handle =
87611878SVenu.Iyer@Sun.COM igb->htable[tx_ring->intr_vector];
87711878SVenu.Iyer@Sun.COM }
8788275SEric Cheng break;
8795779Sxy150489 }
8808275SEric Cheng default:
8818275SEric Cheng break;
8828275SEric Cheng }
8838275SEric Cheng }
8848275SEric Cheng
8858275SEric Cheng void
igb_fill_group(void * arg,mac_ring_type_t rtype,const int index,mac_group_info_t * infop,mac_group_handle_t gh)8868275SEric Cheng igb_fill_group(void *arg, mac_ring_type_t rtype, const int index,
8878275SEric Cheng mac_group_info_t *infop, mac_group_handle_t gh)
8888275SEric Cheng {
8898275SEric Cheng igb_t *igb = (igb_t *)arg;
8905779Sxy150489
8918275SEric Cheng switch (rtype) {
8928275SEric Cheng case MAC_RING_TYPE_RX: {
8938275SEric Cheng igb_rx_group_t *rx_group;
8948275SEric Cheng
8958275SEric Cheng ASSERT((index >= 0) && (index < igb->num_rx_groups));
8968275SEric Cheng
8978275SEric Cheng rx_group = &igb->rx_groups[index];
8988275SEric Cheng rx_group->group_handle = gh;
8998275SEric Cheng
9008275SEric Cheng infop->mgi_driver = (mac_group_driver_t)rx_group;
9018275SEric Cheng infop->mgi_start = NULL;
9028275SEric Cheng infop->mgi_stop = NULL;
9038275SEric Cheng infop->mgi_addmac = igb_addmac;
9048275SEric Cheng infop->mgi_remmac = igb_remmac;
9058275SEric Cheng infop->mgi_count = (igb->num_rx_rings / igb->num_rx_groups);
9068275SEric Cheng
9078275SEric Cheng break;
9085779Sxy150489 }
9098275SEric Cheng case MAC_RING_TYPE_TX:
9108275SEric Cheng break;
9118275SEric Cheng default:
9128275SEric Cheng break;
9138275SEric Cheng }
9145779Sxy150489 }
9155779Sxy150489
9165779Sxy150489 /*
9175779Sxy150489 * Obtain the MAC's capabilities and associated data from
9185779Sxy150489 * the driver.
9195779Sxy150489 */
9205779Sxy150489 boolean_t
igb_m_getcapab(void * arg,mac_capab_t cap,void * cap_data)9215779Sxy150489 igb_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
9225779Sxy150489 {
9235779Sxy150489 igb_t *igb = (igb_t *)arg;
9245779Sxy150489
9255779Sxy150489 switch (cap) {
9265779Sxy150489 case MAC_CAPAB_HCKSUM: {
9275779Sxy150489 uint32_t *tx_hcksum_flags = cap_data;
9285779Sxy150489
9295779Sxy150489 /*
9305779Sxy150489 * We advertise our capabilities only if tx hcksum offload is
9315779Sxy150489 * enabled. On receive, the stack will accept checksummed
9325779Sxy150489 * packets anyway, even if we haven't said we can deliver
9335779Sxy150489 * them.
9345779Sxy150489 */
9355779Sxy150489 if (!igb->tx_hcksum_enable)
9365779Sxy150489 return (B_FALSE);
9375779Sxy150489
9385779Sxy150489 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
9395779Sxy150489 break;
9405779Sxy150489 }
9419188SPaul.Guo@Sun.COM case MAC_CAPAB_LSO: {
9429188SPaul.Guo@Sun.COM mac_capab_lso_t *cap_lso = cap_data;
9439188SPaul.Guo@Sun.COM
9449188SPaul.Guo@Sun.COM if (igb->lso_enable) {
9459188SPaul.Guo@Sun.COM cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
9469188SPaul.Guo@Sun.COM cap_lso->lso_basic_tcp_ipv4.lso_max = IGB_LSO_MAXLEN;
9479188SPaul.Guo@Sun.COM break;
9489188SPaul.Guo@Sun.COM } else {
9499188SPaul.Guo@Sun.COM return (B_FALSE);
9509188SPaul.Guo@Sun.COM }
9519188SPaul.Guo@Sun.COM }
9528275SEric Cheng case MAC_CAPAB_RINGS: {
9538275SEric Cheng mac_capab_rings_t *cap_rings = cap_data;
9548275SEric Cheng
9558275SEric Cheng switch (cap_rings->mr_type) {
9568275SEric Cheng case MAC_RING_TYPE_RX:
9578275SEric Cheng cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
9588275SEric Cheng cap_rings->mr_rnum = igb->num_rx_rings;
9598275SEric Cheng cap_rings->mr_gnum = igb->num_rx_groups;
9608275SEric Cheng cap_rings->mr_rget = igb_fill_ring;
9618275SEric Cheng cap_rings->mr_gget = igb_fill_group;
9628275SEric Cheng cap_rings->mr_gaddring = NULL;
9638275SEric Cheng cap_rings->mr_gremring = NULL;
9645779Sxy150489
9658275SEric Cheng break;
9668275SEric Cheng case MAC_RING_TYPE_TX:
9678275SEric Cheng cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
9688275SEric Cheng cap_rings->mr_rnum = igb->num_tx_rings;
9698275SEric Cheng cap_rings->mr_gnum = 0;
9708275SEric Cheng cap_rings->mr_rget = igb_fill_ring;
9718275SEric Cheng cap_rings->mr_gget = NULL;
9728275SEric Cheng
9738275SEric Cheng break;
9748275SEric Cheng default:
9758275SEric Cheng break;
9768275SEric Cheng }
9775779Sxy150489 break;
9785779Sxy150489 }
9798275SEric Cheng
9805779Sxy150489 default:
9815779Sxy150489 return (B_FALSE);
9825779Sxy150489 }
9835779Sxy150489 return (B_TRUE);
9845779Sxy150489 }
98511502SChenlu.Chen@Sun.COM
98611502SChenlu.Chen@Sun.COM int
igb_m_setprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,const void * pr_val)98711502SChenlu.Chen@Sun.COM igb_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
98811502SChenlu.Chen@Sun.COM uint_t pr_valsize, const void *pr_val)
98911502SChenlu.Chen@Sun.COM {
99011502SChenlu.Chen@Sun.COM igb_t *igb = (igb_t *)arg;
99111502SChenlu.Chen@Sun.COM struct e1000_hw *hw = &igb->hw;
99211502SChenlu.Chen@Sun.COM int err = 0;
99311502SChenlu.Chen@Sun.COM uint32_t flow_control;
99411502SChenlu.Chen@Sun.COM uint32_t cur_mtu, new_mtu;
99511502SChenlu.Chen@Sun.COM uint32_t rx_size;
99611502SChenlu.Chen@Sun.COM uint32_t tx_size;
99711502SChenlu.Chen@Sun.COM
99811502SChenlu.Chen@Sun.COM mutex_enter(&igb->gen_lock);
99911502SChenlu.Chen@Sun.COM if (igb->igb_state & IGB_SUSPENDED) {
100011502SChenlu.Chen@Sun.COM mutex_exit(&igb->gen_lock);
100111502SChenlu.Chen@Sun.COM return (ECANCELED);
100211502SChenlu.Chen@Sun.COM }
100311502SChenlu.Chen@Sun.COM
100411502SChenlu.Chen@Sun.COM if (igb->loopback_mode != IGB_LB_NONE && igb_param_locked(pr_num)) {
100511502SChenlu.Chen@Sun.COM /*
100611502SChenlu.Chen@Sun.COM * All en_* parameters are locked (read-only)
100711502SChenlu.Chen@Sun.COM * while the device is in any sort of loopback mode.
100811502SChenlu.Chen@Sun.COM */
100911502SChenlu.Chen@Sun.COM mutex_exit(&igb->gen_lock);
101011502SChenlu.Chen@Sun.COM return (EBUSY);
101111502SChenlu.Chen@Sun.COM }
101211502SChenlu.Chen@Sun.COM
101311502SChenlu.Chen@Sun.COM switch (pr_num) {
101411502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000FDX_CAP:
101511502SChenlu.Chen@Sun.COM /* read/write on copper, read-only on serdes */
101611502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
101711502SChenlu.Chen@Sun.COM err = ENOTSUP;
101811502SChenlu.Chen@Sun.COM break;
101911502SChenlu.Chen@Sun.COM }
102011502SChenlu.Chen@Sun.COM igb->param_en_1000fdx_cap = *(uint8_t *)pr_val;
102111502SChenlu.Chen@Sun.COM igb->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
102211502SChenlu.Chen@Sun.COM goto setup_link;
102311502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100FDX_CAP:
102411502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
102511502SChenlu.Chen@Sun.COM err = ENOTSUP;
102611502SChenlu.Chen@Sun.COM break;
102711502SChenlu.Chen@Sun.COM }
102811502SChenlu.Chen@Sun.COM igb->param_en_100fdx_cap = *(uint8_t *)pr_val;
102911502SChenlu.Chen@Sun.COM igb->param_adv_100fdx_cap = *(uint8_t *)pr_val;
103011502SChenlu.Chen@Sun.COM goto setup_link;
103111502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100HDX_CAP:
103211502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
103311502SChenlu.Chen@Sun.COM err = ENOTSUP;
103411502SChenlu.Chen@Sun.COM break;
103511502SChenlu.Chen@Sun.COM }
103611502SChenlu.Chen@Sun.COM igb->param_en_100hdx_cap = *(uint8_t *)pr_val;
103711502SChenlu.Chen@Sun.COM igb->param_adv_100hdx_cap = *(uint8_t *)pr_val;
103811502SChenlu.Chen@Sun.COM goto setup_link;
103911502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10FDX_CAP:
104011502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
104111502SChenlu.Chen@Sun.COM err = ENOTSUP;
104211502SChenlu.Chen@Sun.COM break;
104311502SChenlu.Chen@Sun.COM }
104411502SChenlu.Chen@Sun.COM igb->param_en_10fdx_cap = *(uint8_t *)pr_val;
104511502SChenlu.Chen@Sun.COM igb->param_adv_10fdx_cap = *(uint8_t *)pr_val;
104611502SChenlu.Chen@Sun.COM goto setup_link;
104711502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10HDX_CAP:
104811502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
104911502SChenlu.Chen@Sun.COM err = ENOTSUP;
105011502SChenlu.Chen@Sun.COM break;
105111502SChenlu.Chen@Sun.COM }
105211502SChenlu.Chen@Sun.COM igb->param_en_10hdx_cap = *(uint8_t *)pr_val;
105311502SChenlu.Chen@Sun.COM igb->param_adv_10hdx_cap = *(uint8_t *)pr_val;
105411502SChenlu.Chen@Sun.COM goto setup_link;
105511502SChenlu.Chen@Sun.COM case MAC_PROP_AUTONEG:
105611502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
105711502SChenlu.Chen@Sun.COM err = ENOTSUP;
105811502SChenlu.Chen@Sun.COM break;
105911502SChenlu.Chen@Sun.COM }
106011502SChenlu.Chen@Sun.COM igb->param_adv_autoneg_cap = *(uint8_t *)pr_val;
106111502SChenlu.Chen@Sun.COM goto setup_link;
106211502SChenlu.Chen@Sun.COM case MAC_PROP_FLOWCTRL:
106311502SChenlu.Chen@Sun.COM bcopy(pr_val, &flow_control, sizeof (flow_control));
106411502SChenlu.Chen@Sun.COM
106511502SChenlu.Chen@Sun.COM switch (flow_control) {
106611502SChenlu.Chen@Sun.COM default:
106711502SChenlu.Chen@Sun.COM err = EINVAL;
106811502SChenlu.Chen@Sun.COM break;
106911502SChenlu.Chen@Sun.COM case LINK_FLOWCTRL_NONE:
107011502SChenlu.Chen@Sun.COM hw->fc.requested_mode = e1000_fc_none;
107111502SChenlu.Chen@Sun.COM break;
107211502SChenlu.Chen@Sun.COM case LINK_FLOWCTRL_RX:
107311502SChenlu.Chen@Sun.COM hw->fc.requested_mode = e1000_fc_rx_pause;
107411502SChenlu.Chen@Sun.COM break;
107511502SChenlu.Chen@Sun.COM case LINK_FLOWCTRL_TX:
107611502SChenlu.Chen@Sun.COM hw->fc.requested_mode = e1000_fc_tx_pause;
107711502SChenlu.Chen@Sun.COM break;
107811502SChenlu.Chen@Sun.COM case LINK_FLOWCTRL_BI:
107911502SChenlu.Chen@Sun.COM hw->fc.requested_mode = e1000_fc_full;
108011502SChenlu.Chen@Sun.COM break;
108111502SChenlu.Chen@Sun.COM }
108211502SChenlu.Chen@Sun.COM setup_link:
108311502SChenlu.Chen@Sun.COM if (err == 0) {
108411502SChenlu.Chen@Sun.COM if (igb_setup_link(igb, B_TRUE) != IGB_SUCCESS)
108511502SChenlu.Chen@Sun.COM err = EINVAL;
108611502SChenlu.Chen@Sun.COM }
108711502SChenlu.Chen@Sun.COM break;
108811502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000FDX_CAP:
108911502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000HDX_CAP:
109011502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100T4_CAP:
109111502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100FDX_CAP:
109211502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100HDX_CAP:
109311502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10FDX_CAP:
109411502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10HDX_CAP:
109511502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000HDX_CAP:
109611502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100T4_CAP:
109711502SChenlu.Chen@Sun.COM case MAC_PROP_STATUS:
109811502SChenlu.Chen@Sun.COM case MAC_PROP_SPEED:
109911502SChenlu.Chen@Sun.COM case MAC_PROP_DUPLEX:
110011502SChenlu.Chen@Sun.COM err = ENOTSUP; /* read-only prop. Can't set this. */
110111502SChenlu.Chen@Sun.COM break;
110211502SChenlu.Chen@Sun.COM case MAC_PROP_MTU:
110311502SChenlu.Chen@Sun.COM /* adapter must be stopped for an MTU change */
110411502SChenlu.Chen@Sun.COM if (igb->igb_state & IGB_STARTED) {
110511502SChenlu.Chen@Sun.COM err = EBUSY;
110611502SChenlu.Chen@Sun.COM break;
110711502SChenlu.Chen@Sun.COM }
110811502SChenlu.Chen@Sun.COM
110911502SChenlu.Chen@Sun.COM cur_mtu = igb->default_mtu;
111011502SChenlu.Chen@Sun.COM bcopy(pr_val, &new_mtu, sizeof (new_mtu));
111111502SChenlu.Chen@Sun.COM if (new_mtu == cur_mtu) {
111211502SChenlu.Chen@Sun.COM err = 0;
111311502SChenlu.Chen@Sun.COM break;
111411502SChenlu.Chen@Sun.COM }
111511502SChenlu.Chen@Sun.COM
111611502SChenlu.Chen@Sun.COM if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) {
111711502SChenlu.Chen@Sun.COM err = EINVAL;
111811502SChenlu.Chen@Sun.COM break;
111911502SChenlu.Chen@Sun.COM }
112011502SChenlu.Chen@Sun.COM
112111502SChenlu.Chen@Sun.COM err = mac_maxsdu_update(igb->mac_hdl, new_mtu);
112211502SChenlu.Chen@Sun.COM if (err == 0) {
112311502SChenlu.Chen@Sun.COM igb->default_mtu = new_mtu;
112411502SChenlu.Chen@Sun.COM igb->max_frame_size = igb->default_mtu +
112511502SChenlu.Chen@Sun.COM sizeof (struct ether_vlan_header) + ETHERFCSL;
112611502SChenlu.Chen@Sun.COM
112711502SChenlu.Chen@Sun.COM /*
112811502SChenlu.Chen@Sun.COM * Set rx buffer size
112911502SChenlu.Chen@Sun.COM */
113011502SChenlu.Chen@Sun.COM rx_size = igb->max_frame_size + IPHDR_ALIGN_ROOM;
113111502SChenlu.Chen@Sun.COM igb->rx_buf_size = ((rx_size >> 10) + ((rx_size &
113211502SChenlu.Chen@Sun.COM (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
113311502SChenlu.Chen@Sun.COM
113411502SChenlu.Chen@Sun.COM /*
113511502SChenlu.Chen@Sun.COM * Set tx buffer size
113611502SChenlu.Chen@Sun.COM */
113711502SChenlu.Chen@Sun.COM tx_size = igb->max_frame_size;
113811502SChenlu.Chen@Sun.COM igb->tx_buf_size = ((tx_size >> 10) + ((tx_size &
113911502SChenlu.Chen@Sun.COM (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
114011502SChenlu.Chen@Sun.COM }
114111502SChenlu.Chen@Sun.COM break;
114211502SChenlu.Chen@Sun.COM case MAC_PROP_PRIVATE:
114311502SChenlu.Chen@Sun.COM err = igb_set_priv_prop(igb, pr_name, pr_valsize, pr_val);
114411502SChenlu.Chen@Sun.COM break;
114511502SChenlu.Chen@Sun.COM default:
114611502SChenlu.Chen@Sun.COM err = EINVAL;
114711502SChenlu.Chen@Sun.COM break;
114811502SChenlu.Chen@Sun.COM }
114911502SChenlu.Chen@Sun.COM
115011502SChenlu.Chen@Sun.COM mutex_exit(&igb->gen_lock);
115111502SChenlu.Chen@Sun.COM
115211502SChenlu.Chen@Sun.COM if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
115311502SChenlu.Chen@Sun.COM ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
115411502SChenlu.Chen@Sun.COM return (EIO);
115511502SChenlu.Chen@Sun.COM }
115611502SChenlu.Chen@Sun.COM
115711502SChenlu.Chen@Sun.COM return (err);
115811502SChenlu.Chen@Sun.COM }
115911502SChenlu.Chen@Sun.COM
116011502SChenlu.Chen@Sun.COM int
igb_m_getprop(void * arg,const char * pr_name,mac_prop_id_t pr_num,uint_t pr_valsize,void * pr_val)116111502SChenlu.Chen@Sun.COM igb_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
116211878SVenu.Iyer@Sun.COM uint_t pr_valsize, void *pr_val)
116311502SChenlu.Chen@Sun.COM {
116411502SChenlu.Chen@Sun.COM igb_t *igb = (igb_t *)arg;
116511502SChenlu.Chen@Sun.COM struct e1000_hw *hw = &igb->hw;
116611502SChenlu.Chen@Sun.COM int err = 0;
116711502SChenlu.Chen@Sun.COM uint32_t flow_control;
116811502SChenlu.Chen@Sun.COM uint64_t tmp = 0;
116911502SChenlu.Chen@Sun.COM
117011502SChenlu.Chen@Sun.COM switch (pr_num) {
117111502SChenlu.Chen@Sun.COM case MAC_PROP_DUPLEX:
117211878SVenu.Iyer@Sun.COM ASSERT(pr_valsize >= sizeof (link_duplex_t));
117311878SVenu.Iyer@Sun.COM bcopy(&igb->link_duplex, pr_val, sizeof (link_duplex_t));
117411502SChenlu.Chen@Sun.COM break;
117511502SChenlu.Chen@Sun.COM case MAC_PROP_SPEED:
117611878SVenu.Iyer@Sun.COM ASSERT(pr_valsize >= sizeof (uint64_t));
117711878SVenu.Iyer@Sun.COM tmp = igb->link_speed * 1000000ull;
117811878SVenu.Iyer@Sun.COM bcopy(&tmp, pr_val, sizeof (tmp));
117911502SChenlu.Chen@Sun.COM break;
118011502SChenlu.Chen@Sun.COM case MAC_PROP_AUTONEG:
118111878SVenu.Iyer@Sun.COM ASSERT(pr_valsize >= sizeof (uint8_t));
118211502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_autoneg_cap;
118311502SChenlu.Chen@Sun.COM break;
118411502SChenlu.Chen@Sun.COM case MAC_PROP_FLOWCTRL:
118511878SVenu.Iyer@Sun.COM ASSERT(pr_valsize >= sizeof (uint32_t));
118611878SVenu.Iyer@Sun.COM switch (hw->fc.requested_mode) {
118711878SVenu.Iyer@Sun.COM case e1000_fc_none:
118811878SVenu.Iyer@Sun.COM flow_control = LINK_FLOWCTRL_NONE;
118911878SVenu.Iyer@Sun.COM break;
119011878SVenu.Iyer@Sun.COM case e1000_fc_rx_pause:
119111878SVenu.Iyer@Sun.COM flow_control = LINK_FLOWCTRL_RX;
119211878SVenu.Iyer@Sun.COM break;
119311878SVenu.Iyer@Sun.COM case e1000_fc_tx_pause:
119411878SVenu.Iyer@Sun.COM flow_control = LINK_FLOWCTRL_TX;
119511878SVenu.Iyer@Sun.COM break;
119611878SVenu.Iyer@Sun.COM case e1000_fc_full:
119711878SVenu.Iyer@Sun.COM flow_control = LINK_FLOWCTRL_BI;
119811878SVenu.Iyer@Sun.COM break;
119911878SVenu.Iyer@Sun.COM }
120011878SVenu.Iyer@Sun.COM bcopy(&flow_control, pr_val, sizeof (flow_control));
120111502SChenlu.Chen@Sun.COM break;
120211502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000FDX_CAP:
120311502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_1000fdx_cap;
120411502SChenlu.Chen@Sun.COM break;
120511502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000FDX_CAP:
120611502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_1000fdx_cap;
120711502SChenlu.Chen@Sun.COM break;
120811502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000HDX_CAP:
120911502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_1000hdx_cap;
121011502SChenlu.Chen@Sun.COM break;
121111502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000HDX_CAP:
121211502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_1000hdx_cap;
121311502SChenlu.Chen@Sun.COM break;
121411502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100T4_CAP:
121511502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_100t4_cap;
121611502SChenlu.Chen@Sun.COM break;
121711502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100T4_CAP:
121811502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_100t4_cap;
121911502SChenlu.Chen@Sun.COM break;
122011502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100FDX_CAP:
122111502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_100fdx_cap;
122211502SChenlu.Chen@Sun.COM break;
122311502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100FDX_CAP:
122411502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_100fdx_cap;
122511502SChenlu.Chen@Sun.COM break;
122611502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100HDX_CAP:
122711502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_100hdx_cap;
122811502SChenlu.Chen@Sun.COM break;
122911502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100HDX_CAP:
123011502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_100hdx_cap;
123111502SChenlu.Chen@Sun.COM break;
123211502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10FDX_CAP:
123311502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_10fdx_cap;
123411502SChenlu.Chen@Sun.COM break;
123511502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10FDX_CAP:
123611502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_10fdx_cap;
123711502SChenlu.Chen@Sun.COM break;
123811502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10HDX_CAP:
123911502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_adv_10hdx_cap;
124011502SChenlu.Chen@Sun.COM break;
124111502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10HDX_CAP:
124211502SChenlu.Chen@Sun.COM *(uint8_t *)pr_val = igb->param_en_10hdx_cap;
124311502SChenlu.Chen@Sun.COM break;
124411502SChenlu.Chen@Sun.COM case MAC_PROP_PRIVATE:
124511878SVenu.Iyer@Sun.COM err = igb_get_priv_prop(igb, pr_name, pr_valsize, pr_val);
124611502SChenlu.Chen@Sun.COM break;
124711502SChenlu.Chen@Sun.COM default:
124811502SChenlu.Chen@Sun.COM err = EINVAL;
124911502SChenlu.Chen@Sun.COM break;
125011502SChenlu.Chen@Sun.COM }
125111502SChenlu.Chen@Sun.COM return (err);
125211502SChenlu.Chen@Sun.COM }
125311502SChenlu.Chen@Sun.COM
125411878SVenu.Iyer@Sun.COM void
igb_m_propinfo(void * arg,const char * pr_name,mac_prop_id_t pr_num,mac_prop_info_handle_t prh)125511878SVenu.Iyer@Sun.COM igb_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
125611878SVenu.Iyer@Sun.COM mac_prop_info_handle_t prh)
125711502SChenlu.Chen@Sun.COM {
125811878SVenu.Iyer@Sun.COM igb_t *igb = (igb_t *)arg;
125911502SChenlu.Chen@Sun.COM struct e1000_hw *hw = &igb->hw;
126011878SVenu.Iyer@Sun.COM uint16_t phy_status, phy_ext_status;
126111502SChenlu.Chen@Sun.COM
126211502SChenlu.Chen@Sun.COM switch (pr_num) {
126311878SVenu.Iyer@Sun.COM case MAC_PROP_DUPLEX:
126411878SVenu.Iyer@Sun.COM case MAC_PROP_SPEED:
126511502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000FDX_CAP:
126611502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_1000HDX_CAP:
126711502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000HDX_CAP:
126811502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100T4_CAP:
126911502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100T4_CAP:
127011878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
127111502SChenlu.Chen@Sun.COM break;
127211878SVenu.Iyer@Sun.COM
127311878SVenu.Iyer@Sun.COM case MAC_PROP_EN_1000FDX_CAP:
127411878SVenu.Iyer@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
127511878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
127611878SVenu.Iyer@Sun.COM } else {
127711878SVenu.Iyer@Sun.COM (void) e1000_read_phy_reg(hw, PHY_EXT_STATUS,
127811878SVenu.Iyer@Sun.COM &phy_ext_status);
127911878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
128011878SVenu.Iyer@Sun.COM ((phy_ext_status & IEEE_ESR_1000T_FD_CAPS) ||
128111878SVenu.Iyer@Sun.COM (phy_ext_status & IEEE_ESR_1000X_FD_CAPS)) ? 1 : 0);
128211878SVenu.Iyer@Sun.COM }
128311878SVenu.Iyer@Sun.COM break;
128411878SVenu.Iyer@Sun.COM
128511502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100FDX_CAP:
128611502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100FDX_CAP:
128711502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
128811878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
128911502SChenlu.Chen@Sun.COM } else {
129011502SChenlu.Chen@Sun.COM (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
129111878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
129211502SChenlu.Chen@Sun.COM ((phy_status & MII_SR_100X_FD_CAPS) ||
129311878SVenu.Iyer@Sun.COM (phy_status & MII_SR_100T2_FD_CAPS)) ? 1 : 0);
129411502SChenlu.Chen@Sun.COM }
129511502SChenlu.Chen@Sun.COM break;
129611878SVenu.Iyer@Sun.COM
129711502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_100HDX_CAP:
129811502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100HDX_CAP:
129911502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
130011878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
130111502SChenlu.Chen@Sun.COM } else {
130211502SChenlu.Chen@Sun.COM (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
130311878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
130411502SChenlu.Chen@Sun.COM ((phy_status & MII_SR_100X_HD_CAPS) ||
130511878SVenu.Iyer@Sun.COM (phy_status & MII_SR_100T2_HD_CAPS)) ? 1 : 0);
130611502SChenlu.Chen@Sun.COM }
130711502SChenlu.Chen@Sun.COM break;
130811878SVenu.Iyer@Sun.COM
130911502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10FDX_CAP:
131011502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10FDX_CAP:
131111502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
131211878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
131311502SChenlu.Chen@Sun.COM } else {
131411502SChenlu.Chen@Sun.COM (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
131511878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
131611878SVenu.Iyer@Sun.COM (phy_status & MII_SR_10T_FD_CAPS) ? 1 : 0);
131711502SChenlu.Chen@Sun.COM }
131811502SChenlu.Chen@Sun.COM break;
131911878SVenu.Iyer@Sun.COM
132011502SChenlu.Chen@Sun.COM case MAC_PROP_ADV_10HDX_CAP:
132111502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10HDX_CAP:
132211502SChenlu.Chen@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
132311878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
132411878SVenu.Iyer@Sun.COM } else {
132511878SVenu.Iyer@Sun.COM (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
132611878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
132711878SVenu.Iyer@Sun.COM (phy_status & MII_SR_10T_HD_CAPS) ? 1 : 0);
132811878SVenu.Iyer@Sun.COM }
132911878SVenu.Iyer@Sun.COM break;
133011878SVenu.Iyer@Sun.COM
133111878SVenu.Iyer@Sun.COM case MAC_PROP_AUTONEG:
133211878SVenu.Iyer@Sun.COM if (hw->phy.media_type != e1000_media_type_copper) {
133311878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
133411502SChenlu.Chen@Sun.COM } else {
133511502SChenlu.Chen@Sun.COM (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
133611878SVenu.Iyer@Sun.COM mac_prop_info_set_default_uint8(prh,
133711878SVenu.Iyer@Sun.COM (phy_status & MII_SR_AUTONEG_CAPS) ? 1 : 0);
133811502SChenlu.Chen@Sun.COM }
133911502SChenlu.Chen@Sun.COM break;
134011878SVenu.Iyer@Sun.COM
134111878SVenu.Iyer@Sun.COM case MAC_PROP_FLOWCTRL:
134211878SVenu.Iyer@Sun.COM mac_prop_info_set_default_link_flowctrl(prh, LINK_FLOWCTRL_BI);
134311878SVenu.Iyer@Sun.COM break;
134411878SVenu.Iyer@Sun.COM
134511878SVenu.Iyer@Sun.COM case MAC_PROP_MTU:
134611878SVenu.Iyer@Sun.COM mac_prop_info_set_range_uint32(prh, MIN_MTU, MAX_MTU);
134711878SVenu.Iyer@Sun.COM break;
134811878SVenu.Iyer@Sun.COM
134911878SVenu.Iyer@Sun.COM case MAC_PROP_PRIVATE:
135011878SVenu.Iyer@Sun.COM igb_priv_prop_info(igb, pr_name, prh);
135111502SChenlu.Chen@Sun.COM break;
135211502SChenlu.Chen@Sun.COM }
135311878SVenu.Iyer@Sun.COM
135411502SChenlu.Chen@Sun.COM }
135511502SChenlu.Chen@Sun.COM
135611502SChenlu.Chen@Sun.COM boolean_t
igb_param_locked(mac_prop_id_t pr_num)135711502SChenlu.Chen@Sun.COM igb_param_locked(mac_prop_id_t pr_num)
135811502SChenlu.Chen@Sun.COM {
135911502SChenlu.Chen@Sun.COM /*
136011502SChenlu.Chen@Sun.COM * All en_* parameters are locked (read-only) while
136111502SChenlu.Chen@Sun.COM * the device is in any sort of loopback mode ...
136211502SChenlu.Chen@Sun.COM */
136311502SChenlu.Chen@Sun.COM switch (pr_num) {
136411502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000FDX_CAP:
136511502SChenlu.Chen@Sun.COM case MAC_PROP_EN_1000HDX_CAP:
136611502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100T4_CAP:
136711502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100FDX_CAP:
136811502SChenlu.Chen@Sun.COM case MAC_PROP_EN_100HDX_CAP:
136911502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10FDX_CAP:
137011502SChenlu.Chen@Sun.COM case MAC_PROP_EN_10HDX_CAP:
137111502SChenlu.Chen@Sun.COM case MAC_PROP_AUTONEG:
137211502SChenlu.Chen@Sun.COM case MAC_PROP_FLOWCTRL:
137311502SChenlu.Chen@Sun.COM return (B_TRUE);
137411502SChenlu.Chen@Sun.COM }
137511502SChenlu.Chen@Sun.COM return (B_FALSE);
137611502SChenlu.Chen@Sun.COM }
137711502SChenlu.Chen@Sun.COM
137811502SChenlu.Chen@Sun.COM /* ARGSUSED */
137911502SChenlu.Chen@Sun.COM int
igb_set_priv_prop(igb_t * igb,const char * pr_name,uint_t pr_valsize,const void * pr_val)138011502SChenlu.Chen@Sun.COM igb_set_priv_prop(igb_t *igb, const char *pr_name,
138111502SChenlu.Chen@Sun.COM uint_t pr_valsize, const void *pr_val)
138211502SChenlu.Chen@Sun.COM {
138311502SChenlu.Chen@Sun.COM int err = 0;
138411502SChenlu.Chen@Sun.COM long result;
138511502SChenlu.Chen@Sun.COM struct e1000_hw *hw = &igb->hw;
138611502SChenlu.Chen@Sun.COM int i;
138711502SChenlu.Chen@Sun.COM
138811502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
138911502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
139011502SChenlu.Chen@Sun.COM err = EINVAL;
139111502SChenlu.Chen@Sun.COM return (err);
139211502SChenlu.Chen@Sun.COM }
139311502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
139411502SChenlu.Chen@Sun.COM if (result < MIN_TX_COPY_THRESHOLD ||
139511502SChenlu.Chen@Sun.COM result > MAX_TX_COPY_THRESHOLD)
139611502SChenlu.Chen@Sun.COM err = EINVAL;
139711502SChenlu.Chen@Sun.COM else {
139811502SChenlu.Chen@Sun.COM igb->tx_copy_thresh = (uint32_t)result;
139911502SChenlu.Chen@Sun.COM }
140011502SChenlu.Chen@Sun.COM return (err);
140111502SChenlu.Chen@Sun.COM }
140211502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
140311502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
140411502SChenlu.Chen@Sun.COM err = EINVAL;
140511502SChenlu.Chen@Sun.COM return (err);
140611502SChenlu.Chen@Sun.COM }
140711502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
140811502SChenlu.Chen@Sun.COM if (result < MIN_TX_RECYCLE_THRESHOLD ||
140911502SChenlu.Chen@Sun.COM result > MAX_TX_RECYCLE_THRESHOLD)
141011502SChenlu.Chen@Sun.COM err = EINVAL;
141111502SChenlu.Chen@Sun.COM else {
141211502SChenlu.Chen@Sun.COM igb->tx_recycle_thresh = (uint32_t)result;
141311502SChenlu.Chen@Sun.COM }
141411502SChenlu.Chen@Sun.COM return (err);
141511502SChenlu.Chen@Sun.COM }
141611502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
141711502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
141811502SChenlu.Chen@Sun.COM err = EINVAL;
141911502SChenlu.Chen@Sun.COM return (err);
142011502SChenlu.Chen@Sun.COM }
142111502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
142211502SChenlu.Chen@Sun.COM if (result < MIN_TX_OVERLOAD_THRESHOLD ||
142311502SChenlu.Chen@Sun.COM result > MAX_TX_OVERLOAD_THRESHOLD)
142411502SChenlu.Chen@Sun.COM err = EINVAL;
142511502SChenlu.Chen@Sun.COM else {
142611502SChenlu.Chen@Sun.COM igb->tx_overload_thresh = (uint32_t)result;
142711502SChenlu.Chen@Sun.COM }
142811502SChenlu.Chen@Sun.COM return (err);
142911502SChenlu.Chen@Sun.COM }
143011502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
143111502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
143211502SChenlu.Chen@Sun.COM err = EINVAL;
143311502SChenlu.Chen@Sun.COM return (err);
143411502SChenlu.Chen@Sun.COM }
143511502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
143611502SChenlu.Chen@Sun.COM if (result < MIN_TX_RESCHED_THRESHOLD ||
1437*12980SGuoqing.Zhu@Sun.COM result > MAX_TX_RESCHED_THRESHOLD ||
1438*12980SGuoqing.Zhu@Sun.COM result > igb->tx_ring_size)
143911502SChenlu.Chen@Sun.COM err = EINVAL;
144011502SChenlu.Chen@Sun.COM else {
144111502SChenlu.Chen@Sun.COM igb->tx_resched_thresh = (uint32_t)result;
144211502SChenlu.Chen@Sun.COM }
144311502SChenlu.Chen@Sun.COM return (err);
144411502SChenlu.Chen@Sun.COM }
144511502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
144611502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
144711502SChenlu.Chen@Sun.COM err = EINVAL;
144811502SChenlu.Chen@Sun.COM return (err);
144911502SChenlu.Chen@Sun.COM }
145011502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
145111502SChenlu.Chen@Sun.COM if (result < MIN_RX_COPY_THRESHOLD ||
145211502SChenlu.Chen@Sun.COM result > MAX_RX_COPY_THRESHOLD)
145311502SChenlu.Chen@Sun.COM err = EINVAL;
145411502SChenlu.Chen@Sun.COM else {
145511502SChenlu.Chen@Sun.COM igb->rx_copy_thresh = (uint32_t)result;
145611502SChenlu.Chen@Sun.COM }
145711502SChenlu.Chen@Sun.COM return (err);
145811502SChenlu.Chen@Sun.COM }
145911502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
146011502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
146111502SChenlu.Chen@Sun.COM err = EINVAL;
146211502SChenlu.Chen@Sun.COM return (err);
146311502SChenlu.Chen@Sun.COM }
146411502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
146511502SChenlu.Chen@Sun.COM if (result < MIN_RX_LIMIT_PER_INTR ||
146611502SChenlu.Chen@Sun.COM result > MAX_RX_LIMIT_PER_INTR)
146711502SChenlu.Chen@Sun.COM err = EINVAL;
146811502SChenlu.Chen@Sun.COM else {
146911502SChenlu.Chen@Sun.COM igb->rx_limit_per_intr = (uint32_t)result;
147011502SChenlu.Chen@Sun.COM }
147111502SChenlu.Chen@Sun.COM return (err);
147211502SChenlu.Chen@Sun.COM }
147311502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_intr_throttling") == 0) {
147411502SChenlu.Chen@Sun.COM if (pr_val == NULL) {
147511502SChenlu.Chen@Sun.COM err = EINVAL;
147611502SChenlu.Chen@Sun.COM return (err);
147711502SChenlu.Chen@Sun.COM }
147811502SChenlu.Chen@Sun.COM (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
147911502SChenlu.Chen@Sun.COM
148011502SChenlu.Chen@Sun.COM if (result < igb->capab->min_intr_throttle ||
148111502SChenlu.Chen@Sun.COM result > igb->capab->max_intr_throttle)
148211502SChenlu.Chen@Sun.COM err = EINVAL;
148311502SChenlu.Chen@Sun.COM else {
148411502SChenlu.Chen@Sun.COM igb->intr_throttling[0] = (uint32_t)result;
148511502SChenlu.Chen@Sun.COM
148611502SChenlu.Chen@Sun.COM for (i = 0; i < MAX_NUM_EITR; i++)
148711502SChenlu.Chen@Sun.COM igb->intr_throttling[i] =
148811502SChenlu.Chen@Sun.COM igb->intr_throttling[0];
148911502SChenlu.Chen@Sun.COM
149011502SChenlu.Chen@Sun.COM /* Set interrupt throttling rate */
149111502SChenlu.Chen@Sun.COM for (i = 0; i < igb->intr_cnt; i++)
149211502SChenlu.Chen@Sun.COM E1000_WRITE_REG(hw, E1000_EITR(i),
149311502SChenlu.Chen@Sun.COM igb->intr_throttling[i]);
149411502SChenlu.Chen@Sun.COM }
149511502SChenlu.Chen@Sun.COM return (err);
149611502SChenlu.Chen@Sun.COM }
149711502SChenlu.Chen@Sun.COM return (ENOTSUP);
149811502SChenlu.Chen@Sun.COM }
149911502SChenlu.Chen@Sun.COM
150011502SChenlu.Chen@Sun.COM int
igb_get_priv_prop(igb_t * igb,const char * pr_name,uint_t pr_valsize,void * pr_val)150111878SVenu.Iyer@Sun.COM igb_get_priv_prop(igb_t *igb, const char *pr_name, uint_t pr_valsize,
150211878SVenu.Iyer@Sun.COM void *pr_val)
150311502SChenlu.Chen@Sun.COM {
150411502SChenlu.Chen@Sun.COM int value;
150511502SChenlu.Chen@Sun.COM
150611502SChenlu.Chen@Sun.COM if (strcmp(pr_name, "_adv_pause_cap") == 0) {
150711878SVenu.Iyer@Sun.COM value = igb->param_adv_pause_cap;
150811878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
150911878SVenu.Iyer@Sun.COM value = igb->param_adv_asym_pause_cap;
151011878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
151111878SVenu.Iyer@Sun.COM value = igb->tx_copy_thresh;
151211878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
151311878SVenu.Iyer@Sun.COM value = igb->tx_recycle_thresh;
151411878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
151511878SVenu.Iyer@Sun.COM value = igb->tx_overload_thresh;
151611878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
151711878SVenu.Iyer@Sun.COM value = igb->tx_resched_thresh;
151811878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
151911878SVenu.Iyer@Sun.COM value = igb->rx_copy_thresh;
152011878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
152111878SVenu.Iyer@Sun.COM value = igb->rx_limit_per_intr;
152211878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_intr_throttling") == 0) {
152311878SVenu.Iyer@Sun.COM value = igb->intr_throttling[0];
152411878SVenu.Iyer@Sun.COM } else {
152511878SVenu.Iyer@Sun.COM return (ENOTSUP);
152611502SChenlu.Chen@Sun.COM }
152711878SVenu.Iyer@Sun.COM
152811878SVenu.Iyer@Sun.COM (void) snprintf(pr_val, pr_valsize, "%d", value);
152911878SVenu.Iyer@Sun.COM return (0);
153011878SVenu.Iyer@Sun.COM }
153111878SVenu.Iyer@Sun.COM
153211878SVenu.Iyer@Sun.COM void
igb_priv_prop_info(igb_t * igb,const char * pr_name,mac_prop_info_handle_t prh)153311878SVenu.Iyer@Sun.COM igb_priv_prop_info(igb_t *igb, const char *pr_name, mac_prop_info_handle_t prh)
153411878SVenu.Iyer@Sun.COM {
153511878SVenu.Iyer@Sun.COM char valstr[64];
153611878SVenu.Iyer@Sun.COM int value;
153711878SVenu.Iyer@Sun.COM
153811878SVenu.Iyer@Sun.COM if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
153911878SVenu.Iyer@Sun.COM strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
154011878SVenu.Iyer@Sun.COM mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
154111878SVenu.Iyer@Sun.COM return;
154211878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
154311878SVenu.Iyer@Sun.COM value = DEFAULT_TX_COPY_THRESHOLD;
154411878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
154511878SVenu.Iyer@Sun.COM value = DEFAULT_TX_RECYCLE_THRESHOLD;
154611878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
154711878SVenu.Iyer@Sun.COM value = DEFAULT_TX_OVERLOAD_THRESHOLD;
154811878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
154911878SVenu.Iyer@Sun.COM value = DEFAULT_TX_RESCHED_THRESHOLD;
155011878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
155111878SVenu.Iyer@Sun.COM value = DEFAULT_RX_COPY_THRESHOLD;
155211878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
155311878SVenu.Iyer@Sun.COM value = DEFAULT_RX_LIMIT_PER_INTR;
155411878SVenu.Iyer@Sun.COM } else if (strcmp(pr_name, "_intr_throttling") == 0) {
155511878SVenu.Iyer@Sun.COM value = igb->capab->def_intr_throttle;
155611878SVenu.Iyer@Sun.COM } else {
155711878SVenu.Iyer@Sun.COM return;
155811502SChenlu.Chen@Sun.COM }
155911878SVenu.Iyer@Sun.COM
156011878SVenu.Iyer@Sun.COM (void) snprintf(valstr, sizeof (valstr), "%d", value);
156111878SVenu.Iyer@Sun.COM mac_prop_info_set_default_str(prh, valstr);
156211502SChenlu.Chen@Sun.COM }
1563