From d1205d093d72f08d9ff48f987384c2b5ef8e7d2e Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Fri, 4 Mar 2016 13:11:13 +0000 Subject: [PATCH] cxgbe(4): Very basic T6 awareness. This is part of ongoing work to update to the latest internal shared code. - Add a chip_params structure to keep track of hardware constants for all generations of Terminators handled by cxgbe. - Update t4_hw_pci_read_cfg4 to work with T6. - Update the hardware debug sysctls (hidden within dev...misc.*) to work with T6. Most of the changes are in the decoders for the CIM logic analyzer and the MPS TCAM. - Acquire the regwin lock around indirect register accesses. Obtained from: Chelsio Communications Sponsored by: Chelsio Communications --- sys/dev/cxgbe/adapter.h | 5 +- sys/dev/cxgbe/common/common.h | 43 ++- sys/dev/cxgbe/common/t4_hw.c | 152 +++++++-- sys/dev/cxgbe/common/t4_hw.h | 4 + sys/dev/cxgbe/t4_main.c | 570 ++++++++++++++++++++++++++-------- sys/dev/cxgbe/t4_netmap.c | 5 +- sys/dev/cxgbe/t4_sge.c | 5 +- 7 files changed, 608 insertions(+), 176 deletions(-) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 66ae9165765..c91e6a5124f 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -758,9 +758,9 @@ struct adapter { struct sge sge; int lro_timeout; - struct taskqueue *tq[NCHAN]; /* General purpose taskqueues */ + struct taskqueue *tq[MAX_NCHAN]; /* General purpose taskqueues */ struct port_info *port[MAX_NPORTS]; - uint8_t chan_map[NCHAN]; + uint8_t chan_map[MAX_NCHAN]; #ifdef TCP_OFFLOAD void *tom_softc; /* (struct tom_data *) */ @@ -791,6 +791,7 @@ struct adapter { char cfg_file[32]; u_int cfcsum; struct adapter_params params; + const struct chip_params *chip_params; struct t4_virt_res vres; uint16_t linkcaps; diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 38395dc9b5c..f12ad2933a3 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -188,25 +188,25 @@ struct tp_fcoe_stats { }; struct tp_err_stats { - u32 mac_in_errs[4]; - u32 hdr_in_errs[4]; - u32 tcp_in_errs[4]; - u32 tnl_cong_drops[4]; - u32 ofld_chan_drops[4]; - u32 tnl_tx_drops[4]; - u32 ofld_vlan_drops[4]; - u32 tcp6_in_errs[4]; + u32 mac_in_errs[MAX_NCHAN]; + u32 hdr_in_errs[MAX_NCHAN]; + u32 tcp_in_errs[MAX_NCHAN]; + u32 tnl_cong_drops[MAX_NCHAN]; + u32 ofld_chan_drops[MAX_NCHAN]; + u32 tnl_tx_drops[MAX_NCHAN]; + u32 ofld_vlan_drops[MAX_NCHAN]; + u32 tcp6_in_errs[MAX_NCHAN]; u32 ofld_no_neigh; u32 ofld_cong_defer; }; struct tp_proxy_stats { - u32 proxy[4]; + u32 proxy[MAX_NCHAN]; }; struct tp_cpl_stats { - u32 req[4]; - u32 rsp[4]; + u32 req[MAX_NCHAN]; + u32 rsp[MAX_NCHAN]; }; struct tp_rdma_stats { @@ -219,7 +219,7 @@ struct tp_params { unsigned int tre; /* log2 of core clocks per TP tick */ unsigned int dack_re; /* DACK timer resolution */ unsigned int la_mask; /* what events are recorded by TP LA */ - unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */ + unsigned short tx_modq[MAX_NCHAN]; /* channel to modulation queue map */ uint32_t vlan_pri_map; uint32_t ingress_config; int8_t vlan_shift; @@ -253,6 +253,19 @@ struct devlog_params { u32 size; /* size of log */ }; +/* Stores chip specific parameters */ +struct chip_params { + u8 nchan; + u8 pm_stats_cnt; + u8 cng_ch_bits_log; /* congestion channel map bits width */ + u8 nsched_cls; + u8 cim_num_obq; + u16 mps_rplc_size; + u16 vfcount; + u32 sge_fl_db; + u16 mps_tcam_size; +}; + struct adapter_params { struct tp_params tp; struct vpd_params vpd; @@ -292,6 +305,7 @@ struct adapter_params { #define CHELSIO_T4 0x4 #define CHELSIO_T5 0x5 +#define CHELSIO_T6 0x6 struct trace_params { u32 data[TRACE_LEN / 4]; @@ -366,6 +380,11 @@ static inline int is_t5(struct adapter *adap) return adap->params.chipid == CHELSIO_T5; } +static inline int is_t6(struct adapter *adap) +{ + return adap->params.chipid == CHELSIO_T6; +} + static inline int is_fpga(struct adapter *adap) { return adap->params.fpga; diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 2d2fdef038a..980ee963e7e 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -154,26 +154,49 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, * mechanism. This guarantees that we get the real value even if we're * operating within a Virtual Machine and the Hypervisor is trapping our * Configuration Space accesses. + * + * N.B. This routine should only be used as a last resort: the firmware uses + * the backdoor registers on a regular basis and we can end up + * conflicting with it's uses! */ u32 t4_hw_pci_read_cfg4(adapter_t *adap, int reg) { - t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, - F_ENABLE | F_LOCALCFG | V_FUNCTION(adap->pf) | - V_REGISTER(reg)); - return t4_read_reg(adap, A_PCIE_CFG_SPACE_DATA); + u32 req = V_FUNCTION(adap->pf) | V_REGISTER(reg); + u32 val; + + if (chip_id(adap) <= CHELSIO_T5) + req |= F_ENABLE; + else + req |= F_T6_ENABLE; + + if (is_t4(adap)) + req |= F_LOCALCFG; + + t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, req); + val = t4_read_reg(adap, A_PCIE_CFG_SPACE_DATA); + + /* + * Reset F_ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a + * Configuration Space read. (None of the other fields matter when + * F_ENABLE is 0 so a simple register write is easier than a + * read-modify-write via t4_set_reg_field().) + */ + t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, 0); + + return val; } /* - * t4_report_fw_error - report firmware error - * @adap: the adapter + * t4_report_fw_error - report firmware error + * @adap: the adapter * - * The adapter firmware can indicate error conditions to the host. - * This routine prints out the reason for the firmware error (as - * reported by the firmware). + * The adapter firmware can indicate error conditions to the host. + * If the firmware has indicated an error, print out the reason for + * the firmware error. */ static void t4_report_fw_error(struct adapter *adap) { - static const char *reason[] = { + static const char *const reason[] = { "Crash", /* PCIE_FW_EVAL_CRASH */ "During Device Preparation", /* PCIE_FW_EVAL_PREP */ "During Device Configuration", /* PCIE_FW_EVAL_CONF */ @@ -1512,7 +1535,6 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data, void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres) { unsigned int i, v; - int cim_num_obq = is_t4(adap) ? CIM_NUM_OBQ : CIM_NUM_OBQ_T5; for (i = 0; i < CIM_NUM_IBQ; i++) { t4_write_reg(adap, A_CIM_QUEUE_CONFIG_REF, F_IBQSELECT | @@ -1522,7 +1544,7 @@ void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres) *size++ = G_CIMQSIZE(v) * 256; /* value is in 256-byte units */ *thres++ = G_QUEFULLTHRSH(v) * 8; /* 8-byte unit */ } - for (i = 0; i < cim_num_obq; i++) { + for (i = 0; i < adap->chip_params->cim_num_obq; i++) { t4_write_reg(adap, A_CIM_QUEUE_CONFIG_REF, F_OBQSELECT | V_QUENUMSELECT(i)); v = t4_read_reg(adap, A_CIM_QUEUE_CONFIG_CTRL); @@ -1587,9 +1609,8 @@ int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n) { int i, err; unsigned int addr, v, nwords; - int cim_num_obq = is_t4(adap) ? CIM_NUM_OBQ : CIM_NUM_OBQ_T5; - if (qid >= cim_num_obq || (n & 3)) + if (qid >= adap->chip_params->cim_num_obq || (n & 3)) return -EINVAL; t4_write_reg(adap, A_CIM_QUEUE_CONFIG_REF, F_OBQSELECT | @@ -1743,7 +1764,15 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr) ret = t4_cim_read(adap, A_UP_UP_DBG_LA_DATA, 1, &la_buf[i]); if (ret) break; + /* address can't exceed 0xfff (UpDbgLaRdPtr is of 12-bits) */ idx = (idx + 1) & M_UPDBGLARDPTR; + /* + * Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to + * identify the 32-bit portion of the full 312-bit data + */ + if (is_t6(adap)) + while ((idx & 0xf) > 9) + idx = (idx + 1) % M_UPDBGLARDPTR; } restart: if (cfg & F_UPDBGLAEN) { @@ -3223,7 +3252,7 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, */ void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st) { - int nchan = NCHAN; + int nchan = adap->chip_params->nchan; t4_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_DATA, st->mac_in_errs, nchan, A_TP_MIB_MAC_IN_ERR_0); @@ -3255,8 +3284,10 @@ void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st) */ void t4_tp_get_proxy_stats(struct adapter *adap, struct tp_proxy_stats *st) { + int nchan = adap->chip_params->nchan; + t4_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_DATA, st->proxy, - 4, A_TP_MIB_TNL_LPBK_0); + nchan, A_TP_MIB_TNL_LPBK_0); } /** @@ -3268,8 +3299,12 @@ void t4_tp_get_proxy_stats(struct adapter *adap, struct tp_proxy_stats *st) */ void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st) { + int nchan = adap->chip_params->nchan; + t4_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_DATA, st->req, - 8, A_TP_MIB_CPL_IN_REQ_0); + nchan, A_TP_MIB_CPL_IN_REQ_0); + t4_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_DATA, st->rsp, + nchan, A_TP_MIB_CPL_OUT_RSP_0); } /** @@ -3672,14 +3707,18 @@ void t4_get_chan_txrate(struct adapter *adap, u64 *nic_rate, u64 *ofld_rate) v = t4_read_reg(adap, A_TP_TX_TRATE); nic_rate[0] = chan_rate(adap, G_TNLRATE0(v)); nic_rate[1] = chan_rate(adap, G_TNLRATE1(v)); - nic_rate[2] = chan_rate(adap, G_TNLRATE2(v)); - nic_rate[3] = chan_rate(adap, G_TNLRATE3(v)); + if (adap->chip_params->nchan > 2) { + nic_rate[2] = chan_rate(adap, G_TNLRATE2(v)); + nic_rate[3] = chan_rate(adap, G_TNLRATE3(v)); + } v = t4_read_reg(adap, A_TP_TX_ORATE); ofld_rate[0] = chan_rate(adap, G_OFDRATE0(v)); ofld_rate[1] = chan_rate(adap, G_OFDRATE1(v)); - ofld_rate[2] = chan_rate(adap, G_OFDRATE2(v)); - ofld_rate[3] = chan_rate(adap, G_OFDRATE3(v)); + if (adap->chip_params->nchan > 2) { + ofld_rate[2] = chan_rate(adap, G_OFDRATE2(v)); + ofld_rate[3] = chan_rate(adap, G_OFDRATE3(v)); + } } /** @@ -3822,7 +3861,7 @@ void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) int i; u32 data[2]; - for (i = 0; i < PM_NSTATS; i++) { + for (i = 0; i < adap->chip_params->pm_stats_cnt; i++) { t4_write_reg(adap, A_PM_TX_STAT_CONFIG, i + 1); cnt[i] = t4_read_reg(adap, A_PM_TX_STAT_COUNT); if (is_t4(adap)) @@ -3849,7 +3888,7 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) int i; u32 data[2]; - for (i = 0; i < PM_NSTATS; i++) { + for (i = 0; i < adap->chip_params->pm_stats_cnt; i++) { t4_write_reg(adap, A_PM_RX_STAT_CONFIG, i + 1); cnt[i] = t4_read_reg(adap, A_PM_RX_STAT_COUNT); if (is_t4(adap)) @@ -3878,7 +3917,7 @@ static unsigned int get_mps_bg_map(struct adapter *adap, int idx) if (n == 0) return idx == 0 ? 0xf : 0; - if (n == 1) + if (n == 1 && chip_id(adap) <= CHELSIO_T5) return idx < 2 ? (3 << (2 * idx)) : 0; return 1 << idx; } @@ -5130,9 +5169,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, int offset, ret = 0; struct fw_vi_mac_cmd c; unsigned int nfilters = 0; - unsigned int max_naddr = is_t4(adap) ? - NUM_MPS_CLS_SRAM_L_INSTANCES : - NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + unsigned int max_naddr = adap->chip_params->mps_tcam_size; unsigned int rem = naddr; if (naddr > max_naddr) @@ -5223,9 +5260,7 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, int ret, mode; struct fw_vi_mac_cmd c; struct fw_vi_mac_exact *p = c.u.exact; - unsigned int max_mac_addr = is_t4(adap) ? - NUM_MPS_CLS_SRAM_L_INSTANCES : - NUM_MPS_T5_CLS_SRAM_L_INSTANCES; + unsigned int max_mac_addr = adap->chip_params->mps_tcam_size; if (idx < 0) /* new allocation */ idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; @@ -5581,6 +5616,54 @@ static void __devinit set_pcie_completion_timeout(struct adapter *adapter, } } +static const struct chip_params *get_chip_params(int chipid) +{ + static const struct chip_params chip_params[] = { + { + /* T4 */ + .nchan = NCHAN, + .pm_stats_cnt = PM_NSTATS, + .cng_ch_bits_log = 2, + .nsched_cls = 15, + .cim_num_obq = CIM_NUM_OBQ, + .mps_rplc_size = 128, + .vfcount = 128, + .sge_fl_db = F_DBPRIO, + .mps_tcam_size = NUM_MPS_CLS_SRAM_L_INSTANCES, + }, + { + /* T5 */ + .nchan = NCHAN, + .pm_stats_cnt = PM_NSTATS, + .cng_ch_bits_log = 2, + .nsched_cls = 16, + .cim_num_obq = CIM_NUM_OBQ_T5, + .mps_rplc_size = 128, + .vfcount = 128, + .sge_fl_db = F_DBPRIO | F_DBTYPE, + .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES, + }, + { + /* T6 */ + .nchan = T6_NCHAN, + .pm_stats_cnt = T6_PM_NSTATS, + .cng_ch_bits_log = 3, + .nsched_cls = 16, + .cim_num_obq = CIM_NUM_OBQ_T5, + .mps_rplc_size = 256, + .vfcount = 256, + .sge_fl_db = 0, + .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES, + }, + }; + + chipid -= CHELSIO_T4; + if (chipid < 0 || chipid >= ARRAY_SIZE(chip_params)) + return NULL; + + return &chip_params[chipid]; +} + /** * t4_prep_adapter - prepare SW and HW for operation * @adapter: the adapter @@ -5611,6 +5694,11 @@ int __devinit t4_prep_adapter(struct adapter *adapter) return -EINVAL; } } + + adapter->chip_params = get_chip_params(chip_id(adapter)); + if (adapter->chip_params == NULL) + return -EINVAL; + adapter->params.pci.vpd_cap_addr = t4_os_find_pci_capability(adapter, PCI_CAP_ID_VPD); @@ -5624,7 +5712,7 @@ int __devinit t4_prep_adapter(struct adapter *adapter) /* Cards with real ASICs have the chipid in the PCIe device id */ t4_os_pci_read_cfg2(adapter, PCI_DEVICE_ID, &device_id); - if (device_id >> 12 == adapter->params.chipid) + if (device_id >> 12 == chip_id(adapter)) adapter->params.cim_la_size = CIMLA_SIZE; else { /* FPGA */ @@ -5662,7 +5750,7 @@ int __devinit t4_init_tp_params(struct adapter *adap) adap->params.tp.dack_re = G_DELAYEDACKRESOLUTION(v); /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */ - for (chan = 0; chan < NCHAN; chan++) + for (chan = 0; chan < MAX_NCHAN; chan++) adap->params.tp.tx_modq[chan] = chan; t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA, diff --git a/sys/dev/cxgbe/common/t4_hw.h b/sys/dev/cxgbe/common/t4_hw.h index c1a5ce6be3b..cbe2fae1969 100644 --- a/sys/dev/cxgbe/common/t4_hw.h +++ b/sys/dev/cxgbe/common/t4_hw.h @@ -34,6 +34,8 @@ enum { NCHAN = 4, /* # of HW channels */ + T6_NCHAN = 2, + MAX_NCHAN = 4, MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ EEPROMSIZE = 17408, /* Serial EEPROM physical size */ EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */ @@ -44,6 +46,8 @@ enum { NCCTRL_WIN = 32, /* # of congestion control windows */ NTX_SCHED = 8, /* # of HW Tx scheduling queues */ PM_NSTATS = 5, /* # of PM stats */ + T6_PM_NSTATS = 7, + MAX_PM_NSTATS = 7, MBOX_LEN = 64, /* mailbox size in bytes */ NTRACE = 4, /* # of tracing filters */ TRACE_LEN = 112, /* length of trace data and mask */ diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 23e6f503e07..12e32d2148b 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -453,6 +453,7 @@ static int sysctl_temperature(SYSCTL_HANDLER_ARGS); static int sysctl_cctrl(SYSCTL_HANDLER_ARGS); static int sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS); static int sysctl_cim_la(SYSCTL_HANDLER_ARGS); +static int sysctl_cim_la_t6(SYSCTL_HANDLER_ARGS); static int sysctl_cim_ma_la(SYSCTL_HANDLER_ARGS); static int sysctl_cim_pif_la(SYSCTL_HANDLER_ARGS); static int sysctl_cim_qcfg(SYSCTL_HANDLER_ARGS); @@ -465,6 +466,7 @@ static int sysctl_lb_stats(SYSCTL_HANDLER_ARGS); static int sysctl_linkdnrc(SYSCTL_HANDLER_ARGS); static int sysctl_meminfo(SYSCTL_HANDLER_ARGS); static int sysctl_mps_tcam(SYSCTL_HANDLER_ARGS); +static int sysctl_mps_tcam_t6(SYSCTL_HANDLER_ARGS); static int sysctl_path_mtus(SYSCTL_HANDLER_ARGS); static int sysctl_pm_stats(SYSCTL_HANDLER_ARGS); static int sysctl_rdma_stats(SYSCTL_HANDLER_ARGS); @@ -4956,7 +4958,7 @@ cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi) tnl_cong_drops = 0; t4_get_port_stats(sc, pi->tx_chan, &pi->stats); - for (i = 0; i < NCHAN; i++) { + for (i = 0; i < sc->chip_params->nchan; i++) { if (pi->rx_chan_map & (1 << i)) { mtx_lock(&sc->regwin_lock); t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v, @@ -5239,7 +5241,8 @@ t4_sysctls(struct adapter *sc) SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, - sysctl_cim_la, "A", "CIM logic analyzer"); + chip_id(sc) <= CHELSIO_T5 ? sysctl_cim_la : sysctl_cim_la_t6, + "A", "CIM logic analyzer"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ma_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, @@ -5269,7 +5272,7 @@ t4_sysctls(struct adapter *sc) CTLTYPE_STRING | CTLFLAG_RD, sc, 5 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 5 (NCSI)"); - if (is_t5(sc)) { + if (chip_id(sc) > CHELSIO_T4) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_sge0_rx", CTLTYPE_STRING | CTLFLAG_RD, sc, 6 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 6 (SGE0-RX)"); @@ -5321,7 +5324,8 @@ t4_sysctls(struct adapter *sc) SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "mps_tcam", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, - sysctl_mps_tcam, "A", "MPS TCAM entries"); + chip_id(sc) <= CHELSIO_T5 ? sysctl_mps_tcam : sysctl_mps_tcam_t6, + "A", "MPS TCAM entries"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "path_mtus", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, @@ -6034,7 +6038,7 @@ sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS) int rc, i, n, qid = arg2; uint32_t *buf, *p; char *qtype; - u_int cim_num_obq = is_t4(sc) ? CIM_NUM_OBQ : CIM_NUM_OBQ_T5; + u_int cim_num_obq = sc->chip_params->cim_num_obq; KASSERT(qid >= 0 && qid < CIM_NUM_IBQ + cim_num_obq, ("%s: bad qid %d\n", __func__, qid)); @@ -6091,6 +6095,8 @@ sysctl_cim_la(SYSCTL_HANDLER_ARGS) uint32_t *buf, *p; int rc; + MPASS(chip_id(sc) <= CHELSIO_T5); + rc = -t4_cim_read(sc, A_UP_UP_DBG_LA_CFG, 1, &cfg); if (rc != 0) return (rc); @@ -6114,10 +6120,7 @@ sysctl_cim_la(SYSCTL_HANDLER_ARGS) cfg & F_UPDBGLACAPTPCONLY ? "" : " LS0Stat LS0Addr LS0Data"); - KASSERT((sc->params.cim_la_size & 7) == 0, - ("%s: p will walk off the end of buf", __func__)); - - for (p = buf; p < &buf[sc->params.cim_la_size]; p += 8) { + for (p = buf; p <= &buf[sc->params.cim_la_size - 8]; p += 8) { if (cfg & F_UPDBGLACAPTPCONLY) { sbuf_printf(sb, "\n %02x %08x %08x", p[5] & 0xff, p[6], p[7]); @@ -6144,6 +6147,69 @@ sysctl_cim_la(SYSCTL_HANDLER_ARGS) return (rc); } +static int +sysctl_cim_la_t6(SYSCTL_HANDLER_ARGS) +{ + struct adapter *sc = arg1; + u_int cfg; + struct sbuf *sb; + uint32_t *buf, *p; + int rc; + + MPASS(chip_id(sc) > CHELSIO_T5); + + rc = -t4_cim_read(sc, A_UP_UP_DBG_LA_CFG, 1, &cfg); + if (rc != 0) + return (rc); + + rc = sysctl_wire_old_buffer(req, 0); + if (rc != 0) + return (rc); + + sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); + if (sb == NULL) + return (ENOMEM); + + buf = malloc(sc->params.cim_la_size * sizeof(uint32_t), M_CXGBE, + M_ZERO | M_WAITOK); + + rc = -t4_cim_read_la(sc, buf, NULL); + if (rc != 0) + goto done; + + sbuf_printf(sb, "Status Inst Data PC%s", + cfg & F_UPDBGLACAPTPCONLY ? "" : + " LS0Stat LS0Addr LS0Data LS1Stat LS1Addr LS1Data"); + + for (p = buf; p <= &buf[sc->params.cim_la_size - 10]; p += 10) { + if (cfg & F_UPDBGLACAPTPCONLY) { + sbuf_printf(sb, "\n %02x %08x %08x %08x", + p[3] & 0xff, p[2], p[1], p[0]); + sbuf_printf(sb, "\n %02x %02x%06x %02x%06x %02x%06x", + (p[6] >> 8) & 0xff, p[6] & 0xff, p[5] >> 8, + p[5] & 0xff, p[4] >> 8, p[4] & 0xff, p[3] >> 8); + sbuf_printf(sb, "\n %02x %04x%04x %04x%04x %04x%04x", + (p[9] >> 16) & 0xff, p[9] & 0xffff, p[8] >> 16, + p[8] & 0xffff, p[7] >> 16, p[7] & 0xffff, + p[6] >> 16); + } else { + sbuf_printf(sb, "\n %02x %04x%04x %04x%04x %04x%04x " + "%08x %08x %08x %08x %08x %08x", + (p[9] >> 16) & 0xff, + p[9] & 0xffff, p[8] >> 16, + p[8] & 0xffff, p[7] >> 16, + p[7] & 0xffff, p[6] >> 16, + p[2], p[1], p[0], p[5], p[4], p[3]); + } + } + + rc = sbuf_finish(sb); + sbuf_delete(sb); +done: + free(buf, M_CXGBE); + return (rc); +} + static int sysctl_cim_ma_la(SYSCTL_HANDLER_ARGS) { @@ -6212,14 +6278,14 @@ sysctl_cim_pif_la(SYSCTL_HANDLER_ARGS) p = buf; sbuf_printf(sb, "Cntl ID DataBE Addr Data"); - for (i = 0; i < CIM_MALA_SIZE; i++, p += 6) { + for (i = 0; i < CIM_PIFLA_SIZE; i++, p += 6) { sbuf_printf(sb, "\n %02x %02x %04x %08x %08x%08x%08x%08x", (p[5] >> 22) & 0xff, (p[5] >> 16) & 0x3f, p[5] & 0xffff, p[4], p[3], p[2], p[1], p[0]); } sbuf_printf(sb, "\n\nCntl ID Data"); - for (i = 0; i < CIM_MALA_SIZE; i++, p += 6) { + for (i = 0; i < CIM_PIFLA_SIZE; i++, p += 6) { sbuf_printf(sb, "\n %02x %02x %08x%08x%08x%08x", (p[4] >> 6) & 0xff, p[4] & 0x3f, p[3], p[2], p[1], p[0]); } @@ -6243,12 +6309,11 @@ sysctl_cim_qcfg(SYSCTL_HANDLER_ARGS) uint32_t stat[4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5)], *p = stat; u_int cim_num_obq, ibq_rdaddr, obq_rdaddr, nq; + cim_num_obq = sc->chip_params->cim_num_obq; if (is_t4(sc)) { - cim_num_obq = CIM_NUM_OBQ; ibq_rdaddr = A_UP_IBQ_0_RDADDR; obq_rdaddr = A_UP_OBQ_0_REALADDR; } else { - cim_num_obq = CIM_NUM_OBQ_T5; ibq_rdaddr = A_UP_IBQ_0_SHADOW_RDADDR; obq_rdaddr = A_UP_OBQ_0_SHADOW_REALADDR; } @@ -6305,14 +6370,24 @@ sysctl_cpl_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); + mtx_lock(&sc->regwin_lock); t4_tp_get_cpl_stats(sc, &stats); + mtx_unlock(&sc->regwin_lock); - sbuf_printf(sb, " channel 0 channel 1 channel 2 " - "channel 3\n"); - sbuf_printf(sb, "CPL requests: %10u %10u %10u %10u\n", - stats.req[0], stats.req[1], stats.req[2], stats.req[3]); - sbuf_printf(sb, "CPL responses: %10u %10u %10u %10u", - stats.rsp[0], stats.rsp[1], stats.rsp[2], stats.rsp[3]); + if (sc->chip_params->nchan > 2) { + sbuf_printf(sb, " channel 0 channel 1" + " channel 2 channel 3"); + sbuf_printf(sb, "\nCPL requests: %10u %10u %10u %10u", + stats.req[0], stats.req[1], stats.req[2], stats.req[3]); + sbuf_printf(sb, "\nCPL responses: %10u %10u %10u %10u", + stats.rsp[0], stats.rsp[1], stats.rsp[2], stats.rsp[3]); + } else { + sbuf_printf(sb, " channel 0 channel 1"); + sbuf_printf(sb, "\nCPL requests: %10u %10u", + stats.req[0], stats.req[1]); + sbuf_printf(sb, "\nCPL responses: %10u %10u", + stats.rsp[0], stats.rsp[1]); + } rc = sbuf_finish(sb); sbuf_delete(sb); @@ -6476,7 +6551,8 @@ sysctl_fcoe_stats(SYSCTL_HANDLER_ARGS) struct adapter *sc = arg1; struct sbuf *sb; int rc; - struct tp_fcoe_stats stats[4]; + struct tp_fcoe_stats stats[MAX_NCHAN]; + int i, nchan = sc->chip_params->nchan; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6486,22 +6562,30 @@ sysctl_fcoe_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - t4_get_fcoe_stats(sc, 0, &stats[0]); - t4_get_fcoe_stats(sc, 1, &stats[1]); - t4_get_fcoe_stats(sc, 2, &stats[2]); - t4_get_fcoe_stats(sc, 3, &stats[3]); - - sbuf_printf(sb, " channel 0 channel 1 " - "channel 2 channel 3\n"); - sbuf_printf(sb, "octetsDDP: %16ju %16ju %16ju %16ju\n", - stats[0].octets_ddp, stats[1].octets_ddp, stats[2].octets_ddp, - stats[3].octets_ddp); - sbuf_printf(sb, "framesDDP: %16u %16u %16u %16u\n", - stats[0].frames_ddp, stats[1].frames_ddp, stats[2].frames_ddp, - stats[3].frames_ddp); - sbuf_printf(sb, "framesDrop: %16u %16u %16u %16u", - stats[0].frames_drop, stats[1].frames_drop, stats[2].frames_drop, - stats[3].frames_drop); + for (i = 0; i < nchan; i++) + t4_get_fcoe_stats(sc, i, &stats[i]); + + if (nchan > 2) { + sbuf_printf(sb, " channel 0 channel 1" + " channel 2 channel 3"); + sbuf_printf(sb, "\noctetsDDP: %16ju %16ju %16ju %16ju", + stats[0].octets_ddp, stats[1].octets_ddp, + stats[2].octets_ddp, stats[3].octets_ddp); + sbuf_printf(sb, "\nframesDDP: %16u %16u %16u %16u", + stats[0].frames_ddp, stats[1].frames_ddp, + stats[2].frames_ddp, stats[3].frames_ddp); + sbuf_printf(sb, "\nframesDrop: %16u %16u %16u %16u", + stats[0].frames_drop, stats[1].frames_drop, + stats[2].frames_drop, stats[3].frames_drop); + } else { + sbuf_printf(sb, " channel 0 channel 1"); + sbuf_printf(sb, "\noctetsDDP: %16ju %16ju", + stats[0].octets_ddp, stats[1].octets_ddp); + sbuf_printf(sb, "\nframesDDP: %16u %16u", + stats[0].frames_ddp, stats[1].frames_ddp); + sbuf_printf(sb, "\nframesDrop: %16u %16u", + stats[0].frames_drop, stats[1].frames_drop); + } rc = sbuf_finish(sb); sbuf_delete(sb); @@ -6587,7 +6671,7 @@ sysctl_lb_stats(SYSCTL_HANDLER_ARGS) memset(s, 0, sizeof(s)); - for (i = 0; i < 4; i += 2) { + for (i = 0; i < sc->chip_params->nchan; i += 2) { t4_get_lb_stats(sc, i, &s[0]); t4_get_lb_stats(sc, i + 1, &s[1]); @@ -6721,10 +6805,10 @@ sysctl_meminfo(SYSCTL_HANDLER_ARGS) avail[i].base = G_EXT_MEM_BASE(hi) << 20; avail[i].limit = avail[i].base + (G_EXT_MEM_SIZE(hi) << 20); - avail[i].idx = is_t4(sc) ? 2 : 3; /* Call it MC for T4 */ + avail[i].idx = is_t5(sc) ? 3 : 2; /* Call it MC0 for T5 */ i++; } - if (!is_t4(sc) && lo & F_EXT_MEM1_ENABLE) { + if (is_t5(sc) && lo & F_EXT_MEM1_ENABLE) { hi = t4_read_reg(sc, A_MA_EXT_MEMORY1_BAR); avail[i].base = G_EXT_MEM1_BASE(hi) << 20; avail[i].limit = avail[i].base + @@ -6760,9 +6844,14 @@ sysctl_meminfo(SYSCTL_HANDLER_ARGS) md++; if (t4_read_reg(sc, A_LE_DB_CONFIG) & F_HASHEN) { - hi = t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4; - md->base = t4_read_reg(sc, A_LE_DB_HASH_TID_BASE); - md->limit = (sc->tids.ntids - hi) * 16 + md->base - 1; + if (chip_id(sc) <= CHELSIO_T5) { + hi = t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4; + md->base = t4_read_reg(sc, A_LE_DB_HASH_TID_BASE); + } else { + hi = t4_read_reg(sc, A_LE_DB_HASH_TID_BASE); + md->base = t4_read_reg(sc, A_LE_DB_HASH_TBL_BASE_ADDR); + } + md->limit = 0; } else { md->base = 0; md->idx = nitems(region); /* hide it */ @@ -6785,18 +6874,30 @@ sysctl_meminfo(SYSCTL_HANDLER_ARGS) md->base = 0; md->idx = nitems(region); - if (!is_t4(sc) && t4_read_reg(sc, A_SGE_CONTROL2) & F_VFIFO_ENABLE) { - md->base = G_BASEADDR(t4_read_reg(sc, A_SGE_DBVFIFO_BADDR)); - md->limit = md->base + (G_DBVFIFO_SIZE((t4_read_reg(sc, - A_SGE_DBVFIFO_SIZE))) << 2) - 1; + if (!is_t4(sc)) { + uint32_t size = 0; + uint32_t sge_ctrl = t4_read_reg(sc, A_SGE_CONTROL2); + uint32_t fifo_size = t4_read_reg(sc, A_SGE_DBVFIFO_SIZE); + + if (is_t5(sc)) { + if (sge_ctrl & F_VFIFO_ENABLE) + size = G_DBVFIFO_SIZE(fifo_size); + } else + size = G_T6_DBVFIFO_SIZE(fifo_size); + + if (size) { + md->base = G_BASEADDR(t4_read_reg(sc, + A_SGE_DBVFIFO_BADDR)); + md->limit = md->base + (size << 2) - 1; + } } md++; md->base = t4_read_reg(sc, A_ULP_RX_CTX_BASE); - md->limit = md->base + sc->tids.ntids - 1; + md->limit = 0; md++; md->base = t4_read_reg(sc, A_ULP_TX_ERR_TABLE_BASE); - md->limit = md->base + sc->tids.ntids - 1; + md->limit = 0; md++; md->base = sc->vres.ocq.start; @@ -6855,29 +6956,37 @@ sysctl_meminfo(SYSCTL_HANDLER_ARGS) t4_read_reg(sc, A_TP_CMM_MM_MAX_PSTRUCT)); for (i = 0; i < 4; i++) { - lo = t4_read_reg(sc, A_MPS_RX_PG_RSV0 + i * 4); - if (is_t4(sc)) { - used = G_USED(lo); - alloc = G_ALLOC(lo); - } else { + if (chip_id(sc) > CHELSIO_T5) + lo = t4_read_reg(sc, A_MPS_RX_MAC_BG_PG_CNT0 + i * 4); + else + lo = t4_read_reg(sc, A_MPS_RX_PG_RSV0 + i * 4); + if (is_t5(sc)) { used = G_T5_USED(lo); alloc = G_T5_ALLOC(lo); + } else { + used = G_USED(lo); + alloc = G_ALLOC(lo); } + /* For T6 these are MAC buffer groups */ sbuf_printf(sb, "\nPort %d using %u pages out of %u allocated", - i, used, alloc); + i, used, alloc); } - for (i = 0; i < 4; i++) { - lo = t4_read_reg(sc, A_MPS_RX_PG_RSV4 + i * 4); - if (is_t4(sc)) { - used = G_USED(lo); - alloc = G_ALLOC(lo); - } else { + for (i = 0; i < sc->chip_params->nchan; i++) { + if (chip_id(sc) > CHELSIO_T5) + lo = t4_read_reg(sc, A_MPS_RX_LPBK_BG_PG_CNT0 + i * 4); + else + lo = t4_read_reg(sc, A_MPS_RX_PG_RSV4 + i * 4); + if (is_t5(sc)) { used = G_T5_USED(lo); alloc = G_T5_ALLOC(lo); + } else { + used = G_USED(lo); + alloc = G_ALLOC(lo); } + /* For T6 these are MAC buffer groups */ sbuf_printf(sb, - "\nLoopback %d using %u pages out of %u allocated", - i, used, alloc); + "\nLoopback %d using %u pages out of %u allocated", + i, used, alloc); } rc = sbuf_finish(sb); @@ -6899,7 +7008,9 @@ sysctl_mps_tcam(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; - int rc, i, n; + int rc, i; + + MPASS(chip_id(sc) <= CHELSIO_T5); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6912,22 +7023,18 @@ sysctl_mps_tcam(SYSCTL_HANDLER_ARGS) sbuf_printf(sb, "Idx Ethernet address Mask Vld Ports PF" " VF Replication P0 P1 P2 P3 ML"); - n = is_t4(sc) ? NUM_MPS_CLS_SRAM_L_INSTANCES : - NUM_MPS_T5_CLS_SRAM_L_INSTANCES; - for (i = 0; i < n; i++) { + for (i = 0; i < sc->chip_params->mps_tcam_size; i++) { uint64_t tcamx, tcamy, mask; uint32_t cls_lo, cls_hi; uint8_t addr[ETHER_ADDR_LEN]; tcamy = t4_read_reg64(sc, MPS_CLS_TCAM_Y_L(i)); tcamx = t4_read_reg64(sc, MPS_CLS_TCAM_X_L(i)); - cls_lo = t4_read_reg(sc, MPS_CLS_SRAM_L(i)); - cls_hi = t4_read_reg(sc, MPS_CLS_SRAM_H(i)); - if (tcamx & tcamy) continue; - tcamxy2valmask(tcamx, tcamy, addr, &mask); + cls_lo = t4_read_reg(sc, MPS_CLS_SRAM_L(i)); + cls_hi = t4_read_reg(sc, MPS_CLS_SRAM_H(i)); sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x %012jx" " %c %#x%4u%4d", i, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (uintmax_t)mask, @@ -6957,8 +7064,7 @@ sysctl_mps_tcam(SYSCTL_HANDLER_ARGS) end_synchronized_op(sc, 0); if (rc != 0) { - sbuf_printf(sb, - " ------------ error %3u ------------", rc); + sbuf_printf(sb, "%36d", rc); rc = 0; } else { sbuf_printf(sb, " %08x %08x %08x %08x", @@ -6984,6 +7090,162 @@ sysctl_mps_tcam(SYSCTL_HANDLER_ARGS) return (rc); } +static int +sysctl_mps_tcam_t6(SYSCTL_HANDLER_ARGS) +{ + struct adapter *sc = arg1; + struct sbuf *sb; + int rc, i; + + MPASS(chip_id(sc) > CHELSIO_T5); + + rc = sysctl_wire_old_buffer(req, 0); + if (rc != 0) + return (rc); + + sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); + if (sb == NULL) + return (ENOMEM); + + sbuf_printf(sb, "Idx Ethernet address Mask VNI Mask" + " IVLAN Vld DIP_Hit Lookup Port Vld Ports PF VF" + " Replication" + " P0 P1 P2 P3 ML\n"); + + for (i = 0; i < sc->chip_params->mps_tcam_size; i++) { + uint8_t dip_hit, vlan_vld, lookup_type, port_num; + uint16_t ivlan; + uint64_t tcamx, tcamy, val, mask; + uint32_t cls_lo, cls_hi, ctl, data2, vnix, vniy; + uint8_t addr[ETHER_ADDR_LEN]; + + ctl = V_CTLREQID(1) | V_CTLCMDTYPE(0) | V_CTLXYBITSEL(0); + if (i < 256) + ctl |= V_CTLTCAMINDEX(i) | V_CTLTCAMSEL(0); + else + ctl |= V_CTLTCAMINDEX(i - 256) | V_CTLTCAMSEL(1); + t4_write_reg(sc, A_MPS_CLS_TCAM_DATA2_CTL, ctl); + val = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA1_REQ_ID1); + tcamy = G_DMACH(val) << 32; + tcamy |= t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA0_REQ_ID1); + data2 = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA2_REQ_ID1); + lookup_type = G_DATALKPTYPE(data2); + port_num = G_DATAPORTNUM(data2); + if (lookup_type && lookup_type != M_DATALKPTYPE) { + /* Inner header VNI */ + vniy = ((data2 & F_DATAVIDH2) << 23) | + (G_DATAVIDH1(data2) << 16) | G_VIDL(val); + dip_hit = data2 & F_DATADIPHIT; + vlan_vld = 0; + } else { + vniy = 0; + dip_hit = 0; + vlan_vld = data2 & F_DATAVIDH2; + ivlan = G_VIDL(val); + } + + ctl |= V_CTLXYBITSEL(1); + t4_write_reg(sc, A_MPS_CLS_TCAM_DATA2_CTL, ctl); + val = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA1_REQ_ID1); + tcamx = G_DMACH(val) << 32; + tcamx |= t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA0_REQ_ID1); + data2 = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA2_REQ_ID1); + if (lookup_type && lookup_type != M_DATALKPTYPE) { + /* Inner header VNI mask */ + vnix = ((data2 & F_DATAVIDH2) << 23) | + (G_DATAVIDH1(data2) << 16) | G_VIDL(val); + } else + vnix = 0; + + if (tcamx & tcamy) + continue; + tcamxy2valmask(tcamx, tcamy, addr, &mask); + + cls_lo = t4_read_reg(sc, MPS_CLS_SRAM_L(i)); + cls_hi = t4_read_reg(sc, MPS_CLS_SRAM_H(i)); + + if (lookup_type && lookup_type != M_DATALKPTYPE) { + sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x " + "%012jx %06x %06x - - %3c" + " 'I' %4x %3c %#x%4u%4d", i, addr[0], + addr[1], addr[2], addr[3], addr[4], addr[5], + (uintmax_t)mask, vniy, vnix, dip_hit ? 'Y' : 'N', + port_num, cls_lo & F_T6_SRAM_VLD ? 'Y' : 'N', + G_PORTMAP(cls_hi), G_T6_PF(cls_lo), + cls_lo & F_T6_VF_VALID ? G_T6_VF(cls_lo) : -1); + } else { + sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x " + "%012jx - - ", i, addr[0], addr[1], + addr[2], addr[3], addr[4], addr[5], + (uintmax_t)mask); + + if (vlan_vld) + sbuf_printf(sb, "%4u Y ", ivlan); + else + sbuf_printf(sb, " - N "); + + sbuf_printf(sb, "- %3c %4x %3c %#x%4u%4d", + lookup_type ? 'I' : 'O', port_num, + cls_lo & F_T6_SRAM_VLD ? 'Y' : 'N', + G_PORTMAP(cls_hi), G_T6_PF(cls_lo), + cls_lo & F_T6_VF_VALID ? G_T6_VF(cls_lo) : -1); + } + + + if (cls_lo & F_T6_REPLICATE) { + struct fw_ldst_cmd ldst_cmd; + + memset(&ldst_cmd, 0, sizeof(ldst_cmd)); + ldst_cmd.op_to_addrspace = + htobe32(V_FW_CMD_OP(FW_LDST_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_READ | + V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MPS)); + ldst_cmd.cycles_to_len16 = htobe32(FW_LEN16(ldst_cmd)); + ldst_cmd.u.mps.rplc.fid_idx = + htobe16(V_FW_LDST_CMD_FID(FW_LDST_MPS_RPLC) | + V_FW_LDST_CMD_IDX(i)); + + rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, + "t6mps"); + if (rc) + break; + rc = -t4_wr_mbox(sc, sc->mbox, &ldst_cmd, + sizeof(ldst_cmd), &ldst_cmd); + end_synchronized_op(sc, 0); + + if (rc != 0) { + sbuf_printf(sb, "%72d", rc); + rc = 0; + } else { + sbuf_printf(sb, " %08x %08x %08x %08x" + " %08x %08x %08x %08x", + be32toh(ldst_cmd.u.mps.rplc.rplc255_224), + be32toh(ldst_cmd.u.mps.rplc.rplc223_192), + be32toh(ldst_cmd.u.mps.rplc.rplc191_160), + be32toh(ldst_cmd.u.mps.rplc.rplc159_128), + be32toh(ldst_cmd.u.mps.rplc.rplc127_96), + be32toh(ldst_cmd.u.mps.rplc.rplc95_64), + be32toh(ldst_cmd.u.mps.rplc.rplc63_32), + be32toh(ldst_cmd.u.mps.rplc.rplc31_0)); + } + } else + sbuf_printf(sb, "%72s", ""); + + sbuf_printf(sb, "%4u%3u%3u%3u %#x", + G_T6_SRAM_PRIO0(cls_lo), G_T6_SRAM_PRIO1(cls_lo), + G_T6_SRAM_PRIO2(cls_lo), G_T6_SRAM_PRIO3(cls_lo), + (cls_lo >> S_T6_MULTILISTEN0) & 0xf); + } + + if (rc) + (void) sbuf_finish(sb); + else + rc = sbuf_finish(sb); + sbuf_delete(sb); + + return (rc); +} + static int sysctl_path_mtus(SYSCTL_HANDLER_ARGS) { @@ -7019,13 +7281,15 @@ sysctl_pm_stats(SYSCTL_HANDLER_ARGS) struct adapter *sc = arg1; struct sbuf *sb; int rc, i; - uint32_t cnt[PM_NSTATS]; - uint64_t cyc[PM_NSTATS]; - static const char *rx_stats[] = { - "Read:", "Write bypass:", "Write mem:", "Flush:" + uint32_t tx_cnt[MAX_PM_NSTATS], rx_cnt[MAX_PM_NSTATS]; + uint64_t tx_cyc[MAX_PM_NSTATS], rx_cyc[MAX_PM_NSTATS]; + static const char *tx_stats[MAX_PM_NSTATS] = { + "Read:", "Write bypass:", "Write mem:", "Bypass + mem:", + "Tx FIFO wait", NULL, "Tx latency" }; - static const char *tx_stats[] = { - "Read:", "Write bypass:", "Write mem:", "Bypass + mem:" + static const char *rx_stats[MAX_PM_NSTATS] = { + "Read:", "Write bypass:", "Write mem:", "Flush:", + " Rx FIFO wait", NULL, "Rx latency" }; rc = sysctl_wire_old_buffer(req, 0); @@ -7036,17 +7300,39 @@ sysctl_pm_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - t4_pmtx_get_stats(sc, cnt, cyc); + t4_pmtx_get_stats(sc, tx_cnt, tx_cyc); + t4_pmrx_get_stats(sc, rx_cnt, rx_cyc); + sbuf_printf(sb, " Tx pcmds Tx bytes"); - for (i = 0; i < ARRAY_SIZE(tx_stats); i++) - sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], cnt[i], - cyc[i]); + for (i = 0; i < 4; i++) { + sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], + tx_cyc[i]); + } - t4_pmrx_get_stats(sc, cnt, cyc); sbuf_printf(sb, "\n Rx pcmds Rx bytes"); - for (i = 0; i < ARRAY_SIZE(rx_stats); i++) - sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], cnt[i], - cyc[i]); + for (i = 0; i < 4; i++) { + sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], + rx_cyc[i]); + } + + if (chip_id(sc) > CHELSIO_T5) { + sbuf_printf(sb, + "\n Total wait Total occupancy"); + sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], + tx_cyc[i]); + sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], + rx_cyc[i]); + + i += 2; + MPASS(i < nitems(tx_stats)); + + sbuf_printf(sb, + "\n Reads Total wait"); + sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], + tx_cyc[i]); + sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], + rx_cyc[i]); + } rc = sbuf_finish(sb); sbuf_delete(sb); @@ -7070,7 +7356,10 @@ sysctl_rdma_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); + mtx_lock(&sc->regwin_lock); t4_tp_get_rdma_stats(sc, &stats); + mtx_unlock(&sc->regwin_lock); + sbuf_printf(sb, "NoRQEModDefferals: %u\n", stats.rqe_dfr_mod); sbuf_printf(sb, "NoRQEPktDefferals: %u", stats.rqe_dfr_pkt); @@ -7096,7 +7385,10 @@ sysctl_tcp_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); + mtx_lock(&sc->regwin_lock); t4_tp_get_tcp_stats(sc, &v4, &v6); + mtx_unlock(&sc->regwin_lock); + sbuf_printf(sb, " IP IPv6\n"); sbuf_printf(sb, "OutRsts: %20u %20u\n", @@ -7195,34 +7487,57 @@ sysctl_tp_err_stats(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); + mtx_lock(&sc->regwin_lock); t4_tp_get_err_stats(sc, &stats); + mtx_unlock(&sc->regwin_lock); + + if (sc->chip_params->nchan > 2) { + sbuf_printf(sb, " channel 0 channel 1" + " channel 2 channel 3\n"); + sbuf_printf(sb, "macInErrs: %10u %10u %10u %10u\n", + stats.mac_in_errs[0], stats.mac_in_errs[1], + stats.mac_in_errs[2], stats.mac_in_errs[3]); + sbuf_printf(sb, "hdrInErrs: %10u %10u %10u %10u\n", + stats.hdr_in_errs[0], stats.hdr_in_errs[1], + stats.hdr_in_errs[2], stats.hdr_in_errs[3]); + sbuf_printf(sb, "tcpInErrs: %10u %10u %10u %10u\n", + stats.tcp_in_errs[0], stats.tcp_in_errs[1], + stats.tcp_in_errs[2], stats.tcp_in_errs[3]); + sbuf_printf(sb, "tcp6InErrs: %10u %10u %10u %10u\n", + stats.tcp6_in_errs[0], stats.tcp6_in_errs[1], + stats.tcp6_in_errs[2], stats.tcp6_in_errs[3]); + sbuf_printf(sb, "tnlCongDrops: %10u %10u %10u %10u\n", + stats.tnl_cong_drops[0], stats.tnl_cong_drops[1], + stats.tnl_cong_drops[2], stats.tnl_cong_drops[3]); + sbuf_printf(sb, "tnlTxDrops: %10u %10u %10u %10u\n", + stats.tnl_tx_drops[0], stats.tnl_tx_drops[1], + stats.tnl_tx_drops[2], stats.tnl_tx_drops[3]); + sbuf_printf(sb, "ofldVlanDrops: %10u %10u %10u %10u\n", + stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1], + stats.ofld_vlan_drops[2], stats.ofld_vlan_drops[3]); + sbuf_printf(sb, "ofldChanDrops: %10u %10u %10u %10u\n\n", + stats.ofld_chan_drops[0], stats.ofld_chan_drops[1], + stats.ofld_chan_drops[2], stats.ofld_chan_drops[3]); + } else { + sbuf_printf(sb, " channel 0 channel 1\n"); + sbuf_printf(sb, "macInErrs: %10u %10u\n", + stats.mac_in_errs[0], stats.mac_in_errs[1]); + sbuf_printf(sb, "hdrInErrs: %10u %10u\n", + stats.hdr_in_errs[0], stats.hdr_in_errs[1]); + sbuf_printf(sb, "tcpInErrs: %10u %10u\n", + stats.tcp_in_errs[0], stats.tcp_in_errs[1]); + sbuf_printf(sb, "tcp6InErrs: %10u %10u\n", + stats.tcp6_in_errs[0], stats.tcp6_in_errs[1]); + sbuf_printf(sb, "tnlCongDrops: %10u %10u\n", + stats.tnl_cong_drops[0], stats.tnl_cong_drops[1]); + sbuf_printf(sb, "tnlTxDrops: %10u %10u\n", + stats.tnl_tx_drops[0], stats.tnl_tx_drops[1]); + sbuf_printf(sb, "ofldVlanDrops: %10u %10u\n", + stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1]); + sbuf_printf(sb, "ofldChanDrops: %10u %10u\n\n", + stats.ofld_chan_drops[0], stats.ofld_chan_drops[1]); + } - sbuf_printf(sb, " channel 0 channel 1 channel 2 " - "channel 3\n"); - sbuf_printf(sb, "macInErrs: %10u %10u %10u %10u\n", - stats.mac_in_errs[0], stats.mac_in_errs[1], stats.mac_in_errs[2], - stats.mac_in_errs[3]); - sbuf_printf(sb, "hdrInErrs: %10u %10u %10u %10u\n", - stats.hdr_in_errs[0], stats.hdr_in_errs[1], stats.hdr_in_errs[2], - stats.hdr_in_errs[3]); - sbuf_printf(sb, "tcpInErrs: %10u %10u %10u %10u\n", - stats.tcp_in_errs[0], stats.tcp_in_errs[1], stats.tcp_in_errs[2], - stats.tcp_in_errs[3]); - sbuf_printf(sb, "tcp6InErrs: %10u %10u %10u %10u\n", - stats.tcp6_in_errs[0], stats.tcp6_in_errs[1], stats.tcp6_in_errs[2], - stats.tcp6_in_errs[3]); - sbuf_printf(sb, "tnlCongDrops: %10u %10u %10u %10u\n", - stats.tnl_cong_drops[0], stats.tnl_cong_drops[1], - stats.tnl_cong_drops[2], stats.tnl_cong_drops[3]); - sbuf_printf(sb, "tnlTxDrops: %10u %10u %10u %10u\n", - stats.tnl_tx_drops[0], stats.tnl_tx_drops[1], stats.tnl_tx_drops[2], - stats.tnl_tx_drops[3]); - sbuf_printf(sb, "ofldVlanDrops: %10u %10u %10u %10u\n", - stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1], - stats.ofld_vlan_drops[2], stats.ofld_vlan_drops[3]); - sbuf_printf(sb, "ofldChanDrops: %10u %10u %10u %10u\n\n", - stats.ofld_chan_drops[0], stats.ofld_chan_drops[1], - stats.ofld_chan_drops[2], stats.ofld_chan_drops[3]); sbuf_printf(sb, "ofldNoNeigh: %u\nofldCongDefer: %u", stats.ofld_no_neigh, stats.ofld_cong_defer); @@ -7260,7 +7575,7 @@ field_desc_show(struct sbuf *sb, uint64_t v, const struct field_desc *f) sbuf_printf(sb, "\n"); } -static struct field_desc tp_la0[] = { +static const struct field_desc tp_la0[] = { { "RcfOpCodeOut", 60, 4 }, { "State", 56, 4 }, { "WcfState", 52, 4 }, @@ -7297,7 +7612,7 @@ static struct field_desc tp_la0[] = { { NULL } }; -static struct field_desc tp_la1[] = { +static const struct field_desc tp_la1[] = { { "CplCmdIn", 56, 8 }, { "CplCmdOut", 48, 8 }, { "ESynOut", 47, 1 }, @@ -7346,7 +7661,7 @@ static struct field_desc tp_la1[] = { { NULL } }; -static struct field_desc tp_la2[] = { +static const struct field_desc tp_la2[] = { { "CplCmdIn", 56, 8 }, { "MpsVfVld", 55, 1 }, { "MpsPf", 52, 3 }, @@ -7474,7 +7789,7 @@ sysctl_tx_rate(SYSCTL_HANDLER_ARGS) struct adapter *sc = arg1; struct sbuf *sb; int rc; - u64 nrate[NCHAN], orate[NCHAN]; + u64 nrate[MAX_NCHAN], orate[MAX_NCHAN]; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -7485,12 +7800,21 @@ sysctl_tx_rate(SYSCTL_HANDLER_ARGS) return (ENOMEM); t4_get_chan_txrate(sc, nrate, orate); - sbuf_printf(sb, " channel 0 channel 1 channel 2 " - "channel 3\n"); - sbuf_printf(sb, "NIC B/s: %10ju %10ju %10ju %10ju\n", - nrate[0], nrate[1], nrate[2], nrate[3]); - sbuf_printf(sb, "Offload B/s: %10ju %10ju %10ju %10ju", - orate[0], orate[1], orate[2], orate[3]); + + if (sc->chip_params->nchan > 2) { + sbuf_printf(sb, " channel 0 channel 1" + " channel 2 channel 3\n"); + sbuf_printf(sb, "NIC B/s: %10ju %10ju %10ju %10ju\n", + nrate[0], nrate[1], nrate[2], nrate[3]); + sbuf_printf(sb, "Offload B/s: %10ju %10ju %10ju %10ju", + orate[0], orate[1], orate[2], orate[3]); + } else { + sbuf_printf(sb, " channel 0 channel 1\n"); + sbuf_printf(sb, "NIC B/s: %10ju %10ju\n", + nrate[0], nrate[1]); + sbuf_printf(sb, "Offload B/s: %10ju %10ju", + orate[0], orate[1]); + } rc = sbuf_finish(sb); sbuf_delete(sb); @@ -8382,7 +8706,7 @@ set_sched_class(struct adapter *sc, struct t4_sched_params *p) /* Vet our parameters ... */ if (!in_range(p->u.params.channel, 0, 3) || - !in_range(p->u.params.cl, 0, is_t4(sc) ? 15 : 16) || + !in_range(p->u.params.cl, 0, sc->chip_params->nsched_cls) || !in_range(p->u.params.minrate, 0, 10000000) || !in_range(p->u.params.maxrate, 0, 10000000) || !in_range(p->u.params.weight, 0, 100)) { diff --git a/sys/dev/cxgbe/t4_netmap.c b/sys/dev/cxgbe/t4_netmap.c index f01a43c2614..d05812ddd41 100644 --- a/sys/dev/cxgbe/t4_netmap.c +++ b/sys/dev/cxgbe/t4_netmap.c @@ -366,9 +366,8 @@ alloc_nm_rxq_hwq(struct vi_info *vi, struct sge_nm_rxq *nm_rxq, int cong) } sc->sge.eqmap[cntxt_id] = (void *)nm_rxq; - nm_rxq->fl_db_val = F_DBPRIO | V_QID(nm_rxq->fl_cntxt_id) | V_PIDX(0); - if (is_t5(sc)) - nm_rxq->fl_db_val |= F_DBTYPE; + nm_rxq->fl_db_val = V_QID(nm_rxq->fl_cntxt_id) | + sc->chip_params->sge_fl_db; if (is_t5(sc) && cong >= 0) { uint32_t param, val; diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 0c3644d98af..7f1236bbedc 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -2467,7 +2467,6 @@ static inline void init_eq(struct sge_eq *eq, int eqtype, int qsize, uint8_t tx_chan, uint16_t iqid, char *name) { - KASSERT(tx_chan < NCHAN, ("%s: bad tx channel %d", __func__, tx_chan)); KASSERT(eqtype <= EQ_TYPEMASK, ("%s: bad qtype %d", __func__, eqtype)); eq->flags = eqtype & EQ_TYPEMASK; @@ -2681,9 +2680,7 @@ alloc_iq_fl(struct vi_info *vi, struct sge_iq *iq, struct sge_fl *fl, } fl->udb = (volatile void *)udb; } - fl->dbval = F_DBPRIO | V_QID(qid); - if (is_t5(sc)) - fl->dbval |= F_DBTYPE; + fl->dbval = V_QID(qid) | sc->chip_params->sge_fl_db; FL_LOCK(fl); /* Enough to make sure the SGE doesn't think it's starved */ -- 2.45.2