1*6f443ebcSRyan Zezeski /* 2*6f443ebcSRyan Zezeski * This file and its contents are supplied under the terms of the 3*6f443ebcSRyan Zezeski * Common Development and Distribution License ("CDDL"), version 1.0. 4*6f443ebcSRyan Zezeski * You may only use this file in accordance with the terms of version 5*6f443ebcSRyan Zezeski * 1.0 of the CDDL. 6*6f443ebcSRyan Zezeski * 7*6f443ebcSRyan Zezeski * A full copy of the text of the CDDL should have accompanied this 8*6f443ebcSRyan Zezeski * source. A copy of the CDDL is also available via the Internet at 9*6f443ebcSRyan Zezeski * http://www.illumos.org/license/CDDL. 10*6f443ebcSRyan Zezeski */ 11*6f443ebcSRyan Zezeski 12*6f443ebcSRyan Zezeski /* 13*6f443ebcSRyan Zezeski * Copyright 2021 Oxide Computer Company 14*6f443ebcSRyan Zezeski */ 15*6f443ebcSRyan Zezeski #include "ena.h" 16*6f443ebcSRyan Zezeski 17*6f443ebcSRyan Zezeski /* 18*6f443ebcSRyan Zezeski * The ENA device provides the following hardware stats. It appears 19*6f443ebcSRyan Zezeski * that all stats are available at both a device-level and 20*6f443ebcSRyan Zezeski * queue-level. However, Linux and FreeBSD don't implement queue 21*6f443ebcSRyan Zezeski * scope. It's not clear how one would implement queue scope because 22*6f443ebcSRyan Zezeski * there is nothing in the common code describing how to determine the 23*6f443ebcSRyan Zezeski * queue index number. Both the SQ and CQ have device index values, 24*6f443ebcSRyan Zezeski * but for a given logical queue they don't always match and so it's 25*6f443ebcSRyan Zezeski * not clear what value to use for querying the stats. Therefore, 26*6f443ebcSRyan Zezeski * device-wide basic and extended stats come from the device, while 27*6f443ebcSRyan Zezeski * queue/ring stats come from driver. 28*6f443ebcSRyan Zezeski * 29*6f443ebcSRyan Zezeski * From empirical testing, these statistics appear to be cumulative. 30*6f443ebcSRyan Zezeski * However, this guarantee is not explicitly documented anywhere in 31*6f443ebcSRyan Zezeski * the common code that the author could find. 32*6f443ebcSRyan Zezeski * 33*6f443ebcSRyan Zezeski * BASIC (ENAHW_GET_STATS_TYPE_BASIC) 34*6f443ebcSRyan Zezeski * 35*6f443ebcSRyan Zezeski * - Rx packets/bytes 36*6f443ebcSRyan Zezeski * - Rx drops 37*6f443ebcSRyan Zezeski * - Tx packets/bytes 38*6f443ebcSRyan Zezeski * - Tx drops 39*6f443ebcSRyan Zezeski * 40*6f443ebcSRyan Zezeski * EXTENDED (ENAHW_GET_STATS_TYPE_EXTENDED) 41*6f443ebcSRyan Zezeski * 42*6f443ebcSRyan Zezeski * There is no structure defined for these stats in the Linux 43*6f443ebcSRyan Zezeski * driver. Based on the FreeBSD driver, it looks like extended 44*6f443ebcSRyan Zezeski * stats are simply a buffer of C strings? Come back to this 45*6f443ebcSRyan Zezeski * later. 46*6f443ebcSRyan Zezeski * 47*6f443ebcSRyan Zezeski * ENI (ENAHW_GET_STATS_TYPE_ENI) 48*6f443ebcSRyan Zezeski * 49*6f443ebcSRyan Zezeski * - Rx Bandwidth Allowance Exceeded 50*6f443ebcSRyan Zezeski * - Tx Bandwidth Allowance Exceeded 51*6f443ebcSRyan Zezeski * - PPS Allowance Exceeded (presumably for combined Rx/Tx) 52*6f443ebcSRyan Zezeski * - Connection Tracking PPS Allowance Exceeded 53*6f443ebcSRyan Zezeski * - Link-local PPS Alloance Exceeded 54*6f443ebcSRyan Zezeski */ 55*6f443ebcSRyan Zezeski 56*6f443ebcSRyan Zezeski static int 57*6f443ebcSRyan Zezeski ena_stat_device_basic_update(kstat_t *ksp, int rw) 58*6f443ebcSRyan Zezeski { 59*6f443ebcSRyan Zezeski ena_t *ena = ksp->ks_private; 60*6f443ebcSRyan Zezeski ena_basic_stat_t *ebs = ksp->ks_data; 61*6f443ebcSRyan Zezeski enahw_resp_desc_t resp; 62*6f443ebcSRyan Zezeski enahw_resp_basic_stats_t *stats = &resp.erd_resp.erd_basic_stats; 63*6f443ebcSRyan Zezeski int ret = 0; 64*6f443ebcSRyan Zezeski 65*6f443ebcSRyan Zezeski if (rw == KSTAT_WRITE) { 66*6f443ebcSRyan Zezeski return (EACCES); 67*6f443ebcSRyan Zezeski } 68*6f443ebcSRyan Zezeski 69*6f443ebcSRyan Zezeski if ((ret = ena_admin_get_basic_stats(ena, &resp)) != 0) { 70*6f443ebcSRyan Zezeski return (ret); 71*6f443ebcSRyan Zezeski } 72*6f443ebcSRyan Zezeski 73*6f443ebcSRyan Zezeski mutex_enter(&ena->ena_lock); 74*6f443ebcSRyan Zezeski 75*6f443ebcSRyan Zezeski ebs->ebs_tx_bytes.value.ui64 = 76*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_tx_bytes_high << 32) | 77*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_tx_bytes_low; 78*6f443ebcSRyan Zezeski ebs->ebs_tx_pkts.value.ui64 = 79*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_tx_pkts_high << 32) | 80*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_tx_pkts_low; 81*6f443ebcSRyan Zezeski ebs->ebs_tx_drops.value.ui64 = 82*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_tx_drops_high << 32) | 83*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_tx_drops_low; 84*6f443ebcSRyan Zezeski 85*6f443ebcSRyan Zezeski ebs->ebs_rx_bytes.value.ui64 = 86*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_rx_bytes_high << 32) | 87*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_rx_bytes_low; 88*6f443ebcSRyan Zezeski ebs->ebs_rx_pkts.value.ui64 = 89*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_rx_pkts_high << 32) | 90*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_rx_pkts_low; 91*6f443ebcSRyan Zezeski ebs->ebs_rx_drops.value.ui64 = 92*6f443ebcSRyan Zezeski ((uint64_t)stats->erbs_rx_drops_high << 32) | 93*6f443ebcSRyan Zezeski (uint64_t)stats->erbs_rx_drops_low; 94*6f443ebcSRyan Zezeski 95*6f443ebcSRyan Zezeski mutex_exit(&ena->ena_lock); 96*6f443ebcSRyan Zezeski 97*6f443ebcSRyan Zezeski return (0); 98*6f443ebcSRyan Zezeski } 99*6f443ebcSRyan Zezeski 100*6f443ebcSRyan Zezeski void 101*6f443ebcSRyan Zezeski ena_stat_device_basic_cleanup(ena_t *ena) 102*6f443ebcSRyan Zezeski { 103*6f443ebcSRyan Zezeski if (ena->ena_device_basic_kstat != NULL) { 104*6f443ebcSRyan Zezeski kstat_delete(ena->ena_device_basic_kstat); 105*6f443ebcSRyan Zezeski ena->ena_device_basic_kstat = NULL; 106*6f443ebcSRyan Zezeski } 107*6f443ebcSRyan Zezeski } 108*6f443ebcSRyan Zezeski 109*6f443ebcSRyan Zezeski boolean_t 110*6f443ebcSRyan Zezeski ena_stat_device_basic_init(ena_t *ena) 111*6f443ebcSRyan Zezeski { 112*6f443ebcSRyan Zezeski kstat_t *ksp = kstat_create(ENA_MODULE_NAME, 113*6f443ebcSRyan Zezeski ddi_get_instance(ena->ena_dip), "device_basic", "net", 114*6f443ebcSRyan Zezeski KSTAT_TYPE_NAMED, 115*6f443ebcSRyan Zezeski sizeof (ena_basic_stat_t) / sizeof (kstat_named_t), 0); 116*6f443ebcSRyan Zezeski ena_basic_stat_t *ebs = NULL; 117*6f443ebcSRyan Zezeski 118*6f443ebcSRyan Zezeski if (ksp == NULL) { 119*6f443ebcSRyan Zezeski ena_err(ena, "!failed to create device_basic kstats"); 120*6f443ebcSRyan Zezeski return (B_FALSE); 121*6f443ebcSRyan Zezeski } 122*6f443ebcSRyan Zezeski 123*6f443ebcSRyan Zezeski ena->ena_device_basic_kstat = ksp; 124*6f443ebcSRyan Zezeski ebs = ksp->ks_data; 125*6f443ebcSRyan Zezeski ksp->ks_update = ena_stat_device_basic_update; 126*6f443ebcSRyan Zezeski ksp->ks_private = ena; 127*6f443ebcSRyan Zezeski 128*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_tx_bytes, "tx_bytes", KSTAT_DATA_UINT64); 129*6f443ebcSRyan Zezeski ebs->ebs_tx_bytes.value.ui64 = 0; 130*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_tx_pkts, "tx_packets", KSTAT_DATA_UINT64); 131*6f443ebcSRyan Zezeski ebs->ebs_tx_pkts.value.ui64 = 0; 132*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_tx_drops, "tx_drops", KSTAT_DATA_UINT64); 133*6f443ebcSRyan Zezeski ebs->ebs_tx_drops.value.ui64 = 0; 134*6f443ebcSRyan Zezeski 135*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_rx_bytes, "rx_bytes", KSTAT_DATA_UINT64); 136*6f443ebcSRyan Zezeski ebs->ebs_rx_bytes.value.ui64 = 0; 137*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_rx_pkts, "rx_packets", KSTAT_DATA_UINT64); 138*6f443ebcSRyan Zezeski ebs->ebs_rx_pkts.value.ui64 = 0; 139*6f443ebcSRyan Zezeski kstat_named_init(&ebs->ebs_rx_drops, "rx_drops", KSTAT_DATA_UINT64); 140*6f443ebcSRyan Zezeski ebs->ebs_rx_drops.value.ui64 = 0; 141*6f443ebcSRyan Zezeski 142*6f443ebcSRyan Zezeski kstat_install(ena->ena_device_basic_kstat); 143*6f443ebcSRyan Zezeski return (B_TRUE); 144*6f443ebcSRyan Zezeski } 145*6f443ebcSRyan Zezeski 146*6f443ebcSRyan Zezeski int 147*6f443ebcSRyan Zezeski ena_stat_device_extended_update(kstat_t *ksp, int rw) 148*6f443ebcSRyan Zezeski { 149*6f443ebcSRyan Zezeski ena_t *ena = ksp->ks_private; 150*6f443ebcSRyan Zezeski ena_extended_stat_t *ees = ksp->ks_data; 151*6f443ebcSRyan Zezeski enahw_resp_desc_t resp; 152*6f443ebcSRyan Zezeski enahw_resp_eni_stats_t *stats = &resp.erd_resp.erd_eni_stats; 153*6f443ebcSRyan Zezeski int ret = 0; 154*6f443ebcSRyan Zezeski 155*6f443ebcSRyan Zezeski if (rw == KSTAT_WRITE) { 156*6f443ebcSRyan Zezeski return (EACCES); 157*6f443ebcSRyan Zezeski } 158*6f443ebcSRyan Zezeski 159*6f443ebcSRyan Zezeski if ((ret = ena_admin_get_eni_stats(ena, &resp)) != 0) { 160*6f443ebcSRyan Zezeski return (ret); 161*6f443ebcSRyan Zezeski } 162*6f443ebcSRyan Zezeski 163*6f443ebcSRyan Zezeski mutex_enter(&ena->ena_lock); 164*6f443ebcSRyan Zezeski 165*6f443ebcSRyan Zezeski ees->ees_bw_in_exceeded.value.ui64 = stats->eres_bw_in_exceeded; 166*6f443ebcSRyan Zezeski ees->ees_bw_out_exceeded.value.ui64 = stats->eres_bw_out_exceeded; 167*6f443ebcSRyan Zezeski ees->ees_pps_exceeded.value.ui64 = stats->eres_pps_exceeded; 168*6f443ebcSRyan Zezeski ees->ees_conns_exceeded.value.ui64 = stats->eres_conns_exceeded; 169*6f443ebcSRyan Zezeski ees->ees_linklocal_exceeded.value.ui64 = stats->eres_linklocal_exceeded; 170*6f443ebcSRyan Zezeski 171*6f443ebcSRyan Zezeski mutex_exit(&ena->ena_lock); 172*6f443ebcSRyan Zezeski 173*6f443ebcSRyan Zezeski return (0); 174*6f443ebcSRyan Zezeski } 175*6f443ebcSRyan Zezeski 176*6f443ebcSRyan Zezeski void 177*6f443ebcSRyan Zezeski ena_stat_device_extended_cleanup(ena_t *ena) 178*6f443ebcSRyan Zezeski { 179*6f443ebcSRyan Zezeski if (ena->ena_device_extended_kstat != NULL) { 180*6f443ebcSRyan Zezeski kstat_delete(ena->ena_device_extended_kstat); 181*6f443ebcSRyan Zezeski ena->ena_device_extended_kstat = NULL; 182*6f443ebcSRyan Zezeski } 183*6f443ebcSRyan Zezeski } 184*6f443ebcSRyan Zezeski 185*6f443ebcSRyan Zezeski boolean_t 186*6f443ebcSRyan Zezeski ena_stat_device_extended_init(ena_t *ena) 187*6f443ebcSRyan Zezeski { 188*6f443ebcSRyan Zezeski kstat_t *ksp = kstat_create(ENA_MODULE_NAME, 189*6f443ebcSRyan Zezeski ddi_get_instance(ena->ena_dip), "device_ext", "net", 190*6f443ebcSRyan Zezeski KSTAT_TYPE_NAMED, 191*6f443ebcSRyan Zezeski sizeof (ena_extended_stat_t) / sizeof (kstat_named_t), 0); 192*6f443ebcSRyan Zezeski ena_extended_stat_t *ees; 193*6f443ebcSRyan Zezeski 194*6f443ebcSRyan Zezeski if (ksp == NULL) { 195*6f443ebcSRyan Zezeski ena_err(ena, "!failed to create device_ext kstats"); 196*6f443ebcSRyan Zezeski return (B_FALSE); 197*6f443ebcSRyan Zezeski } 198*6f443ebcSRyan Zezeski 199*6f443ebcSRyan Zezeski ena->ena_device_extended_kstat = ksp; 200*6f443ebcSRyan Zezeski ees = ksp->ks_data; 201*6f443ebcSRyan Zezeski ksp->ks_update = ena_stat_device_extended_update; 202*6f443ebcSRyan Zezeski ksp->ks_private = ena; 203*6f443ebcSRyan Zezeski 204*6f443ebcSRyan Zezeski kstat_named_init(&ees->ees_bw_in_exceeded, "bw_in_exceeded", 205*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 206*6f443ebcSRyan Zezeski ees->ees_bw_in_exceeded.value.ui64 = 0; 207*6f443ebcSRyan Zezeski 208*6f443ebcSRyan Zezeski kstat_named_init(&ees->ees_bw_out_exceeded, "bw_out_exceeded", 209*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 210*6f443ebcSRyan Zezeski ees->ees_bw_out_exceeded.value.ui64 = 0; 211*6f443ebcSRyan Zezeski 212*6f443ebcSRyan Zezeski kstat_named_init(&ees->ees_pps_exceeded, "pps_exceeded", 213*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 214*6f443ebcSRyan Zezeski ees->ees_pps_exceeded.value.ui64 = 0; 215*6f443ebcSRyan Zezeski 216*6f443ebcSRyan Zezeski kstat_named_init(&ees->ees_conns_exceeded, "conns_exceeded", 217*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 218*6f443ebcSRyan Zezeski ees->ees_conns_exceeded.value.ui64 = 0; 219*6f443ebcSRyan Zezeski 220*6f443ebcSRyan Zezeski kstat_named_init(&ees->ees_linklocal_exceeded, "linklocal_exceeded", 221*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 222*6f443ebcSRyan Zezeski ees->ees_linklocal_exceeded.value.ui64 = 0; 223*6f443ebcSRyan Zezeski 224*6f443ebcSRyan Zezeski kstat_install(ena->ena_device_extended_kstat); 225*6f443ebcSRyan Zezeski return (B_TRUE); 226*6f443ebcSRyan Zezeski } 227*6f443ebcSRyan Zezeski 228*6f443ebcSRyan Zezeski void 229*6f443ebcSRyan Zezeski ena_stat_aenq_cleanup(ena_t *ena) 230*6f443ebcSRyan Zezeski { 231*6f443ebcSRyan Zezeski if (ena->ena_aenq_kstat != NULL) { 232*6f443ebcSRyan Zezeski kstat_delete(ena->ena_aenq_kstat); 233*6f443ebcSRyan Zezeski ena->ena_aenq_kstat = NULL; 234*6f443ebcSRyan Zezeski } 235*6f443ebcSRyan Zezeski } 236*6f443ebcSRyan Zezeski 237*6f443ebcSRyan Zezeski boolean_t 238*6f443ebcSRyan Zezeski ena_stat_aenq_init(ena_t *ena) 239*6f443ebcSRyan Zezeski { 240*6f443ebcSRyan Zezeski kstat_t *ksp = kstat_create(ENA_MODULE_NAME, 241*6f443ebcSRyan Zezeski ddi_get_instance(ena->ena_dip), "aenq", "net", KSTAT_TYPE_NAMED, 242*6f443ebcSRyan Zezeski sizeof (ena_aenq_stat_t) / sizeof (kstat_named_t), 243*6f443ebcSRyan Zezeski KSTAT_FLAG_VIRTUAL); 244*6f443ebcSRyan Zezeski ena_aenq_stat_t *eas = &ena->ena_aenq_stat; 245*6f443ebcSRyan Zezeski 246*6f443ebcSRyan Zezeski if (ksp == NULL) { 247*6f443ebcSRyan Zezeski ena_err(ena, "!failed to create aenq kstats"); 248*6f443ebcSRyan Zezeski return (B_FALSE); 249*6f443ebcSRyan Zezeski } 250*6f443ebcSRyan Zezeski 251*6f443ebcSRyan Zezeski ena->ena_aenq_kstat = ksp; 252*6f443ebcSRyan Zezeski ksp->ks_data = eas; 253*6f443ebcSRyan Zezeski 254*6f443ebcSRyan Zezeski kstat_named_init(&eas->eaes_default, "default", KSTAT_DATA_UINT64); 255*6f443ebcSRyan Zezeski eas->eaes_default.value.ui64 = 0; 256*6f443ebcSRyan Zezeski 257*6f443ebcSRyan Zezeski kstat_named_init(&eas->eaes_link_change, "link_change", 258*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 259*6f443ebcSRyan Zezeski eas->eaes_link_change.value.ui64 = 0; 260*6f443ebcSRyan Zezeski 261*6f443ebcSRyan Zezeski kstat_install(ena->ena_aenq_kstat); 262*6f443ebcSRyan Zezeski return (B_TRUE); 263*6f443ebcSRyan Zezeski } 264*6f443ebcSRyan Zezeski 265*6f443ebcSRyan Zezeski void 266*6f443ebcSRyan Zezeski ena_stat_txq_cleanup(ena_txq_t *txq) 267*6f443ebcSRyan Zezeski { 268*6f443ebcSRyan Zezeski if (txq->et_kstat != NULL) { 269*6f443ebcSRyan Zezeski kstat_delete(txq->et_kstat); 270*6f443ebcSRyan Zezeski txq->et_kstat = NULL; 271*6f443ebcSRyan Zezeski } 272*6f443ebcSRyan Zezeski } 273*6f443ebcSRyan Zezeski 274*6f443ebcSRyan Zezeski boolean_t 275*6f443ebcSRyan Zezeski ena_stat_txq_init(ena_txq_t *txq) 276*6f443ebcSRyan Zezeski { 277*6f443ebcSRyan Zezeski ena_t *ena = txq->et_ena; 278*6f443ebcSRyan Zezeski kstat_t *ksp; 279*6f443ebcSRyan Zezeski char buf[128]; 280*6f443ebcSRyan Zezeski ena_txq_stat_t *ets = &txq->et_stat; 281*6f443ebcSRyan Zezeski 282*6f443ebcSRyan Zezeski (void) snprintf(buf, sizeof (buf), "txq_%d", txq->et_txqs_idx); 283*6f443ebcSRyan Zezeski 284*6f443ebcSRyan Zezeski ksp = kstat_create(ENA_MODULE_NAME, ddi_get_instance(ena->ena_dip), buf, 285*6f443ebcSRyan Zezeski "net", KSTAT_TYPE_NAMED, 286*6f443ebcSRyan Zezeski sizeof (ena_txq_stat_t) / sizeof (kstat_named_t), 287*6f443ebcSRyan Zezeski KSTAT_FLAG_VIRTUAL); 288*6f443ebcSRyan Zezeski 289*6f443ebcSRyan Zezeski if (ksp == NULL) { 290*6f443ebcSRyan Zezeski ena_err(ena, "!failed to create %s kstats", buf); 291*6f443ebcSRyan Zezeski return (B_FALSE); 292*6f443ebcSRyan Zezeski } 293*6f443ebcSRyan Zezeski 294*6f443ebcSRyan Zezeski txq->et_kstat = ksp; 295*6f443ebcSRyan Zezeski ksp->ks_data = ets; 296*6f443ebcSRyan Zezeski 297*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_hck_meoifail, "meoi_fail", 298*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 299*6f443ebcSRyan Zezeski ets->ets_hck_meoifail.value.ui64 = 0; 300*6f443ebcSRyan Zezeski 301*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_blocked, "blocked", KSTAT_DATA_UINT64); 302*6f443ebcSRyan Zezeski ets->ets_blocked.value.ui64 = 0; 303*6f443ebcSRyan Zezeski 304*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_unblocked, "unblocked", KSTAT_DATA_UINT64); 305*6f443ebcSRyan Zezeski ets->ets_unblocked.value.ui64 = 0; 306*6f443ebcSRyan Zezeski 307*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_recycled, "recycled", KSTAT_DATA_UINT64); 308*6f443ebcSRyan Zezeski ets->ets_recycled.value.ui64 = 0; 309*6f443ebcSRyan Zezeski 310*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_bytes, "bytes", KSTAT_DATA_UINT64); 311*6f443ebcSRyan Zezeski ets->ets_bytes.value.ui64 = 0; 312*6f443ebcSRyan Zezeski 313*6f443ebcSRyan Zezeski kstat_named_init(&ets->ets_packets, "packets", KSTAT_DATA_UINT64); 314*6f443ebcSRyan Zezeski ets->ets_packets.value.ui64 = 0; 315*6f443ebcSRyan Zezeski 316*6f443ebcSRyan Zezeski kstat_install(txq->et_kstat); 317*6f443ebcSRyan Zezeski return (B_TRUE); 318*6f443ebcSRyan Zezeski } 319*6f443ebcSRyan Zezeski 320*6f443ebcSRyan Zezeski void 321*6f443ebcSRyan Zezeski ena_stat_rxq_cleanup(ena_rxq_t *rxq) 322*6f443ebcSRyan Zezeski { 323*6f443ebcSRyan Zezeski if (rxq->er_kstat != NULL) { 324*6f443ebcSRyan Zezeski kstat_delete(rxq->er_kstat); 325*6f443ebcSRyan Zezeski rxq->er_kstat = NULL; 326*6f443ebcSRyan Zezeski } 327*6f443ebcSRyan Zezeski } 328*6f443ebcSRyan Zezeski 329*6f443ebcSRyan Zezeski boolean_t 330*6f443ebcSRyan Zezeski ena_stat_rxq_init(ena_rxq_t *rxq) 331*6f443ebcSRyan Zezeski { 332*6f443ebcSRyan Zezeski ena_t *ena = rxq->er_ena; 333*6f443ebcSRyan Zezeski kstat_t *ksp; 334*6f443ebcSRyan Zezeski char buf[128]; 335*6f443ebcSRyan Zezeski ena_rxq_stat_t *ers = &rxq->er_stat; 336*6f443ebcSRyan Zezeski 337*6f443ebcSRyan Zezeski (void) snprintf(buf, sizeof (buf), "rxq_%d", rxq->er_rxqs_idx); 338*6f443ebcSRyan Zezeski 339*6f443ebcSRyan Zezeski ksp = kstat_create(ENA_MODULE_NAME, ddi_get_instance(ena->ena_dip), buf, 340*6f443ebcSRyan Zezeski "net", KSTAT_TYPE_NAMED, 341*6f443ebcSRyan Zezeski sizeof (ena_rxq_stat_t) / sizeof (kstat_named_t), 342*6f443ebcSRyan Zezeski KSTAT_FLAG_VIRTUAL); 343*6f443ebcSRyan Zezeski 344*6f443ebcSRyan Zezeski if (ksp == NULL) { 345*6f443ebcSRyan Zezeski ena_err(ena, "!failed to create %s kstats", buf); 346*6f443ebcSRyan Zezeski return (B_FALSE); 347*6f443ebcSRyan Zezeski } 348*6f443ebcSRyan Zezeski 349*6f443ebcSRyan Zezeski rxq->er_kstat = ksp; 350*6f443ebcSRyan Zezeski ksp->ks_data = ers; 351*6f443ebcSRyan Zezeski 352*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_packets, "packets", KSTAT_DATA_UINT64); 353*6f443ebcSRyan Zezeski ers->ers_packets.value.ui64 = 0; 354*6f443ebcSRyan Zezeski 355*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_bytes, "bytes", KSTAT_DATA_UINT64); 356*6f443ebcSRyan Zezeski ers->ers_bytes.value.ui64 = 0; 357*6f443ebcSRyan Zezeski 358*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_multi_desc, "multi_desc", KSTAT_DATA_UINT64); 359*6f443ebcSRyan Zezeski ers->ers_multi_desc.value.ui64 = 0; 360*6f443ebcSRyan Zezeski 361*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_allocb_fail, "allocb_fail", 362*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 363*6f443ebcSRyan Zezeski ers->ers_allocb_fail.value.ui64 = 0; 364*6f443ebcSRyan Zezeski 365*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_intr_limit, "intr_limit", KSTAT_DATA_UINT64); 366*6f443ebcSRyan Zezeski ers->ers_intr_limit.value.ui64 = 0; 367*6f443ebcSRyan Zezeski 368*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_hck_ipv4_err, "hck_ipv4_err", 369*6f443ebcSRyan Zezeski KSTAT_DATA_UINT64); 370*6f443ebcSRyan Zezeski ers->ers_hck_ipv4_err.value.ui64 = 0; 371*6f443ebcSRyan Zezeski 372*6f443ebcSRyan Zezeski kstat_named_init(&ers->ers_hck_l4_err, "hck_l4_err", KSTAT_DATA_UINT64); 373*6f443ebcSRyan Zezeski ers->ers_hck_l4_err.value.ui64 = 0; 374*6f443ebcSRyan Zezeski 375*6f443ebcSRyan Zezeski kstat_install(rxq->er_kstat); 376*6f443ebcSRyan Zezeski return (B_TRUE); 377*6f443ebcSRyan Zezeski } 378*6f443ebcSRyan Zezeski 379*6f443ebcSRyan Zezeski int 380*6f443ebcSRyan Zezeski ena_ring_rx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 381*6f443ebcSRyan Zezeski { 382*6f443ebcSRyan Zezeski int ret = 0; 383*6f443ebcSRyan Zezeski ena_rxq_t *rxq = (ena_rxq_t *)rh; 384*6f443ebcSRyan Zezeski 385*6f443ebcSRyan Zezeski mutex_enter(&rxq->er_stat_lock); 386*6f443ebcSRyan Zezeski 387*6f443ebcSRyan Zezeski switch (stat) { 388*6f443ebcSRyan Zezeski case MAC_STAT_RBYTES: 389*6f443ebcSRyan Zezeski *val = rxq->er_stat.ers_bytes.value.ui64; 390*6f443ebcSRyan Zezeski break; 391*6f443ebcSRyan Zezeski case MAC_STAT_IPACKETS: 392*6f443ebcSRyan Zezeski *val = rxq->er_stat.ers_packets.value.ui64; 393*6f443ebcSRyan Zezeski break; 394*6f443ebcSRyan Zezeski default: 395*6f443ebcSRyan Zezeski *val = 0; 396*6f443ebcSRyan Zezeski ret = ENOTSUP; 397*6f443ebcSRyan Zezeski } 398*6f443ebcSRyan Zezeski 399*6f443ebcSRyan Zezeski mutex_exit(&rxq->er_stat_lock); 400*6f443ebcSRyan Zezeski return (ret); 401*6f443ebcSRyan Zezeski } 402*6f443ebcSRyan Zezeski 403*6f443ebcSRyan Zezeski int 404*6f443ebcSRyan Zezeski ena_ring_tx_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val) 405*6f443ebcSRyan Zezeski { 406*6f443ebcSRyan Zezeski int ret = 0; 407*6f443ebcSRyan Zezeski ena_txq_t *txq = (ena_txq_t *)rh; 408*6f443ebcSRyan Zezeski 409*6f443ebcSRyan Zezeski mutex_enter(&txq->et_stat_lock); 410*6f443ebcSRyan Zezeski 411*6f443ebcSRyan Zezeski switch (stat) { 412*6f443ebcSRyan Zezeski case MAC_STAT_OBYTES: 413*6f443ebcSRyan Zezeski *val = txq->et_stat.ets_bytes.value.ui64; 414*6f443ebcSRyan Zezeski break; 415*6f443ebcSRyan Zezeski case MAC_STAT_OPACKETS: 416*6f443ebcSRyan Zezeski *val = txq->et_stat.ets_packets.value.ui64; 417*6f443ebcSRyan Zezeski break; 418*6f443ebcSRyan Zezeski default: 419*6f443ebcSRyan Zezeski *val = 0; 420*6f443ebcSRyan Zezeski ret = ENOTSUP; 421*6f443ebcSRyan Zezeski } 422*6f443ebcSRyan Zezeski 423*6f443ebcSRyan Zezeski mutex_exit(&txq->et_stat_lock); 424*6f443ebcSRyan Zezeski return (ret); 425*6f443ebcSRyan Zezeski } 426*6f443ebcSRyan Zezeski 427*6f443ebcSRyan Zezeski int 428*6f443ebcSRyan Zezeski ena_m_stat(void *arg, uint_t stat, uint64_t *val) 429*6f443ebcSRyan Zezeski { 430*6f443ebcSRyan Zezeski ena_t *ena = arg; 431*6f443ebcSRyan Zezeski ena_basic_stat_t *ebs = ena->ena_device_basic_kstat->ks_data; 432*6f443ebcSRyan Zezeski int ret = 0; 433*6f443ebcSRyan Zezeski 434*6f443ebcSRyan Zezeski ret = ena_stat_device_basic_update(ena->ena_device_basic_kstat, 435*6f443ebcSRyan Zezeski KSTAT_READ); 436*6f443ebcSRyan Zezeski 437*6f443ebcSRyan Zezeski if (ret != 0) { 438*6f443ebcSRyan Zezeski return (ret); 439*6f443ebcSRyan Zezeski } 440*6f443ebcSRyan Zezeski 441*6f443ebcSRyan Zezeski mutex_enter(&ena->ena_lock); 442*6f443ebcSRyan Zezeski 443*6f443ebcSRyan Zezeski /* 444*6f443ebcSRyan Zezeski * The ENA device does not provide a lot of the stats that a 445*6f443ebcSRyan Zezeski * traditional NIC device would. 446*6f443ebcSRyan Zezeski */ 447*6f443ebcSRyan Zezeski switch (stat) { 448*6f443ebcSRyan Zezeski case MAC_STAT_NORCVBUF: 449*6f443ebcSRyan Zezeski *val = ebs->ebs_rx_drops.value.ui64; 450*6f443ebcSRyan Zezeski break; 451*6f443ebcSRyan Zezeski 452*6f443ebcSRyan Zezeski case MAC_STAT_RBYTES: 453*6f443ebcSRyan Zezeski *val = ebs->ebs_rx_bytes.value.ui64; 454*6f443ebcSRyan Zezeski break; 455*6f443ebcSRyan Zezeski 456*6f443ebcSRyan Zezeski case MAC_STAT_IPACKETS: 457*6f443ebcSRyan Zezeski *val = ebs->ebs_rx_pkts.value.ui64; 458*6f443ebcSRyan Zezeski break; 459*6f443ebcSRyan Zezeski 460*6f443ebcSRyan Zezeski case MAC_STAT_OBYTES: 461*6f443ebcSRyan Zezeski *val = ebs->ebs_tx_bytes.value.ui64; 462*6f443ebcSRyan Zezeski break; 463*6f443ebcSRyan Zezeski 464*6f443ebcSRyan Zezeski case MAC_STAT_OPACKETS: 465*6f443ebcSRyan Zezeski *val = ebs->ebs_tx_pkts.value.ui64; 466*6f443ebcSRyan Zezeski break; 467*6f443ebcSRyan Zezeski 468*6f443ebcSRyan Zezeski default: 469*6f443ebcSRyan Zezeski ret = ENOTSUP; 470*6f443ebcSRyan Zezeski break; 471*6f443ebcSRyan Zezeski } 472*6f443ebcSRyan Zezeski 473*6f443ebcSRyan Zezeski mutex_exit(&ena->ena_lock); 474*6f443ebcSRyan Zezeski return (ret); 475*6f443ebcSRyan Zezeski } 476