1c869993eSxy150489 /* 2c869993eSxy150489 * CDDL HEADER START 3c869993eSxy150489 * 4c869993eSxy150489 * The contents of this file are subject to the terms of the 5c869993eSxy150489 * Common Development and Distribution License (the "License"). 6c869993eSxy150489 * You may not use this file except in compliance with the License. 7c869993eSxy150489 * 8da14cebeSEric Cheng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da14cebeSEric Cheng * or http://www.opensolaris.org/os/licensing. 10c869993eSxy150489 * See the License for the specific language governing permissions 11c869993eSxy150489 * and limitations under the License. 12c869993eSxy150489 * 13da14cebeSEric Cheng * When distributing Covered Code, include this CDDL HEADER in each 14da14cebeSEric Cheng * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c869993eSxy150489 * If applicable, add the following below this CDDL HEADER, with the 16c869993eSxy150489 * fields enclosed by brackets "[]" replaced with your own identifying 17c869993eSxy150489 * information: Portions Copyright [yyyy] [name of copyright owner] 18c869993eSxy150489 * 19c869993eSxy150489 * CDDL HEADER END 20c869993eSxy150489 */ 21c869993eSxy150489 22c869993eSxy150489 /* 2369b2d733SGuoqing Zhu * Copyright(c) 2007-2010 Intel Corporation. All rights reserved. 24c869993eSxy150489 */ 25c869993eSxy150489 26da14cebeSEric Cheng /* 2769b2d733SGuoqing Zhu * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 2843ae5505SDan McDonald * Copyright 2013, Nexenta Systems, Inc. All rights reserved. 2913485e69SGarrett D'Amore * Copyright 2014 Pluribus Networks Inc. 30238d8f47SDale Ghent * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved. 31*b142f83dSRobert Mustacchi * Copyright (c) 2017, Joyent, Inc. 32da14cebeSEric Cheng */ 33c869993eSxy150489 34c869993eSxy150489 #include "igb_sw.h" 35c869993eSxy150489 36c869993eSxy150489 int 37c869993eSxy150489 igb_m_stat(void *arg, uint_t stat, uint64_t *val) 38c869993eSxy150489 { 39c869993eSxy150489 igb_t *igb = (igb_t *)arg; 40c869993eSxy150489 struct e1000_hw *hw = &igb->hw; 41c869993eSxy150489 igb_stat_t *igb_ks; 42c869993eSxy150489 uint32_t low_val, high_val; 43c869993eSxy150489 44c869993eSxy150489 igb_ks = (igb_stat_t *)igb->igb_ks->ks_data; 45c869993eSxy150489 46c869993eSxy150489 mutex_enter(&igb->gen_lock); 47c869993eSxy150489 48c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 49c869993eSxy150489 mutex_exit(&igb->gen_lock); 50c869993eSxy150489 return (ECANCELED); 51c869993eSxy150489 } 52c869993eSxy150489 53c869993eSxy150489 switch (stat) { 54c869993eSxy150489 case MAC_STAT_IFSPEED: 55c869993eSxy150489 *val = igb->link_speed * 1000000ull; 56c869993eSxy150489 break; 57c869993eSxy150489 58c869993eSxy150489 case MAC_STAT_MULTIRCV: 5913485e69SGarrett D'Amore igb->stat_mprc += E1000_READ_REG(hw, E1000_MPRC); 6013485e69SGarrett D'Amore *val = igb->stat_mprc; 61c869993eSxy150489 break; 62c869993eSxy150489 63c869993eSxy150489 case MAC_STAT_BRDCSTRCV: 6413485e69SGarrett D'Amore igb->stat_bprc += E1000_READ_REG(hw, E1000_BPRC); 6513485e69SGarrett D'Amore *val = igb->stat_bprc; 66c869993eSxy150489 break; 67c869993eSxy150489 68c869993eSxy150489 case MAC_STAT_MULTIXMT: 6913485e69SGarrett D'Amore igb->stat_mptc += E1000_READ_REG(hw, E1000_MPTC); 7013485e69SGarrett D'Amore *val = igb->stat_mptc; 71c869993eSxy150489 break; 72c869993eSxy150489 73c869993eSxy150489 case MAC_STAT_BRDCSTXMT: 7413485e69SGarrett D'Amore igb->stat_bptc += E1000_READ_REG(hw, E1000_BPTC); 7513485e69SGarrett D'Amore *val = igb->stat_bptc; 76c869993eSxy150489 break; 77c869993eSxy150489 78c869993eSxy150489 case MAC_STAT_NORCVBUF: 7913485e69SGarrett D'Amore igb->stat_rnbc += E1000_READ_REG(hw, E1000_RNBC); 8013485e69SGarrett D'Amore *val = igb->stat_rnbc; 81c869993eSxy150489 break; 82c869993eSxy150489 83c869993eSxy150489 case MAC_STAT_IERRORS: 8413485e69SGarrett D'Amore igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC); 8513485e69SGarrett D'Amore igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC); 86c869993eSxy150489 igb_ks->rlec.value.ui64 += 87c869993eSxy150489 E1000_READ_REG(hw, E1000_RLEC); 8813485e69SGarrett D'Amore igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS); 8913485e69SGarrett D'Amore igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR); 9013485e69SGarrett D'Amore *val = igb->stat_rxerrc + 9113485e69SGarrett D'Amore igb->stat_algnerrc + 92c869993eSxy150489 igb_ks->rlec.value.ui64 + 9313485e69SGarrett D'Amore igb->stat_crcerrs + 9413485e69SGarrett D'Amore igb->stat_cexterr; 95c869993eSxy150489 break; 96c869993eSxy150489 97c869993eSxy150489 case MAC_STAT_NOXMTBUF: 98c869993eSxy150489 *val = 0; 99c869993eSxy150489 break; 100c869993eSxy150489 101c869993eSxy150489 case MAC_STAT_OERRORS: 10213485e69SGarrett D'Amore igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 10313485e69SGarrett D'Amore *val = igb->stat_ecol; 104c869993eSxy150489 break; 105c869993eSxy150489 106c869993eSxy150489 case MAC_STAT_COLLISIONS: 10713485e69SGarrett D'Amore igb->stat_colc += E1000_READ_REG(hw, E1000_COLC); 10813485e69SGarrett D'Amore *val = igb->stat_colc; 109c869993eSxy150489 break; 110c869993eSxy150489 111c869993eSxy150489 case MAC_STAT_RBYTES: 112c869993eSxy150489 /* 113c869993eSxy150489 * The 64-bit register will reset whenever the upper 114c869993eSxy150489 * 32 bits are read. So we need to read the lower 115c869993eSxy150489 * 32 bits first, then read the upper 32 bits. 116c869993eSxy150489 */ 117c869993eSxy150489 low_val = E1000_READ_REG(hw, E1000_TORL); 118c869993eSxy150489 high_val = E1000_READ_REG(hw, E1000_TORH); 11913485e69SGarrett D'Amore igb->stat_tor += (uint64_t)high_val << 32 | (uint64_t)low_val; 12013485e69SGarrett D'Amore *val = igb->stat_tor; 121c869993eSxy150489 break; 122c869993eSxy150489 123c869993eSxy150489 case MAC_STAT_IPACKETS: 12413485e69SGarrett D'Amore igb->stat_tpr += E1000_READ_REG(hw, E1000_TPR); 12513485e69SGarrett D'Amore *val = igb->stat_tpr; 126c869993eSxy150489 break; 127c869993eSxy150489 128c869993eSxy150489 case MAC_STAT_OBYTES: 129c869993eSxy150489 /* 130c869993eSxy150489 * The 64-bit register will reset whenever the upper 131c869993eSxy150489 * 32 bits are read. So we need to read the lower 132c869993eSxy150489 * 32 bits first, then read the upper 32 bits. 133c869993eSxy150489 */ 134c869993eSxy150489 low_val = E1000_READ_REG(hw, E1000_TOTL); 135c869993eSxy150489 high_val = E1000_READ_REG(hw, E1000_TOTH); 13613485e69SGarrett D'Amore igb->stat_tot += (uint64_t)high_val << 32 | (uint64_t)low_val; 13713485e69SGarrett D'Amore *val = igb->stat_tot; 138c869993eSxy150489 break; 139c869993eSxy150489 140c869993eSxy150489 case MAC_STAT_OPACKETS: 14113485e69SGarrett D'Amore igb->stat_tpt += E1000_READ_REG(hw, E1000_TPT); 14213485e69SGarrett D'Amore *val = igb->stat_tpt; 143c869993eSxy150489 break; 144c869993eSxy150489 145c869993eSxy150489 /* RFC 1643 stats */ 146c869993eSxy150489 case ETHER_STAT_ALIGN_ERRORS: 14713485e69SGarrett D'Amore igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC); 14813485e69SGarrett D'Amore *val = igb->stat_algnerrc; 149c869993eSxy150489 break; 150c869993eSxy150489 151c869993eSxy150489 case ETHER_STAT_FCS_ERRORS: 15213485e69SGarrett D'Amore igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS); 15313485e69SGarrett D'Amore *val = igb->stat_crcerrs; 154c869993eSxy150489 break; 155c869993eSxy150489 156c869993eSxy150489 case ETHER_STAT_FIRST_COLLISIONS: 15713485e69SGarrett D'Amore igb->stat_scc += E1000_READ_REG(hw, E1000_SCC); 15813485e69SGarrett D'Amore *val = igb->stat_scc; 159c869993eSxy150489 break; 160c869993eSxy150489 161c869993eSxy150489 case ETHER_STAT_MULTI_COLLISIONS: 16213485e69SGarrett D'Amore igb->stat_mcc += E1000_READ_REG(hw, E1000_MCC); 16313485e69SGarrett D'Amore *val = igb->stat_mcc; 164c869993eSxy150489 break; 165c869993eSxy150489 166c869993eSxy150489 case ETHER_STAT_SQE_ERRORS: 16713485e69SGarrett D'Amore igb->stat_sec += E1000_READ_REG(hw, E1000_SEC); 16813485e69SGarrett D'Amore *val = igb->stat_sec; 169c869993eSxy150489 break; 170c869993eSxy150489 171c869993eSxy150489 case ETHER_STAT_DEFER_XMTS: 17213485e69SGarrett D'Amore igb->stat_dc += E1000_READ_REG(hw, E1000_DC); 17313485e69SGarrett D'Amore *val = igb->stat_dc; 174c869993eSxy150489 break; 175c869993eSxy150489 176c869993eSxy150489 case ETHER_STAT_TX_LATE_COLLISIONS: 17713485e69SGarrett D'Amore igb->stat_latecol += E1000_READ_REG(hw, E1000_LATECOL); 17813485e69SGarrett D'Amore *val = igb->stat_latecol; 179c869993eSxy150489 break; 180c869993eSxy150489 181c869993eSxy150489 case ETHER_STAT_EX_COLLISIONS: 18213485e69SGarrett D'Amore igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 18313485e69SGarrett D'Amore *val = igb->stat_ecol; 184c869993eSxy150489 break; 185c869993eSxy150489 186c869993eSxy150489 case ETHER_STAT_MACXMT_ERRORS: 18713485e69SGarrett D'Amore igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL); 18813485e69SGarrett D'Amore *val = igb->stat_ecol; 189c869993eSxy150489 break; 190c869993eSxy150489 191c869993eSxy150489 case ETHER_STAT_CARRIER_ERRORS: 19213485e69SGarrett D'Amore igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR); 19313485e69SGarrett D'Amore *val = igb->stat_cexterr; 194c869993eSxy150489 break; 195c869993eSxy150489 196c869993eSxy150489 case ETHER_STAT_TOOLONG_ERRORS: 19713485e69SGarrett D'Amore igb->stat_roc += E1000_READ_REG(hw, E1000_ROC); 19813485e69SGarrett D'Amore *val = igb->stat_roc; 199c869993eSxy150489 break; 200c869993eSxy150489 201c869993eSxy150489 case ETHER_STAT_MACRCV_ERRORS: 20213485e69SGarrett D'Amore igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC); 20313485e69SGarrett D'Amore *val = igb->stat_rxerrc; 204c869993eSxy150489 break; 205c869993eSxy150489 206c869993eSxy150489 /* MII/GMII stats */ 207c869993eSxy150489 case ETHER_STAT_XCVR_ADDR: 208c869993eSxy150489 /* The Internal PHY's MDI address for each MAC is 1 */ 209c869993eSxy150489 *val = 1; 210c869993eSxy150489 break; 211c869993eSxy150489 212c869993eSxy150489 case ETHER_STAT_XCVR_ID: 213c869993eSxy150489 *val = hw->phy.id | hw->phy.revision; 214c869993eSxy150489 break; 215c869993eSxy150489 216c869993eSxy150489 case ETHER_STAT_XCVR_INUSE: 217c869993eSxy150489 switch (igb->link_speed) { 218c869993eSxy150489 case SPEED_1000: 219c869993eSxy150489 *val = 220c869993eSxy150489 (hw->phy.media_type == e1000_media_type_copper) ? 221c869993eSxy150489 XCVR_1000T : XCVR_1000X; 222c869993eSxy150489 break; 223c869993eSxy150489 case SPEED_100: 224c869993eSxy150489 *val = 225c869993eSxy150489 (hw->phy.media_type == e1000_media_type_copper) ? 226c869993eSxy150489 (igb->param_100t4_cap == 1) ? 227c869993eSxy150489 XCVR_100T4 : XCVR_100T2 : XCVR_100X; 228c869993eSxy150489 break; 229c869993eSxy150489 case SPEED_10: 230c869993eSxy150489 *val = XCVR_10; 231c869993eSxy150489 break; 232c869993eSxy150489 default: 233c869993eSxy150489 *val = XCVR_NONE; 234c869993eSxy150489 break; 235c869993eSxy150489 } 236c869993eSxy150489 break; 237c869993eSxy150489 238c869993eSxy150489 case ETHER_STAT_CAP_1000FDX: 239c869993eSxy150489 *val = igb->param_1000fdx_cap; 240c869993eSxy150489 break; 241c869993eSxy150489 242c869993eSxy150489 case ETHER_STAT_CAP_1000HDX: 243c869993eSxy150489 *val = igb->param_1000hdx_cap; 244c869993eSxy150489 break; 245c869993eSxy150489 246c869993eSxy150489 case ETHER_STAT_CAP_100FDX: 247c869993eSxy150489 *val = igb->param_100fdx_cap; 248c869993eSxy150489 break; 249c869993eSxy150489 250c869993eSxy150489 case ETHER_STAT_CAP_100HDX: 251c869993eSxy150489 *val = igb->param_100hdx_cap; 252c869993eSxy150489 break; 253c869993eSxy150489 254c869993eSxy150489 case ETHER_STAT_CAP_10FDX: 255c869993eSxy150489 *val = igb->param_10fdx_cap; 256c869993eSxy150489 break; 257c869993eSxy150489 258c869993eSxy150489 case ETHER_STAT_CAP_10HDX: 259c869993eSxy150489 *val = igb->param_10hdx_cap; 260c869993eSxy150489 break; 261c869993eSxy150489 262c869993eSxy150489 case ETHER_STAT_CAP_ASMPAUSE: 263c869993eSxy150489 *val = igb->param_asym_pause_cap; 264c869993eSxy150489 break; 265c869993eSxy150489 266c869993eSxy150489 case ETHER_STAT_CAP_PAUSE: 267c869993eSxy150489 *val = igb->param_pause_cap; 268c869993eSxy150489 break; 269c869993eSxy150489 270c869993eSxy150489 case ETHER_STAT_CAP_AUTONEG: 271c869993eSxy150489 *val = igb->param_autoneg_cap; 272c869993eSxy150489 break; 273c869993eSxy150489 274c869993eSxy150489 case ETHER_STAT_ADV_CAP_1000FDX: 275c869993eSxy150489 *val = igb->param_adv_1000fdx_cap; 276c869993eSxy150489 break; 277c869993eSxy150489 278c869993eSxy150489 case ETHER_STAT_ADV_CAP_1000HDX: 279c869993eSxy150489 *val = igb->param_adv_1000hdx_cap; 280c869993eSxy150489 break; 281c869993eSxy150489 282c869993eSxy150489 case ETHER_STAT_ADV_CAP_100FDX: 283c869993eSxy150489 *val = igb->param_adv_100fdx_cap; 284c869993eSxy150489 break; 285c869993eSxy150489 286c869993eSxy150489 case ETHER_STAT_ADV_CAP_100HDX: 287c869993eSxy150489 *val = igb->param_adv_100hdx_cap; 288c869993eSxy150489 break; 289c869993eSxy150489 290c869993eSxy150489 case ETHER_STAT_ADV_CAP_10FDX: 291c869993eSxy150489 *val = igb->param_adv_10fdx_cap; 292c869993eSxy150489 break; 293c869993eSxy150489 294c869993eSxy150489 case ETHER_STAT_ADV_CAP_10HDX: 295c869993eSxy150489 *val = igb->param_adv_10hdx_cap; 296c869993eSxy150489 break; 297c869993eSxy150489 298c869993eSxy150489 case ETHER_STAT_ADV_CAP_ASMPAUSE: 299c869993eSxy150489 *val = igb->param_adv_asym_pause_cap; 300c869993eSxy150489 break; 301c869993eSxy150489 302c869993eSxy150489 case ETHER_STAT_ADV_CAP_PAUSE: 303c869993eSxy150489 *val = igb->param_adv_pause_cap; 304c869993eSxy150489 break; 305c869993eSxy150489 306c869993eSxy150489 case ETHER_STAT_ADV_CAP_AUTONEG: 307c869993eSxy150489 *val = hw->mac.autoneg; 308c869993eSxy150489 break; 309c869993eSxy150489 310c869993eSxy150489 case ETHER_STAT_LP_CAP_1000FDX: 311c869993eSxy150489 *val = igb->param_lp_1000fdx_cap; 312c869993eSxy150489 break; 313c869993eSxy150489 314c869993eSxy150489 case ETHER_STAT_LP_CAP_1000HDX: 315c869993eSxy150489 *val = igb->param_lp_1000hdx_cap; 316c869993eSxy150489 break; 317c869993eSxy150489 318c869993eSxy150489 case ETHER_STAT_LP_CAP_100FDX: 319c869993eSxy150489 *val = igb->param_lp_100fdx_cap; 320c869993eSxy150489 break; 321c869993eSxy150489 322c869993eSxy150489 case ETHER_STAT_LP_CAP_100HDX: 323c869993eSxy150489 *val = igb->param_lp_100hdx_cap; 324c869993eSxy150489 break; 325c869993eSxy150489 326c869993eSxy150489 case ETHER_STAT_LP_CAP_10FDX: 327c869993eSxy150489 *val = igb->param_lp_10fdx_cap; 328c869993eSxy150489 break; 329c869993eSxy150489 330c869993eSxy150489 case ETHER_STAT_LP_CAP_10HDX: 331c869993eSxy150489 *val = igb->param_lp_10hdx_cap; 332c869993eSxy150489 break; 333c869993eSxy150489 334c869993eSxy150489 case ETHER_STAT_LP_CAP_ASMPAUSE: 335c869993eSxy150489 *val = igb->param_lp_asym_pause_cap; 336c869993eSxy150489 break; 337c869993eSxy150489 338c869993eSxy150489 case ETHER_STAT_LP_CAP_PAUSE: 339c869993eSxy150489 *val = igb->param_lp_pause_cap; 340c869993eSxy150489 break; 341c869993eSxy150489 342c869993eSxy150489 case ETHER_STAT_LP_CAP_AUTONEG: 343c869993eSxy150489 *val = igb->param_lp_autoneg_cap; 344c869993eSxy150489 break; 345c869993eSxy150489 346c869993eSxy150489 case ETHER_STAT_LINK_ASMPAUSE: 347c869993eSxy150489 *val = igb->param_asym_pause_cap; 348c869993eSxy150489 break; 349c869993eSxy150489 350c869993eSxy150489 case ETHER_STAT_LINK_PAUSE: 351c869993eSxy150489 *val = igb->param_pause_cap; 352c869993eSxy150489 break; 353c869993eSxy150489 354c869993eSxy150489 case ETHER_STAT_LINK_AUTONEG: 355c869993eSxy150489 *val = hw->mac.autoneg; 356c869993eSxy150489 break; 357c869993eSxy150489 358c869993eSxy150489 case ETHER_STAT_LINK_DUPLEX: 359c869993eSxy150489 *val = (igb->link_duplex == FULL_DUPLEX) ? 360c869993eSxy150489 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF; 361c869993eSxy150489 break; 362c869993eSxy150489 363c869993eSxy150489 case ETHER_STAT_TOOSHORT_ERRORS: 36413485e69SGarrett D'Amore igb->stat_ruc += E1000_READ_REG(hw, E1000_RUC); 36513485e69SGarrett D'Amore *val = igb->stat_ruc; 366c869993eSxy150489 break; 367c869993eSxy150489 368c869993eSxy150489 case ETHER_STAT_CAP_REMFAULT: 369c869993eSxy150489 *val = igb->param_rem_fault; 370c869993eSxy150489 break; 371c869993eSxy150489 372c869993eSxy150489 case ETHER_STAT_ADV_REMFAULT: 373c869993eSxy150489 *val = igb->param_adv_rem_fault; 374c869993eSxy150489 break; 375c869993eSxy150489 376c869993eSxy150489 case ETHER_STAT_LP_REMFAULT: 377c869993eSxy150489 *val = igb->param_lp_rem_fault; 378c869993eSxy150489 break; 379c869993eSxy150489 380c869993eSxy150489 case ETHER_STAT_JABBER_ERRORS: 38113485e69SGarrett D'Amore igb->stat_rjc += E1000_READ_REG(hw, E1000_RJC); 38213485e69SGarrett D'Amore *val = igb->stat_rjc; 383c869993eSxy150489 break; 384c869993eSxy150489 385c869993eSxy150489 case ETHER_STAT_CAP_100T4: 386c869993eSxy150489 *val = igb->param_100t4_cap; 387c869993eSxy150489 break; 388c869993eSxy150489 389c869993eSxy150489 case ETHER_STAT_ADV_CAP_100T4: 390c869993eSxy150489 *val = igb->param_adv_100t4_cap; 391c869993eSxy150489 break; 392c869993eSxy150489 393c869993eSxy150489 case ETHER_STAT_LP_CAP_100T4: 394c869993eSxy150489 *val = igb->param_lp_100t4_cap; 395c869993eSxy150489 break; 396c869993eSxy150489 397c869993eSxy150489 default: 398c869993eSxy150489 mutex_exit(&igb->gen_lock); 399c869993eSxy150489 return (ENOTSUP); 400c869993eSxy150489 } 401c869993eSxy150489 402c869993eSxy150489 mutex_exit(&igb->gen_lock); 403c869993eSxy150489 404cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 405cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 406cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China return (EIO); 407cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China } 4088bb4b220Sgl147354 409c869993eSxy150489 return (0); 410c869993eSxy150489 } 411c869993eSxy150489 412c869993eSxy150489 /* 413c869993eSxy150489 * Bring the device out of the reset/quiesced state that it 414c869993eSxy150489 * was in when the interface was registered. 415c869993eSxy150489 */ 416c869993eSxy150489 int 417c869993eSxy150489 igb_m_start(void *arg) 418c869993eSxy150489 { 419c869993eSxy150489 igb_t *igb = (igb_t *)arg; 420c869993eSxy150489 421c869993eSxy150489 mutex_enter(&igb->gen_lock); 422c869993eSxy150489 423c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 424c869993eSxy150489 mutex_exit(&igb->gen_lock); 425c869993eSxy150489 return (ECANCELED); 426c869993eSxy150489 } 427c869993eSxy150489 428ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb_start(igb, B_TRUE) != IGB_SUCCESS) { 429c869993eSxy150489 mutex_exit(&igb->gen_lock); 430c869993eSxy150489 return (EIO); 431c869993eSxy150489 } 432c869993eSxy150489 433cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China atomic_or_32(&igb->igb_state, IGB_STARTED); 434c869993eSxy150489 435c869993eSxy150489 mutex_exit(&igb->gen_lock); 436c869993eSxy150489 437c869993eSxy150489 /* 438c869993eSxy150489 * Enable and start the watchdog timer 439c869993eSxy150489 */ 440c869993eSxy150489 igb_enable_watchdog_timer(igb); 441c869993eSxy150489 442c869993eSxy150489 return (0); 443c869993eSxy150489 } 444c869993eSxy150489 445c869993eSxy150489 /* 446c869993eSxy150489 * Stop the device and put it in a reset/quiesced state such 447c869993eSxy150489 * that the interface can be unregistered. 448c869993eSxy150489 */ 449c869993eSxy150489 void 450c869993eSxy150489 igb_m_stop(void *arg) 451c869993eSxy150489 { 452c869993eSxy150489 igb_t *igb = (igb_t *)arg; 453c869993eSxy150489 454c869993eSxy150489 mutex_enter(&igb->gen_lock); 455c869993eSxy150489 456c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 457c869993eSxy150489 mutex_exit(&igb->gen_lock); 458c869993eSxy150489 return; 459c869993eSxy150489 } 460c869993eSxy150489 461cf8dcc9bSzhefeng xu - Sun Microsystems - Beijing China atomic_and_32(&igb->igb_state, ~IGB_STARTED); 462c869993eSxy150489 463ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_stop(igb, B_TRUE); 464c869993eSxy150489 465c869993eSxy150489 mutex_exit(&igb->gen_lock); 466c869993eSxy150489 467c869993eSxy150489 /* 468c869993eSxy150489 * Disable and stop the watchdog timer 469c869993eSxy150489 */ 470c869993eSxy150489 igb_disable_watchdog_timer(igb); 471c869993eSxy150489 } 472c869993eSxy150489 473c869993eSxy150489 /* 474c869993eSxy150489 * Set the promiscuity of the device. 475c869993eSxy150489 */ 476c869993eSxy150489 int 477c869993eSxy150489 igb_m_promisc(void *arg, boolean_t on) 478c869993eSxy150489 { 479c869993eSxy150489 igb_t *igb = (igb_t *)arg; 480c869993eSxy150489 uint32_t reg_val; 481c869993eSxy150489 482c869993eSxy150489 mutex_enter(&igb->gen_lock); 483c869993eSxy150489 484c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 485c869993eSxy150489 mutex_exit(&igb->gen_lock); 486c869993eSxy150489 return (ECANCELED); 487c869993eSxy150489 } 488c869993eSxy150489 489c869993eSxy150489 reg_val = E1000_READ_REG(&igb->hw, E1000_RCTL); 490c869993eSxy150489 491c869993eSxy150489 if (on) 492c869993eSxy150489 reg_val |= (E1000_RCTL_UPE | E1000_RCTL_MPE); 493c869993eSxy150489 else 494c869993eSxy150489 reg_val &= (~(E1000_RCTL_UPE | E1000_RCTL_MPE)); 495c869993eSxy150489 496c869993eSxy150489 E1000_WRITE_REG(&igb->hw, E1000_RCTL, reg_val); 497c869993eSxy150489 498c869993eSxy150489 mutex_exit(&igb->gen_lock); 499c869993eSxy150489 5008bb4b220Sgl147354 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 5018bb4b220Sgl147354 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 5028bb4b220Sgl147354 return (EIO); 5038bb4b220Sgl147354 } 5048bb4b220Sgl147354 505c869993eSxy150489 return (0); 506c869993eSxy150489 } 507c869993eSxy150489 508c869993eSxy150489 /* 509c869993eSxy150489 * Add/remove the addresses to/from the set of multicast 510c869993eSxy150489 * addresses for which the device will receive packets. 511c869993eSxy150489 */ 512c869993eSxy150489 int 513c869993eSxy150489 igb_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr) 514c869993eSxy150489 { 515c869993eSxy150489 igb_t *igb = (igb_t *)arg; 516c869993eSxy150489 int result; 517c869993eSxy150489 518c869993eSxy150489 mutex_enter(&igb->gen_lock); 519c869993eSxy150489 520c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 521c869993eSxy150489 mutex_exit(&igb->gen_lock); 522c869993eSxy150489 return (ECANCELED); 523c869993eSxy150489 } 524c869993eSxy150489 525c869993eSxy150489 result = (add) ? igb_multicst_add(igb, mcst_addr) 526c869993eSxy150489 : igb_multicst_remove(igb, mcst_addr); 527c869993eSxy150489 528c869993eSxy150489 mutex_exit(&igb->gen_lock); 529c869993eSxy150489 530c869993eSxy150489 return (result); 531c869993eSxy150489 } 532c869993eSxy150489 533c869993eSxy150489 /* 534c869993eSxy150489 * Pass on M_IOCTL messages passed to the DLD, and support 535c869993eSxy150489 * private IOCTLs for debugging and ndd. 536c869993eSxy150489 */ 537c869993eSxy150489 void 538c869993eSxy150489 igb_m_ioctl(void *arg, queue_t *q, mblk_t *mp) 539c869993eSxy150489 { 540c869993eSxy150489 igb_t *igb = (igb_t *)arg; 541c869993eSxy150489 struct iocblk *iocp; 542c869993eSxy150489 enum ioc_reply status; 543c869993eSxy150489 544c869993eSxy150489 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr; 545c869993eSxy150489 iocp->ioc_error = 0; 546c869993eSxy150489 547ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_enter(&igb->gen_lock); 548ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb->igb_state & IGB_SUSPENDED) { 549ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_exit(&igb->gen_lock); 550ac7f5757Schenlu chen - Sun Microsystems - Beijing China miocnak(q, mp, 0, EINVAL); 551ac7f5757Schenlu chen - Sun Microsystems - Beijing China return; 552ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 553ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_exit(&igb->gen_lock); 554ac7f5757Schenlu chen - Sun Microsystems - Beijing China 555c869993eSxy150489 switch (iocp->ioc_cmd) { 556c869993eSxy150489 case LB_GET_INFO_SIZE: 557c869993eSxy150489 case LB_GET_INFO: 558c869993eSxy150489 case LB_GET_MODE: 559c869993eSxy150489 case LB_SET_MODE: 560c869993eSxy150489 status = igb_loopback_ioctl(igb, iocp, mp); 561c869993eSxy150489 break; 562c869993eSxy150489 563c869993eSxy150489 default: 564c869993eSxy150489 status = IOC_INVAL; 565c869993eSxy150489 break; 566c869993eSxy150489 } 567c869993eSxy150489 568c869993eSxy150489 /* 569c869993eSxy150489 * Decide how to reply 570c869993eSxy150489 */ 571c869993eSxy150489 switch (status) { 572c869993eSxy150489 default: 573c869993eSxy150489 case IOC_INVAL: 574c869993eSxy150489 /* 575c869993eSxy150489 * Error, reply with a NAK and EINVAL or the specified error 576c869993eSxy150489 */ 577c869993eSxy150489 miocnak(q, mp, 0, iocp->ioc_error == 0 ? 578c869993eSxy150489 EINVAL : iocp->ioc_error); 579c869993eSxy150489 break; 580c869993eSxy150489 581c869993eSxy150489 case IOC_DONE: 582c869993eSxy150489 /* 583c869993eSxy150489 * OK, reply already sent 584c869993eSxy150489 */ 585c869993eSxy150489 break; 586c869993eSxy150489 587c869993eSxy150489 case IOC_ACK: 588c869993eSxy150489 /* 589c869993eSxy150489 * OK, reply with an ACK 590c869993eSxy150489 */ 591c869993eSxy150489 miocack(q, mp, 0, 0); 592c869993eSxy150489 break; 593c869993eSxy150489 594c869993eSxy150489 case IOC_REPLY: 595c869993eSxy150489 /* 596c869993eSxy150489 * OK, send prepared reply as ACK or NAK 597c869993eSxy150489 */ 598c869993eSxy150489 mp->b_datap->db_type = iocp->ioc_error == 0 ? 599c869993eSxy150489 M_IOCACK : M_IOCNAK; 600c869993eSxy150489 qreply(q, mp); 601c869993eSxy150489 break; 602c869993eSxy150489 } 603c869993eSxy150489 } 604c869993eSxy150489 605c869993eSxy150489 /* 606da14cebeSEric Cheng * Add a MAC address to the target RX group. 607c869993eSxy150489 */ 608da14cebeSEric Cheng static int 609da14cebeSEric Cheng igb_addmac(void *arg, const uint8_t *mac_addr) 610c869993eSxy150489 { 611da14cebeSEric Cheng igb_rx_group_t *rx_group = (igb_rx_group_t *)arg; 612da14cebeSEric Cheng igb_t *igb = rx_group->igb; 613da14cebeSEric Cheng struct e1000_hw *hw = &igb->hw; 614da14cebeSEric Cheng int i, slot; 615c869993eSxy150489 616c869993eSxy150489 mutex_enter(&igb->gen_lock); 617c869993eSxy150489 618c869993eSxy150489 if (igb->igb_state & IGB_SUSPENDED) { 619c869993eSxy150489 mutex_exit(&igb->gen_lock); 620c869993eSxy150489 return (ECANCELED); 621c869993eSxy150489 } 622c869993eSxy150489 623c869993eSxy150489 if (igb->unicst_avail == 0) { 624c869993eSxy150489 /* no slots available */ 625c869993eSxy150489 mutex_exit(&igb->gen_lock); 626c869993eSxy150489 return (ENOSPC); 627c869993eSxy150489 } 628c869993eSxy150489 629c869993eSxy150489 /* 630da14cebeSEric Cheng * The slots from 0 to igb->num_rx_groups are reserved slots which 631da14cebeSEric Cheng * are 1 to 1 mapped with group index directly. The other slots are 632da14cebeSEric Cheng * shared between the all of groups. While adding a MAC address, 633da14cebeSEric Cheng * it will try to set the reserved slots first, then the shared slots. 634c869993eSxy150489 */ 635da14cebeSEric Cheng slot = -1; 636da14cebeSEric Cheng if (igb->unicst_addr[rx_group->index].mac.set == 1) { 637da14cebeSEric Cheng /* 638da14cebeSEric Cheng * The reserved slot for current group is used, find the free 639da14cebeSEric Cheng * slots in the shared slots. 640da14cebeSEric Cheng */ 641da14cebeSEric Cheng for (i = igb->num_rx_groups; i < igb->unicst_total; i++) { 642da14cebeSEric Cheng if (igb->unicst_addr[i].mac.set == 0) { 643da14cebeSEric Cheng slot = i; 644c869993eSxy150489 break; 645c869993eSxy150489 } 646da14cebeSEric Cheng } 647da14cebeSEric Cheng } else 648da14cebeSEric Cheng slot = rx_group->index; 649c869993eSxy150489 650da14cebeSEric Cheng if (slot == -1) { 651da14cebeSEric Cheng /* no slots available in the shared slots */ 652da14cebeSEric Cheng mutex_exit(&igb->gen_lock); 653da14cebeSEric Cheng return (ENOSPC); 654da14cebeSEric Cheng } 655c869993eSxy150489 656da14cebeSEric Cheng /* Set VMDq according to the mode supported by hardware. */ 657da14cebeSEric Cheng e1000_rar_set_vmdq(hw, mac_addr, slot, igb->vmdq_mode, rx_group->index); 658c869993eSxy150489 659da14cebeSEric Cheng bcopy(mac_addr, igb->unicst_addr[slot].mac.addr, ETHERADDRL); 660da14cebeSEric Cheng igb->unicst_addr[slot].mac.group_index = rx_group->index; 661fa25784cSxy150489 igb->unicst_addr[slot].mac.set = 1; 662fa25784cSxy150489 igb->unicst_avail--; 663c869993eSxy150489 664fa25784cSxy150489 mutex_exit(&igb->gen_lock); 665fa25784cSxy150489 666c869993eSxy150489 return (0); 667c869993eSxy150489 } 668c869993eSxy150489 669c869993eSxy150489 /* 670da14cebeSEric Cheng * Remove a MAC address from the specified RX group. 671da14cebeSEric Cheng */ 672da14cebeSEric Cheng static int 673da14cebeSEric Cheng igb_remmac(void *arg, const uint8_t *mac_addr) 674da14cebeSEric Cheng { 675da14cebeSEric Cheng igb_rx_group_t *rx_group = (igb_rx_group_t *)arg; 676da14cebeSEric Cheng igb_t *igb = rx_group->igb; 677da14cebeSEric Cheng struct e1000_hw *hw = &igb->hw; 678da14cebeSEric Cheng int slot; 679da14cebeSEric Cheng 680da14cebeSEric Cheng mutex_enter(&igb->gen_lock); 681da14cebeSEric Cheng 682da14cebeSEric Cheng if (igb->igb_state & IGB_SUSPENDED) { 683da14cebeSEric Cheng mutex_exit(&igb->gen_lock); 684da14cebeSEric Cheng return (ECANCELED); 685da14cebeSEric Cheng } 686da14cebeSEric Cheng 687da14cebeSEric Cheng slot = igb_unicst_find(igb, mac_addr); 688da14cebeSEric Cheng if (slot == -1) { 689da14cebeSEric Cheng mutex_exit(&igb->gen_lock); 690da14cebeSEric Cheng return (EINVAL); 691da14cebeSEric Cheng } 692da14cebeSEric Cheng 693da14cebeSEric Cheng if (igb->unicst_addr[slot].mac.set == 0) { 694da14cebeSEric Cheng mutex_exit(&igb->gen_lock); 695da14cebeSEric Cheng return (EINVAL); 696da14cebeSEric Cheng } 697da14cebeSEric Cheng 698da14cebeSEric Cheng /* Clear the MAC ddress in the slot */ 699da14cebeSEric Cheng e1000_rar_clear(hw, slot); 700da14cebeSEric Cheng igb->unicst_addr[slot].mac.set = 0; 701da14cebeSEric Cheng igb->unicst_avail++; 702da14cebeSEric Cheng 703da14cebeSEric Cheng mutex_exit(&igb->gen_lock); 704da14cebeSEric Cheng 705da14cebeSEric Cheng return (0); 706da14cebeSEric Cheng } 707da14cebeSEric Cheng 708da14cebeSEric Cheng /* 709da14cebeSEric Cheng * Enable interrupt on the specificed rx ring. 710da14cebeSEric Cheng */ 711da14cebeSEric Cheng int 712da14cebeSEric Cheng igb_rx_ring_intr_enable(mac_intr_handle_t intrh) 713da14cebeSEric Cheng { 714da14cebeSEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh; 715da14cebeSEric Cheng igb_t *igb = rx_ring->igb; 716da14cebeSEric Cheng struct e1000_hw *hw = &igb->hw; 717da14cebeSEric Cheng uint32_t index = rx_ring->index; 718da14cebeSEric Cheng 719da14cebeSEric Cheng if (igb->intr_type == DDI_INTR_TYPE_MSIX) { 720da14cebeSEric Cheng /* Interrupt enabling for MSI-X */ 721da14cebeSEric Cheng igb->eims_mask |= (E1000_EICR_RX_QUEUE0 << index); 722da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask); 723da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask); 724da14cebeSEric Cheng } else { 725da14cebeSEric Cheng ASSERT(index == 0); 726da14cebeSEric Cheng /* Interrupt enabling for MSI and legacy */ 727da14cebeSEric Cheng igb->ims_mask |= E1000_IMS_RXT0; 728da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_IMS, igb->ims_mask); 729da14cebeSEric Cheng } 730da14cebeSEric Cheng 731da14cebeSEric Cheng E1000_WRITE_FLUSH(hw); 732da14cebeSEric Cheng 733da14cebeSEric Cheng return (0); 734da14cebeSEric Cheng } 735da14cebeSEric Cheng 736da14cebeSEric Cheng /* 737da14cebeSEric Cheng * Disable interrupt on the specificed rx ring. 738da14cebeSEric Cheng */ 739da14cebeSEric Cheng int 740da14cebeSEric Cheng igb_rx_ring_intr_disable(mac_intr_handle_t intrh) 741da14cebeSEric Cheng { 742da14cebeSEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh; 743da14cebeSEric Cheng igb_t *igb = rx_ring->igb; 744da14cebeSEric Cheng struct e1000_hw *hw = &igb->hw; 745da14cebeSEric Cheng uint32_t index = rx_ring->index; 746da14cebeSEric Cheng 747da14cebeSEric Cheng if (igb->intr_type == DDI_INTR_TYPE_MSIX) { 748da14cebeSEric Cheng /* Interrupt disabling for MSI-X */ 749da14cebeSEric Cheng igb->eims_mask &= ~(E1000_EICR_RX_QUEUE0 << index); 750da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_EIMC, 751da14cebeSEric Cheng (E1000_EICR_RX_QUEUE0 << index)); 752da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask); 753da14cebeSEric Cheng } else { 754da14cebeSEric Cheng ASSERT(index == 0); 755da14cebeSEric Cheng /* Interrupt disabling for MSI and legacy */ 756da14cebeSEric Cheng igb->ims_mask &= ~E1000_IMS_RXT0; 757da14cebeSEric Cheng E1000_WRITE_REG(hw, E1000_IMC, E1000_IMS_RXT0); 758da14cebeSEric Cheng } 759da14cebeSEric Cheng 760da14cebeSEric Cheng E1000_WRITE_FLUSH(hw); 761da14cebeSEric Cheng 762da14cebeSEric Cheng return (0); 763da14cebeSEric Cheng } 764da14cebeSEric Cheng 765da14cebeSEric Cheng /* 766da14cebeSEric Cheng * Get the global ring index by a ring index within a group. 767da14cebeSEric Cheng */ 768da14cebeSEric Cheng int 769da14cebeSEric Cheng igb_get_rx_ring_index(igb_t *igb, int gindex, int rindex) 770da14cebeSEric Cheng { 771da14cebeSEric Cheng igb_rx_ring_t *rx_ring; 772da14cebeSEric Cheng int i; 773da14cebeSEric Cheng 774da14cebeSEric Cheng for (i = 0; i < igb->num_rx_rings; i++) { 775da14cebeSEric Cheng rx_ring = &igb->rx_rings[i]; 776da14cebeSEric Cheng if (rx_ring->group_index == gindex) 777da14cebeSEric Cheng rindex--; 778da14cebeSEric Cheng if (rindex < 0) 779da14cebeSEric Cheng return (i); 780da14cebeSEric Cheng } 781da14cebeSEric Cheng 782da14cebeSEric Cheng return (-1); 783da14cebeSEric Cheng } 784da14cebeSEric Cheng 785da14cebeSEric Cheng static int 786da14cebeSEric Cheng igb_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num) 787da14cebeSEric Cheng { 788da14cebeSEric Cheng igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)rh; 789da14cebeSEric Cheng 790da14cebeSEric Cheng mutex_enter(&rx_ring->rx_lock); 791da14cebeSEric Cheng rx_ring->ring_gen_num = mr_gen_num; 792da14cebeSEric Cheng mutex_exit(&rx_ring->rx_lock); 793da14cebeSEric Cheng return (0); 794da14cebeSEric Cheng } 795da14cebeSEric Cheng 796da14cebeSEric Cheng /* 797da14cebeSEric Cheng * Callback funtion for MAC layer to register all rings. 798da14cebeSEric Cheng */ 799da14cebeSEric Cheng /* ARGSUSED */ 800da14cebeSEric Cheng void 801da14cebeSEric Cheng igb_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index, 802da14cebeSEric Cheng const int index, mac_ring_info_t *infop, mac_ring_handle_t rh) 803da14cebeSEric Cheng { 804da14cebeSEric Cheng igb_t *igb = (igb_t *)arg; 805da14cebeSEric Cheng mac_intr_t *mintr = &infop->mri_intr; 806da14cebeSEric Cheng 807da14cebeSEric Cheng switch (rtype) { 808da14cebeSEric Cheng case MAC_RING_TYPE_RX: { 809da14cebeSEric Cheng igb_rx_ring_t *rx_ring; 810da14cebeSEric Cheng int global_index; 811da14cebeSEric Cheng 812da14cebeSEric Cheng /* 813da14cebeSEric Cheng * 'index' is the ring index within the group. 814da14cebeSEric Cheng * We need the global ring index by searching in group. 815da14cebeSEric Cheng */ 816da14cebeSEric Cheng global_index = igb_get_rx_ring_index(igb, rg_index, index); 817da14cebeSEric Cheng 818da14cebeSEric Cheng ASSERT(global_index >= 0); 819da14cebeSEric Cheng 820da14cebeSEric Cheng rx_ring = &igb->rx_rings[global_index]; 821da14cebeSEric Cheng rx_ring->ring_handle = rh; 822da14cebeSEric Cheng 823da14cebeSEric Cheng infop->mri_driver = (mac_ring_driver_t)rx_ring; 824da14cebeSEric Cheng infop->mri_start = igb_ring_start; 825da14cebeSEric Cheng infop->mri_stop = NULL; 826da14cebeSEric Cheng infop->mri_poll = (mac_ring_poll_t)igb_rx_ring_poll; 8270dc2366fSVenugopal Iyer infop->mri_stat = igb_rx_ring_stat; 828da14cebeSEric Cheng 829da14cebeSEric Cheng mintr->mi_handle = (mac_intr_handle_t)rx_ring; 830da14cebeSEric Cheng mintr->mi_enable = igb_rx_ring_intr_enable; 831da14cebeSEric Cheng mintr->mi_disable = igb_rx_ring_intr_disable; 8320dc2366fSVenugopal Iyer if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 8330dc2366fSVenugopal Iyer mintr->mi_ddi_handle = 8340dc2366fSVenugopal Iyer igb->htable[rx_ring->intr_vector]; 8350dc2366fSVenugopal Iyer } 836da14cebeSEric Cheng break; 837da14cebeSEric Cheng } 838da14cebeSEric Cheng case MAC_RING_TYPE_TX: { 839da14cebeSEric Cheng ASSERT(index < igb->num_tx_rings); 840da14cebeSEric Cheng 841da14cebeSEric Cheng igb_tx_ring_t *tx_ring = &igb->tx_rings[index]; 842da14cebeSEric Cheng tx_ring->ring_handle = rh; 843da14cebeSEric Cheng 844da14cebeSEric Cheng infop->mri_driver = (mac_ring_driver_t)tx_ring; 845da14cebeSEric Cheng infop->mri_start = NULL; 846da14cebeSEric Cheng infop->mri_stop = NULL; 847da14cebeSEric Cheng infop->mri_tx = igb_tx_ring_send; 8480dc2366fSVenugopal Iyer infop->mri_stat = igb_tx_ring_stat; 8490dc2366fSVenugopal Iyer if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) { 8500dc2366fSVenugopal Iyer mintr->mi_ddi_handle = 8510dc2366fSVenugopal Iyer igb->htable[tx_ring->intr_vector]; 8520dc2366fSVenugopal Iyer } 853da14cebeSEric Cheng break; 854da14cebeSEric Cheng } 855da14cebeSEric Cheng default: 856da14cebeSEric Cheng break; 857da14cebeSEric Cheng } 858da14cebeSEric Cheng } 859da14cebeSEric Cheng 860da14cebeSEric Cheng void 861da14cebeSEric Cheng igb_fill_group(void *arg, mac_ring_type_t rtype, const int index, 862da14cebeSEric Cheng mac_group_info_t *infop, mac_group_handle_t gh) 863da14cebeSEric Cheng { 864da14cebeSEric Cheng igb_t *igb = (igb_t *)arg; 865da14cebeSEric Cheng 866da14cebeSEric Cheng switch (rtype) { 867da14cebeSEric Cheng case MAC_RING_TYPE_RX: { 868da14cebeSEric Cheng igb_rx_group_t *rx_group; 869da14cebeSEric Cheng 870da14cebeSEric Cheng ASSERT((index >= 0) && (index < igb->num_rx_groups)); 871da14cebeSEric Cheng 872da14cebeSEric Cheng rx_group = &igb->rx_groups[index]; 873da14cebeSEric Cheng rx_group->group_handle = gh; 874da14cebeSEric Cheng 875da14cebeSEric Cheng infop->mgi_driver = (mac_group_driver_t)rx_group; 876da14cebeSEric Cheng infop->mgi_start = NULL; 877da14cebeSEric Cheng infop->mgi_stop = NULL; 878da14cebeSEric Cheng infop->mgi_addmac = igb_addmac; 879da14cebeSEric Cheng infop->mgi_remmac = igb_remmac; 880da14cebeSEric Cheng infop->mgi_count = (igb->num_rx_rings / igb->num_rx_groups); 881da14cebeSEric Cheng 882da14cebeSEric Cheng break; 883da14cebeSEric Cheng } 884da14cebeSEric Cheng case MAC_RING_TYPE_TX: 885da14cebeSEric Cheng break; 886da14cebeSEric Cheng default: 887da14cebeSEric Cheng break; 888da14cebeSEric Cheng } 889da14cebeSEric Cheng } 890da14cebeSEric Cheng 891*b142f83dSRobert Mustacchi static int 892*b142f83dSRobert Mustacchi igb_led_set(void *arg, mac_led_mode_t mode, uint_t flags) 893*b142f83dSRobert Mustacchi { 894*b142f83dSRobert Mustacchi igb_t *igb = arg; 895*b142f83dSRobert Mustacchi 896*b142f83dSRobert Mustacchi if (flags != 0) 897*b142f83dSRobert Mustacchi return (EINVAL); 898*b142f83dSRobert Mustacchi 899*b142f83dSRobert Mustacchi if (mode != MAC_LED_DEFAULT && 900*b142f83dSRobert Mustacchi mode != MAC_LED_IDENT && 901*b142f83dSRobert Mustacchi mode != MAC_LED_OFF && 902*b142f83dSRobert Mustacchi mode != MAC_LED_ON) 903*b142f83dSRobert Mustacchi return (ENOTSUP); 904*b142f83dSRobert Mustacchi 905*b142f83dSRobert Mustacchi if (mode != MAC_LED_DEFAULT && !igb->igb_led_setup) { 906*b142f83dSRobert Mustacchi if (e1000_setup_led(&igb->hw) != E1000_SUCCESS) 907*b142f83dSRobert Mustacchi return (EIO); 908*b142f83dSRobert Mustacchi 909*b142f83dSRobert Mustacchi igb->igb_led_setup = B_TRUE; 910*b142f83dSRobert Mustacchi } 911*b142f83dSRobert Mustacchi 912*b142f83dSRobert Mustacchi switch (mode) { 913*b142f83dSRobert Mustacchi case MAC_LED_DEFAULT: 914*b142f83dSRobert Mustacchi if (igb->igb_led_setup) { 915*b142f83dSRobert Mustacchi if (e1000_cleanup_led(&igb->hw) != E1000_SUCCESS) 916*b142f83dSRobert Mustacchi return (EIO); 917*b142f83dSRobert Mustacchi igb->igb_led_setup = B_FALSE; 918*b142f83dSRobert Mustacchi } 919*b142f83dSRobert Mustacchi break; 920*b142f83dSRobert Mustacchi case MAC_LED_IDENT: 921*b142f83dSRobert Mustacchi if (e1000_blink_led(&igb->hw) != E1000_SUCCESS) 922*b142f83dSRobert Mustacchi return (EIO); 923*b142f83dSRobert Mustacchi break; 924*b142f83dSRobert Mustacchi case MAC_LED_OFF: 925*b142f83dSRobert Mustacchi if (e1000_led_off(&igb->hw) != E1000_SUCCESS) 926*b142f83dSRobert Mustacchi return (EIO); 927*b142f83dSRobert Mustacchi break; 928*b142f83dSRobert Mustacchi case MAC_LED_ON: 929*b142f83dSRobert Mustacchi if (e1000_led_on(&igb->hw) != E1000_SUCCESS) 930*b142f83dSRobert Mustacchi return (EIO); 931*b142f83dSRobert Mustacchi break; 932*b142f83dSRobert Mustacchi default: 933*b142f83dSRobert Mustacchi return (ENOTSUP); 934*b142f83dSRobert Mustacchi } 935*b142f83dSRobert Mustacchi 936*b142f83dSRobert Mustacchi return (0); 937*b142f83dSRobert Mustacchi } 938*b142f83dSRobert Mustacchi 939da14cebeSEric Cheng /* 940c869993eSxy150489 * Obtain the MAC's capabilities and associated data from 941c869993eSxy150489 * the driver. 942c869993eSxy150489 */ 943c869993eSxy150489 boolean_t 944c869993eSxy150489 igb_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) 945c869993eSxy150489 { 946c869993eSxy150489 igb_t *igb = (igb_t *)arg; 947c869993eSxy150489 948c869993eSxy150489 switch (cap) { 949c869993eSxy150489 case MAC_CAPAB_HCKSUM: { 950c869993eSxy150489 uint32_t *tx_hcksum_flags = cap_data; 951c869993eSxy150489 952c869993eSxy150489 /* 953c869993eSxy150489 * We advertise our capabilities only if tx hcksum offload is 954c869993eSxy150489 * enabled. On receive, the stack will accept checksummed 955c869993eSxy150489 * packets anyway, even if we haven't said we can deliver 956c869993eSxy150489 * them. 957c869993eSxy150489 */ 958c869993eSxy150489 if (!igb->tx_hcksum_enable) 959c869993eSxy150489 return (B_FALSE); 960c869993eSxy150489 961c869993eSxy150489 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM; 962c869993eSxy150489 break; 963c869993eSxy150489 } 964d11274aaSPaul Guo case MAC_CAPAB_LSO: { 965d11274aaSPaul Guo mac_capab_lso_t *cap_lso = cap_data; 966d11274aaSPaul Guo 967d11274aaSPaul Guo if (igb->lso_enable) { 968d11274aaSPaul Guo cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; 969d11274aaSPaul Guo cap_lso->lso_basic_tcp_ipv4.lso_max = IGB_LSO_MAXLEN; 970d11274aaSPaul Guo break; 971d11274aaSPaul Guo } else { 972d11274aaSPaul Guo return (B_FALSE); 973d11274aaSPaul Guo } 974d11274aaSPaul Guo } 975da14cebeSEric Cheng case MAC_CAPAB_RINGS: { 976da14cebeSEric Cheng mac_capab_rings_t *cap_rings = cap_data; 977c869993eSxy150489 978da14cebeSEric Cheng switch (cap_rings->mr_type) { 979da14cebeSEric Cheng case MAC_RING_TYPE_RX: 980da14cebeSEric Cheng cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 981da14cebeSEric Cheng cap_rings->mr_rnum = igb->num_rx_rings; 982da14cebeSEric Cheng cap_rings->mr_gnum = igb->num_rx_groups; 983da14cebeSEric Cheng cap_rings->mr_rget = igb_fill_ring; 984da14cebeSEric Cheng cap_rings->mr_gget = igb_fill_group; 985da14cebeSEric Cheng cap_rings->mr_gaddring = NULL; 986da14cebeSEric Cheng cap_rings->mr_gremring = NULL; 987da14cebeSEric Cheng 988da14cebeSEric Cheng break; 989da14cebeSEric Cheng case MAC_RING_TYPE_TX: 990da14cebeSEric Cheng cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC; 991da14cebeSEric Cheng cap_rings->mr_rnum = igb->num_tx_rings; 992da14cebeSEric Cheng cap_rings->mr_gnum = 0; 993da14cebeSEric Cheng cap_rings->mr_rget = igb_fill_ring; 994da14cebeSEric Cheng cap_rings->mr_gget = NULL; 995da14cebeSEric Cheng 996da14cebeSEric Cheng break; 997da14cebeSEric Cheng default: 998c869993eSxy150489 break; 999c869993eSxy150489 } 1000da14cebeSEric Cheng break; 1001da14cebeSEric Cheng } 1002da14cebeSEric Cheng 1003*b142f83dSRobert Mustacchi case MAC_CAPAB_LED: { 1004*b142f83dSRobert Mustacchi mac_capab_led_t *cap_led = cap_data; 1005*b142f83dSRobert Mustacchi 1006*b142f83dSRobert Mustacchi cap_led->mcl_flags = 0; 1007*b142f83dSRobert Mustacchi cap_led->mcl_modes = MAC_LED_DEFAULT; 1008*b142f83dSRobert Mustacchi if (igb->hw.mac.ops.blink_led != NULL && 1009*b142f83dSRobert Mustacchi igb->hw.mac.ops.blink_led != e1000_null_ops_generic) { 1010*b142f83dSRobert Mustacchi cap_led->mcl_modes |= MAC_LED_IDENT; 1011*b142f83dSRobert Mustacchi } 1012*b142f83dSRobert Mustacchi if (igb->hw.mac.ops.led_off != NULL && 1013*b142f83dSRobert Mustacchi igb->hw.mac.ops.led_off != e1000_null_ops_generic) { 1014*b142f83dSRobert Mustacchi cap_led->mcl_modes |= MAC_LED_OFF; 1015*b142f83dSRobert Mustacchi } 1016*b142f83dSRobert Mustacchi if (igb->hw.mac.ops.led_on != NULL && 1017*b142f83dSRobert Mustacchi igb->hw.mac.ops.led_on != e1000_null_ops_generic) { 1018*b142f83dSRobert Mustacchi cap_led->mcl_modes |= MAC_LED_ON; 1019*b142f83dSRobert Mustacchi } 1020*b142f83dSRobert Mustacchi cap_led->mcl_set = igb_led_set; 1021*b142f83dSRobert Mustacchi break; 1022*b142f83dSRobert Mustacchi } 1023*b142f83dSRobert Mustacchi 1024c869993eSxy150489 default: 1025c869993eSxy150489 return (B_FALSE); 1026c869993eSxy150489 } 1027c869993eSxy150489 return (B_TRUE); 1028c869993eSxy150489 } 1029ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1030ac7f5757Schenlu chen - Sun Microsystems - Beijing China int 1031ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 1032ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint_t pr_valsize, const void *pr_val) 1033ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 1034ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_t *igb = (igb_t *)arg; 1035ac7f5757Schenlu chen - Sun Microsystems - Beijing China struct e1000_hw *hw = &igb->hw; 1036ac7f5757Schenlu chen - Sun Microsystems - Beijing China int err = 0; 1037ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint32_t flow_control; 1038ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint32_t cur_mtu, new_mtu; 1039ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint32_t rx_size; 1040ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint32_t tx_size; 1041ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1042ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_enter(&igb->gen_lock); 1043ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb->igb_state & IGB_SUSPENDED) { 1044ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_exit(&igb->gen_lock); 1045ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (ECANCELED); 1046ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1047ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1048ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb->loopback_mode != IGB_LB_NONE && igb_param_locked(pr_num)) { 1049ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* 1050ac7f5757Schenlu chen - Sun Microsystems - Beijing China * All en_* parameters are locked (read-only) 1051ac7f5757Schenlu chen - Sun Microsystems - Beijing China * while the device is in any sort of loopback mode. 1052ac7f5757Schenlu chen - Sun Microsystems - Beijing China */ 1053ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_exit(&igb->gen_lock); 1054ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (EBUSY); 1055ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1056ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1057ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (pr_num) { 1058ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000FDX_CAP: 1059ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* read/write on copper, read-only on serdes */ 1060ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1061ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1062ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1063ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1064ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_en_1000fdx_cap = *(uint8_t *)pr_val; 1065ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_1000fdx_cap = *(uint8_t *)pr_val; 1066ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1067ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100FDX_CAP: 1068ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1069ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1070ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1071ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1072ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_en_100fdx_cap = *(uint8_t *)pr_val; 1073ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_100fdx_cap = *(uint8_t *)pr_val; 1074ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1075ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100HDX_CAP: 1076ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1077ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1078ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1079ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1080ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_en_100hdx_cap = *(uint8_t *)pr_val; 1081ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_100hdx_cap = *(uint8_t *)pr_val; 1082ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1083ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10FDX_CAP: 1084ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1085ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1086ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1087ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1088ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_en_10fdx_cap = *(uint8_t *)pr_val; 1089ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_10fdx_cap = *(uint8_t *)pr_val; 1090ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1091ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10HDX_CAP: 1092ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1093ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1094ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1095ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1096ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_en_10hdx_cap = *(uint8_t *)pr_val; 1097ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_10hdx_cap = *(uint8_t *)pr_val; 1098ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1099ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_AUTONEG: 1100ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 1101ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; 1102ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1103ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1104ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->param_adv_autoneg_cap = *(uint8_t *)pr_val; 1105ac7f5757Schenlu chen - Sun Microsystems - Beijing China goto setup_link; 1106ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_FLOWCTRL: 1107ac7f5757Schenlu chen - Sun Microsystems - Beijing China bcopy(pr_val, &flow_control, sizeof (flow_control)); 1108ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1109ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (flow_control) { 1110ac7f5757Schenlu chen - Sun Microsystems - Beijing China default: 1111ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1112ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1113ac7f5757Schenlu chen - Sun Microsystems - Beijing China case LINK_FLOWCTRL_NONE: 1114ac7f5757Schenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = e1000_fc_none; 1115ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1116ac7f5757Schenlu chen - Sun Microsystems - Beijing China case LINK_FLOWCTRL_RX: 1117ac7f5757Schenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = e1000_fc_rx_pause; 1118ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1119ac7f5757Schenlu chen - Sun Microsystems - Beijing China case LINK_FLOWCTRL_TX: 1120ac7f5757Schenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = e1000_fc_tx_pause; 1121ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1122ac7f5757Schenlu chen - Sun Microsystems - Beijing China case LINK_FLOWCTRL_BI: 1123ac7f5757Schenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = e1000_fc_full; 1124ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1125ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1126ac7f5757Schenlu chen - Sun Microsystems - Beijing China setup_link: 1127ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (err == 0) { 1128ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb_setup_link(igb, B_TRUE) != IGB_SUCCESS) 1129ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1130ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1131ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1132ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000FDX_CAP: 1133ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000HDX_CAP: 1134ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100T4_CAP: 1135ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100FDX_CAP: 1136ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100HDX_CAP: 1137ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10FDX_CAP: 1138ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10HDX_CAP: 1139ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000HDX_CAP: 1140ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100T4_CAP: 1141ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_STATUS: 1142ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_SPEED: 1143ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_DUPLEX: 1144ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = ENOTSUP; /* read-only prop. Can't set this. */ 1145ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1146ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_MTU: 1147ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* adapter must be stopped for an MTU change */ 1148ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb->igb_state & IGB_STARTED) { 1149ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EBUSY; 1150ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1151ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1152ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1153ac7f5757Schenlu chen - Sun Microsystems - Beijing China cur_mtu = igb->default_mtu; 1154ac7f5757Schenlu chen - Sun Microsystems - Beijing China bcopy(pr_val, &new_mtu, sizeof (new_mtu)); 1155ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (new_mtu == cur_mtu) { 1156ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = 0; 1157ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1158ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1159ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1160ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) { 1161ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1162ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1163ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1164ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1165ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = mac_maxsdu_update(igb->mac_hdl, new_mtu); 1166ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (err == 0) { 1167ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->default_mtu = new_mtu; 1168ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->max_frame_size = igb->default_mtu + 1169ac7f5757Schenlu chen - Sun Microsystems - Beijing China sizeof (struct ether_vlan_header) + ETHERFCSL; 1170ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1171ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* 1172ac7f5757Schenlu chen - Sun Microsystems - Beijing China * Set rx buffer size 1173ac7f5757Schenlu chen - Sun Microsystems - Beijing China */ 1174ac7f5757Schenlu chen - Sun Microsystems - Beijing China rx_size = igb->max_frame_size + IPHDR_ALIGN_ROOM; 1175ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->rx_buf_size = ((rx_size >> 10) + ((rx_size & 1176ac7f5757Schenlu chen - Sun Microsystems - Beijing China (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 1177ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1178ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* 1179ac7f5757Schenlu chen - Sun Microsystems - Beijing China * Set tx buffer size 1180ac7f5757Schenlu chen - Sun Microsystems - Beijing China */ 1181ac7f5757Schenlu chen - Sun Microsystems - Beijing China tx_size = igb->max_frame_size; 1182ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->tx_buf_size = ((tx_size >> 10) + ((tx_size & 1183ac7f5757Schenlu chen - Sun Microsystems - Beijing China (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10; 1184ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1185ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1186ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_PRIVATE: 1187ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = igb_set_priv_prop(igb, pr_name, pr_valsize, pr_val); 1188ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1189ac7f5757Schenlu chen - Sun Microsystems - Beijing China default: 1190238d8f47SDale Ghent err = ENOTSUP; 1191ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1192ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1193ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1194ac7f5757Schenlu chen - Sun Microsystems - Beijing China mutex_exit(&igb->gen_lock); 1195ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1196ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) { 1197ac7f5757Schenlu chen - Sun Microsystems - Beijing China ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED); 1198ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (EIO); 1199ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1200ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1201ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1202ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1203ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1204ac7f5757Schenlu chen - Sun Microsystems - Beijing China int 1205ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num, 12060dc2366fSVenugopal Iyer uint_t pr_valsize, void *pr_val) 1207ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 1208ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_t *igb = (igb_t *)arg; 1209ac7f5757Schenlu chen - Sun Microsystems - Beijing China struct e1000_hw *hw = &igb->hw; 1210ac7f5757Schenlu chen - Sun Microsystems - Beijing China int err = 0; 1211ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint32_t flow_control; 1212ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint64_t tmp = 0; 1213ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1214ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (pr_num) { 1215ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_DUPLEX: 12160dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (link_duplex_t)); 12170dc2366fSVenugopal Iyer bcopy(&igb->link_duplex, pr_val, sizeof (link_duplex_t)); 1218ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1219ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_SPEED: 12200dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (uint64_t)); 1221ac7f5757Schenlu chen - Sun Microsystems - Beijing China tmp = igb->link_speed * 1000000ull; 1222ac7f5757Schenlu chen - Sun Microsystems - Beijing China bcopy(&tmp, pr_val, sizeof (tmp)); 1223ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1224ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_AUTONEG: 12250dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (uint8_t)); 1226ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_autoneg_cap; 1227ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1228ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_FLOWCTRL: 12290dc2366fSVenugopal Iyer ASSERT(pr_valsize >= sizeof (uint32_t)); 1230ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (hw->fc.requested_mode) { 1231ac7f5757Schenlu chen - Sun Microsystems - Beijing China case e1000_fc_none: 1232ac7f5757Schenlu chen - Sun Microsystems - Beijing China flow_control = LINK_FLOWCTRL_NONE; 1233ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1234ac7f5757Schenlu chen - Sun Microsystems - Beijing China case e1000_fc_rx_pause: 1235ac7f5757Schenlu chen - Sun Microsystems - Beijing China flow_control = LINK_FLOWCTRL_RX; 1236ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1237ac7f5757Schenlu chen - Sun Microsystems - Beijing China case e1000_fc_tx_pause: 1238ac7f5757Schenlu chen - Sun Microsystems - Beijing China flow_control = LINK_FLOWCTRL_TX; 1239ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1240ac7f5757Schenlu chen - Sun Microsystems - Beijing China case e1000_fc_full: 1241ac7f5757Schenlu chen - Sun Microsystems - Beijing China flow_control = LINK_FLOWCTRL_BI; 1242ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1243ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1244ac7f5757Schenlu chen - Sun Microsystems - Beijing China bcopy(&flow_control, pr_val, sizeof (flow_control)); 1245ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1246ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000FDX_CAP: 1247ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_1000fdx_cap; 1248ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1249ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000FDX_CAP: 1250ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_1000fdx_cap; 1251ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1252ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000HDX_CAP: 1253ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_1000hdx_cap; 1254ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1255ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000HDX_CAP: 1256ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_1000hdx_cap; 1257ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1258ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100T4_CAP: 1259ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_100t4_cap; 1260ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1261ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100T4_CAP: 1262ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_100t4_cap; 1263ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1264ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100FDX_CAP: 1265ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_100fdx_cap; 1266ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1267ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100FDX_CAP: 1268ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_100fdx_cap; 1269ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1270ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100HDX_CAP: 1271ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_100hdx_cap; 1272ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1273ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100HDX_CAP: 1274ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_100hdx_cap; 1275ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1276ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10FDX_CAP: 1277ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_10fdx_cap; 1278ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1279ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10FDX_CAP: 1280ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_10fdx_cap; 1281ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1282ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10HDX_CAP: 1283ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_adv_10hdx_cap; 1284ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1285ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10HDX_CAP: 1286ac7f5757Schenlu chen - Sun Microsystems - Beijing China *(uint8_t *)pr_val = igb->param_en_10hdx_cap; 1287ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1288ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_PRIVATE: 12890dc2366fSVenugopal Iyer err = igb_get_priv_prop(igb, pr_name, pr_valsize, pr_val); 1290ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1291ac7f5757Schenlu chen - Sun Microsystems - Beijing China default: 1292238d8f47SDale Ghent err = ENOTSUP; 1293ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1294ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1295ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1296ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1297ac7f5757Schenlu chen - Sun Microsystems - Beijing China 12980dc2366fSVenugopal Iyer void 12990dc2366fSVenugopal Iyer igb_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num, 13000dc2366fSVenugopal Iyer mac_prop_info_handle_t prh) 1301ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 13020dc2366fSVenugopal Iyer igb_t *igb = (igb_t *)arg; 1303ac7f5757Schenlu chen - Sun Microsystems - Beijing China struct e1000_hw *hw = &igb->hw; 13040dc2366fSVenugopal Iyer uint16_t phy_status, phy_ext_status; 1305ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1306ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (pr_num) { 13070dc2366fSVenugopal Iyer case MAC_PROP_DUPLEX: 13080dc2366fSVenugopal Iyer case MAC_PROP_SPEED: 1309ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000FDX_CAP: 1310ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_1000HDX_CAP: 1311ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000HDX_CAP: 1312ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100T4_CAP: 1313ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100T4_CAP: 13140dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1315ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 13160dc2366fSVenugopal Iyer 13170dc2366fSVenugopal Iyer case MAC_PROP_EN_1000FDX_CAP: 13180dc2366fSVenugopal Iyer if (hw->phy.media_type != e1000_media_type_copper) { 13190dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 13200dc2366fSVenugopal Iyer } else { 13210dc2366fSVenugopal Iyer (void) e1000_read_phy_reg(hw, PHY_EXT_STATUS, 13220dc2366fSVenugopal Iyer &phy_ext_status); 13230dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 13240dc2366fSVenugopal Iyer ((phy_ext_status & IEEE_ESR_1000T_FD_CAPS) || 13250dc2366fSVenugopal Iyer (phy_ext_status & IEEE_ESR_1000X_FD_CAPS)) ? 1 : 0); 13260dc2366fSVenugopal Iyer } 13270dc2366fSVenugopal Iyer break; 13280dc2366fSVenugopal Iyer 1329ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100FDX_CAP: 1330ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100FDX_CAP: 1331ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 13320dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1333ac7f5757Schenlu chen - Sun Microsystems - Beijing China } else { 1334ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 13350dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 1336ac7f5757Schenlu chen - Sun Microsystems - Beijing China ((phy_status & MII_SR_100X_FD_CAPS) || 13370dc2366fSVenugopal Iyer (phy_status & MII_SR_100T2_FD_CAPS)) ? 1 : 0); 1338ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1339ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 13400dc2366fSVenugopal Iyer 1341ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_100HDX_CAP: 1342ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100HDX_CAP: 1343ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 13440dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1345ac7f5757Schenlu chen - Sun Microsystems - Beijing China } else { 1346ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 13470dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 1348ac7f5757Schenlu chen - Sun Microsystems - Beijing China ((phy_status & MII_SR_100X_HD_CAPS) || 13490dc2366fSVenugopal Iyer (phy_status & MII_SR_100T2_HD_CAPS)) ? 1 : 0); 1350ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1351ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 13520dc2366fSVenugopal Iyer 1353ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10FDX_CAP: 1354ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10FDX_CAP: 1355ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 13560dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1357ac7f5757Schenlu chen - Sun Microsystems - Beijing China } else { 1358ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 13590dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 13600dc2366fSVenugopal Iyer (phy_status & MII_SR_10T_FD_CAPS) ? 1 : 0); 1361ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1362ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 13630dc2366fSVenugopal Iyer 1364ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_ADV_10HDX_CAP: 1365ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10HDX_CAP: 1366ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (hw->phy.media_type != e1000_media_type_copper) { 13670dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 1368ac7f5757Schenlu chen - Sun Microsystems - Beijing China } else { 1369ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 13700dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 13710dc2366fSVenugopal Iyer (phy_status & MII_SR_10T_HD_CAPS) ? 1 : 0); 1372ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1373ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 13740dc2366fSVenugopal Iyer 13750dc2366fSVenugopal Iyer case MAC_PROP_AUTONEG: 13760dc2366fSVenugopal Iyer if (hw->phy.media_type != e1000_media_type_copper) { 13770dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 13780dc2366fSVenugopal Iyer } else { 13790dc2366fSVenugopal Iyer (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); 13800dc2366fSVenugopal Iyer mac_prop_info_set_default_uint8(prh, 13810dc2366fSVenugopal Iyer (phy_status & MII_SR_AUTONEG_CAPS) ? 1 : 0); 13820dc2366fSVenugopal Iyer } 13830dc2366fSVenugopal Iyer break; 13840dc2366fSVenugopal Iyer 13850dc2366fSVenugopal Iyer case MAC_PROP_FLOWCTRL: 13860dc2366fSVenugopal Iyer mac_prop_info_set_default_link_flowctrl(prh, LINK_FLOWCTRL_BI); 13870dc2366fSVenugopal Iyer break; 13880dc2366fSVenugopal Iyer 13890dc2366fSVenugopal Iyer case MAC_PROP_MTU: 13900dc2366fSVenugopal Iyer mac_prop_info_set_range_uint32(prh, MIN_MTU, MAX_MTU); 13910dc2366fSVenugopal Iyer break; 13920dc2366fSVenugopal Iyer 13930dc2366fSVenugopal Iyer case MAC_PROP_PRIVATE: 13940dc2366fSVenugopal Iyer igb_priv_prop_info(igb, pr_name, prh); 1395ac7f5757Schenlu chen - Sun Microsystems - Beijing China break; 1396ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 13970dc2366fSVenugopal Iyer 1398ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1399ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1400ac7f5757Schenlu chen - Sun Microsystems - Beijing China boolean_t 1401ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_param_locked(mac_prop_id_t pr_num) 1402ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 1403ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* 1404ac7f5757Schenlu chen - Sun Microsystems - Beijing China * All en_* parameters are locked (read-only) while 1405ac7f5757Schenlu chen - Sun Microsystems - Beijing China * the device is in any sort of loopback mode ... 1406ac7f5757Schenlu chen - Sun Microsystems - Beijing China */ 1407ac7f5757Schenlu chen - Sun Microsystems - Beijing China switch (pr_num) { 1408ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000FDX_CAP: 1409ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_1000HDX_CAP: 1410ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100T4_CAP: 1411ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100FDX_CAP: 1412ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_100HDX_CAP: 1413ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10FDX_CAP: 1414ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_EN_10HDX_CAP: 1415ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_AUTONEG: 1416ac7f5757Schenlu chen - Sun Microsystems - Beijing China case MAC_PROP_FLOWCTRL: 1417ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (B_TRUE); 1418ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1419ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (B_FALSE); 1420ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1421ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1422ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* ARGSUSED */ 1423ac7f5757Schenlu chen - Sun Microsystems - Beijing China int 1424ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb_set_priv_prop(igb_t *igb, const char *pr_name, 1425ac7f5757Schenlu chen - Sun Microsystems - Beijing China uint_t pr_valsize, const void *pr_val) 1426ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 1427ac7f5757Schenlu chen - Sun Microsystems - Beijing China int err = 0; 1428ac7f5757Schenlu chen - Sun Microsystems - Beijing China long result; 1429ac7f5757Schenlu chen - Sun Microsystems - Beijing China struct e1000_hw *hw = &igb->hw; 1430ac7f5757Schenlu chen - Sun Microsystems - Beijing China int i; 1431ac7f5757Schenlu chen - Sun Microsystems - Beijing China 143243ae5505SDan McDonald if (strcmp(pr_name, "_eee_support") == 0) { 143343ae5505SDan McDonald if (pr_val == NULL) 143443ae5505SDan McDonald return (EINVAL); 143543ae5505SDan McDonald (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 143643ae5505SDan McDonald switch (result) { 143743ae5505SDan McDonald case 0: 143843ae5505SDan McDonald case 1: 143943ae5505SDan McDonald /* 144013485e69SGarrett D'Amore * For now, only supported on I350/I354. 144143ae5505SDan McDonald * Add new mac.type values (or use < instead) 144243ae5505SDan McDonald * as new cards offer up EEE. 144343ae5505SDan McDonald */ 144413485e69SGarrett D'Amore switch (hw->mac.type) { 144513485e69SGarrett D'Amore case e1000_i350: 144643ae5505SDan McDonald /* Must set this prior to the set call. */ 144743ae5505SDan McDonald hw->dev_spec._82575.eee_disable = !result; 144842cc51e0SRobert Mustacchi if (e1000_set_eee_i350(hw, result, 144942cc51e0SRobert Mustacchi result) != E1000_SUCCESS) 145043ae5505SDan McDonald err = EIO; 145143ae5505SDan McDonald break; 145213485e69SGarrett D'Amore case e1000_i354: 145313485e69SGarrett D'Amore /* Must set this prior to the set call. */ 145413485e69SGarrett D'Amore hw->dev_spec._82575.eee_disable = !result; 145542cc51e0SRobert Mustacchi if (e1000_set_eee_i354(hw, result, 145642cc51e0SRobert Mustacchi result) != E1000_SUCCESS) 145713485e69SGarrett D'Amore err = EIO; 145813485e69SGarrett D'Amore break; 145913485e69SGarrett D'Amore default: 146013485e69SGarrett D'Amore return (ENXIO); 146113485e69SGarrett D'Amore } 146213485e69SGarrett D'Amore break; 146343ae5505SDan McDonald default: 146443ae5505SDan McDonald err = EINVAL; 146543ae5505SDan McDonald /* FALLTHRU */ 146643ae5505SDan McDonald } 146743ae5505SDan McDonald return (err); 146843ae5505SDan McDonald } 1469ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 1470ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1471ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1472ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1473ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1474ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1475ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_TX_COPY_THRESHOLD || 1476ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > MAX_TX_COPY_THRESHOLD) 1477ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1478ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1479ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->tx_copy_thresh = (uint32_t)result; 1480ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1481ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1482ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1483ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 1484ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1485ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1486ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1487ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1488ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1489ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_TX_RECYCLE_THRESHOLD || 1490ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > MAX_TX_RECYCLE_THRESHOLD) 1491ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1492ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1493ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->tx_recycle_thresh = (uint32_t)result; 1494ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1495ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1496ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1497ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 1498ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1499ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1500ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1501ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1502ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1503ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_TX_OVERLOAD_THRESHOLD || 1504ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > MAX_TX_OVERLOAD_THRESHOLD) 1505ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1506ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1507ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->tx_overload_thresh = (uint32_t)result; 1508ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1509ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1510ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1511ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 1512ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1513ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1514ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1515ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1516ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1517ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_TX_RESCHED_THRESHOLD || 151869b2d733SGuoqing Zhu result > MAX_TX_RESCHED_THRESHOLD || 151969b2d733SGuoqing Zhu result > igb->tx_ring_size) 1520ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1521ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1522ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->tx_resched_thresh = (uint32_t)result; 1523ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1524ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1525ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1526ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 1527ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1528ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1529ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1530ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1531ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1532ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_RX_COPY_THRESHOLD || 1533ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > MAX_RX_COPY_THRESHOLD) 1534ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1535ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1536ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->rx_copy_thresh = (uint32_t)result; 1537ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1538ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1539ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1540ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 1541ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1542ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1543ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1544ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1545ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1546ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < MIN_RX_LIMIT_PER_INTR || 1547ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > MAX_RX_LIMIT_PER_INTR) 1548ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1549ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1550ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->rx_limit_per_intr = (uint32_t)result; 1551ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1552ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1553ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1554ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_intr_throttling") == 0) { 1555ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (pr_val == NULL) { 1556ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1557ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1558ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1559ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); 1560ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1561ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (result < igb->capab->min_intr_throttle || 1562ac7f5757Schenlu chen - Sun Microsystems - Beijing China result > igb->capab->max_intr_throttle) 1563ac7f5757Schenlu chen - Sun Microsystems - Beijing China err = EINVAL; 1564ac7f5757Schenlu chen - Sun Microsystems - Beijing China else { 1565ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->intr_throttling[0] = (uint32_t)result; 1566ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1567ac7f5757Schenlu chen - Sun Microsystems - Beijing China for (i = 0; i < MAX_NUM_EITR; i++) 1568ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->intr_throttling[i] = 1569ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->intr_throttling[0]; 1570ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1571ac7f5757Schenlu chen - Sun Microsystems - Beijing China /* Set interrupt throttling rate */ 1572ac7f5757Schenlu chen - Sun Microsystems - Beijing China for (i = 0; i < igb->intr_cnt; i++) 1573ac7f5757Schenlu chen - Sun Microsystems - Beijing China E1000_WRITE_REG(hw, E1000_EITR(i), 1574ac7f5757Schenlu chen - Sun Microsystems - Beijing China igb->intr_throttling[i]); 1575ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1576ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (err); 1577ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1578ac7f5757Schenlu chen - Sun Microsystems - Beijing China return (ENOTSUP); 1579ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1580ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1581ac7f5757Schenlu chen - Sun Microsystems - Beijing China int 15820dc2366fSVenugopal Iyer igb_get_priv_prop(igb_t *igb, const char *pr_name, uint_t pr_valsize, 15830dc2366fSVenugopal Iyer void *pr_val) 1584ac7f5757Schenlu chen - Sun Microsystems - Beijing China { 1585ac7f5757Schenlu chen - Sun Microsystems - Beijing China int value; 1586ac7f5757Schenlu chen - Sun Microsystems - Beijing China 1587ac7f5757Schenlu chen - Sun Microsystems - Beijing China if (strcmp(pr_name, "_adv_pause_cap") == 0) { 15880dc2366fSVenugopal Iyer value = igb->param_adv_pause_cap; 15890dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 15900dc2366fSVenugopal Iyer value = igb->param_adv_asym_pause_cap; 159143ae5505SDan McDonald } else if (strcmp(pr_name, "_eee_support") == 0) { 159243ae5505SDan McDonald /* 159343ae5505SDan McDonald * For now, only supported on I350. Add new mac.type values 159443ae5505SDan McDonald * (or use < instead) as new cards offer up EEE. 159543ae5505SDan McDonald */ 159613485e69SGarrett D'Amore switch (igb->hw.mac.type) { 159713485e69SGarrett D'Amore case e1000_i350: 159813485e69SGarrett D'Amore case e1000_i354: 159913485e69SGarrett D'Amore value = !(igb->hw.dev_spec._82575.eee_disable); 160013485e69SGarrett D'Amore break; 160113485e69SGarrett D'Amore default: 160213485e69SGarrett D'Amore value = 0; 160313485e69SGarrett D'Amore } 16040dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 16050dc2366fSVenugopal Iyer value = igb->tx_copy_thresh; 16060dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 16070dc2366fSVenugopal Iyer value = igb->tx_recycle_thresh; 16080dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 16090dc2366fSVenugopal Iyer value = igb->tx_overload_thresh; 16100dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 16110dc2366fSVenugopal Iyer value = igb->tx_resched_thresh; 16120dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 16130dc2366fSVenugopal Iyer value = igb->rx_copy_thresh; 16140dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 16150dc2366fSVenugopal Iyer value = igb->rx_limit_per_intr; 16160dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_intr_throttling") == 0) { 16170dc2366fSVenugopal Iyer value = igb->intr_throttling[0]; 16180dc2366fSVenugopal Iyer } else { 16190dc2366fSVenugopal Iyer return (ENOTSUP); 1620ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 16210dc2366fSVenugopal Iyer 1622ac7f5757Schenlu chen - Sun Microsystems - Beijing China (void) snprintf(pr_val, pr_valsize, "%d", value); 16230dc2366fSVenugopal Iyer return (0); 1624ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 16250dc2366fSVenugopal Iyer 16260dc2366fSVenugopal Iyer void 16270dc2366fSVenugopal Iyer igb_priv_prop_info(igb_t *igb, const char *pr_name, mac_prop_info_handle_t prh) 16280dc2366fSVenugopal Iyer { 16290dc2366fSVenugopal Iyer char valstr[64]; 16300dc2366fSVenugopal Iyer int value; 16310dc2366fSVenugopal Iyer 16320dc2366fSVenugopal Iyer if (strcmp(pr_name, "_adv_pause_cap") == 0 || 16330dc2366fSVenugopal Iyer strcmp(pr_name, "_adv_asym_pause_cap") == 0) { 16340dc2366fSVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ); 16350dc2366fSVenugopal Iyer return; 16360dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) { 16370dc2366fSVenugopal Iyer value = DEFAULT_TX_COPY_THRESHOLD; 16380dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) { 16390dc2366fSVenugopal Iyer value = DEFAULT_TX_RECYCLE_THRESHOLD; 16400dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) { 16410dc2366fSVenugopal Iyer value = DEFAULT_TX_OVERLOAD_THRESHOLD; 16420dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) { 16430dc2366fSVenugopal Iyer value = DEFAULT_TX_RESCHED_THRESHOLD; 16440dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) { 16450dc2366fSVenugopal Iyer value = DEFAULT_RX_COPY_THRESHOLD; 16460dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) { 16470dc2366fSVenugopal Iyer value = DEFAULT_RX_LIMIT_PER_INTR; 16480dc2366fSVenugopal Iyer } else if (strcmp(pr_name, "_intr_throttling") == 0) { 16490dc2366fSVenugopal Iyer value = igb->capab->def_intr_throttle; 16500dc2366fSVenugopal Iyer } else { 16510dc2366fSVenugopal Iyer return; 16520dc2366fSVenugopal Iyer } 16530dc2366fSVenugopal Iyer 16540dc2366fSVenugopal Iyer (void) snprintf(valstr, sizeof (valstr), "%d", value); 16550dc2366fSVenugopal Iyer mac_prop_info_set_default_str(prh, valstr); 1656ac7f5757Schenlu chen - Sun Microsystems - Beijing China } 1657