mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00

Refreshed patches for qualcommb/ipq95xx by running make target/linux/refresh after creating a .config containing: CONFIG_TARGET_qualcommbe=y CONFIG_TARGET_qualcommbe_ipq95xx=y CONFIG_TARGET_qualcommbe_ipq95xx_DEVICE_qcom_rdp433=y Signed-off-by: John Audia <therealgraysky@proton.me> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
343 lines
11 KiB
Diff
343 lines
11 KiB
Diff
From b052daae2f22a7a7fcfe981598444c3f5fb370b4 Mon Sep 17 00:00:00 2001
|
|
From: Luo Jie <quic_luoj@quicinc.com>
|
|
Date: Wed, 27 Dec 2023 14:52:13 +0800
|
|
Subject: [PATCH 25/50] net: ethernet: qualcomm: Add PPE RSS hash config
|
|
|
|
PPE RSS hash is generated by the configured seed based on the
|
|
packet content, which is used to select queue and can also be
|
|
passed to EDMA RX descriptor.
|
|
|
|
Change-Id: If02cb25aa81a3afb0f3d68b2a5a354bd6cee28b8
|
|
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
|
---
|
|
.../net/ethernet/qualcomm/ppe/ppe_config.c | 182 +++++++++++++++++-
|
|
.../net/ethernet/qualcomm/ppe/ppe_config.h | 36 ++++
|
|
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 47 +++++
|
|
3 files changed, 263 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
|
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
|
@@ -1282,6 +1282,143 @@ int ppe_counter_set(struct ppe_device *p
|
|
val);
|
|
}
|
|
|
|
+static int ppe_rss_hash_ipv4_config(struct ppe_device *ppe_dev, int index,
|
|
+ struct ppe_rss_hash_cfg cfg)
|
|
+{
|
|
+ u32 reg, val;
|
|
+
|
|
+ switch (index) {
|
|
+ case 0:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sip_mix[0]);
|
|
+ break;
|
|
+ case 1:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dip_mix[0]);
|
|
+ break;
|
|
+ case 2:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_protocol_mix);
|
|
+ break;
|
|
+ case 3:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dport_mix);
|
|
+ break;
|
|
+ case 4:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sport_mix);
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ reg = PPE_RSS_HASH_MIX_IPV4_ADDR + index * PPE_RSS_HASH_MIX_IPV4_INC;
|
|
+
|
|
+ return regmap_write(ppe_dev->regmap, reg, val);
|
|
+}
|
|
+
|
|
+static int ppe_rss_hash_ipv6_config(struct ppe_device *ppe_dev, int index,
|
|
+ struct ppe_rss_hash_cfg cfg)
|
|
+{
|
|
+ u32 reg, val;
|
|
+
|
|
+ switch (index) {
|
|
+ case 0 ... 3:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sip_mix[index]);
|
|
+ break;
|
|
+ case 4 ... 7:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dip_mix[index - 4]);
|
|
+ break;
|
|
+ case 8:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_protocol_mix);
|
|
+ break;
|
|
+ case 9:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dport_mix);
|
|
+ break;
|
|
+ case 10:
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sport_mix);
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ reg = PPE_RSS_HASH_MIX_ADDR + index * PPE_RSS_HASH_MIX_INC;
|
|
+
|
|
+ return regmap_write(ppe_dev->regmap, reg, val);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * ppe_rss_hash_config_set - Set PPE RSS hash seed
|
|
+ * @ppe_dev: PPE device
|
|
+ * @mode: Packet format mode
|
|
+ * @hash_cfg: RSS hash configuration
|
|
+ *
|
|
+ * PPE RSS hash seed is configured based on the packet format.
|
|
+ *
|
|
+ * Return 0 on success, negative error code on failure.
|
|
+ */
|
|
+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
|
+ struct ppe_rss_hash_cfg cfg)
|
|
+{
|
|
+ u32 val, reg;
|
|
+ int i, ret;
|
|
+
|
|
+ if (mode & PPE_RSS_HASH_MODE_IPV4) {
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_HASH_MASK, cfg.hash_mask);
|
|
+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_FRAGMENT, cfg.hash_fragment_mode);
|
|
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_IPV4_ADDR, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_SEED_IPV4_VAL, cfg.hash_seed);
|
|
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_IPV4_ADDR, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ for (i = 0; i < PPE_RSS_HASH_MIX_IPV4_NUM; i++) {
|
|
+ ret = ppe_rss_hash_ipv4_config(ppe_dev, i, cfg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < PPE_RSS_HASH_FIN_IPV4_NUM; i++) {
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_INNER, cfg.hash_fin_inner[i]);
|
|
+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_OUTER, cfg.hash_fin_outer[i]);
|
|
+ reg = PPE_RSS_HASH_FIN_IPV4_ADDR + i * PPE_RSS_HASH_FIN_IPV4_INC;
|
|
+
|
|
+ ret = regmap_write(ppe_dev->regmap, reg, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (mode & PPE_RSS_HASH_MODE_IPV6) {
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_MASK_HASH_MASK, cfg.hash_mask);
|
|
+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_FRAGMENT, cfg.hash_fragment_mode);
|
|
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_ADDR, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_SEED_VAL, cfg.hash_seed);
|
|
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_ADDR, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ for (i = 0; i < PPE_RSS_HASH_MIX_NUM; i++) {
|
|
+ ret = ppe_rss_hash_ipv6_config(ppe_dev, i, cfg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < PPE_RSS_HASH_FIN_NUM; i++) {
|
|
+ val = FIELD_PREP(PPE_RSS_HASH_FIN_INNER, cfg.hash_fin_inner[i]);
|
|
+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_OUTER, cfg.hash_fin_outer[i]);
|
|
+ reg = PPE_RSS_HASH_FIN_ADDR + i * PPE_RSS_HASH_FIN_INC;
|
|
+
|
|
+ ret = regmap_write(ppe_dev->regmap, reg, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
|
struct ppe_bm_port_config port_cfg)
|
|
{
|
|
@@ -1324,7 +1461,7 @@ static int ppe_config_bm_threshold(struc
|
|
return regmap_update_bits(ppe_dev->regmap, reg,
|
|
PPE_BM_PORT_FC_MODE_EN,
|
|
val);
|
|
-}
|
|
+};
|
|
|
|
/* Configure the buffer threshold for the port flow control function. */
|
|
static int ppe_config_bm(struct ppe_device *ppe_dev)
|
|
@@ -1744,6 +1881,43 @@ static int ppe_port_ctrl_init(struct ppe
|
|
return ppe_counter_set(ppe_dev, 0, true);
|
|
}
|
|
|
|
+/* Initialize PPE RSS hash configuration, the RSS hash configs decides the
|
|
+ * random hash value generated, which is used to generate the queue offset.
|
|
+ */
|
|
+static int ppe_rss_hash_init(struct ppe_device *ppe_dev)
|
|
+{
|
|
+ u16 fins[PPE_RSS_HASH_TUPLES] = { 0x205, 0x264, 0x227, 0x245, 0x201 };
|
|
+ u8 ips[PPE_RSS_HASH_IP_LENGTH] = { 0x13, 0xb, 0x13, 0xb };
|
|
+ struct ppe_rss_hash_cfg hash_cfg;
|
|
+ int i, ret;
|
|
+
|
|
+ hash_cfg.hash_seed = get_random_u32();
|
|
+ hash_cfg.hash_mask = 0xfff;
|
|
+ hash_cfg.hash_fragment_mode = false;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(fins); i++) {
|
|
+ hash_cfg.hash_fin_inner[i] = fins[i] & 0x1f;
|
|
+ hash_cfg.hash_fin_outer[i] = fins[i] >> 5;
|
|
+ }
|
|
+
|
|
+ hash_cfg.hash_protocol_mix = 0x13;
|
|
+ hash_cfg.hash_dport_mix = 0xb;
|
|
+ hash_cfg.hash_sport_mix = 0x13;
|
|
+ hash_cfg.hash_sip_mix[0] = 0x13;
|
|
+ hash_cfg.hash_dip_mix[0] = 0xb;
|
|
+
|
|
+ ret = ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV4, hash_cfg);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(ips); i++) {
|
|
+ hash_cfg.hash_sip_mix[i] = ips[i];
|
|
+ hash_cfg.hash_dip_mix[i] = ips[i];
|
|
+ }
|
|
+
|
|
+ return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg);
|
|
+}
|
|
+
|
|
/* Initialize PPE device to handle traffic correctly. */
|
|
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
|
{
|
|
@@ -1757,7 +1931,11 @@ static int ppe_dev_hw_init(struct ppe_de
|
|
if (ret)
|
|
return ret;
|
|
|
|
- return ppe_port_ctrl_init(ppe_dev);
|
|
+ ret = ppe_port_ctrl_init(ppe_dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ return ppe_rss_hash_init(ppe_dev);
|
|
}
|
|
|
|
int ppe_hw_config(struct ppe_device *ppe_dev)
|
|
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
|
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
|
@@ -15,6 +15,11 @@
|
|
#define PPE_QUEUE_BASE_CPU_CODE 1024
|
|
#define PPE_QUEUE_BASE_SERVICE_CODE 2048
|
|
|
|
+#define PPE_RSS_HASH_MODE_IPV4 BIT(0)
|
|
+#define PPE_RSS_HASH_MODE_IPV6 BIT(1)
|
|
+#define PPE_RSS_HASH_IP_LENGTH 4
|
|
+#define PPE_RSS_HASH_TUPLES 5
|
|
+
|
|
/**
|
|
* struct ppe_qos_scheduler_cfg - PPE QoS scheduler configuration.
|
|
* @flow_id: PPE flow ID.
|
|
@@ -202,6 +207,35 @@ enum ppe_action_type {
|
|
PPE_ACTION_REDIRECT_TO_CPU = 3,
|
|
};
|
|
|
|
+/**
|
|
+ * struct ppe_rss_hash_cfg - PPE RSS hash configuration.
|
|
+ * @hash_mask: Mask of the generated hash value.
|
|
+ * @hash_fragment_mode: Mode of the fragment packet for 3 tuples.
|
|
+ * @hash_seed: Seed to generate RSS hash.
|
|
+ * @hash_sip_mix: Source IP selection.
|
|
+ * @hash_dip_mix: Destination IP selection.
|
|
+ * @hash_protocol_mix: Protocol selection.
|
|
+ * @hash_sport_mix: Source L4 port selection.
|
|
+ * @hash_sport_mix: Destination L4 port selection.
|
|
+ * @hash_fin_inner: RSS hash value first selection.
|
|
+ * @hash_fin_outer: RSS hash value second selection.
|
|
+ *
|
|
+ * PPE RSS hash value is generated based on the RSS hash configuration
|
|
+ * with the received packet.
|
|
+ */
|
|
+struct ppe_rss_hash_cfg {
|
|
+ u32 hash_mask;
|
|
+ bool hash_fragment_mode;
|
|
+ u32 hash_seed;
|
|
+ u8 hash_sip_mix[PPE_RSS_HASH_IP_LENGTH];
|
|
+ u8 hash_dip_mix[PPE_RSS_HASH_IP_LENGTH];
|
|
+ u8 hash_protocol_mix;
|
|
+ u8 hash_sport_mix;
|
|
+ u8 hash_dport_mix;
|
|
+ u8 hash_fin_inner[PPE_RSS_HASH_TUPLES];
|
|
+ u8 hash_fin_outer[PPE_RSS_HASH_TUPLES];
|
|
+};
|
|
+
|
|
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,
|
|
@@ -227,4 +261,6 @@ int ppe_servcode_config_set(struct ppe_d
|
|
int servcode,
|
|
struct ppe_servcode_cfg cfg);
|
|
int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable);
|
|
+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
|
+ struct ppe_rss_hash_cfg hash_cfg);
|
|
#endif
|
|
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
|
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
|
@@ -23,6 +23,53 @@
|
|
#define PPE_RX_FIFO_CFG_INC 4
|
|
#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)
|
|
|
|
+/* RSS configs contributes to the random RSS hash value generated, which
|
|
+ * is used to configure the queue offset.
|
|
+ */
|
|
+#define PPE_RSS_HASH_MASK_ADDR 0xb4318
|
|
+#define PPE_RSS_HASH_MASK_NUM 1
|
|
+#define PPE_RSS_HASH_MASK_INC 4
|
|
+#define PPE_RSS_HASH_MASK_HASH_MASK GENMASK(20, 0)
|
|
+#define PPE_RSS_HASH_MASK_FRAGMENT BIT(28)
|
|
+
|
|
+#define PPE_RSS_HASH_SEED_ADDR 0xb431c
|
|
+#define PPE_RSS_HASH_SEED_NUM 1
|
|
+#define PPE_RSS_HASH_SEED_INC 4
|
|
+#define PPE_RSS_HASH_SEED_VAL GENMASK(31, 0)
|
|
+
|
|
+#define PPE_RSS_HASH_MIX_ADDR 0xb4320
|
|
+#define PPE_RSS_HASH_MIX_NUM 11
|
|
+#define PPE_RSS_HASH_MIX_INC 4
|
|
+#define PPE_RSS_HASH_MIX_VAL GENMASK(4, 0)
|
|
+
|
|
+#define PPE_RSS_HASH_FIN_ADDR 0xb4350
|
|
+#define PPE_RSS_HASH_FIN_NUM 5
|
|
+#define PPE_RSS_HASH_FIN_INC 4
|
|
+#define PPE_RSS_HASH_FIN_INNER GENMASK(4, 0)
|
|
+#define PPE_RSS_HASH_FIN_OUTER GENMASK(9, 5)
|
|
+
|
|
+#define PPE_RSS_HASH_MASK_IPV4_ADDR 0xb4380
|
|
+#define PPE_RSS_HASH_MASK_IPV4_NUM 1
|
|
+#define PPE_RSS_HASH_MASK_IPV4_INC 4
|
|
+#define PPE_RSS_HASH_MASK_IPV4_HASH_MASK GENMASK(20, 0)
|
|
+#define PPE_RSS_HASH_MASK_IPV4_FRAGMENT BIT(28)
|
|
+
|
|
+#define PPE_RSS_HASH_SEED_IPV4_ADDR 0xb4384
|
|
+#define PPE_RSS_HASH_SEED_IPV4_NUM 1
|
|
+#define PPE_RSS_HASH_SEED_IPV4_INC 4
|
|
+#define PPE_RSS_HASH_SEED_IPV4_VAL GENMASK(31, 0)
|
|
+
|
|
+#define PPE_RSS_HASH_MIX_IPV4_ADDR 0xb4390
|
|
+#define PPE_RSS_HASH_MIX_IPV4_NUM 5
|
|
+#define PPE_RSS_HASH_MIX_IPV4_INC 4
|
|
+#define PPE_RSS_HASH_MIX_IPV4_VAL GENMASK(4, 0)
|
|
+
|
|
+#define PPE_RSS_HASH_FIN_IPV4_ADDR 0xb43b0
|
|
+#define PPE_RSS_HASH_FIN_IPV4_NUM 5
|
|
+#define PPE_RSS_HASH_FIN_IPV4_INC 4
|
|
+#define PPE_RSS_HASH_FIN_IPV4_INNER GENMASK(4, 0)
|
|
+#define PPE_RSS_HASH_FIN_IPV4_OUTER GENMASK(9, 5)
|
|
+
|
|
#define PPE_BM_SCH_CFG_TBL_ADDR 0xc000
|
|
#define PPE_BM_SCH_CFG_TBL_NUM 128
|
|
#define PPE_BM_SCH_CFG_TBL_INC 0x10
|