]> www.infradead.org Git - users/willy/linux.git/commitdiff
net: ethernet: qualcomm: Initialize PPE port control settings
authorLuo Jie <quic_luoj@quicinc.com>
Mon, 18 Aug 2025 13:14:33 +0000 (21:14 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 21 Aug 2025 10:38:41 +0000 (12:38 +0200)
Configure the default action as drop when the packet size is more than
the configured MTU of physical port. Also enable port specific counters
in PPE.

Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Link: https://patch.msgid.link/20250818-qcom_ipq_ppe-v8-9-1d4ff641fce9@quicinc.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/qualcomm/ppe/ppe_config.c
drivers/net/ethernet/qualcomm/ppe/ppe_config.h
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h

index 39a01f25f5ef840fd131fa70cebf4329a538fa71..a02d3300bac0e5e1dac23a5d894e877ba45d54b4 100644 (file)
@@ -1178,6 +1178,44 @@ int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc, struct ppe_sc_cfg cfg)
        return regmap_write(ppe_dev->regmap, reg, val);
 }
 
+/**
+ * ppe_counter_enable_set - Set PPE port counter enabled
+ * @ppe_dev: PPE device
+ * @port: PPE port ID
+ *
+ * Enable PPE counters on the given port for the unicast packet, multicast
+ * packet and VLAN packet received and transmitted by PPE.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port)
+{
+       u32 reg, mru_mtu_val[3];
+       int ret;
+
+       reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * port;
+       ret = regmap_bulk_read(ppe_dev->regmap, reg,
+                              mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
+       if (ret)
+               return ret;
+
+       PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(mru_mtu_val, true);
+       PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(mru_mtu_val, true);
+       ret = regmap_bulk_write(ppe_dev->regmap, reg,
+                               mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
+       if (ret)
+               return ret;
+
+       reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * port;
+       ret = regmap_set_bits(ppe_dev->regmap, reg, PPE_MC_MTU_CTRL_TBL_TX_CNT_EN);
+       if (ret)
+               return ret;
+
+       reg = PPE_PORT_EG_VLAN_TBL_ADDR + PPE_PORT_EG_VLAN_TBL_INC * port;
+
+       return regmap_set_bits(ppe_dev->regmap, reg, PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN);
+}
+
 static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
                                   const struct ppe_bm_port_config port_cfg)
 {
@@ -1606,6 +1644,49 @@ static int ppe_servcode_init(struct ppe_device *ppe_dev)
        return ppe_sc_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, sc_cfg);
 }
 
+/* Initialize PPE port configurations. */
+static int ppe_port_config_init(struct ppe_device *ppe_dev)
+{
+       u32 reg, val, mru_mtu_val[3];
+       int i, ret;
+
+       /* MTU and MRU settings are not required for CPU port 0. */
+       for (i = 1; i < ppe_dev->num_ports; i++) {
+               /* Enable Ethernet port counter */
+               ret = ppe_counter_enable_set(ppe_dev, i);
+               if (ret)
+                       return ret;
+
+               reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * i;
+               ret = regmap_bulk_read(ppe_dev->regmap, reg,
+                                      mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
+               if (ret)
+                       return ret;
+
+               /* Drop the packet when the packet size is more than the MTU
+                * and redirect the packet to the CPU port when the received
+                * packet size is more than the MRU of the physical interface.
+                */
+               PPE_MRU_MTU_CTRL_SET_MRU_CMD(mru_mtu_val, PPE_ACTION_REDIRECT_TO_CPU);
+               PPE_MRU_MTU_CTRL_SET_MTU_CMD(mru_mtu_val, PPE_ACTION_DROP);
+               ret = regmap_bulk_write(ppe_dev->regmap, reg,
+                                       mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
+               if (ret)
+                       return ret;
+
+               reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * i;
+               val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU_CMD, PPE_ACTION_DROP);
+               ret = regmap_update_bits(ppe_dev->regmap, reg,
+                                        PPE_MC_MTU_CTRL_TBL_MTU_CMD,
+                                        val);
+               if (ret)
+                       return ret;
+       }
+
+       /* Enable CPU port counters. */
+       return ppe_counter_enable_set(ppe_dev, 0);
+}
+
 int ppe_hw_config(struct ppe_device *ppe_dev)
 {
        int ret;
@@ -1626,5 +1707,9 @@ int ppe_hw_config(struct ppe_device *ppe_dev)
        if (ret)
                return ret;
 
-       return ppe_servcode_init(ppe_dev);
+       ret = ppe_servcode_init(ppe_dev);
+       if (ret)
+               return ret;
+
+       return ppe_port_config_init(ppe_dev);
 }
index 2b3f7e39cc7eada67e6102622087cc0121d77ae6..84fa447742e30f6cdd91bf7ada394eda5c45415f 100644 (file)
@@ -233,6 +233,20 @@ struct ppe_sc_cfg {
        int eip_offset_sel;
 };
 
+/**
+ * enum ppe_action_type - PPE action of the received packet.
+ * @PPE_ACTION_FORWARD: Packet forwarded per L2/L3 process.
+ * @PPE_ACTION_DROP: Packet dropped by PPE.
+ * @PPE_ACTION_COPY_TO_CPU: Packet copied to CPU port per multicast queue.
+ * @PPE_ACTION_REDIRECT_TO_CPU: Packet redirected to CPU port per unicast queue.
+ */
+enum ppe_action_type {
+       PPE_ACTION_FORWARD = 0,
+       PPE_ACTION_DROP = 1,
+       PPE_ACTION_COPY_TO_CPU = 2,
+       PPE_ACTION_REDIRECT_TO_CPU = 3,
+};
+
 int ppe_hw_config(struct ppe_device *ppe_dev);
 int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
                            int node_id, bool flow_level, int port,
@@ -254,4 +268,5 @@ int ppe_port_resource_get(struct ppe_device *ppe_dev, int port,
                          int *res_start, int *res_end);
 int ppe_sc_config_set(struct ppe_device *ppe_dev, int sc,
                      struct ppe_sc_cfg cfg);
+int ppe_counter_enable_set(struct ppe_device *ppe_dev, int port);
 #endif
index 4cb76313db87bbc900c3969f74bbee1e87d5c15f..c26bee83252feb1df4f727f6944f1c12c876e9ca 100644 (file)
 #define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value)      \
        FIELD_MODIFY(PPE_SERVICE_W1_RX_CNT_EN, (tbl_cfg) + 0x1, value)
 
+/* PPE port egress VLAN configurations. */
+#define PPE_PORT_EG_VLAN_TBL_ADDR              0x20020
+#define PPE_PORT_EG_VLAN_TBL_ENTRIES           8
+#define PPE_PORT_EG_VLAN_TBL_INC               4
+#define PPE_PORT_EG_VLAN_TBL_VLAN_TYPE         BIT(0)
+#define PPE_PORT_EG_VLAN_TBL_CTAG_MODE         GENMASK(2, 1)
+#define PPE_PORT_EG_VLAN_TBL_STAG_MODE         GENMASK(4, 3)
+#define PPE_PORT_EG_VLAN_TBL_VSI_TAG_MODE_EN   BIT(5)
+#define PPE_PORT_EG_VLAN_TBL_PCP_PROP_CMD      BIT(6)
+#define PPE_PORT_EG_VLAN_TBL_DEI_PROP_CMD      BIT(7)
+#define PPE_PORT_EG_VLAN_TBL_TX_COUNTING_EN    BIT(8)
+
 /* PPE queue counters enable/disable control. */
 #define PPE_EG_BRIDGE_CONFIG_ADDR              0x20044
 #define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN      BIT(2)
 #define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value)   \
        FIELD_MODIFY(PPE_EG_SERVICE_W1_TX_CNT_EN, (tbl_cfg) + 0x1, value)
 
+/* PPE port control configurations for the traffic to the multicast queues. */
+#define PPE_MC_MTU_CTRL_TBL_ADDR               0x60a00
+#define PPE_MC_MTU_CTRL_TBL_ENTRIES            8
+#define PPE_MC_MTU_CTRL_TBL_INC                        4
+#define PPE_MC_MTU_CTRL_TBL_MTU                        GENMASK(13, 0)
+#define PPE_MC_MTU_CTRL_TBL_MTU_CMD            GENMASK(15, 14)
+#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN          BIT(16)
+
+/* PPE port control configurations for the traffic to the unicast queues. */
+#define PPE_MRU_MTU_CTRL_TBL_ADDR              0x65000
+#define PPE_MRU_MTU_CTRL_TBL_ENTRIES           256
+#define PPE_MRU_MTU_CTRL_TBL_INC               0x10
+#define PPE_MRU_MTU_CTRL_W0_MRU                        GENMASK(13, 0)
+#define PPE_MRU_MTU_CTRL_W0_MRU_CMD            GENMASK(15, 14)
+#define PPE_MRU_MTU_CTRL_W0_MTU                        GENMASK(29, 16)
+#define PPE_MRU_MTU_CTRL_W0_MTU_CMD            GENMASK(31, 30)
+#define PPE_MRU_MTU_CTRL_W1_RX_CNT_EN          BIT(0)
+#define PPE_MRU_MTU_CTRL_W1_TX_CNT_EN          BIT(1)
+#define PPE_MRU_MTU_CTRL_W1_SRC_PROFILE                GENMASK(3, 2)
+#define PPE_MRU_MTU_CTRL_W1_INNER_PREC_LOW     BIT(31)
+#define PPE_MRU_MTU_CTRL_W2_INNER_PREC_HIGH    GENMASK(1, 0)
+
+#define PPE_MRU_MTU_CTRL_SET_MRU(tbl_cfg, value)       \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W0_MRU, tbl_cfg, value)
+#define PPE_MRU_MTU_CTRL_SET_MRU_CMD(tbl_cfg, value)   \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W0_MRU_CMD, tbl_cfg, value)
+#define PPE_MRU_MTU_CTRL_SET_MTU(tbl_cfg, value)       \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W0_MTU, tbl_cfg, value)
+#define PPE_MRU_MTU_CTRL_SET_MTU_CMD(tbl_cfg, value)   \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W0_MTU_CMD, tbl_cfg, value)
+#define PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(tbl_cfg, value) \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W1_RX_CNT_EN, (tbl_cfg) + 0x1, value)
+#define PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(tbl_cfg, value) \
+       FIELD_MODIFY(PPE_MRU_MTU_CTRL_W1_TX_CNT_EN, (tbl_cfg) + 0x1, value)
+
 /* PPE service code configuration for destination port and counter. */
 #define PPE_IN_L2_SERVICE_TBL_ADDR             0x66000
 #define PPE_IN_L2_SERVICE_TBL_ENTRIES          256