SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += clip_tbl.c
SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += mps_tcam.c
SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += l2t.c
+SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += smt.c
SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t4vf_hw.c
include $(RTE_SDK)/mk/rte.lib.mk
unsigned int l2t_end; /* Layer 2 table end */
struct clip_tbl *clipt; /* CLIP table */
struct l2t_data *l2t; /* Layer 2 table */
+ struct smt_data *smt; /* Source mac table */
struct mpstcam_table *mpstcam;
struct tid_info tids; /* Info used to access TID related tables */
FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A,
FW_PARAMS_PARAM_PFVF_MAX_PKTS_PER_ETH_TX_PKTS_WR = 0x3D,
+ FW_PARAMS_PARAM_PFVF_GET_SMT_START = 0x3E,
+ FW_PARAMS_PARAM_PFVF_GET_SMT_SIZE = 0x3F,
};
/*
#include "cxgbe_pfvf.h"
#include "clip_tbl.h"
#include "l2t.h"
+#include "smt.h"
#include "mps_tcam.h"
/**
t4_cleanup_mpstcam(adapter);
t4_cleanup_clip_tbl(adapter);
t4_cleanup_l2t(adapter);
+ t4_cleanup_smt(adapter);
if (is_pf4(adapter))
t4_intr_disable(adapter);
t4_sge_tx_monitor_stop(adapter);
t4_fw_bye(adapter, adapter->mbox);
}
+static void adap_smt_index(struct adapter *adapter, u32 *smt_start_idx,
+ u32 *smt_size)
+{
+ u32 params[2], smt_val[2];
+ int ret;
+
+ params[0] = CXGBE_FW_PARAM_PFVF(GET_SMT_START);
+ params[1] = CXGBE_FW_PARAM_PFVF(GET_SMT_SIZE);
+
+ ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
+ 2, params, smt_val);
+
+ /* if FW doesn't recognize this command then set it to default setting
+ * which is start index as 0 and size as 256.
+ */
+ if (ret < 0) {
+ *smt_start_idx = 0;
+ *smt_size = SMT_SIZE;
+ } else {
+ *smt_start_idx = smt_val[0];
+ /* smt size can be zero, if nsmt is not yet configured in
+ * the config file or set as zero, then configure all the
+ * remaining entries to this PF itself.
+ */
+ if (!smt_val[1])
+ *smt_size = SMT_SIZE - *smt_start_idx;
+ else
+ *smt_size = smt_val[1];
+ }
+}
+
int cxgbe_probe(struct adapter *adapter)
{
+ u32 smt_start_idx, smt_size;
struct port_info *pi;
- int chip;
int func, i;
int err = 0;
u32 whoami;
+ int chip;
whoami = t4_read_reg(adapter, A_PL_WHOAMI);
chip = t4_get_chip_type(adapter,
dev_warn(adapter, "could not allocate CLIP. Continuing\n");
}
+ adap_smt_index(adapter, &smt_start_idx, &smt_size);
+ adapter->smt = t4_init_smt(smt_start_idx, smt_size);
+ if (!adapter->smt)
+ dev_warn(adapter, "could not allocate SMT, continuing\n");
+
adapter->l2t = t4_init_l2t(adapter->l2t_start, adapter->l2t_end);
if (!adapter->l2t) {
/* We tolerate a lack of L2T, giving up some functionality */
'clip_tbl.c',
'mps_tcam.c',
'l2t.c',
+ 'smt.c',
'base/t4_hw.c',
'base/t4vf_hw.c')
includes += include_directories('base')
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Chelsio Communications.
+ * All rights reserved.
+ */
+
+#include "base/common.h"
+#include "smt.h"
+
+/**
+ * Initialize Source MAC Table
+ */
+struct smt_data *t4_init_smt(u32 smt_start_idx, u32 smt_size)
+{
+ struct smt_data *s;
+ u32 i;
+
+ s = t4_alloc_mem(sizeof(*s) + smt_size * sizeof(struct smt_entry));
+ if (!s)
+ return NULL;
+
+ s->smt_start = smt_start_idx;
+ s->smt_size = smt_size;
+ t4_os_rwlock_init(&s->lock);
+
+ for (i = 0; i < s->smt_size; ++i) {
+ s->smtab[i].idx = i;
+ s->smtab[i].hw_idx = smt_start_idx + i;
+ s->smtab[i].state = SMT_STATE_UNUSED;
+ memset(&s->smtab[i].src_mac, 0, RTE_ETHER_ADDR_LEN);
+ t4_os_lock_init(&s->smtab[i].lock);
+ rte_atomic32_set(&s->smtab[i].refcnt, 0);
+ }
+ return s;
+}
+
+/**
+ * Cleanup Source MAC Table
+ */
+void t4_cleanup_smt(struct adapter *adap)
+{
+ if (adap->smt)
+ t4_os_free(adap->smt);
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Chelsio Communications.
+ * All rights reserved.
+ */
+#ifndef __CXGBE_SMT_H_
+#define __CXGBE_SMT_H_
+
+enum {
+ SMT_STATE_SWITCHING,
+ SMT_STATE_UNUSED,
+ SMT_STATE_ERROR
+};
+
+enum {
+ SMT_SIZE = 256
+};
+
+struct smt_entry {
+ u16 state;
+ u16 idx;
+ u16 pfvf;
+ u16 hw_idx;
+ u8 src_mac[RTE_ETHER_ADDR_LEN];
+ rte_atomic32_t refcnt;
+ rte_spinlock_t lock;
+};
+
+struct smt_data {
+ unsigned int smt_size;
+ unsigned int smt_start;
+ rte_rwlock_t lock;
+ struct smt_entry smtab[0];
+};
+
+struct smt_data *t4_init_smt(u32 smt_start_idx, u32 smt_size);
+void t4_cleanup_smt(struct adapter *adap);
+
+#endif /* __CXGBE_SMT_H_ */
+