1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
  14  * Copyright 2019 Joyent, Inc.
  15  */
  16 
  17 #include "i40e_sw.h"
  18 
  19 /*
  20  * -------------------
  21  * Statistics Overview
  22  * -------------------
  23  *
  24  * As part of managing the driver and understanding what's going on, we keep
  25  * track of statistics from two different sources:
  26  *
  27  *   - Statistics from the device
  28  *   - Statistics maintained by the driver
  29  *
  30  * Generally, the hardware provides us traditional IETF and MIB Ethernet
  31  * statistics, for example, the total packets in and out, various errors in
  32  * packets, the negotiated status etc. The driver, on the other hand, primarily
  33  * contains statistics around driver-specific issues, such as information about
  34  * checksumming on receive and transmit and the data in and out of a specific
  35  * ring.
  36  *
  37  * We export statistics in two different forms. The first form is the required
  38  * GLDv3 endpoints, specifically:
  39  *
  40  *   - The general GLDv3 mc_getstat interface
  41  *   - The GLDv3 ring mri_stat interface
  42  *
  43  * The second form that we export statistics is through kstats. kstats are
  44  * exported in different ways. Particularly we arrange the kstats to monitor the
  45  * layout of the device. Currently we have kstats which capture both the IEEE
  46  * and driver-implementation specific stats. There are kstats for each of the
  47  * following structures:
  48  *
  49  *   - Each physical function
  50  *   - Each VSI
  51  *   - Each Queue
  52  *
  53  * The PF's kstat is called 'pfstats' so as not to collide with other system
  54  * provided kstats. Thus, for instance 0, usually the first PF, the full kstat
  55  * would be: i40e:0:pfstats:.
  56  *
  57  * The kstat for each VSI is called vsi_%instance. So for the first PF, which is
  58  * instance zero and the first vsi, which has id 0, it will be named vsi_0 and
  59  * the full kstat would be i40e:0:vsi_0:.
  60  *
  61  * The kstat for each queue is trqpair_tx_%queue and trqpair_rx_%queue. Note
  62  * that these are labeled based on their local index, which may mean that
  63  * different instances have overlapping sets of queues. This isn't a problem as
  64  * the kstats will always use the instance number of the pf to distinguish it in
  65  * the kstat tuple.
  66  *
  67  * ---------------------
  68  * Hardware Arrangements
  69  * ---------------------
  70  *
  71  * The hardware keeps statistics at each physical function/MAC (PF) and it keeps
  72  * statistics on each virtual station interface (VSI).
  73  *
  74  * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
  75  * required to read them and then compute the differences between them. The
  76  * 48-bit counters span more than one 32-bit register in the BAR. The hardware
  77  * suggests that to read them, we perform 64-bit reads of the lower of the two
  78  * registers that make up a 48-bit stat. The hardware guarantees that the reads
  79  * of those two registers will be atomic and we'll get a consistent value, not a
  80  * property it has for every read of two registers.
  81  *
  82  * For every kstat we have based on this, we have a corresponding uint64_t that
  83  * we keep around as a base value in a separate structure. Whenever we read a
  84  * value, we end up grabbing the current value, calculating a difference between
  85  * the previously stored value and the current one, and updating the kstat with
  86  * that difference. After which, we go through and update the base value that we
  87  * stored. This is all encapsulated in i40e_stat_get_uint32() and
  88  * i40e_stat_get_uint48().
  89  *
  90  * The only unfortunate thing here is that the hardware doesn't give us any kind
  91  * of overflow counter. It just tries to make sure that the uint32_t and
  92  * uint48_t counters are large enough to hopefully not overflow right away. This
  93  * isn't the most reassuring statement and we should investigate ways of
  94  * ensuring that if a system is active, but not actively measured, we don't lose
  95  * data.
  96  *
  97  * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
  98  * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstats are in
  99  * i40e_t`i40e_vsis[idx].iv_kstats and the data is backed in the
 100  * i40e_t`i40e_vsis[idx].iv_stats. All of this data is protected by the
 101  * i40e_stat_lock, which should be taken last, when acquiring locks.
 102  */
 103 
 104 static void
 105 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
 106     uint64_t *base, boolean_t init)
 107 {
 108         i40e_hw_t *hw = &i40e->i40e_hw_space;
 109         uint64_t raw, delta;
 110 
 111         ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
 112 
 113         raw = ddi_get64(i40e->i40e_osdep_space.ios_reg_handle,
 114             (uint64_t *)((uintptr_t)hw->hw_addr + reg));
 115 
 116         if (init == B_TRUE) {
 117                 *base = raw;
 118                 return;
 119         }
 120 
 121         /*
 122          * Check for wraparound, note that the counter is actually only 48-bits,
 123          * even though it has two uint32_t regs present.
 124          */
 125         if (raw >= *base) {
 126                 delta = raw - *base;
 127         } else {
 128                 delta = 0x1000000000000ULL - *base + raw;
 129         }
 130 
 131         kstat->value.ui64 += delta;
 132         *base = raw;
 133 }
 134 
 135 static void
 136 i40e_stat_get_uint32(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
 137     uint64_t *base, boolean_t init)
 138 {
 139         i40e_hw_t *hw = &i40e->i40e_hw_space;
 140         uint64_t raw, delta;
 141 
 142         ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
 143 
 144         raw = ddi_get32(i40e->i40e_osdep_space.ios_reg_handle,
 145             (uint32_t *)((uintptr_t)hw->hw_addr + reg));
 146 
 147         if (init == B_TRUE) {
 148                 *base = raw;
 149                 return;
 150         }
 151 
 152         /*
 153          * Watch out for wraparound as we only have a 32-bit counter.
 154          */
 155         if (raw >= *base) {
 156                 delta = raw - *base;
 157         } else {
 158                 delta = 0x100000000ULL - *base + raw;
 159         }
 160 
 161         kstat->value.ui64 += delta;
 162         *base = raw;
 163 
 164 }
 165 
 166 static void
 167 i40e_stat_vsi_update(i40e_t *i40e, uint_t idx, boolean_t init)
 168 {
 169         i40e_vsi_stats_t *ivs;
 170         i40e_vsi_kstats_t *ivk;
 171         uint16_t id = i40e->i40e_vsis[idx].iv_stats_id;
 172 
 173         ASSERT3P(i40e->i40e_vsis[idx].iv_kstats, !=, NULL);
 174         ivs = &i40e->i40e_vsis[idx].iv_stats;
 175         ivk = i40e->i40e_vsis[idx].iv_kstats->ks_data;
 176 
 177         mutex_enter(&i40e->i40e_stat_lock);
 178 
 179         i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
 180             &ivs->ivs_rx_bytes, init);
 181         i40e_stat_get_uint48(i40e, I40E_GLV_UPRCL(id), &ivk->ivk_rx_unicast,
 182             &ivs->ivs_rx_unicast, init);
 183         i40e_stat_get_uint48(i40e, I40E_GLV_MPRCL(id), &ivk->ivk_rx_multicast,
 184             &ivs->ivs_rx_multicast, init);
 185         i40e_stat_get_uint48(i40e, I40E_GLV_BPRCL(id), &ivk->ivk_rx_broadcast,
 186             &ivs->ivs_rx_broadcast, init);
 187 
 188         i40e_stat_get_uint32(i40e, I40E_GLV_RDPC(id), &ivk->ivk_rx_discards,
 189             &ivs->ivs_rx_discards, init);
 190         i40e_stat_get_uint32(i40e, I40E_GLV_RUPP(id),
 191             &ivk->ivk_rx_unknown_protocol,
 192             &ivs->ivs_rx_unknown_protocol,
 193             init);
 194 
 195         i40e_stat_get_uint48(i40e, I40E_GLV_GOTCL(id), &ivk->ivk_tx_bytes,
 196             &ivs->ivs_tx_bytes, init);
 197         i40e_stat_get_uint48(i40e, I40E_GLV_UPTCL(id), &ivk->ivk_tx_unicast,
 198             &ivs->ivs_tx_unicast, init);
 199         i40e_stat_get_uint48(i40e, I40E_GLV_MPTCL(id), &ivk->ivk_tx_multicast,
 200             &ivs->ivs_tx_multicast, init);
 201         i40e_stat_get_uint48(i40e, I40E_GLV_BPTCL(id), &ivk->ivk_tx_broadcast,
 202             &ivs->ivs_tx_broadcast, init);
 203 
 204         i40e_stat_get_uint32(i40e, I40E_GLV_TEPC(id), &ivk->ivk_tx_errors,
 205             &ivs->ivs_tx_errors, init);
 206 
 207         mutex_exit(&i40e->i40e_stat_lock);
 208 
 209         /*
 210          * We follow ixgbe's lead here and that if a kstat update didn't work
 211          * 100% then we mark service unaffected as opposed to when fetching
 212          * things for MAC directly.
 213          */
 214         if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
 215             DDI_FM_OK) {
 216                 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
 217         }
 218 }
 219 
 220 static int
 221 i40e_stat_vsi_kstat_update(kstat_t *ksp, int rw)
 222 {
 223         i40e_t *i40e;
 224 
 225         if (rw == KSTAT_WRITE)
 226                 return (EACCES);
 227 
 228         i40e = ksp->ks_private;
 229         for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++)
 230                 i40e_stat_vsi_update(i40e, i, B_FALSE);
 231 
 232         return (0);
 233 }
 234 
 235 void
 236 i40e_stat_vsi_fini(i40e_t *i40e, uint_t idx)
 237 {
 238         if (i40e->i40e_vsis[idx].iv_kstats != NULL) {
 239                 kstat_delete(i40e->i40e_vsis[idx].iv_kstats);
 240                 i40e->i40e_vsis[idx].iv_kstats = NULL;
 241         }
 242 }
 243 
 244 boolean_t
 245 i40e_stat_vsi_init(i40e_t *i40e, uint_t idx)
 246 {
 247         kstat_t *ksp;
 248         i40e_vsi_kstats_t *ivk;
 249         char buf[64];
 250         uint16_t vsi_id = i40e->i40e_vsis[idx].iv_seid;
 251 
 252         (void) snprintf(buf, sizeof (buf), "vsi_%u", vsi_id);
 253 
 254         ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
 255             buf, "net", KSTAT_TYPE_NAMED,
 256             sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
 257 
 258         if (ksp == NULL) {
 259                 i40e_error(i40e, "Failed to create kstats for VSI %u", vsi_id);
 260                 return (B_FALSE);
 261         }
 262 
 263         i40e->i40e_vsis[idx].iv_kstats = ksp;
 264         ivk = ksp->ks_data;
 265         ksp->ks_update = i40e_stat_vsi_kstat_update;
 266         ksp->ks_private = i40e;
 267 
 268         kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
 269             KSTAT_DATA_UINT64);
 270         kstat_named_init(&ivk->ivk_rx_unicast, "rx_unicast",
 271             KSTAT_DATA_UINT64);
 272         kstat_named_init(&ivk->ivk_rx_multicast, "rx_multicast",
 273             KSTAT_DATA_UINT64);
 274         kstat_named_init(&ivk->ivk_rx_broadcast, "rx_broadcast",
 275             KSTAT_DATA_UINT64);
 276         kstat_named_init(&ivk->ivk_rx_discards, "rx_discards",
 277             KSTAT_DATA_UINT64);
 278         kstat_named_init(&ivk->ivk_rx_unknown_protocol, "rx_unknown_protocol",
 279             KSTAT_DATA_UINT64);
 280         kstat_named_init(&ivk->ivk_tx_bytes, "tx_bytes",
 281             KSTAT_DATA_UINT64);
 282         kstat_named_init(&ivk->ivk_tx_unicast, "tx_unicast",
 283             KSTAT_DATA_UINT64);
 284         kstat_named_init(&ivk->ivk_tx_multicast, "tx_multicast",
 285             KSTAT_DATA_UINT64);
 286         kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
 287             KSTAT_DATA_UINT64);
 288         kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
 289             KSTAT_DATA_UINT64);
 290 
 291         bzero(&i40e->i40e_vsis[idx].iv_stats, sizeof (i40e_vsi_stats_t));
 292         i40e_stat_vsi_update(i40e, idx, B_TRUE);
 293         kstat_install(i40e->i40e_vsis[idx].iv_kstats);
 294 
 295         return (B_TRUE);
 296 }
 297 
 298 static void
 299 i40e_stat_pf_update(i40e_t *i40e, boolean_t init)
 300 {
 301         i40e_pf_stats_t *ips;
 302         i40e_pf_kstats_t *ipk;
 303         int port = i40e->i40e_hw_space.port;
 304         int i;
 305 
 306         ASSERT(i40e->i40e_pf_kstat != NULL);
 307         ips = &i40e->i40e_pf_stat;
 308         ipk = i40e->i40e_pf_kstat->ks_data;
 309 
 310         mutex_enter(&i40e->i40e_stat_lock);
 311 
 312         /* 64-bit PCIe regs */
 313         i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
 314             &ipk->ipk_rx_bytes, &ips->ips_rx_bytes, init);
 315         i40e_stat_get_uint48(i40e, I40E_GLPRT_UPRCL(port),
 316             &ipk->ipk_rx_unicast, &ips->ips_rx_unicast, init);
 317         i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
 318             &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, init);
 319         i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
 320             &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, init);
 321         i40e_stat_get_uint48(i40e, I40E_GLPRT_GOTCL(port),
 322             &ipk->ipk_tx_bytes, &ips->ips_tx_bytes, init);
 323         i40e_stat_get_uint48(i40e, I40E_GLPRT_UPTCL(port),
 324             &ipk->ipk_tx_unicast, &ips->ips_tx_unicast, init);
 325         i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
 326             &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, init);
 327         i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
 328             &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, init);
 329 
 330         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC64L(port),
 331             &ipk->ipk_rx_size_64, &ips->ips_rx_size_64, init);
 332         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC127L(port),
 333             &ipk->ipk_rx_size_127, &ips->ips_rx_size_127, init);
 334         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC255L(port),
 335             &ipk->ipk_rx_size_255, &ips->ips_rx_size_255, init);
 336         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC511L(port),
 337             &ipk->ipk_rx_size_511, &ips->ips_rx_size_511, init);
 338         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC1023L(port),
 339             &ipk->ipk_rx_size_1023, &ips->ips_rx_size_1023, init);
 340         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC1522L(port),
 341             &ipk->ipk_rx_size_1522, &ips->ips_rx_size_1522, init);
 342         i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC9522L(port),
 343             &ipk->ipk_rx_size_9522, &ips->ips_rx_size_9522, init);
 344 
 345         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC64L(port),
 346             &ipk->ipk_tx_size_64, &ips->ips_tx_size_64, init);
 347         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC127L(port),
 348             &ipk->ipk_tx_size_127, &ips->ips_tx_size_127, init);
 349         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC255L(port),
 350             &ipk->ipk_tx_size_255, &ips->ips_tx_size_255, init);
 351         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC511L(port),
 352             &ipk->ipk_tx_size_511, &ips->ips_tx_size_511, init);
 353         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC1023L(port),
 354             &ipk->ipk_tx_size_1023, &ips->ips_tx_size_1023, init);
 355         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC1522L(port),
 356             &ipk->ipk_tx_size_1522, &ips->ips_tx_size_1522, init);
 357         i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC9522L(port),
 358             &ipk->ipk_tx_size_9522, &ips->ips_tx_size_9522, init);
 359 
 360         /* 32-bit PCIe regs */
 361         i40e_stat_get_uint32(i40e, I40E_GLPRT_LXONRXC(port),
 362             &ipk->ipk_link_xon_rx, &ips->ips_link_xon_rx, init);
 363         i40e_stat_get_uint32(i40e, I40E_GLPRT_LXOFFRXC(port),
 364             &ipk->ipk_link_xoff_rx, &ips->ips_link_xoff_rx, init);
 365         i40e_stat_get_uint32(i40e, I40E_GLPRT_LXONTXC(port),
 366             &ipk->ipk_link_xon_tx, &ips->ips_link_xon_tx, init);
 367         i40e_stat_get_uint32(i40e, I40E_GLPRT_LXOFFTXC(port),
 368             &ipk->ipk_link_xoff_tx, &ips->ips_link_xoff_tx, init);
 369 
 370         for (i = 0; i < 8; i++) {
 371                 i40e_stat_get_uint32(i40e, I40E_GLPRT_PXONRXC(port, i),
 372                     &ipk->ipk_priority_xon_rx[i], &ips->ips_priority_xon_rx[i],
 373                     init);
 374                 i40e_stat_get_uint32(i40e, I40E_GLPRT_PXOFFRXC(port, i),
 375                     &ipk->ipk_priority_xoff_rx[i],
 376                     &ips->ips_priority_xoff_rx[i],
 377                     init);
 378                 i40e_stat_get_uint32(i40e, I40E_GLPRT_PXONTXC(port, i),
 379                     &ipk->ipk_priority_xon_tx[i], &ips->ips_priority_xon_tx[i],
 380                     init);
 381                 i40e_stat_get_uint32(i40e, I40E_GLPRT_PXOFFTXC(port, i),
 382                     &ipk->ipk_priority_xoff_tx[i],
 383                     &ips->ips_priority_xoff_tx[i],
 384                     init);
 385                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RXON2OFFCNT(port, i),
 386                     &ipk->ipk_priority_xon_2_xoff[i],
 387                     &ips->ips_priority_xon_2_xoff[i],
 388                     init);
 389         }
 390 
 391         i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
 392             &ipk->ipk_crc_errors, &ips->ips_crc_errors, init);
 393         i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
 394             &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, init);
 395         i40e_stat_get_uint32(i40e, I40E_GLPRT_MLFC(port),
 396             &ipk->ipk_mac_local_faults, &ips->ips_mac_local_faults, init);
 397         i40e_stat_get_uint32(i40e, I40E_GLPRT_MRFC(port),
 398             &ipk->ipk_mac_remote_faults, &ips->ips_mac_remote_faults, init);
 399         i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
 400             &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors, init);
 401         i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
 402             &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, init);
 403         i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
 404             &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, init);
 405         i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
 406             &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, init);
 407         i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
 408             &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, init);
 409         i40e_stat_get_uint32(i40e, I40E_GLPRT_RDPC(port),
 410             &ipk->ipk_rx_discards, &ips->ips_rx_discards, init);
 411         i40e_stat_get_uint32(i40e, I40E_GLPRT_LDPC(port),
 412             &ipk->ipk_rx_vm_discards, &ips->ips_rx_vm_discards, init);
 413         i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
 414             &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards, init);
 415         i40e_stat_get_uint32(i40e, I40E_GLPRT_TDOLD(port),
 416             &ipk->ipk_tx_dropped_link_down, &ips->ips_tx_dropped_link_down,
 417             init);
 418         i40e_stat_get_uint32(i40e, I40E_GLPRT_RUPP(port),
 419             &ipk->ipk_rx_unknown_protocol, &ips->ips_rx_unknown_protocol, init);
 420 
 421         /* 64-bit */
 422         i40e_stat_get_uint48(i40e, I40E_GL_RXERR1_L(port), &ipk->ipk_rx_err1,
 423             &ips->ips_rx_err1, init);
 424         i40e_stat_get_uint48(i40e, I40E_GL_RXERR2_L(port), &ipk->ipk_rx_err2,
 425             &ips->ips_rx_err2, init);
 426 
 427         mutex_exit(&i40e->i40e_stat_lock);
 428 
 429         /*
 430          * We follow ixgbe's lead here and that if a kstat update didn't work
 431          * 100% then we mark service unaffected as opposed to when fetching
 432          * things for MAC directly.
 433          */
 434         if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
 435             DDI_FM_OK) {
 436                 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
 437         }
 438 }
 439 
 440 static int
 441 i40e_stat_pf_kstat_update(kstat_t *ksp, int rw)
 442 {
 443         i40e_t *i40e;
 444 
 445         if (rw == KSTAT_WRITE)
 446                 return (EACCES);
 447 
 448         i40e = ksp->ks_private;
 449         i40e_stat_pf_update(i40e, B_FALSE);
 450         return (0);
 451 }
 452 
 453 
 454 static boolean_t
 455 i40e_stat_pf_init(i40e_t *i40e)
 456 {
 457         kstat_t *ksp;
 458         i40e_pf_kstats_t *ipk;
 459 
 460         ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
 461             "pfstats", "net", KSTAT_TYPE_NAMED,
 462             sizeof (i40e_pf_kstats_t) / sizeof (kstat_named_t), 0);
 463         if (ksp == NULL) {
 464                 i40e_error(i40e, "Could not create kernel statistics.");
 465                 return (B_FALSE);
 466         }
 467 
 468         i40e->i40e_pf_kstat = ksp;
 469         ipk = ksp->ks_data;
 470         ksp->ks_update = i40e_stat_pf_kstat_update;
 471         ksp->ks_private = i40e;
 472 
 473         kstat_named_init(&ipk->ipk_rx_bytes, "rx_bytes",
 474             KSTAT_DATA_UINT64);
 475         kstat_named_init(&ipk->ipk_rx_unicast, "rx_unicast",
 476             KSTAT_DATA_UINT64);
 477         kstat_named_init(&ipk->ipk_rx_multicast, "rx_multicast",
 478             KSTAT_DATA_UINT64);
 479         kstat_named_init(&ipk->ipk_rx_broadcast, "rx_broadcast",
 480             KSTAT_DATA_UINT64);
 481         kstat_named_init(&ipk->ipk_tx_bytes, "tx_bytes",
 482             KSTAT_DATA_UINT64);
 483         kstat_named_init(&ipk->ipk_tx_unicast, "tx_unicast",
 484             KSTAT_DATA_UINT64);
 485         kstat_named_init(&ipk->ipk_tx_multicast, "tx_multicast",
 486             KSTAT_DATA_UINT64);
 487         kstat_named_init(&ipk->ipk_tx_broadcast, "tx_broadcast",
 488             KSTAT_DATA_UINT64);
 489 
 490         kstat_named_init(&ipk->ipk_rx_size_64, "rx_size_64",
 491             KSTAT_DATA_UINT64);
 492         kstat_named_init(&ipk->ipk_rx_size_127, "rx_size_127",
 493             KSTAT_DATA_UINT64);
 494         kstat_named_init(&ipk->ipk_rx_size_255, "rx_size_255",
 495             KSTAT_DATA_UINT64);
 496         kstat_named_init(&ipk->ipk_rx_size_511, "rx_size_511",
 497             KSTAT_DATA_UINT64);
 498         kstat_named_init(&ipk->ipk_rx_size_1023, "rx_size_1023",
 499             KSTAT_DATA_UINT64);
 500         kstat_named_init(&ipk->ipk_rx_size_1522, "rx_size_1522",
 501             KSTAT_DATA_UINT64);
 502         kstat_named_init(&ipk->ipk_rx_size_9522, "rx_size_9522",
 503             KSTAT_DATA_UINT64);
 504 
 505         kstat_named_init(&ipk->ipk_tx_size_64, "tx_size_64",
 506             KSTAT_DATA_UINT64);
 507         kstat_named_init(&ipk->ipk_tx_size_127, "tx_size_127",
 508             KSTAT_DATA_UINT64);
 509         kstat_named_init(&ipk->ipk_tx_size_255, "tx_size_255",
 510             KSTAT_DATA_UINT64);
 511         kstat_named_init(&ipk->ipk_tx_size_511, "tx_size_511",
 512             KSTAT_DATA_UINT64);
 513         kstat_named_init(&ipk->ipk_tx_size_1023, "tx_size_1023",
 514             KSTAT_DATA_UINT64);
 515         kstat_named_init(&ipk->ipk_tx_size_1522, "tx_size_1522",
 516             KSTAT_DATA_UINT64);
 517         kstat_named_init(&ipk->ipk_tx_size_9522, "tx_size_9522",
 518             KSTAT_DATA_UINT64);
 519 
 520         kstat_named_init(&ipk->ipk_link_xon_rx, "link_xon_rx",
 521             KSTAT_DATA_UINT64);
 522         kstat_named_init(&ipk->ipk_link_xoff_rx, "link_xoff_rx",
 523             KSTAT_DATA_UINT64);
 524         kstat_named_init(&ipk->ipk_link_xon_tx, "link_xon_tx",
 525             KSTAT_DATA_UINT64);
 526         kstat_named_init(&ipk->ipk_link_xoff_tx, "link_xoff_tx",
 527             KSTAT_DATA_UINT64);
 528 
 529         kstat_named_init(&ipk->ipk_priority_xon_rx[0], "priority_xon_rx[0]",
 530             KSTAT_DATA_UINT64);
 531         kstat_named_init(&ipk->ipk_priority_xoff_rx[0], "priority_xoff_rx[0]",
 532             KSTAT_DATA_UINT64);
 533         kstat_named_init(&ipk->ipk_priority_xon_tx[0], "priority_xon_tx[0]",
 534             KSTAT_DATA_UINT64);
 535         kstat_named_init(&ipk->ipk_priority_xoff_tx[0], "priority_xoff_tx[0]",
 536             KSTAT_DATA_UINT64);
 537         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[0],
 538             "priority_xon_2_xoff[0]",
 539             KSTAT_DATA_UINT64);
 540 
 541         kstat_named_init(&ipk->ipk_priority_xon_rx[1], "priority_xon_rx[1]",
 542             KSTAT_DATA_UINT64);
 543         kstat_named_init(&ipk->ipk_priority_xoff_rx[1], "priority_xoff_rx[1]",
 544             KSTAT_DATA_UINT64);
 545         kstat_named_init(&ipk->ipk_priority_xon_tx[1], "priority_xon_tx[1]",
 546             KSTAT_DATA_UINT64);
 547         kstat_named_init(&ipk->ipk_priority_xoff_tx[1], "priority_xoff_tx[1]",
 548             KSTAT_DATA_UINT64);
 549         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[1],
 550             "priority_xon_2_xoff[1]",
 551             KSTAT_DATA_UINT64);
 552 
 553         kstat_named_init(&ipk->ipk_priority_xon_rx[2], "priority_xon_rx[2]",
 554             KSTAT_DATA_UINT64);
 555         kstat_named_init(&ipk->ipk_priority_xoff_rx[2], "priority_xoff_rx[2]",
 556             KSTAT_DATA_UINT64);
 557         kstat_named_init(&ipk->ipk_priority_xon_tx[2], "priority_xon_tx[2]",
 558             KSTAT_DATA_UINT64);
 559         kstat_named_init(&ipk->ipk_priority_xoff_tx[2], "priority_xoff_tx[2]",
 560             KSTAT_DATA_UINT64);
 561         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[2],
 562             "priority_xon_2_xoff[2]",
 563             KSTAT_DATA_UINT64);
 564 
 565         kstat_named_init(&ipk->ipk_priority_xon_rx[3], "priority_xon_rx[3]",
 566             KSTAT_DATA_UINT64);
 567         kstat_named_init(&ipk->ipk_priority_xoff_rx[3], "priority_xoff_rx[3]",
 568             KSTAT_DATA_UINT64);
 569         kstat_named_init(&ipk->ipk_priority_xon_tx[3], "priority_xon_tx[3]",
 570             KSTAT_DATA_UINT64);
 571         kstat_named_init(&ipk->ipk_priority_xoff_tx[3], "priority_xoff_tx[3]",
 572             KSTAT_DATA_UINT64);
 573         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[3],
 574             "priority_xon_2_xoff[3]",
 575             KSTAT_DATA_UINT64);
 576 
 577         kstat_named_init(&ipk->ipk_priority_xon_rx[4], "priority_xon_rx[4]",
 578             KSTAT_DATA_UINT64);
 579         kstat_named_init(&ipk->ipk_priority_xoff_rx[4], "priority_xoff_rx[4]",
 580             KSTAT_DATA_UINT64);
 581         kstat_named_init(&ipk->ipk_priority_xon_tx[4], "priority_xon_tx[4]",
 582             KSTAT_DATA_UINT64);
 583         kstat_named_init(&ipk->ipk_priority_xoff_tx[4], "priority_xoff_tx[4]",
 584             KSTAT_DATA_UINT64);
 585         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[4],
 586             "priority_xon_2_xoff[4]",
 587             KSTAT_DATA_UINT64);
 588 
 589         kstat_named_init(&ipk->ipk_priority_xon_rx[5], "priority_xon_rx[5]",
 590             KSTAT_DATA_UINT64);
 591         kstat_named_init(&ipk->ipk_priority_xoff_rx[5], "priority_xoff_rx[5]",
 592             KSTAT_DATA_UINT64);
 593         kstat_named_init(&ipk->ipk_priority_xon_tx[5], "priority_xon_tx[5]",
 594             KSTAT_DATA_UINT64);
 595         kstat_named_init(&ipk->ipk_priority_xoff_tx[5], "priority_xoff_tx[5]",
 596             KSTAT_DATA_UINT64);
 597         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[5],
 598             "priority_xon_2_xoff[5]",
 599             KSTAT_DATA_UINT64);
 600 
 601         kstat_named_init(&ipk->ipk_priority_xon_rx[6], "priority_xon_rx[6]",
 602             KSTAT_DATA_UINT64);
 603         kstat_named_init(&ipk->ipk_priority_xoff_rx[6], "priority_xoff_rx[6]",
 604             KSTAT_DATA_UINT64);
 605         kstat_named_init(&ipk->ipk_priority_xon_tx[6], "priority_xon_tx[6]",
 606             KSTAT_DATA_UINT64);
 607         kstat_named_init(&ipk->ipk_priority_xoff_tx[6], "priority_xoff_tx[6]",
 608             KSTAT_DATA_UINT64);
 609         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[6],
 610             "priority_xon_2_xoff[6]",
 611             KSTAT_DATA_UINT64);
 612 
 613         kstat_named_init(&ipk->ipk_priority_xon_rx[7], "priority_xon_rx[7]",
 614             KSTAT_DATA_UINT64);
 615         kstat_named_init(&ipk->ipk_priority_xoff_rx[7], "priority_xoff_rx[7]",
 616             KSTAT_DATA_UINT64);
 617         kstat_named_init(&ipk->ipk_priority_xon_tx[7], "priority_xon_tx[7]",
 618             KSTAT_DATA_UINT64);
 619         kstat_named_init(&ipk->ipk_priority_xoff_tx[7], "priority_xoff_tx[7]",
 620             KSTAT_DATA_UINT64);
 621         kstat_named_init(&ipk->ipk_priority_xon_2_xoff[7],
 622             "priority_xon_2_xoff[7]",
 623             KSTAT_DATA_UINT64);
 624 
 625         kstat_named_init(&ipk->ipk_crc_errors, "crc_errors",
 626             KSTAT_DATA_UINT64);
 627         kstat_named_init(&ipk->ipk_illegal_bytes, "illegal_bytes",
 628             KSTAT_DATA_UINT64);
 629         kstat_named_init(&ipk->ipk_mac_local_faults, "mac_local_faults",
 630             KSTAT_DATA_UINT64);
 631         kstat_named_init(&ipk->ipk_mac_remote_faults, "mac_remote_faults",
 632             KSTAT_DATA_UINT64);
 633         kstat_named_init(&ipk->ipk_rx_length_errors, "rx_length_errors",
 634             KSTAT_DATA_UINT64);
 635         kstat_named_init(&ipk->ipk_rx_undersize, "rx_undersize",
 636             KSTAT_DATA_UINT64);
 637         kstat_named_init(&ipk->ipk_rx_fragments, "rx_fragments",
 638             KSTAT_DATA_UINT64);
 639         kstat_named_init(&ipk->ipk_rx_oversize, "rx_oversize",
 640             KSTAT_DATA_UINT64);
 641         kstat_named_init(&ipk->ipk_rx_jabber, "rx_jabber",
 642             KSTAT_DATA_UINT64);
 643         kstat_named_init(&ipk->ipk_rx_discards, "rx_discards",
 644             KSTAT_DATA_UINT64);
 645         kstat_named_init(&ipk->ipk_rx_vm_discards, "rx_vm_discards",
 646             KSTAT_DATA_UINT64);
 647         kstat_named_init(&ipk->ipk_rx_short_discards, "rx_short_discards",
 648             KSTAT_DATA_UINT64);
 649         kstat_named_init(&ipk->ipk_tx_dropped_link_down, "tx_dropped_link_down",
 650             KSTAT_DATA_UINT64);
 651         kstat_named_init(&ipk->ipk_rx_unknown_protocol, "rx_unknown_protocol",
 652             KSTAT_DATA_UINT64);
 653         kstat_named_init(&ipk->ipk_rx_err1, "rx_err1",
 654             KSTAT_DATA_UINT64);
 655         kstat_named_init(&ipk->ipk_rx_err2, "rx_err2",
 656             KSTAT_DATA_UINT64);
 657 
 658 
 659         bzero(&i40e->i40e_pf_stat, sizeof (i40e_pf_stats_t));
 660         i40e_stat_pf_update(i40e, B_TRUE);
 661 
 662         kstat_install(i40e->i40e_pf_kstat);
 663 
 664         return (B_TRUE);
 665 }
 666 
 667 void
 668 i40e_stats_fini(i40e_t *i40e)
 669 {
 670 #ifdef DEBUG
 671         for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++) {
 672                 ASSERT3P(i40e->i40e_vsis[i].iv_kstats, ==, NULL);
 673         }
 674 #endif
 675 
 676         if (i40e->i40e_pf_kstat != NULL) {
 677                 kstat_delete(i40e->i40e_pf_kstat);
 678                 i40e->i40e_pf_kstat = NULL;
 679         }
 680 
 681         mutex_destroy(&i40e->i40e_stat_lock);
 682 }
 683 
 684 boolean_t
 685 i40e_stats_init(i40e_t *i40e)
 686 {
 687         mutex_init(&i40e->i40e_stat_lock, NULL, MUTEX_DRIVER, NULL);
 688         if (i40e_stat_pf_init(i40e) == B_FALSE) {
 689                 mutex_destroy(&i40e->i40e_stat_lock);
 690                 return (B_FALSE);
 691         }
 692 
 693         return (B_TRUE);
 694 }
 695 
 696 /*
 697  * For Nemo/GLDv3.
 698  */
 699 int
 700 i40e_m_stat(void *arg, uint_t stat, uint64_t *val)
 701 {
 702         i40e_t *i40e = (i40e_t *)arg;
 703         i40e_hw_t *hw = &i40e->i40e_hw_space;
 704         int port = i40e->i40e_hw_space.port;
 705         i40e_pf_stats_t *ips;
 706         i40e_pf_kstats_t *ipk;
 707 
 708 
 709         ASSERT(i40e->i40e_pf_kstat != NULL);
 710         ips = &i40e->i40e_pf_stat;
 711         ipk = i40e->i40e_pf_kstat->ks_data;
 712 
 713         /*
 714          * We need both locks, as various stats are protected by different
 715          * things here.
 716          */
 717         mutex_enter(&i40e->i40e_general_lock);
 718 
 719         if (i40e->i40e_state & I40E_SUSPENDED) {
 720                 mutex_exit(&i40e->i40e_general_lock);
 721                 return (ECANCELED);
 722         }
 723 
 724         mutex_enter(&i40e->i40e_stat_lock);
 725 
 726         /*
 727          * Unfortunately the GLDv3 conflates two rather different things here.
 728          * We're combining statistics about the physical port represented by
 729          * this instance with statistics that describe the properties of the
 730          * logical interface. As such, we're going to use the various aspects of
 731          * the port to describe these stats as they represent what the physical
 732          * instance is doing, even though that that means some tools may be
 733          * confused and that to see the logical traffic on the interface itself
 734          * sans VNICs and the like will require more work.
 735          *
 736          * Stats which are not listed in this switch statement are unimplemented
 737          * at this time in hardware or don't currently apply to the device.
 738          */
 739         switch (stat) {
 740         /* MIB-II stats (RFC 1213 and RFC 1573) */
 741         case MAC_STAT_IFSPEED:
 742                 *val = i40e->i40e_link_speed * 1000000ull;
 743                 break;
 744         case MAC_STAT_MULTIRCV:
 745                 i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
 746                     &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, B_FALSE);
 747                 *val = ipk->ipk_rx_multicast.value.ui64;
 748                 break;
 749         case MAC_STAT_BRDCSTRCV:
 750                 i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
 751                     &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, B_FALSE);
 752                 *val = ipk->ipk_rx_broadcast.value.ui64;
 753                 break;
 754         case MAC_STAT_MULTIXMT:
 755                 i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
 756                     &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, B_FALSE);
 757                 *val = ipk->ipk_tx_multicast.value.ui64;
 758                 break;
 759         case MAC_STAT_BRDCSTXMT:
 760                 i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
 761                     &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, B_FALSE);
 762                 *val = ipk->ipk_tx_broadcast.value.ui64;
 763                 break;
 764         case MAC_STAT_NORCVBUF:
 765                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RDPC(port),
 766                     &ipk->ipk_rx_discards, &ips->ips_rx_discards, B_FALSE);
 767                 i40e_stat_get_uint32(i40e, I40E_GLPRT_LDPC(port),
 768                     &ipk->ipk_rx_vm_discards, &ips->ips_rx_vm_discards,
 769                     B_FALSE);
 770                 *val = ipk->ipk_rx_discards.value.ui64 +
 771                     ipk->ipk_rx_vm_discards.value.ui64;
 772                 break;
 773         /*
 774          * Note, that some RXERR2 stats are also duplicated by the switch filter
 775          * stats; however, since we're not using those at this time, it seems
 776          * reasonable to include them.
 777          */
 778         case MAC_STAT_IERRORS:
 779                 i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
 780                     &ipk->ipk_crc_errors, &ips->ips_crc_errors, B_FALSE);
 781                 i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
 782                     &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, B_FALSE);
 783                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
 784                     &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors,
 785                     B_FALSE);
 786                 i40e_stat_get_uint48(i40e, I40E_GL_RXERR1_L(port),
 787                     &ipk->ipk_rx_err1, &ips->ips_rx_err1, B_FALSE);
 788                 i40e_stat_get_uint48(i40e, I40E_GL_RXERR2_L(port),
 789                     &ipk->ipk_rx_err2, &ips->ips_rx_err2, B_FALSE);
 790 
 791                 *val = ipk->ipk_crc_errors.value.ui64 +
 792                     ipk->ipk_illegal_bytes.value.ui64 +
 793                     ipk->ipk_rx_length_errors.value.ui64 +
 794                     ipk->ipk_rx_err1.value.ui64 +
 795                     ipk->ipk_rx_err2.value.ui64;
 796                 break;
 797         case MAC_STAT_UNKNOWNS:
 798                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RUPP(port),
 799                     &ipk->ipk_rx_unknown_protocol,
 800                     &ips->ips_rx_unknown_protocol,
 801                     B_FALSE);
 802                 *val = ipk->ipk_rx_unknown_protocol.value.ui64;
 803                 break;
 804         case MAC_STAT_RBYTES:
 805                 i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
 806                     &ipk->ipk_rx_bytes, &ips->ips_rx_bytes, B_FALSE);
 807                 *val = ipk->ipk_rx_bytes.value.ui64;
 808                 break;
 809         case MAC_STAT_IPACKETS:
 810                 i40e_stat_get_uint48(i40e, I40E_GLPRT_UPRCL(port),
 811                     &ipk->ipk_rx_unicast, &ips->ips_rx_unicast, B_FALSE);
 812                 i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
 813                     &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, B_FALSE);
 814                 i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
 815                     &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, B_FALSE);
 816                 *val = ipk->ipk_rx_unicast.value.ui64 +
 817                     ipk->ipk_rx_multicast.value.ui64 +
 818                     ipk->ipk_rx_broadcast.value.ui64;
 819                 break;
 820         case MAC_STAT_OBYTES:
 821                 i40e_stat_get_uint48(i40e, I40E_GLPRT_GOTCL(port),
 822                     &ipk->ipk_tx_bytes, &ips->ips_tx_bytes, B_FALSE);
 823                 *val = ipk->ipk_tx_bytes.value.ui64;
 824                 break;
 825         case MAC_STAT_OPACKETS:
 826                 i40e_stat_get_uint48(i40e, I40E_GLPRT_UPTCL(port),
 827                     &ipk->ipk_tx_unicast, &ips->ips_tx_unicast, B_FALSE);
 828                 i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
 829                     &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, B_FALSE);
 830                 i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
 831                     &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, B_FALSE);
 832                 *val = ipk->ipk_tx_unicast.value.ui64 +
 833                     ipk->ipk_tx_multicast.value.ui64 +
 834                     ipk->ipk_tx_broadcast.value.ui64;
 835                 break;
 836         case MAC_STAT_UNDERFLOWS:
 837                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
 838                     &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, B_FALSE);
 839                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
 840                     &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, B_FALSE);
 841                 i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
 842                     &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards,
 843                     B_FALSE);
 844                 *val = ipk->ipk_rx_undersize.value.ui64 +
 845                     ipk->ipk_rx_fragments.value.ui64 +
 846                     ipk->ipk_rx_short_discards.value.ui64;
 847                 break;
 848         case MAC_STAT_OVERFLOWS:
 849                 i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
 850                     &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, B_FALSE);
 851                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
 852                     &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, B_FALSE);
 853                 *val = ipk->ipk_rx_oversize.value.ui64 +
 854                     ipk->ipk_rx_fragments.value.ui64;
 855                 break;
 856 
 857         /* RFC 1643 stats */
 858         case ETHER_STAT_FCS_ERRORS:
 859                 i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
 860                     &ipk->ipk_crc_errors, &ips->ips_crc_errors, B_FALSE);
 861                 *val = ipk->ipk_crc_errors.value.ui64;
 862                 break;
 863         case ETHER_STAT_TOOLONG_ERRORS:
 864                 i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
 865                     &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, B_FALSE);
 866                 *val = ipk->ipk_rx_oversize.value.ui64;
 867                 break;
 868         case ETHER_STAT_MACRCV_ERRORS:
 869                 i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
 870                     &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, B_FALSE);
 871                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
 872                     &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors,
 873                     B_FALSE);
 874                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
 875                     &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, B_FALSE);
 876                 *val = ipk->ipk_illegal_bytes.value.ui64 +
 877                     ipk->ipk_rx_length_errors.value.ui64 +
 878                     ipk->ipk_rx_fragments.value.ui64;
 879                 break;
 880         /* MII/GMII stats */
 881 
 882         /*
 883          * The receiver address is apparently the same as the port number.
 884          */
 885         case ETHER_STAT_XCVR_ADDR:
 886                 /* The Receiver address is apparently the same as the port */
 887                 *val = i40e->i40e_hw_space.port;
 888                 break;
 889         case ETHER_STAT_XCVR_ID:
 890                 switch (hw->phy.media_type) {
 891                 case I40E_MEDIA_TYPE_BASET:
 892                         /*
 893                          * Transform the data here into the ID. Note, generally
 894                          * the revision is left out.
 895                          */
 896                         *val = i40e->i40e_phy.phy_id[3] << 24 |
 897                             i40e->i40e_phy.phy_id[2] << 16 |
 898                             i40e->i40e_phy.phy_id[1] << 8;
 899                         break;
 900                 case I40E_MEDIA_TYPE_FIBER:
 901                 case I40E_MEDIA_TYPE_BACKPLANE:
 902                 case I40E_MEDIA_TYPE_CX4:
 903                 case I40E_MEDIA_TYPE_DA:
 904                 case I40E_MEDIA_TYPE_VIRTUAL:
 905                         *val = i40e->i40e_phy.phy_id[0] |
 906                             i40e->i40e_phy.phy_id[1] << 8 |
 907                             i40e->i40e_phy.phy_id[2] << 16;
 908                         break;
 909                 case I40E_MEDIA_TYPE_UNKNOWN:
 910                 default:
 911                         goto unimpl;
 912                 }
 913                 break;
 914         case ETHER_STAT_XCVR_INUSE:
 915                 switch (hw->phy.link_info.phy_type) {
 916                 case I40E_PHY_TYPE_100BASE_TX:
 917                         *val = XCVR_100T2;
 918                         break;
 919                 case I40E_PHY_TYPE_1000BASE_T:
 920                         *val = XCVR_1000T;
 921                         break;
 922                 default:
 923                         *val = XCVR_UNDEFINED;
 924                         break;
 925                 }
 926                 break;
 927 
 928         /*
 929          * This group answers the question of do we support a given speed in
 930          * theory.
 931          */
 932         case ETHER_STAT_CAP_100FDX:
 933                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0;
 934                 break;
 935         case ETHER_STAT_CAP_1000FDX:
 936                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0;
 937                 break;
 938         case ETHER_STAT_CAP_10GFDX:
 939                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0;
 940                 break;
 941         case ETHER_STAT_CAP_25GFDX:
 942                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0;
 943                 break;
 944         case ETHER_STAT_CAP_40GFDX:
 945                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0;
 946                 break;
 947 
 948         /*
 949          * These ask are we currently advertising these speeds and abilities.
 950          * Until we support setting these because we're working with a copper
 951          * PHY, then the only things we advertise are based on the link PHY
 952          * speeds. In other words, we advertise everything we support.
 953          */
 954         case ETHER_STAT_ADV_CAP_100FDX:
 955                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0;
 956                 break;
 957         case ETHER_STAT_ADV_CAP_1000FDX:
 958                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0;
 959                 break;
 960         case ETHER_STAT_ADV_CAP_10GFDX:
 961                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0;
 962                 break;
 963         case ETHER_STAT_ADV_CAP_25GFDX:
 964                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0;
 965                 break;
 966         case ETHER_STAT_ADV_CAP_40GFDX:
 967                 *val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0;
 968                 break;
 969 
 970         /*
 971          * These ask if the peer supports these speeds, e.g. what did they tell
 972          * us in auto-negotiation. Unfortunately, hardware doesn't appear to
 973          * give us a way to determine whether or not they actually support
 974          * something, only what they have enabled. This means that all we can
 975          * tell the user is the speed that we're currently at, unfortunately.
 976          */
 977         case ETHER_STAT_LP_CAP_100FDX:
 978                 *val = i40e->i40e_link_speed == 100;
 979                 break;
 980         case ETHER_STAT_LP_CAP_1000FDX:
 981                 *val = i40e->i40e_link_speed == 1000;
 982                 break;
 983         case ETHER_STAT_LP_CAP_10GFDX:
 984                 *val = i40e->i40e_link_speed == 10000;
 985                 break;
 986         case ETHER_STAT_LP_CAP_25GFDX:
 987                 *val = i40e->i40e_link_speed == 25000;
 988                 break;
 989         case ETHER_STAT_LP_CAP_40GFDX:
 990                 *val = i40e->i40e_link_speed == 40000;
 991                 break;
 992 
 993         /*
 994          * Statistics for unsupported speeds. Note that these often have the
 995          * same constraints as the other ones. For example, we can't answer the
 996          * question of the ETHER_STAT_LP_CAP family because hardware doesn't
 997          * give us any way of knowing whether or not it does.
 998          */
 999         case ETHER_STAT_CAP_100HDX:
1000         case ETHER_STAT_CAP_1000HDX:
1001         case ETHER_STAT_CAP_10FDX:
1002         case ETHER_STAT_CAP_10HDX:
1003         case ETHER_STAT_CAP_100T4:
1004         case ETHER_STAT_CAP_100GFDX:
1005         case ETHER_STAT_CAP_50GFDX:
1006         case ETHER_STAT_CAP_2500FDX:
1007         case ETHER_STAT_CAP_5000FDX:
1008         case ETHER_STAT_ADV_CAP_1000HDX:
1009         case ETHER_STAT_ADV_CAP_100HDX:
1010         case ETHER_STAT_ADV_CAP_10FDX:
1011         case ETHER_STAT_ADV_CAP_10HDX:
1012         case ETHER_STAT_ADV_CAP_100T4:
1013         case ETHER_STAT_ADV_CAP_100GFDX:
1014         case ETHER_STAT_ADV_CAP_50GFDX:
1015         case ETHER_STAT_ADV_CAP_2500FDX:
1016         case ETHER_STAT_ADV_CAP_5000FDX:
1017         case ETHER_STAT_LP_CAP_1000HDX:
1018         case ETHER_STAT_LP_CAP_100HDX:
1019         case ETHER_STAT_LP_CAP_10FDX:
1020         case ETHER_STAT_LP_CAP_10HDX:
1021         case ETHER_STAT_LP_CAP_100T4:
1022         case ETHER_STAT_LP_CAP_100GFDX:
1023         case ETHER_STAT_LP_CAP_50GFDX:
1024         case ETHER_STAT_LP_CAP_2500FDX:
1025         case ETHER_STAT_LP_CAP_5000FDX:
1026                 *val = 0;
1027                 break;
1028 
1029         case ETHER_STAT_LINK_DUPLEX:
1030                 *val = i40e->i40e_link_duplex;
1031                 break;
1032         case ETHER_STAT_TOOSHORT_ERRORS:
1033                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
1034                     &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, B_FALSE);
1035 
1036                 i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
1037                     &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards,
1038                     B_FALSE);
1039                 *val = ipk->ipk_rx_undersize.value.ui64 +
1040                     ipk->ipk_rx_short_discards.value.ui64;
1041                 break;
1042         case ETHER_STAT_JABBER_ERRORS:
1043                 i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
1044                     &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, B_FALSE);
1045                 *val = ipk->ipk_rx_jabber.value.ui64;
1046                 break;
1047 
1048         /*
1049          * Non-Link speed related capabilities.
1050          */
1051         case ETHER_STAT_CAP_AUTONEG:
1052                 *val = 1;
1053                 break;
1054 
1055         case ETHER_STAT_ADV_CAP_AUTONEG:
1056                 *val = 1;
1057                 break;
1058 
1059         case ETHER_STAT_LP_CAP_AUTONEG:
1060                 *val = (hw->phy.link_info.an_info & I40E_AQ_LP_AN_ABILITY) != 0;
1061                 break;
1062 
1063         case ETHER_STAT_LINK_AUTONEG:
1064                 *val = 1;
1065                 break;
1066 
1067         /*
1068          * Note that while the hardware does support the pause functionality, at
1069          * this time we do not use it at all and effectively disable it.
1070          */
1071         case ETHER_STAT_CAP_ASMPAUSE:
1072                 *val = (i40e->i40e_phy.abilities &
1073                     I40E_AQ_PHY_FLAG_PAUSE_RX) != 0;
1074                 break;
1075         case ETHER_STAT_CAP_PAUSE:
1076                 *val = (i40e->i40e_phy.abilities &
1077                     I40E_AQ_PHY_FLAG_PAUSE_TX) != 0;
1078                 break;
1079 
1080         /*
1081          * Because we don't support these at this time, they are always
1082          * hard-coded to zero.
1083          */
1084         case ETHER_STAT_ADV_CAP_ASMPAUSE:
1085         case ETHER_STAT_ADV_CAP_PAUSE:
1086                 *val = 0;
1087                 break;
1088 
1089         /*
1090          * Like the other LP fields, we can only answer the question have we
1091          * enabled it, not whether the other end actually supports it.
1092          */
1093         case ETHER_STAT_LP_CAP_ASMPAUSE:
1094         case ETHER_STAT_LINK_ASMPAUSE:
1095                 *val = (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX) != 0;
1096                 break;
1097         case ETHER_STAT_LP_CAP_PAUSE:
1098         case ETHER_STAT_LINK_PAUSE:
1099                 *val = (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX) != 0;
1100                 break;
1101 
1102         default:
1103         unimpl:
1104                 mutex_exit(&i40e->i40e_stat_lock);
1105                 mutex_exit(&i40e->i40e_general_lock);
1106                 return (ENOTSUP);
1107         }
1108 
1109         mutex_exit(&i40e->i40e_stat_lock);
1110         mutex_exit(&i40e->i40e_general_lock);
1111 
1112         if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
1113             DDI_FM_OK) {
1114                 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_DEGRADED);
1115                 return (EIO);
1116         }
1117 
1118         return (0);
1119 }
1120 
1121 int
1122 i40e_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1123 {
1124         i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh;
1125         i40e_t *i40e = itrq->itrq_i40e;
1126 
1127         if (i40e->i40e_state & I40E_SUSPENDED) {
1128                 return (ECANCELED);
1129         }
1130 
1131         switch (stat) {
1132         case MAC_STAT_RBYTES:
1133                 *val = itrq->itrq_rxstat.irxs_bytes.value.ui64;
1134                 break;
1135         case MAC_STAT_IPACKETS:
1136                 *val = itrq->itrq_rxstat.irxs_packets.value.ui64;
1137                 break;
1138         default:
1139                 *val = 0;
1140                 return (ENOTSUP);
1141         }
1142 
1143         return (0);
1144 }
1145 
1146 int
1147 i40e_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1148 {
1149         i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh;
1150         i40e_t *i40e = itrq->itrq_i40e;
1151 
1152         if (i40e->i40e_state & I40E_SUSPENDED) {
1153                 return (ECANCELED);
1154         }
1155 
1156         switch (stat) {
1157         case MAC_STAT_OBYTES:
1158                 *val = itrq->itrq_txstat.itxs_bytes.value.ui64;
1159                 break;
1160         case MAC_STAT_OPACKETS:
1161                 *val = itrq->itrq_txstat.itxs_packets.value.ui64;
1162                 break;
1163         default:
1164                 *val = 0;
1165                 return (ENOTSUP);
1166         }
1167 
1168         return (0);
1169 }
1170 
1171 /*
1172  * When we end up refactoring all off the queue assignments and have non-static
1173  * queue to VSI mappings, then we may need to revisit the general locking
1174  * strategy that we employ and have the kstat creation / deletion be part of the
1175  * ring start and stop routines.
1176  */
1177 void
1178 i40e_stats_trqpair_fini(i40e_trqpair_t *itrq)
1179 {
1180         if (itrq->itrq_txkstat != NULL) {
1181                 kstat_delete(itrq->itrq_txkstat);
1182                 itrq->itrq_txkstat = NULL;
1183         }
1184 
1185         if (itrq->itrq_rxkstat != NULL) {
1186                 kstat_delete(itrq->itrq_rxkstat);
1187                 itrq->itrq_rxkstat = NULL;
1188         }
1189 }
1190 
1191 boolean_t
1192 i40e_stats_trqpair_init(i40e_trqpair_t *itrq)
1193 {
1194         char buf[128];
1195         i40e_t *i40e = itrq->itrq_i40e;
1196         i40e_txq_stat_t *tsp = &itrq->itrq_txstat;
1197         i40e_rxq_stat_t *rsp = &itrq->itrq_rxstat;
1198 
1199         (void) snprintf(buf, sizeof (buf), "trqpair_tx_%d", itrq->itrq_index);
1200         itrq->itrq_txkstat = kstat_create(I40E_MODULE_NAME,
1201             ddi_get_instance(i40e->i40e_dip), buf, "net", KSTAT_TYPE_NAMED,
1202             sizeof (i40e_txq_stat_t) / sizeof (kstat_named_t),
1203             KSTAT_FLAG_VIRTUAL);
1204 
1205         if (itrq->itrq_txkstat == NULL)
1206                 return (B_FALSE);
1207 
1208         (void) snprintf(buf, sizeof (buf), "trqpair_rx_%d", itrq->itrq_index);
1209         itrq->itrq_rxkstat = kstat_create(I40E_MODULE_NAME,
1210             ddi_get_instance(i40e->i40e_dip), buf, "net", KSTAT_TYPE_NAMED,
1211             sizeof (i40e_rxq_stat_t) / sizeof (kstat_named_t),
1212             KSTAT_FLAG_VIRTUAL);
1213 
1214         if (itrq->itrq_rxkstat == NULL) {
1215                 kstat_delete(itrq->itrq_txkstat);
1216                 itrq->itrq_txkstat = NULL;
1217                 return (B_FALSE);
1218         }
1219 
1220         itrq->itrq_txkstat->ks_data = &itrq->itrq_txstat;
1221         itrq->itrq_rxkstat->ks_data = &itrq->itrq_rxstat;
1222 
1223         kstat_named_init(&tsp->itxs_bytes, "tx_bytes",
1224             KSTAT_DATA_UINT64);
1225         tsp->itxs_bytes.value.ui64 = 0;
1226         kstat_named_init(&tsp->itxs_packets, "tx_packets",
1227             KSTAT_DATA_UINT64);
1228         tsp->itxs_packets.value.ui64 = 0;
1229         kstat_named_init(&tsp->itxs_descriptors, "tx_descriptors",
1230             KSTAT_DATA_UINT64);
1231         tsp->itxs_descriptors.value.ui64 = 0;
1232         kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
1233             KSTAT_DATA_UINT64);
1234         tsp->itxs_recycled.value.ui64 = 0;
1235         kstat_named_init(&tsp->itxs_force_copy, "tx_force_copy",
1236             KSTAT_DATA_UINT64);
1237         tsp->itxs_force_copy.value.ui64 = 0;
1238         kstat_named_init(&tsp->itxs_tso_force_copy, "tx_tso_force_copy",
1239             KSTAT_DATA_UINT64);
1240         tsp->itxs_tso_force_copy.value.ui64 = 0;
1241 
1242         kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
1243             KSTAT_DATA_UINT64);
1244         tsp->itxs_hck_meoifail.value.ui64 = 0;
1245         kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
1246             KSTAT_DATA_UINT64);
1247         tsp->itxs_hck_nol2info.value.ui64 = 0;
1248         kstat_named_init(&tsp->itxs_hck_nol3info, "tx_hck_nol3info",
1249             KSTAT_DATA_UINT64);
1250         tsp->itxs_hck_nol3info.value.ui64 = 0;
1251         kstat_named_init(&tsp->itxs_hck_nol4info, "tx_hck_nol4info",
1252             KSTAT_DATA_UINT64);
1253         tsp->itxs_hck_nol4info.value.ui64 = 0;
1254         kstat_named_init(&tsp->itxs_hck_badl3, "tx_hck_badl3",
1255             KSTAT_DATA_UINT64);
1256         tsp->itxs_hck_badl3.value.ui64 = 0;
1257         kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
1258             KSTAT_DATA_UINT64);
1259         tsp->itxs_hck_badl4.value.ui64 = 0;
1260         kstat_named_init(&tsp->itxs_lso_nohck, "tx_lso_nohck",
1261             KSTAT_DATA_UINT64);
1262         tsp->itxs_lso_nohck.value.ui64 = 0;
1263         kstat_named_init(&tsp->itxs_bind_fails, "tx_bind_fails",
1264             KSTAT_DATA_UINT64);
1265         tsp->itxs_bind_fails.value.ui64 = 0;
1266         kstat_named_init(&tsp->itxs_tx_short, "tx_short",
1267             KSTAT_DATA_UINT64);
1268         tsp->itxs_tx_short.value.ui64 = 0;
1269         kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
1270             KSTAT_DATA_UINT64);
1271         tsp->itxs_err_notcb.value.ui64 = 0;
1272         kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1273             KSTAT_DATA_UINT64);
1274         tsp->itxs_err_nodescs.value.ui64 = 0;
1275         kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1276             KSTAT_DATA_UINT64);
1277         tsp->itxs_err_context.value.ui64 = 0;
1278         kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1279             KSTAT_DATA_UINT64);
1280         tsp->itxs_num_unblocked.value.ui64 = 0;
1281 
1282 
1283         kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1284             KSTAT_DATA_UINT64);
1285         rsp->irxs_bytes.value.ui64 = 0;
1286         kstat_named_init(&rsp->irxs_packets, "rx_packets",
1287             KSTAT_DATA_UINT64);
1288         rsp->irxs_packets.value.ui64 = 0;
1289         kstat_named_init(&rsp->irxs_rx_desc_error, "rx_desc_error",
1290             KSTAT_DATA_UINT64);
1291         rsp->irxs_rx_desc_error.value.ui64 = 0;
1292         kstat_named_init(&rsp->irxs_rx_intr_limit, "rx_intr_limit",
1293             KSTAT_DATA_UINT64);
1294         rsp->irxs_rx_intr_limit.value.ui64 = 0;
1295         kstat_named_init(&rsp->irxs_rx_bind_norcb, "rx_bind_norcb",
1296             KSTAT_DATA_UINT64);
1297         rsp->irxs_rx_bind_norcb.value.ui64 = 0;
1298         kstat_named_init(&rsp->irxs_rx_bind_nomp, "rx_bind_nomp",
1299             KSTAT_DATA_UINT64);
1300         rsp->irxs_rx_bind_nomp.value.ui64 = 0;
1301         kstat_named_init(&rsp->irxs_rx_copy_nomem, "rx_copy_nomem",
1302             KSTAT_DATA_UINT64);
1303         rsp->irxs_rx_copy_nomem.value.ui64 = 0;
1304         kstat_named_init(&rsp->irxs_hck_v4hdrok, "rx_hck_v4hdrok",
1305             KSTAT_DATA_UINT64);
1306         rsp->irxs_hck_v4hdrok.value.ui64 = 0;
1307         kstat_named_init(&rsp->irxs_hck_l4hdrok, "rx_hck_l4hdrok",
1308             KSTAT_DATA_UINT64);
1309         rsp->irxs_hck_l4hdrok.value.ui64 = 0;
1310         kstat_named_init(&rsp->irxs_hck_unknown, "rx_hck_unknown",
1311             KSTAT_DATA_UINT64);
1312         rsp->irxs_hck_unknown.value.ui64 = 0;
1313         kstat_named_init(&rsp->irxs_hck_nol3l4p, "rx_hck_nol3l4p",
1314             KSTAT_DATA_UINT64);
1315         rsp->irxs_hck_nol3l4p.value.ui64 = 0;
1316         kstat_named_init(&rsp->irxs_hck_iperr, "rx_hck_iperr",
1317             KSTAT_DATA_UINT64);
1318         rsp->irxs_hck_iperr.value.ui64 = 0;
1319         kstat_named_init(&rsp->irxs_hck_eiperr, "rx_hck_eiperr",
1320             KSTAT_DATA_UINT64);
1321         rsp->irxs_hck_eiperr.value.ui64 = 0;
1322         kstat_named_init(&rsp->irxs_hck_l4err, "rx_hck_l4err",
1323             KSTAT_DATA_UINT64);
1324         rsp->irxs_hck_l4err.value.ui64 = 0;
1325         kstat_named_init(&rsp->irxs_hck_v6skip, "rx_hck_v6skip",
1326             KSTAT_DATA_UINT64);
1327         rsp->irxs_hck_v6skip.value.ui64 = 0;
1328         kstat_named_init(&rsp->irxs_hck_set, "rx_hck_set",
1329             KSTAT_DATA_UINT64);
1330         rsp->irxs_hck_set.value.ui64 = 0;
1331         kstat_named_init(&rsp->irxs_hck_miss, "rx_hck_miss",
1332             KSTAT_DATA_UINT64);
1333         rsp->irxs_hck_miss.value.ui64 = 0;
1334 
1335         kstat_install(itrq->itrq_txkstat);
1336         kstat_install(itrq->itrq_rxkstat);
1337 
1338         return (B_TRUE);
1339 }