1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  28  */
  29 
  30 #include "ixgbe_sw.h"
  31 
  32 /*
  33  * Update driver private statistics.
  34  */
  35 static int
  36 ixgbe_update_stats(kstat_t *ks, int rw)
  37 {
  38         ixgbe_t *ixgbe;
  39         struct ixgbe_hw *hw;
  40         ixgbe_stat_t *ixgbe_ks;
  41         int i;
  42 
  43         if (rw == KSTAT_WRITE)
  44                 return (EACCES);
  45 
  46         ixgbe = (ixgbe_t *)ks->ks_private;
  47         ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
  48         hw = &ixgbe->hw;
  49 
  50         mutex_enter(&ixgbe->gen_lock);
  51 
  52         /*
  53          * Basic information
  54          */
  55         ixgbe_ks->link_speed.value.ui64 = ixgbe->link_speed;
  56         ixgbe_ks->reset_count.value.ui64 = ixgbe->reset_count;
  57         ixgbe_ks->lroc.value.ui64 = ixgbe->lro_pkt_count;
  58 
  59 #ifdef IXGBE_DEBUG
  60         ixgbe_ks->rx_frame_error.value.ui64 = 0;
  61         ixgbe_ks->rx_cksum_error.value.ui64 = 0;
  62         ixgbe_ks->rx_exceed_pkt.value.ui64 = 0;
  63         for (i = 0; i < ixgbe->num_rx_rings; i++) {
  64                 ixgbe_ks->rx_frame_error.value.ui64 +=
  65                     ixgbe->rx_rings[i].stat_frame_error;
  66                 ixgbe_ks->rx_cksum_error.value.ui64 +=
  67                     ixgbe->rx_rings[i].stat_cksum_error;
  68                 ixgbe_ks->rx_exceed_pkt.value.ui64 +=
  69                     ixgbe->rx_rings[i].stat_exceed_pkt;
  70         }
  71 
  72         ixgbe_ks->tx_overload.value.ui64 = 0;
  73         ixgbe_ks->tx_fail_no_tbd.value.ui64 = 0;
  74         ixgbe_ks->tx_fail_no_tcb.value.ui64 = 0;
  75         ixgbe_ks->tx_fail_dma_bind.value.ui64 = 0;
  76         ixgbe_ks->tx_reschedule.value.ui64 = 0;
  77         for (i = 0; i < ixgbe->num_tx_rings; i++) {
  78                 ixgbe_ks->tx_overload.value.ui64 +=
  79                     ixgbe->tx_rings[i].stat_overload;
  80                 ixgbe_ks->tx_fail_no_tbd.value.ui64 +=
  81                     ixgbe->tx_rings[i].stat_fail_no_tbd;
  82                 ixgbe_ks->tx_fail_no_tcb.value.ui64 +=
  83                     ixgbe->tx_rings[i].stat_fail_no_tcb;
  84                 ixgbe_ks->tx_fail_dma_bind.value.ui64 +=
  85                     ixgbe->tx_rings[i].stat_fail_dma_bind;
  86                 ixgbe_ks->tx_reschedule.value.ui64 +=
  87                     ixgbe->tx_rings[i].stat_reschedule;
  88         }
  89 #endif
  90 
  91         /*
  92          * Hardware calculated statistics.
  93          */
  94         ixgbe_ks->gprc.value.ui64 = 0;
  95         ixgbe_ks->gptc.value.ui64 = 0;
  96         ixgbe_ks->tor.value.ui64 = 0;
  97         ixgbe_ks->tot.value.ui64 = 0;
  98         for (i = 0; i < 16; i++) {
  99                 ixgbe_ks->qprc[i].value.ui64 +=
 100                     IXGBE_READ_REG(hw, IXGBE_QPRC(i));
 101                 ixgbe_ks->gprc.value.ui64 += ixgbe_ks->qprc[i].value.ui64;
 102                 ixgbe_ks->qptc[i].value.ui64 +=
 103                     IXGBE_READ_REG(hw, IXGBE_QPTC(i));
 104                 ixgbe_ks->gptc.value.ui64 += ixgbe_ks->qptc[i].value.ui64;
 105                 ixgbe_ks->qbrc[i].value.ui64 +=
 106                     IXGBE_READ_REG(hw, IXGBE_QBRC(i));
 107                 ixgbe_ks->tor.value.ui64 += ixgbe_ks->qbrc[i].value.ui64;
 108                 switch (hw->mac.type) {
 109                 case ixgbe_mac_82598EB:
 110                         ixgbe_ks->qbtc[i].value.ui64 +=
 111                             IXGBE_READ_REG(hw, IXGBE_QBTC(i));
 112                         break;
 113 
 114                 case ixgbe_mac_82599EB:
 115                         ixgbe_ks->qbtc[i].value.ui64 +=
 116                             IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
 117                         ixgbe_ks->qbtc[i].value.ui64 +=
 118                             ((uint64_t)((IXGBE_READ_REG(hw,
 119                             IXGBE_QBTC_H(i))) & 0xF) << 32);
 120                         break;
 121 
 122                 default:
 123                         break;
 124                 }
 125                 ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64;
 126         }
 127         /*
 128          * This is a Workaround:
 129          * Currently h/w GORCH, GOTCH, TORH registers are not
 130          * correctly implemented. We found that the values in
 131          * these registers are same as those in corresponding
 132          * *L registers (i.e. GORCL, GOTCL, and TORL). Here the
 133          * gor and got stat data will not be retrieved through
 134          * GORC{H/L} and GOTC{H/L} registers but be obtained by
 135          * simply assigning tor/tot stat data, so the gor/got
 136          * stat data will not be accurate.
 137          */
 138         ixgbe_ks->gor.value.ui64 = ixgbe_ks->tor.value.ui64;
 139         ixgbe_ks->got.value.ui64 = ixgbe_ks->tot.value.ui64;
 140 
 141         ixgbe_ks->prc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC64);
 142         ixgbe_ks->prc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC127);
 143         ixgbe_ks->prc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC255);
 144         ixgbe_ks->prc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC511);
 145         ixgbe_ks->prc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1023);
 146         ixgbe_ks->prc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1522);
 147         ixgbe_ks->ptc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC64);
 148         ixgbe_ks->ptc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC127);
 149         ixgbe_ks->ptc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC255);
 150         ixgbe_ks->ptc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC511);
 151         ixgbe_ks->ptc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1023);
 152         ixgbe_ks->ptc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1522);
 153 
 154         ixgbe_ks->mspdc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MSPDC);
 155         for (i = 0; i < 8; i++)
 156                 ixgbe_ks->mpc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MPC(i));
 157         ixgbe_ks->mlfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MLFC);
 158         ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC);
 159         ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC);
 160         ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
 161         switch (hw->mac.type) {
 162         case ixgbe_mac_82598EB:
 163                 ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
 164                     IXGBE_LXONRXC);
 165                 break;
 166 
 167         case ixgbe_mac_82599EB:
 168                 ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
 169                     IXGBE_LXONRXCNT);
 170                 break;
 171 
 172         default:
 173                 break;
 174         }
 175         ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
 176         switch (hw->mac.type) {
 177         case ixgbe_mac_82598EB:
 178                 ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
 179                     IXGBE_LXOFFRXC);
 180                 break;
 181 
 182         case ixgbe_mac_82599EB:
 183                 ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
 184                     IXGBE_LXOFFRXCNT);
 185                 break;
 186 
 187         default:
 188                 break;
 189         }
 190         ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC);
 191         ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC);
 192         ixgbe_ks->roc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_ROC);
 193         ixgbe_ks->rjc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RJC);
 194 
 195         mutex_exit(&ixgbe->gen_lock);
 196 
 197         if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK)
 198                 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_UNAFFECTED);
 199 
 200         return (0);
 201 }
 202 
 203 /*
 204  * Create and initialize the driver private statistics.
 205  */
 206 int
 207 ixgbe_init_stats(ixgbe_t *ixgbe)
 208 {
 209         kstat_t *ks;
 210         ixgbe_stat_t *ixgbe_ks;
 211 
 212         /*
 213          * Create and init kstat
 214          */
 215         ks = kstat_create(MODULE_NAME, ddi_get_instance(ixgbe->dip),
 216             "statistics", "net", KSTAT_TYPE_NAMED,
 217             sizeof (ixgbe_stat_t) / sizeof (kstat_named_t), 0);
 218 
 219         if (ks == NULL) {
 220                 ixgbe_error(ixgbe,
 221                     "Could not create kernel statistics");
 222                 return (IXGBE_FAILURE);
 223         }
 224 
 225         ixgbe->ixgbe_ks = ks;
 226 
 227         ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
 228 
 229         /*
 230          * Initialize all the statistics.
 231          */
 232         kstat_named_init(&ixgbe_ks->link_speed, "link_speed",
 233             KSTAT_DATA_UINT64);
 234         kstat_named_init(&ixgbe_ks->reset_count, "reset_count",
 235             KSTAT_DATA_UINT64);
 236 
 237 #ifdef IXGBE_DEBUG
 238         kstat_named_init(&ixgbe_ks->rx_frame_error, "rx_frame_error",
 239             KSTAT_DATA_UINT64);
 240         kstat_named_init(&ixgbe_ks->rx_cksum_error, "rx_cksum_error",
 241             KSTAT_DATA_UINT64);
 242         kstat_named_init(&ixgbe_ks->rx_exceed_pkt, "rx_exceed_pkt",
 243             KSTAT_DATA_UINT64);
 244         kstat_named_init(&ixgbe_ks->tx_overload, "tx_overload",
 245             KSTAT_DATA_UINT64);
 246         kstat_named_init(&ixgbe_ks->tx_fail_no_tbd, "tx_fail_no_tbd",
 247             KSTAT_DATA_UINT64);
 248         kstat_named_init(&ixgbe_ks->tx_fail_no_tcb, "tx_fail_no_tcb",
 249             KSTAT_DATA_UINT64);
 250         kstat_named_init(&ixgbe_ks->tx_fail_dma_bind, "tx_fail_dma_bind",
 251             KSTAT_DATA_UINT64);
 252         kstat_named_init(&ixgbe_ks->tx_reschedule, "tx_reschedule",
 253             KSTAT_DATA_UINT64);
 254 #endif
 255 
 256         kstat_named_init(&ixgbe_ks->gprc, "good_pkts_recvd",
 257             KSTAT_DATA_UINT64);
 258         kstat_named_init(&ixgbe_ks->gptc, "good_pkts_xmitd",
 259             KSTAT_DATA_UINT64);
 260         kstat_named_init(&ixgbe_ks->gor, "good_octets_recvd",
 261             KSTAT_DATA_UINT64);
 262         kstat_named_init(&ixgbe_ks->got, "good_octets_xmitd",
 263             KSTAT_DATA_UINT64);
 264         kstat_named_init(&ixgbe_ks->prc64, "pkts_recvd_(  64b)",
 265             KSTAT_DATA_UINT64);
 266         kstat_named_init(&ixgbe_ks->prc127, "pkts_recvd_(  65- 127b)",
 267             KSTAT_DATA_UINT64);
 268         kstat_named_init(&ixgbe_ks->prc255, "pkts_recvd_( 127- 255b)",
 269             KSTAT_DATA_UINT64);
 270         kstat_named_init(&ixgbe_ks->prc511, "pkts_recvd_( 256- 511b)",
 271             KSTAT_DATA_UINT64);
 272         kstat_named_init(&ixgbe_ks->prc1023, "pkts_recvd_( 511-1023b)",
 273             KSTAT_DATA_UINT64);
 274         kstat_named_init(&ixgbe_ks->prc1522, "pkts_recvd_(1024-1522b)",
 275             KSTAT_DATA_UINT64);
 276         kstat_named_init(&ixgbe_ks->ptc64, "pkts_xmitd_(  64b)",
 277             KSTAT_DATA_UINT64);
 278         kstat_named_init(&ixgbe_ks->ptc127, "pkts_xmitd_(  65- 127b)",
 279             KSTAT_DATA_UINT64);
 280         kstat_named_init(&ixgbe_ks->ptc255, "pkts_xmitd_( 128- 255b)",
 281             KSTAT_DATA_UINT64);
 282         kstat_named_init(&ixgbe_ks->ptc511, "pkts_xmitd_( 255- 511b)",
 283             KSTAT_DATA_UINT64);
 284         kstat_named_init(&ixgbe_ks->ptc1023, "pkts_xmitd_( 512-1023b)",
 285             KSTAT_DATA_UINT64);
 286         kstat_named_init(&ixgbe_ks->ptc1522, "pkts_xmitd_(1024-1522b)",
 287             KSTAT_DATA_UINT64);
 288 
 289         kstat_named_init(&ixgbe_ks->qprc[0], "queue_pkts_recvd [ 0]",
 290             KSTAT_DATA_UINT64);
 291         kstat_named_init(&ixgbe_ks->qprc[1], "queue_pkts_recvd [ 1]",
 292             KSTAT_DATA_UINT64);
 293         kstat_named_init(&ixgbe_ks->qprc[2], "queue_pkts_recvd [ 2]",
 294             KSTAT_DATA_UINT64);
 295         kstat_named_init(&ixgbe_ks->qprc[3], "queue_pkts_recvd [ 3]",
 296             KSTAT_DATA_UINT64);
 297         kstat_named_init(&ixgbe_ks->qprc[4], "queue_pkts_recvd [ 4]",
 298             KSTAT_DATA_UINT64);
 299         kstat_named_init(&ixgbe_ks->qprc[5], "queue_pkts_recvd [ 5]",
 300             KSTAT_DATA_UINT64);
 301         kstat_named_init(&ixgbe_ks->qprc[6], "queue_pkts_recvd [ 6]",
 302             KSTAT_DATA_UINT64);
 303         kstat_named_init(&ixgbe_ks->qprc[7], "queue_pkts_recvd [ 7]",
 304             KSTAT_DATA_UINT64);
 305         kstat_named_init(&ixgbe_ks->qprc[8], "queue_pkts_recvd [ 8]",
 306             KSTAT_DATA_UINT64);
 307         kstat_named_init(&ixgbe_ks->qprc[9], "queue_pkts_recvd [ 9]",
 308             KSTAT_DATA_UINT64);
 309         kstat_named_init(&ixgbe_ks->qprc[10], "queue_pkts_recvd [10]",
 310             KSTAT_DATA_UINT64);
 311         kstat_named_init(&ixgbe_ks->qprc[11], "queue_pkts_recvd [11]",
 312             KSTAT_DATA_UINT64);
 313         kstat_named_init(&ixgbe_ks->qprc[12], "queue_pkts_recvd [12]",
 314             KSTAT_DATA_UINT64);
 315         kstat_named_init(&ixgbe_ks->qprc[13], "queue_pkts_recvd [13]",
 316             KSTAT_DATA_UINT64);
 317         kstat_named_init(&ixgbe_ks->qprc[14], "queue_pkts_recvd [14]",
 318             KSTAT_DATA_UINT64);
 319         kstat_named_init(&ixgbe_ks->qprc[15], "queue_pkts_recvd [15]",
 320             KSTAT_DATA_UINT64);
 321 
 322         kstat_named_init(&ixgbe_ks->qptc[0], "queue_pkts_xmitd [ 0]",
 323             KSTAT_DATA_UINT64);
 324         kstat_named_init(&ixgbe_ks->qptc[1], "queue_pkts_xmitd [ 1]",
 325             KSTAT_DATA_UINT64);
 326         kstat_named_init(&ixgbe_ks->qptc[2], "queue_pkts_xmitd [ 2]",
 327             KSTAT_DATA_UINT64);
 328         kstat_named_init(&ixgbe_ks->qptc[3], "queue_pkts_xmitd [ 3]",
 329             KSTAT_DATA_UINT64);
 330         kstat_named_init(&ixgbe_ks->qptc[4], "queue_pkts_xmitd [ 4]",
 331             KSTAT_DATA_UINT64);
 332         kstat_named_init(&ixgbe_ks->qptc[5], "queue_pkts_xmitd [ 5]",
 333             KSTAT_DATA_UINT64);
 334         kstat_named_init(&ixgbe_ks->qptc[6], "queue_pkts_xmitd [ 6]",
 335             KSTAT_DATA_UINT64);
 336         kstat_named_init(&ixgbe_ks->qptc[7], "queue_pkts_xmitd [ 7]",
 337             KSTAT_DATA_UINT64);
 338         kstat_named_init(&ixgbe_ks->qptc[8], "queue_pkts_xmitd [ 8]",
 339             KSTAT_DATA_UINT64);
 340         kstat_named_init(&ixgbe_ks->qptc[9], "queue_pkts_xmitd [ 9]",
 341             KSTAT_DATA_UINT64);
 342         kstat_named_init(&ixgbe_ks->qptc[10], "queue_pkts_xmitd [10]",
 343             KSTAT_DATA_UINT64);
 344         kstat_named_init(&ixgbe_ks->qptc[11], "queue_pkts_xmitd [11]",
 345             KSTAT_DATA_UINT64);
 346         kstat_named_init(&ixgbe_ks->qptc[12], "queue_pkts_xmitd [12]",
 347             KSTAT_DATA_UINT64);
 348         kstat_named_init(&ixgbe_ks->qptc[13], "queue_pkts_xmitd [13]",
 349             KSTAT_DATA_UINT64);
 350         kstat_named_init(&ixgbe_ks->qptc[14], "queue_pkts_xmitd [14]",
 351             KSTAT_DATA_UINT64);
 352         kstat_named_init(&ixgbe_ks->qptc[15], "queue_pkts_xmitd [15]",
 353             KSTAT_DATA_UINT64);
 354 
 355         kstat_named_init(&ixgbe_ks->qbrc[0], "queue_bytes_recvd [ 0]",
 356             KSTAT_DATA_UINT64);
 357         kstat_named_init(&ixgbe_ks->qbrc[1], "queue_bytes_recvd [ 1]",
 358             KSTAT_DATA_UINT64);
 359         kstat_named_init(&ixgbe_ks->qbrc[2], "queue_bytes_recvd [ 2]",
 360             KSTAT_DATA_UINT64);
 361         kstat_named_init(&ixgbe_ks->qbrc[3], "queue_bytes_recvd [ 3]",
 362             KSTAT_DATA_UINT64);
 363         kstat_named_init(&ixgbe_ks->qbrc[4], "queue_bytes_recvd [ 4]",
 364             KSTAT_DATA_UINT64);
 365         kstat_named_init(&ixgbe_ks->qbrc[5], "queue_bytes_recvd [ 5]",
 366             KSTAT_DATA_UINT64);
 367         kstat_named_init(&ixgbe_ks->qbrc[6], "queue_bytes_recvd [ 6]",
 368             KSTAT_DATA_UINT64);
 369         kstat_named_init(&ixgbe_ks->qbrc[7], "queue_bytes_recvd [ 7]",
 370             KSTAT_DATA_UINT64);
 371         kstat_named_init(&ixgbe_ks->qbrc[8], "queue_bytes_recvd [ 8]",
 372             KSTAT_DATA_UINT64);
 373         kstat_named_init(&ixgbe_ks->qbrc[9], "queue_bytes_recvd [ 9]",
 374             KSTAT_DATA_UINT64);
 375         kstat_named_init(&ixgbe_ks->qbrc[10], "queue_bytes_recvd [10]",
 376             KSTAT_DATA_UINT64);
 377         kstat_named_init(&ixgbe_ks->qbrc[11], "queue_bytes_recvd [11]",
 378             KSTAT_DATA_UINT64);
 379         kstat_named_init(&ixgbe_ks->qbrc[12], "queue_bytes_recvd [12]",
 380             KSTAT_DATA_UINT64);
 381         kstat_named_init(&ixgbe_ks->qbrc[13], "queue_bytes_recvd [13]",
 382             KSTAT_DATA_UINT64);
 383         kstat_named_init(&ixgbe_ks->qbrc[14], "queue_bytes_recvd [14]",
 384             KSTAT_DATA_UINT64);
 385         kstat_named_init(&ixgbe_ks->qbrc[15], "queue_bytes_recvd [15]",
 386             KSTAT_DATA_UINT64);
 387 
 388         kstat_named_init(&ixgbe_ks->qbtc[0], "queue_bytes_xmitd [ 0]",
 389             KSTAT_DATA_UINT64);
 390         kstat_named_init(&ixgbe_ks->qbtc[1], "queue_bytes_xmitd [ 1]",
 391             KSTAT_DATA_UINT64);
 392         kstat_named_init(&ixgbe_ks->qbtc[2], "queue_bytes_xmitd [ 2]",
 393             KSTAT_DATA_UINT64);
 394         kstat_named_init(&ixgbe_ks->qbtc[3], "queue_bytes_xmitd [ 3]",
 395             KSTAT_DATA_UINT64);
 396         kstat_named_init(&ixgbe_ks->qbtc[4], "queue_bytes_xmitd [ 4]",
 397             KSTAT_DATA_UINT64);
 398         kstat_named_init(&ixgbe_ks->qbtc[5], "queue_bytes_xmitd [ 5]",
 399             KSTAT_DATA_UINT64);
 400         kstat_named_init(&ixgbe_ks->qbtc[6], "queue_bytes_xmitd [ 6]",
 401             KSTAT_DATA_UINT64);
 402         kstat_named_init(&ixgbe_ks->qbtc[7], "queue_bytes_xmitd [ 7]",
 403             KSTAT_DATA_UINT64);
 404         kstat_named_init(&ixgbe_ks->qbtc[8], "queue_bytes_xmitd [ 8]",
 405             KSTAT_DATA_UINT64);
 406         kstat_named_init(&ixgbe_ks->qbtc[9], "queue_bytes_xmitd [ 9]",
 407             KSTAT_DATA_UINT64);
 408         kstat_named_init(&ixgbe_ks->qbtc[10], "queue_bytes_xmitd [10]",
 409             KSTAT_DATA_UINT64);
 410         kstat_named_init(&ixgbe_ks->qbtc[11], "queue_bytes_xmitd [11]",
 411             KSTAT_DATA_UINT64);
 412         kstat_named_init(&ixgbe_ks->qbtc[12], "queue_bytes_xmitd [12]",
 413             KSTAT_DATA_UINT64);
 414         kstat_named_init(&ixgbe_ks->qbtc[13], "queue_bytes_xmitd [13]",
 415             KSTAT_DATA_UINT64);
 416         kstat_named_init(&ixgbe_ks->qbtc[14], "queue_bytes_xmitd [14]",
 417             KSTAT_DATA_UINT64);
 418         kstat_named_init(&ixgbe_ks->qbtc[15], "queue_bytes_xmitd [15]",
 419             KSTAT_DATA_UINT64);
 420 
 421         kstat_named_init(&ixgbe_ks->mspdc, "mac_short_packet_discard",
 422             KSTAT_DATA_UINT64);
 423         kstat_named_init(&ixgbe_ks->mpc, "missed_packets",
 424             KSTAT_DATA_UINT64);
 425         kstat_named_init(&ixgbe_ks->mlfc, "mac_local_fault",
 426             KSTAT_DATA_UINT64);
 427         kstat_named_init(&ixgbe_ks->mrfc, "mac_remote_fault",
 428             KSTAT_DATA_UINT64);
 429         kstat_named_init(&ixgbe_ks->rlec, "recv_length_err",
 430             KSTAT_DATA_UINT64);
 431         kstat_named_init(&ixgbe_ks->lxontxc, "link_xon_xmitd",
 432             KSTAT_DATA_UINT64);
 433         kstat_named_init(&ixgbe_ks->lxonrxc, "link_xon_recvd",
 434             KSTAT_DATA_UINT64);
 435         kstat_named_init(&ixgbe_ks->lxofftxc, "link_xoff_xmitd",
 436             KSTAT_DATA_UINT64);
 437         kstat_named_init(&ixgbe_ks->lxoffrxc, "link_xoff_recvd",
 438             KSTAT_DATA_UINT64);
 439         kstat_named_init(&ixgbe_ks->ruc, "recv_undersize",
 440             KSTAT_DATA_UINT64);
 441         kstat_named_init(&ixgbe_ks->rfc, "recv_fragment",
 442             KSTAT_DATA_UINT64);
 443         kstat_named_init(&ixgbe_ks->roc, "recv_oversize",
 444             KSTAT_DATA_UINT64);
 445         kstat_named_init(&ixgbe_ks->rjc, "recv_jabber",
 446             KSTAT_DATA_UINT64);
 447         kstat_named_init(&ixgbe_ks->rnbc, "recv_no_buffer",
 448             KSTAT_DATA_UINT64);
 449         kstat_named_init(&ixgbe_ks->lroc, "lro_pkt_count",
 450             KSTAT_DATA_UINT64);
 451         /*
 452          * Function to provide kernel stat update on demand
 453          */
 454         ks->ks_update = ixgbe_update_stats;
 455 
 456         ks->ks_private = (void *)ixgbe;
 457 
 458         /*
 459          * Add kstat to systems kstat chain
 460          */
 461         kstat_install(ks);
 462 
 463         return (IXGBE_SUCCESS);
 464 }
 465 
 466 /*
 467  * Retrieve a value for one of the statistics.
 468  */
 469 int
 470 ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val)
 471 {
 472         ixgbe_t *ixgbe = (ixgbe_t *)arg;
 473         struct ixgbe_hw *hw = &ixgbe->hw;
 474         ixgbe_stat_t *ixgbe_ks;
 475         int i;
 476 
 477         ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data;
 478 
 479         mutex_enter(&ixgbe->gen_lock);
 480 
 481         if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 482                 mutex_exit(&ixgbe->gen_lock);
 483                 return (ECANCELED);
 484         }
 485 
 486         switch (stat) {
 487         case MAC_STAT_IFSPEED:
 488                 *val = ixgbe->link_speed * 1000000ull;
 489                 break;
 490 
 491         case MAC_STAT_MULTIRCV:
 492                 ixgbe_ks->mprc.value.ui64 +=
 493                     IXGBE_READ_REG(hw, IXGBE_MPRC);
 494                 *val = ixgbe_ks->mprc.value.ui64;
 495                 break;
 496 
 497         case MAC_STAT_BRDCSTRCV:
 498                 ixgbe_ks->bprc.value.ui64 +=
 499                     IXGBE_READ_REG(hw, IXGBE_BPRC);
 500                 *val = ixgbe_ks->bprc.value.ui64;
 501                 break;
 502 
 503         case MAC_STAT_MULTIXMT:
 504                 ixgbe_ks->mptc.value.ui64 +=
 505                     IXGBE_READ_REG(hw, IXGBE_MPTC);
 506                 *val = ixgbe_ks->mptc.value.ui64;
 507                 break;
 508 
 509         case MAC_STAT_BRDCSTXMT:
 510                 ixgbe_ks->bptc.value.ui64 +=
 511                     IXGBE_READ_REG(hw, IXGBE_BPTC);
 512                 *val = ixgbe_ks->bptc.value.ui64;
 513                 break;
 514 
 515         case MAC_STAT_NORCVBUF:
 516                 for (i = 0; i < 8; i++) {
 517                         ixgbe_ks->rnbc.value.ui64 +=
 518                             IXGBE_READ_REG(hw, IXGBE_RNBC(i));
 519                 }
 520                 *val = ixgbe_ks->rnbc.value.ui64;
 521                 break;
 522 
 523         case MAC_STAT_IERRORS:
 524                 ixgbe_ks->crcerrs.value.ui64 +=
 525                     IXGBE_READ_REG(hw, IXGBE_CRCERRS);
 526                 ixgbe_ks->illerrc.value.ui64 +=
 527                     IXGBE_READ_REG(hw, IXGBE_ILLERRC);
 528                 ixgbe_ks->errbc.value.ui64 +=
 529                     IXGBE_READ_REG(hw, IXGBE_ERRBC);
 530                 ixgbe_ks->rlec.value.ui64 +=
 531                     IXGBE_READ_REG(hw, IXGBE_RLEC);
 532                 *val = ixgbe_ks->crcerrs.value.ui64 +
 533                     ixgbe_ks->illerrc.value.ui64 +
 534                     ixgbe_ks->errbc.value.ui64 +
 535                     ixgbe_ks->rlec.value.ui64;
 536                 break;
 537 
 538         case MAC_STAT_RBYTES:
 539                 ixgbe_ks->tor.value.ui64 = 0;
 540                 for (i = 0; i < 16; i++) {
 541                         ixgbe_ks->qbrc[i].value.ui64 +=
 542                             IXGBE_READ_REG(hw, IXGBE_QBRC(i));
 543                         ixgbe_ks->tor.value.ui64 +=
 544                             ixgbe_ks->qbrc[i].value.ui64;
 545                 }
 546                 *val = ixgbe_ks->tor.value.ui64;
 547                 break;
 548 
 549         case MAC_STAT_OBYTES:
 550                 ixgbe_ks->tot.value.ui64 = 0;
 551                 for (i = 0; i < 16; i++) {
 552                         switch (hw->mac.type) {
 553                         case ixgbe_mac_82598EB:
 554                                 ixgbe_ks->qbtc[i].value.ui64 +=
 555                                     IXGBE_READ_REG(hw, IXGBE_QBTC(i));
 556                                 break;
 557 
 558                         case ixgbe_mac_82599EB:
 559                                 ixgbe_ks->qbtc[i].value.ui64 +=
 560                                     IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
 561                                 ixgbe_ks->qbtc[i].value.ui64 +=
 562                                     ((uint64_t)((IXGBE_READ_REG(hw,
 563                                     IXGBE_QBTC_H(i))) & 0xF) << 32);
 564                                 break;
 565 
 566                         default:
 567                                 break;
 568                         }
 569                         ixgbe_ks->tot.value.ui64 +=
 570                             ixgbe_ks->qbtc[i].value.ui64;
 571                 }
 572                 *val = ixgbe_ks->tot.value.ui64;
 573                 break;
 574 
 575         case MAC_STAT_IPACKETS:
 576                 ixgbe_ks->tpr.value.ui64 +=
 577                     IXGBE_READ_REG(hw, IXGBE_TPR);
 578                 *val = ixgbe_ks->tpr.value.ui64;
 579                 break;
 580 
 581         case MAC_STAT_OPACKETS:
 582                 ixgbe_ks->tpt.value.ui64 +=
 583                     IXGBE_READ_REG(hw, IXGBE_TPT);
 584                 *val = ixgbe_ks->tpt.value.ui64;
 585                 break;
 586 
 587         /* RFC 1643 stats */
 588         case ETHER_STAT_FCS_ERRORS:
 589                 ixgbe_ks->crcerrs.value.ui64 +=
 590                     IXGBE_READ_REG(hw, IXGBE_CRCERRS);
 591                 *val = ixgbe_ks->crcerrs.value.ui64;
 592                 break;
 593 
 594         case ETHER_STAT_TOOLONG_ERRORS:
 595                 ixgbe_ks->roc.value.ui64 +=
 596                     IXGBE_READ_REG(hw, IXGBE_ROC);
 597                 *val = ixgbe_ks->roc.value.ui64;
 598                 break;
 599 
 600         case ETHER_STAT_MACRCV_ERRORS:
 601                 ixgbe_ks->crcerrs.value.ui64 +=
 602                     IXGBE_READ_REG(hw, IXGBE_CRCERRS);
 603                 ixgbe_ks->illerrc.value.ui64 +=
 604                     IXGBE_READ_REG(hw, IXGBE_ILLERRC);
 605                 ixgbe_ks->errbc.value.ui64 +=
 606                     IXGBE_READ_REG(hw, IXGBE_ERRBC);
 607                 ixgbe_ks->rlec.value.ui64 +=
 608                     IXGBE_READ_REG(hw, IXGBE_RLEC);
 609                 *val = ixgbe_ks->crcerrs.value.ui64 +
 610                     ixgbe_ks->illerrc.value.ui64 +
 611                     ixgbe_ks->errbc.value.ui64 +
 612                     ixgbe_ks->rlec.value.ui64;
 613                 break;
 614 
 615         /* MII/GMII stats */
 616         case ETHER_STAT_XCVR_ADDR:
 617                 /* The Internal PHY's MDI address for each MAC is 1 */
 618                 *val = 1;
 619                 break;
 620 
 621         case ETHER_STAT_XCVR_ID:
 622                 *val = hw->phy.id;
 623                 break;
 624 
 625         case ETHER_STAT_XCVR_INUSE:
 626                 switch (ixgbe->link_speed) {
 627                 case IXGBE_LINK_SPEED_1GB_FULL:
 628                         *val =
 629                             (hw->phy.media_type == ixgbe_media_type_copper) ?
 630                             XCVR_1000T : XCVR_1000X;
 631                         break;
 632                 case IXGBE_LINK_SPEED_100_FULL:
 633                         *val = (hw->phy.media_type == ixgbe_media_type_copper) ?
 634                             XCVR_100T2 : XCVR_100X;
 635                         break;
 636                 default:
 637                         *val = XCVR_NONE;
 638                         break;
 639                 }
 640                 break;
 641 
 642         case ETHER_STAT_CAP_10GFDX:
 643                 *val = 1;
 644                 break;
 645 
 646         case ETHER_STAT_CAP_1000FDX:
 647                 *val = 1;
 648                 break;
 649 
 650         case ETHER_STAT_CAP_100FDX:
 651                 *val = 1;
 652                 break;
 653 
 654         case ETHER_STAT_CAP_ASMPAUSE:
 655                 *val = ixgbe->param_asym_pause_cap;
 656                 break;
 657 
 658         case ETHER_STAT_CAP_PAUSE:
 659                 *val = ixgbe->param_pause_cap;
 660                 break;
 661 
 662         case ETHER_STAT_CAP_AUTONEG:
 663                 *val = 1;
 664                 break;
 665 
 666         case ETHER_STAT_ADV_CAP_10GFDX:
 667                 *val = ixgbe->param_adv_10000fdx_cap;
 668                 break;
 669 
 670         case ETHER_STAT_ADV_CAP_1000FDX:
 671                 *val = ixgbe->param_adv_1000fdx_cap;
 672                 break;
 673 
 674         case ETHER_STAT_ADV_CAP_100FDX:
 675                 *val = ixgbe->param_adv_100fdx_cap;
 676                 break;
 677 
 678         case ETHER_STAT_ADV_CAP_ASMPAUSE:
 679                 *val = ixgbe->param_adv_asym_pause_cap;
 680                 break;
 681 
 682         case ETHER_STAT_ADV_CAP_PAUSE:
 683                 *val = ixgbe->param_adv_pause_cap;
 684                 break;
 685 
 686         case ETHER_STAT_ADV_CAP_AUTONEG:
 687                 *val = ixgbe->param_adv_autoneg_cap;
 688                 break;
 689 
 690         case ETHER_STAT_LP_CAP_10GFDX:
 691                 *val = ixgbe->param_lp_10000fdx_cap;
 692                 break;
 693 
 694         case ETHER_STAT_LP_CAP_1000FDX:
 695                 *val = ixgbe->param_lp_1000fdx_cap;
 696                 break;
 697 
 698         case ETHER_STAT_LP_CAP_100FDX:
 699                 *val = ixgbe->param_lp_100fdx_cap;
 700                 break;
 701 
 702         case ETHER_STAT_LP_CAP_ASMPAUSE:
 703                 *val = ixgbe->param_lp_asym_pause_cap;
 704                 break;
 705 
 706         case ETHER_STAT_LP_CAP_PAUSE:
 707                 *val = ixgbe->param_lp_pause_cap;
 708                 break;
 709 
 710         case ETHER_STAT_LP_CAP_AUTONEG:
 711                 *val = ixgbe->param_lp_autoneg_cap;
 712                 break;
 713 
 714         case ETHER_STAT_LINK_ASMPAUSE:
 715                 *val = ixgbe->param_asym_pause_cap;
 716                 break;
 717 
 718         case ETHER_STAT_LINK_PAUSE:
 719                 *val = ixgbe->param_pause_cap;
 720                 break;
 721 
 722         case ETHER_STAT_LINK_AUTONEG:
 723                 *val = ixgbe->param_adv_autoneg_cap;
 724                 break;
 725 
 726         case ETHER_STAT_LINK_DUPLEX:
 727                 *val = ixgbe->link_duplex;
 728                 break;
 729 
 730         case ETHER_STAT_TOOSHORT_ERRORS:
 731                 ixgbe_ks->ruc.value.ui64 +=
 732                     IXGBE_READ_REG(hw, IXGBE_RUC);
 733                 *val = ixgbe_ks->ruc.value.ui64;
 734                 break;
 735 
 736         case ETHER_STAT_CAP_REMFAULT:
 737                 *val = ixgbe->param_rem_fault;
 738                 break;
 739 
 740         case ETHER_STAT_ADV_REMFAULT:
 741                 *val = ixgbe->param_adv_rem_fault;
 742                 break;
 743 
 744         case ETHER_STAT_LP_REMFAULT:
 745                 *val = ixgbe->param_lp_rem_fault;
 746                 break;
 747 
 748         case ETHER_STAT_JABBER_ERRORS:
 749                 ixgbe_ks->rjc.value.ui64 +=
 750                     IXGBE_READ_REG(hw, IXGBE_RJC);
 751                 *val = ixgbe_ks->rjc.value.ui64;
 752                 break;
 753 
 754         default:
 755                 mutex_exit(&ixgbe->gen_lock);
 756                 return (ENOTSUP);
 757         }
 758 
 759         mutex_exit(&ixgbe->gen_lock);
 760 
 761         if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
 762                 ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
 763                 return (EIO);
 764         }
 765 
 766         return (0);
 767 }
 768 
 769 /*
 770  * Retrieve a value for one of the statistics for a particular rx ring
 771  */
 772 int
 773 ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
 774 {
 775         ixgbe_rx_ring_t *rx_ring = (ixgbe_rx_ring_t *)rh;
 776         ixgbe_t *ixgbe = rx_ring->ixgbe;
 777 
 778         if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 779                 return (ECANCELED);
 780         }
 781 
 782         switch (stat) {
 783         case MAC_STAT_RBYTES:
 784                 *val = rx_ring->stat_rbytes;
 785                 break;
 786 
 787         case MAC_STAT_IPACKETS:
 788                 *val = rx_ring->stat_ipackets;
 789                 break;
 790 
 791         default:
 792                 *val = 0;
 793                 return (ENOTSUP);
 794         }
 795 
 796         return (0);
 797 }
 798 
 799 /*
 800  * Retrieve a value for one of the statistics for a particular tx ring
 801  */
 802 int
 803 ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
 804 {
 805         ixgbe_tx_ring_t *tx_ring = (ixgbe_tx_ring_t *)rh;
 806         ixgbe_t *ixgbe = tx_ring->ixgbe;
 807 
 808         if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 809                 return (ECANCELED);
 810         }
 811 
 812         switch (stat) {
 813         case MAC_STAT_OBYTES:
 814                 *val = tx_ring->stat_obytes;
 815                 break;
 816 
 817         case MAC_STAT_OPACKETS:
 818                 *val = tx_ring->stat_opackets;
 819                 break;
 820 
 821         default:
 822                 *val = 0;
 823                 return (ENOTSUP);
 824         }
 825 
 826         return (0);
 827 }