net/cxgbe: support Source MAC Table
authorKarra Satwik <kaara.satwik@chelsio.com>
Wed, 11 Mar 2020 09:05:48 +0000 (14:35 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 18 Mar 2020 14:29:39 +0000 (15:29 +0100)
Source MAC Table (SMT) is used for storing Source MAC
addresses to be written in packets transmitted on the
wire. Hence, the SMT table can be used for overwriting
Source MAC addresses in packets, hitting corresponding
filter rules inserted by the rte_flow API.

Query firmware for SMT start and size information available
to the underlying PF. Allocate and maintain the corresponding
driver's copy of the hardware SMT table, with appropriate
refcount mechanism. If SMT information is not available, then
use the entire hardware SMT table.

Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
drivers/net/cxgbe/Makefile
drivers/net/cxgbe/base/adapter.h
drivers/net/cxgbe/base/t4fw_interface.h
drivers/net/cxgbe/cxgbe_main.c
drivers/net/cxgbe/meson.build
drivers/net/cxgbe/smt.c [new file with mode: 0644]
drivers/net/cxgbe/smt.h [new file with mode: 0644]

index 79c6e1d..53b2bb5 100644 (file)
@@ -51,6 +51,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t4_hw.c
 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
index c6b8036..ae318cc 100644 (file)
@@ -342,6 +342,7 @@ struct adapter {
        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 */
index 39e0207..3684c80 100644 (file)
@@ -695,6 +695,8 @@ enum fw_params_param_pfvf {
        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,
 };
 
 /*
index a286d85..1ab6f8f 100644 (file)
@@ -40,6 +40,7 @@
 #include "cxgbe_pfvf.h"
 #include "clip_tbl.h"
 #include "l2t.h"
+#include "smt.h"
 #include "mps_tcam.h"
 
 /**
@@ -1735,6 +1736,7 @@ void cxgbe_close(struct adapter *adapter)
                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);
@@ -1753,13 +1755,45 @@ void cxgbe_close(struct adapter *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,
@@ -1904,6 +1938,11 @@ allocate_mac:
                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 */
index c51af26..3992aba 100644 (file)
@@ -11,6 +11,7 @@ sources = files('cxgbe_ethdev.c',
        'clip_tbl.c',
        'mps_tcam.c',
        'l2t.c',
+       'smt.c',
        'base/t4_hw.c',
        'base/t4vf_hw.c')
 includes += include_directories('base')
diff --git a/drivers/net/cxgbe/smt.c b/drivers/net/cxgbe/smt.c
new file mode 100644 (file)
index 0000000..cf40c8a
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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);
+}
diff --git a/drivers/net/cxgbe/smt.h b/drivers/net/cxgbe/smt.h
new file mode 100644 (file)
index 0000000..aa4afcc
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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_ */
+