Author: np
Date: Fri Mar  4 13:11:13 2016
New Revision: 296383
URL: https://svnweb.freebsd.org/changeset/base/296383

Log:
  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.<tNnex>.<n>.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

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/common/common.h
  head/sys/dev/cxgbe/common/t4_hw.c
  head/sys/dev/cxgbe/common/t4_hw.h
  head/sys/dev/cxgbe/t4_main.c
  head/sys/dev/cxgbe/t4_netmap.c
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h        Fri Mar  4 09:07:30 2016        
(r296382)
+++ head/sys/dev/cxgbe/adapter.h        Fri Mar  4 13:11:13 2016        
(r296383)
@@ -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;

Modified: head/sys/dev/cxgbe/common/common.h
==============================================================================
--- head/sys/dev/cxgbe/common/common.h  Fri Mar  4 09:07:30 2016        
(r296382)
+++ head/sys/dev/cxgbe/common/common.h  Fri Mar  4 13:11:13 2016        
(r296383)
@@ -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 *
        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;

Modified: head/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- head/sys/dev/cxgbe/common/t4_hw.c   Fri Mar  4 09:07:30 2016        
(r296382)
+++ head/sys/dev/cxgbe/common/t4_hw.c   Fri Mar  4 13:11:13 2016        
(r296383)
@@ -154,26 +154,49 @@ void t4_write_indirect(struct adapter *a
  * 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 @@ out:
 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 *ad
                *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
 {
        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,
                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 
  */
 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 
  */
 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 adapte
  */
 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 *
        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 *a
        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 *a
        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(struc
 
        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 *ad
        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, 
        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_completio
        }
 }
 
+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 ada
                        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 ada
 
        /* 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 a
        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,

Modified: head/sys/dev/cxgbe/common/t4_hw.h
==============================================================================
--- head/sys/dev/cxgbe/common/t4_hw.h   Fri Mar  4 09:07:30 2016        
(r296382)
+++ head/sys/dev/cxgbe/common/t4_hw.h   Fri Mar  4 13:11:13 2016        
(r296383)
@@ -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 */

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Fri Mar  4 09:07:30 2016        
(r296382)
+++ head/sys/dev/cxgbe/t4_main.c        Fri Mar  4 13:11:13 2016        
(r296383)
@@ -453,6 +453,7 @@ static int sysctl_temperature(SYSCTL_HAN
 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_HANDLE
 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, 
 
        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]);
@@ -6145,6 +6148,69 @@ done:
 }
 
 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)
 {
        struct adapter *sc = arg1;
@@ -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",
@@ -6985,6 +7091,162 @@ sysctl_mps_tcam(SYSCTL_HANDLER_ARGS)
 }
 
 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)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to