diff mbox series

[net-next,16/20] net: ethernet: qualcomm: Add PPE L2 bridge initialization

Message ID 20240110114033.32575-17-quic_luoj@quicinc.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: ethernet: Add qcom PPE driver | expand

Checks

Context Check Description
netdev/series_format fail Series longer than 15 patches (and no cover letter)
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 26 this patch: 26
netdev/cc_maintainers success CCed 0 of 0 maintainers
netdev/build_clang fail Errors and warnings before: 45 this patch: 46
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 26 this patch: 26
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 226 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jie Luo Jan. 10, 2024, 11:40 a.m. UTC
From: Lei Wei <quic_leiwei@quicinc.com>

Add PPE L2 bridge initialization. The default per-port
settings are as follows: For PPE physical port, the L2
learning is enabled and the forward action is initialized
to forward to CPU port. The PPE bridge tx is also enabled
for PPE CPU port and disabled for PPE physical port.

Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
 drivers/net/ethernet/qualcomm/ppe/ppe.c      |  78 ++++++++++++++
 drivers/net/ethernet/qualcomm/ppe/ppe.h      |  10 ++
 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 102 +++++++++++++++++++
 3 files changed, 190 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
index 71973bce2cd2..04f80589c05b 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
@@ -1260,6 +1260,80 @@  static int ppe_rss_hash_init(struct ppe_device *ppe_dev)
 						  hash_cfg);
 }
 
+static int ppe_bridge_init(struct ppe_device *ppe_dev)
+{
+	union ppe_l2_vp_port_tbl_u port_tbl;
+	union ppe_vsi_tbl_u vsi_tbl;
+	u32 reg_val = 0;
+	int i = 0;
+
+	/* CPU port0 initialization */
+	reg_val = FIELD_PREP(PPE_PORT_BRIDGE_CTRL_ISOLATION_BITMAP, 0x7F) |
+			PPE_PORT_BRIDGE_CTRL_PROMISC_EN;
+	ppe_mask(ppe_dev,
+		 PPE_PORT_BRIDGE_CTRL + PPE_PORT_BRIDGE_CTRL_INC * PPE_PORT0,
+		 PPE_PORT_BRIDGE_CTRL_MASK,
+		 reg_val | PPE_PORT_BRIDGE_CTRL_TXMAC_EN);
+
+	/* Physical and virtual physical port initialization */
+	reg_val |= (PPE_PORT_BRIDGE_CTRL_STATION_MODE_LRN_EN |
+			PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN);
+	for (i = PPE_PORT1; i <= PPE_PORT6; i++) {
+		ppe_mask(ppe_dev,
+			 PPE_PORT_BRIDGE_CTRL + PPE_PORT_BRIDGE_CTRL_INC * i,
+			 PPE_PORT_BRIDGE_CTRL_MASK,
+			 reg_val);
+
+		/* Invalid vsi fowarding to CPU port0 */
+		memset(&port_tbl, 0, sizeof(port_tbl));
+		ppe_read_tbl(ppe_dev,
+			     PPE_L2_VP_PORT_TBL + PPE_L2_VP_PORT_TBL_INC * i,
+			     port_tbl.val,
+			     sizeof(port_tbl.val));
+		port_tbl.bf.invalid_vsi_forwarding_en = true;
+		port_tbl.bf.dst_info = PPE_PORT0;
+		ppe_write_tbl(ppe_dev,
+			      PPE_L2_VP_PORT_TBL + PPE_L2_VP_PORT_TBL_INC * i,
+			      port_tbl.val,
+			      sizeof(port_tbl.val));
+	}
+
+	/* Internal port7 initialization */
+	ppe_mask(ppe_dev,
+		 PPE_PORT_BRIDGE_CTRL + PPE_PORT_BRIDGE_CTRL_INC * PPE_PORT7,
+		 PPE_PORT_BRIDGE_CTRL_MASK,
+		 reg_val | PPE_PORT_BRIDGE_CTRL_TXMAC_EN);
+
+	/* Enable Global L2 Learn and Ageing */
+	ppe_mask(ppe_dev,
+		 PPE_L2_GLOBAL_CONFIG,
+		 PPE_L2_GLOBAL_CONFIG_LRN_EN | PPE_L2_GLOBAL_CONFIG_AGE_EN,
+		 PPE_L2_GLOBAL_CONFIG_LRN_EN | PPE_L2_GLOBAL_CONFIG_AGE_EN);
+
+	/* Vsi initialization */
+	for (i = 0; i < PPE_VSI_TBL_NUM; i++) {
+		memset(&vsi_tbl, 0, sizeof(vsi_tbl));
+		ppe_read_tbl(ppe_dev,
+			     PPE_VSI_TBL + PPE_VSI_TBL_INC * i,
+			     vsi_tbl.val,
+			     sizeof(vsi_tbl.val));
+		vsi_tbl.bf.member_port_bitmap = BIT(PPE_PORT0);
+		vsi_tbl.bf.uuc_bitmap = BIT(PPE_PORT0);
+		vsi_tbl.bf.umc_bitmap = BIT(PPE_PORT0);
+		vsi_tbl.bf.bc_bitmap = BIT(PPE_PORT0);
+		vsi_tbl.bf.new_addr_lrn_en = true;
+		vsi_tbl.bf.new_addr_fwd_cmd = 0;
+		vsi_tbl.bf.station_move_lrn_en = true;
+		vsi_tbl.bf.station_move_fwd_cmd = 0;
+		ppe_write_tbl(ppe_dev,
+			      PPE_VSI_TBL + PPE_VSI_TBL_INC * i,
+			      vsi_tbl.val,
+			      sizeof(vsi_tbl.val));
+	}
+
+	return 0;
+}
+
 static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
 {
 	int ret;
@@ -1276,6 +1350,10 @@  static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
 	if (ret)
 		return ret;
 
+	ret = ppe_bridge_init(ppe_dev);
+	if (ret)
+		return ret;
+
 	return ppe_rss_hash_init(ppe_dev);
 }
 
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h
index 507626b6ab2e..828d467540c9 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
@@ -11,6 +11,16 @@ 
 #include <linux/clk.h>
 #include <linux/reset.h>
 
+/* PPE Ports */
+#define PPE_PORT0		0
+#define PPE_PORT1		1
+#define PPE_PORT2		2
+#define PPE_PORT3		3
+#define PPE_PORT4		4
+#define PPE_PORT5		5
+#define PPE_PORT6		6
+#define PPE_PORT7		7
+
 enum ppe_clk_id {
 	/* clocks for CMN PLL */
 	PPE_CMN_AHB_CLK,
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
index 98bf19f974ce..13115405bad9 100644
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
@@ -238,6 +238,39 @@  union ppe_eg_service_cfg_u {
 #define PPE_TX_BUFF_THRSH_XOFF					GENMASK(7, 0)
 #define PPE_TX_BUFF_THRSH_XON					GENMASK(15, 8)
 
+#define PPE_L2_GLOBAL_CONFIG					0x60038
+#define PPE_L2_GLOBAL_CONFIG_LRN_EN				BIT(6)
+#define PPE_L2_GLOBAL_CONFIG_AGE_EN				BIT(7)
+
+#define PPE_MIRROR_ANALYZER					0x60040
+#define PPE_MIRROR_ANALYZER_NUM					1
+#define PPE_MIRROR_ANALYZER_INC					4
+#define PPE_MIRROR_ANALYZER_INGRESS_PORT			GENMASK(5, 0)
+#define PPE_MIRROR_ANALYZER_EGRESS_PORT				GENMASK(13, 8)
+
+#define PPE_PORT_BRIDGE_CTRL					0x60300
+#define PPE_PORT_BRIDGE_CTRL_NUM				8
+#define PPE_PORT_BRIDGE_CTRL_INC				4
+#define PPE_PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN			BIT(0)
+#define PPE_PORT_BRIDGE_CTRL_NEW_ADDR_FWD_CMD			GENMASK(2, 1)
+#define PPE_PORT_BRIDGE_CTRL_STATION_MODE_LRN_EN		BIT(3)
+#define PPE_PORT_BRIDGE_CTRL_STATION_MODE_FWD_CMD		GENMASK(5, 4)
+#define PPE_PORT_BRIDGE_CTRL_ISOLATION_BITMAP			GENMASK(15, 8)
+#define PPE_PORT_BRIDGE_CTRL_TXMAC_EN				BIT(16)
+#define PPE_PORT_BRIDGE_CTRL_PROMISC_EN				BIT(17)
+#define PPE_PORT_BRIDGE_CTRL_MASK				GENMASK(17, 0)
+
+#define PPE_PORT_MIRROR						0x60800
+#define PPE_PORT_MIRROR_NUM					8
+#define PPE_PORT_MIRROR_INC					4
+#define PPE_PORT_MIRROR_INGRESS_EN				BIT(0)
+#define PPE_PORT_MIRROR_EGRESS_EN				BIT(1)
+
+#define PPE_CST_STATE						0x60100
+#define PPE_CST_STATE_NUM					8
+#define PPE_CST_STATE_INC					4
+#define PPE_CST_STATE_PORT_STATE				GENMASK(1, 0)
+
 #define PPE_MC_MTU_CTRL_TBL					0x60a00
 #define PPE_MC_MTU_CTRL_TBL_NUM					8
 #define PPE_MC_MTU_CTRL_TBL_INC					4
@@ -245,6 +278,28 @@  union ppe_eg_service_cfg_u {
 #define PPE_MC_MTU_CTRL_TBL_MTU_CMD				GENMASK(15, 14)
 #define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN				BIT(16)
 
+#define PPE_VSI_TBL						0x63800
+#define PPE_VSI_TBL_NUM						64
+#define PPE_VSI_TBL_INC						0x10
+
+/* PPE vsi configurations */
+struct ppe_vsi_tbl {
+	u32 member_port_bitmap:8,
+	    uuc_bitmap:8,
+	    umc_bitmap:8,
+	    bc_bitmap:8;
+	u32 new_addr_lrn_en:1,
+	    new_addr_fwd_cmd:2,
+	    station_move_lrn_en:1,
+	    station_move_fwd_cmd:2,
+	    res0:26;
+};
+
+union ppe_vsi_tbl_u {
+	u32 val[2];
+	struct ppe_vsi_tbl bf;
+};
+
 #define PPE_MRU_MTU_CTRL_TBL					0x65000
 #define PPE_MRU_MTU_CTRL_TBL_NUM				256
 #define PPE_MRU_MTU_CTRL_TBL_INC				0x10
@@ -295,6 +350,53 @@  union ppe_mru_mtu_ctrl_cfg_u {
 #define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN				BIT(30)
 #define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN				BIT(31)
 
+#define PPE_L2_VP_PORT_TBL					0x98000
+#define PPE_L2_VP_PORT_TBL_NUM					256
+#define PPE_L2_VP_PORT_TBL_INC					0x10
+
+/* Port configurations */
+struct ppe_l2_vp_port_tbl {
+	u32 invalid_vsi_forwarding_en:1,
+	    promisc_en:1,
+	    dst_info:8,
+	    physical_port:3,
+	    new_addr_lrn_en:1,
+	    new_addr_fwd_cmd:2,
+	    station_move_lrn_en:1,
+	    station_move_fwd_cmd:2,
+	    lrn_lmt_cnt:12,
+	    lrn_lmt_en:1;
+	u32 lrn_lmt_exceed_fwd:2,
+	    eg_vlan_fltr_cmd:1,
+	    port_isolation_bitmap:8,
+	    isol_profile:6,
+	    isol_en:1,
+	    policer_en:1,
+	    policer_index:9,
+	    vp_state_check_en:1,
+	    vp_type:1,
+	    vp_context_active:1,
+	    vp_eg_data_valid:1;
+	u32 physical_port_mtu_check_en:1,
+	    mtu_check_type:1,
+	    extra_header_len:8,
+	    eg_vlan_fmt_valid:1,
+	    eg_stag_fmt:1,
+	    eg_ctag_fmt:1,
+	    exception_fmt_ctrl:1,
+	    enq_service_code_en:1,
+	    enq_service_code:8,
+	    enq_phy_port:3,
+	    app_ctrl_profile_0:6;
+	u32 app_ctrl_profile_1:2,
+	    res0:30;
+};
+
+union ppe_l2_vp_port_tbl_u {
+	u32 val[4];
+	struct ppe_l2_vp_port_tbl bf;
+};
+
 #define PPE_PORT_RX_CNT_TBL					0x150000
 #define PPE_PORT_RX_CNT_TBL_NUM					256
 #define PPE_PORT_RX_CNT_TBL_INC					0x20