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 2016 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
 
  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). Currently we only use one
  73  * VSI per PF (see the i40e_main.c theory statement). The hardware has a limited
  74  * number of statistics units available. While every PF is guaranteed to have a
  75  * statistics unit, it is possible that we will run out for a given VSI. We'll
  76  * have to figure out an appropriate strategy here when we end up supporting
  77  * multiple VSIs.
  78  *
  79  * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
  80  * required to read them and then compute the differences between them. The
  81  * 48-bit counters span more than one 32-bit register in the BAR. The hardware
  82  * suggests that to read them, we perform 64-bit reads of the lower of the two
  83  * registers that make up a 48-bit stat. The hardware guarantees that the reads
  84  * of those two registers will be atomic and we'll get a consistent value, not a
  85  * property it has for every read of two registers.
  86  *
  87  * For every kstat we have based on this, we have a corresponding uint64_t that
  88  * we keep around as a base value in a separate structure. Whenever we read a
  89  * value, we end up grabbing the current value, calculating a difference between
  90  * the previously stored value and the current one, and updating the kstat with
  91  * that difference. After which, we go through and update the base value that we
  92  * stored. This is all encapsulated in i40e_stat_get_uint32() and
  93  * i40e_stat_get_uint48().
  94  *
  95  * The only unfortunate thing here is that the hardware doesn't give us any kind
  96  * of overflow counter. It just tries to make sure that the uint32_t and
  97  * uint48_t counters are large enough to hopefully not overflow right away. This
  98  * isn't the most reassuring statement and we should investigate ways of
  99  * ensuring that if a system is active, but not actively measured, we don't lose
 100  * data.
 101  *
 102  * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
 103  * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstat is in
 104  * i40e_t`i40e_vsi_kstat and the data is backed in the i40e_t`i40e_vsi_stat. All
 105  * of this data is protected by the i40e_stat_lock, which should be taken last,
 106  * when acquiring locks.
 107  */
 108 
 109 static void
 110 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
 111     uint64_t *base, boolean_t init)
 112 {
 113         i40e_hw_t *hw = &i40e->i40e_hw_space;
 114         uint64_t raw, delta;
 115 
 116         ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
 117 
 118         raw = ddi_get64(i40e->i40e_osdep_space.ios_reg_handle,
 119             (uint64_t *)((uintptr_t)hw->hw_addr + reg));
 120 
 121         if (init == B_TRUE) {
 122                 *base = raw;
 123                 return;
 124         }
 125 
 126         /*
 
 152         if (init == B_TRUE) {
 153                 *base = raw;
 154                 return;
 155         }
 156 
 157         /*
 158          * Watch out for wraparound as we only have a 32-bit counter.
 159          */
 160         if (raw >= *base) {
 161                 delta = raw - *base;
 162         } else {
 163                 delta = 0x100000000ULL - *base + raw;
 164         }
 165 
 166         kstat->value.ui64 += delta;
 167         *base = raw;
 168 
 169 }
 170 
 171 static void
 172 i40e_stat_vsi_update(i40e_t *i40e, boolean_t init)
 173 {
 174         i40e_vsi_stats_t *ivs;
 175         i40e_vsi_kstats_t *ivk;
 176         int id = i40e->i40e_vsi_stat_id;
 177 
 178         ASSERT(i40e->i40e_vsi_kstat != NULL);
 179         ivs = &i40e->i40e_vsi_stat;
 180         ivk = i40e->i40e_vsi_kstat->ks_data;
 181 
 182         mutex_enter(&i40e->i40e_stat_lock);
 183 
 184         i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
 185             &ivs->ivs_rx_bytes, init);
 186         i40e_stat_get_uint48(i40e, I40E_GLV_UPRCL(id), &ivk->ivk_rx_unicast,
 187             &ivs->ivs_rx_unicast, init);
 188         i40e_stat_get_uint48(i40e, I40E_GLV_MPRCL(id), &ivk->ivk_rx_multicast,
 189             &ivs->ivs_rx_multicast, init);
 190         i40e_stat_get_uint48(i40e, I40E_GLV_BPRCL(id), &ivk->ivk_rx_broadcast,
 191             &ivs->ivs_rx_broadcast, init);
 192 
 193         i40e_stat_get_uint32(i40e, I40E_GLV_RDPC(id), &ivk->ivk_rx_discards,
 194             &ivs->ivs_rx_discards, init);
 195         i40e_stat_get_uint32(i40e, I40E_GLV_RUPP(id),
 196             &ivk->ivk_rx_unknown_protocol,
 197             &ivs->ivs_rx_unknown_protocol,
 198             init);
 199 
 200         i40e_stat_get_uint48(i40e, I40E_GLV_GOTCL(id), &ivk->ivk_tx_bytes,
 
 214         /*
 215          * We follow ixgbe's lead here and that if a kstat update didn't work
 216          * 100% then we mark service unaffected as opposed to when fetching
 217          * things for MAC directly.
 218          */
 219         if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
 220             DDI_FM_OK) {
 221                 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
 222         }
 223 }
 224 
 225 static int
 226 i40e_stat_vsi_kstat_update(kstat_t *ksp, int rw)
 227 {
 228         i40e_t *i40e;
 229 
 230         if (rw == KSTAT_WRITE)
 231                 return (EACCES);
 232 
 233         i40e = ksp->ks_private;
 234         i40e_stat_vsi_update(i40e, B_FALSE);
 235         return (0);
 236 }
 237 
 238 void
 239 i40e_stat_vsi_fini(i40e_t *i40e)
 240 {
 241         if (i40e->i40e_vsi_kstat != NULL) {
 242                 kstat_delete(i40e->i40e_vsi_kstat);
 243                 i40e->i40e_vsi_kstat = NULL;
 244         }
 245 }
 246 
 247 boolean_t
 248 i40e_stat_vsi_init(i40e_t *i40e)
 249 {
 250         kstat_t *ksp;
 251         i40e_vsi_kstats_t *ivk;
 252         char buf[64];
 253 
 254         (void) snprintf(buf, sizeof (buf), "vsi_%d", i40e->i40e_vsi_id);
 255 
 256         ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
 257             buf, "net", KSTAT_TYPE_NAMED,
 258             sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
 259 
 260         if (ksp == NULL) {
 261                 i40e_error(i40e, "Failed to create kstats for VSI %d",
 262                     i40e->i40e_vsi_id);
 263                 return (B_FALSE);
 264         }
 265 
 266         i40e->i40e_vsi_kstat = ksp;
 267         ivk = ksp->ks_data;
 268         ksp->ks_update = i40e_stat_vsi_kstat_update;
 269         ksp->ks_private = i40e;
 270 
 271         kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
 272             KSTAT_DATA_UINT64);
 273         kstat_named_init(&ivk->ivk_rx_unicast, "rx_unicast",
 274             KSTAT_DATA_UINT64);
 275         kstat_named_init(&ivk->ivk_rx_multicast, "rx_multicast",
 276             KSTAT_DATA_UINT64);
 277         kstat_named_init(&ivk->ivk_rx_broadcast, "rx_broadcast",
 278             KSTAT_DATA_UINT64);
 279         kstat_named_init(&ivk->ivk_rx_discards, "rx_discards",
 280             KSTAT_DATA_UINT64);
 281         kstat_named_init(&ivk->ivk_rx_unknown_protocol, "rx_unknown_protocol",
 282             KSTAT_DATA_UINT64);
 283         kstat_named_init(&ivk->ivk_tx_bytes, "tx_bytes",
 284             KSTAT_DATA_UINT64);
 285         kstat_named_init(&ivk->ivk_tx_unicast, "tx_unicast",
 286             KSTAT_DATA_UINT64);
 287         kstat_named_init(&ivk->ivk_tx_multicast, "tx_multicast",
 288             KSTAT_DATA_UINT64);
 289         kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
 290             KSTAT_DATA_UINT64);
 291         kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
 292             KSTAT_DATA_UINT64);
 293 
 294         bzero(&i40e->i40e_vsi_stat, sizeof (i40e_vsi_stats_t));
 295         i40e_stat_vsi_update(i40e, B_TRUE);
 296         kstat_install(i40e->i40e_vsi_kstat);
 297 
 298         return (B_TRUE);
 299 }
 300 
 301 static void
 302 i40e_stat_pf_update(i40e_t *i40e, boolean_t init)
 303 {
 304         i40e_pf_stats_t *ips;
 305         i40e_pf_kstats_t *ipk;
 306         int port = i40e->i40e_hw_space.port;
 307         int i;
 308 
 309         ASSERT(i40e->i40e_pf_kstat != NULL);
 310         ips = &i40e->i40e_pf_stat;
 311         ipk = i40e->i40e_pf_kstat->ks_data;
 312 
 313         mutex_enter(&i40e->i40e_stat_lock);
 314 
 315         /* 64-bit PCIe regs */
 316         i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
 
 653             KSTAT_DATA_UINT64);
 654         kstat_named_init(&ipk->ipk_rx_unknown_protocol, "rx_unknown_protocol",
 655             KSTAT_DATA_UINT64);
 656         kstat_named_init(&ipk->ipk_rx_err1, "rx_err1",
 657             KSTAT_DATA_UINT64);
 658         kstat_named_init(&ipk->ipk_rx_err2, "rx_err2",
 659             KSTAT_DATA_UINT64);
 660 
 661 
 662         bzero(&i40e->i40e_pf_stat, sizeof (i40e_pf_stats_t));
 663         i40e_stat_pf_update(i40e, B_TRUE);
 664 
 665         kstat_install(i40e->i40e_pf_kstat);
 666 
 667         return (B_TRUE);
 668 }
 669 
 670 void
 671 i40e_stats_fini(i40e_t *i40e)
 672 {
 673         ASSERT(i40e->i40e_vsi_kstat == NULL);
 674         if (i40e->i40e_pf_kstat != NULL) {
 675                 kstat_delete(i40e->i40e_pf_kstat);
 676                 i40e->i40e_pf_kstat = NULL;
 677         }
 678 
 679         mutex_destroy(&i40e->i40e_stat_lock);
 680 }
 681 
 682 boolean_t
 683 i40e_stats_init(i40e_t *i40e)
 684 {
 685         mutex_init(&i40e->i40e_stat_lock, NULL, MUTEX_DRIVER, NULL);
 686         if (i40e_stat_pf_init(i40e) == B_FALSE) {
 687                 mutex_destroy(&i40e->i40e_stat_lock);
 688                 return (B_FALSE);
 689         }
 690 
 691         return (B_TRUE);
 692 }
 693 
 
1213                 kstat_delete(itrq->itrq_txkstat);
1214                 itrq->itrq_txkstat = NULL;
1215                 return (B_FALSE);
1216         }
1217 
1218         itrq->itrq_txkstat->ks_data = &itrq->itrq_txstat;
1219         itrq->itrq_rxkstat->ks_data = &itrq->itrq_rxstat;
1220 
1221         kstat_named_init(&tsp->itxs_bytes, "tx_bytes",
1222             KSTAT_DATA_UINT64);
1223         tsp->itxs_bytes.value.ui64 = 0;
1224         kstat_named_init(&tsp->itxs_packets, "tx_packets",
1225             KSTAT_DATA_UINT64);
1226         tsp->itxs_packets.value.ui64 = 0;
1227         kstat_named_init(&tsp->itxs_descriptors, "tx_descriptors",
1228             KSTAT_DATA_UINT64);
1229         tsp->itxs_descriptors.value.ui64 = 0;
1230         kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
1231             KSTAT_DATA_UINT64);
1232         tsp->itxs_recycled.value.ui64 = 0;
1233 
1234         kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
1235             KSTAT_DATA_UINT64);
1236         tsp->itxs_hck_meoifail.value.ui64 = 0;
1237         kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
1238             KSTAT_DATA_UINT64);
1239         tsp->itxs_hck_nol2info.value.ui64 = 0;
1240         kstat_named_init(&tsp->itxs_hck_nol3info, "tx_hck_nol3info",
1241             KSTAT_DATA_UINT64);
1242         tsp->itxs_hck_nol3info.value.ui64 = 0;
1243         kstat_named_init(&tsp->itxs_hck_nol4info, "tx_hck_nol4info",
1244             KSTAT_DATA_UINT64);
1245         tsp->itxs_hck_nol4info.value.ui64 = 0;
1246         kstat_named_init(&tsp->itxs_hck_badl3, "tx_hck_badl3",
1247             KSTAT_DATA_UINT64);
1248         tsp->itxs_hck_badl3.value.ui64 = 0;
1249         kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
1250             KSTAT_DATA_UINT64);
1251         tsp->itxs_hck_badl4.value.ui64 = 0;
1252         kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
1253             KSTAT_DATA_UINT64);
1254         tsp->itxs_err_notcb.value.ui64 = 0;
1255         kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1256             KSTAT_DATA_UINT64);
1257         tsp->itxs_err_nodescs.value.ui64 = 0;
1258         kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1259             KSTAT_DATA_UINT64);
1260         tsp->itxs_err_context.value.ui64 = 0;
1261         kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1262             KSTAT_DATA_UINT64);
1263         tsp->itxs_num_unblocked.value.ui64 = 0;
1264 
1265 
1266         kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1267             KSTAT_DATA_UINT64);
1268         rsp->irxs_bytes.value.ui64 = 0;
1269         kstat_named_init(&rsp->irxs_packets, "rx_packets",
1270             KSTAT_DATA_UINT64);
1271         rsp->irxs_packets.value.ui64 = 0;
  
 | 
   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
 
  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         /*
 
 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,
 
 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),
 
 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 
 
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_err_notcb, "tx_err_notcb",
1267             KSTAT_DATA_UINT64);
1268         tsp->itxs_err_notcb.value.ui64 = 0;
1269         kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1270             KSTAT_DATA_UINT64);
1271         tsp->itxs_err_nodescs.value.ui64 = 0;
1272         kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1273             KSTAT_DATA_UINT64);
1274         tsp->itxs_err_context.value.ui64 = 0;
1275         kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1276             KSTAT_DATA_UINT64);
1277         tsp->itxs_num_unblocked.value.ui64 = 0;
1278 
1279 
1280         kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1281             KSTAT_DATA_UINT64);
1282         rsp->irxs_bytes.value.ui64 = 0;
1283         kstat_named_init(&rsp->irxs_packets, "rx_packets",
1284             KSTAT_DATA_UINT64);
1285         rsp->irxs_packets.value.ui64 = 0;
  
 |