1 From 12a50075552d0e2ada65c039e5a09ca50421f152 Mon Sep 17 00:00:00 2001
2 From: Luo Jie <quic_luoj@quicinc.com>
3 Date: Tue, 26 Dec 2023 19:34:49 +0800
4 Subject: [PATCH 20/50] net: ethernet: qualcomm: Add PPE queue management
7 QM (queue management) config decides the length of PPE port queues
8 and the threshold to drop packet.
10 There are two types of PPE queue, unicast queue (0-255) and multicast
11 queue (256-299) are configured with different length, which are used
12 to forward the different types of traffic.
14 Change-Id: I74ffcb6a39618ca8f585b5204d483fb45edecba8
15 Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
17 .../net/ethernet/qualcomm/ppe/ppe_config.c | 176 +++++++++++++++++-
18 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 82 ++++++++
19 2 files changed, 257 insertions(+), 1 deletion(-)
21 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
22 index 0ba4efdfd509..4192fdc8d3a3 100644
23 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
24 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
25 @@ -43,6 +43,27 @@ struct ppe_bm_port_config {
30 + * struct ppe_qm_queue_config - PPE queue config.
31 + * @queue_start: PPE start of queue ID.
32 + * @queue_end: PPE end of queue ID.
33 + * @prealloc_buf: Queue dedicated buffer number.
34 + * @ceil: Ceil to start drop packet from queue.
35 + * @weight: Weight value.
36 + * @resume_offset: Resume offset from the threshold.
37 + * @dynamic: Threshold value is decided dynamically or statically.
40 +struct ppe_qm_queue_config {
41 + unsigned int queue_start;
42 + unsigned int queue_end;
43 + unsigned int prealloc_buf;
45 + unsigned int weight;
46 + unsigned int resume_offset;
50 static int ipq9574_ppe_bm_group_config = 1550;
51 static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
53 @@ -91,6 +112,31 @@ static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
57 +/* Default QM group settings for IPQ9754. */
58 +static int ipq9574_ppe_qm_group_config = 2000;
60 +/* Default QM settings for unicast and multicast queues for IPQ9754. */
61 +static struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
68 + .resume_offset = 36,
77 + .resume_offset = 36,
82 static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
83 struct ppe_bm_port_config port_cfg)
85 @@ -175,7 +221,135 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)
89 +/* Configure PPE hardware queue depth, which is decided by the threshold
92 +static int ppe_config_qm(struct ppe_device *ppe_dev)
94 + struct ppe_qm_queue_config *queue_cfg;
95 + int ret, i, queue_id, queue_cfg_count;
96 + u32 reg, multicast_queue_cfg[5];
97 + u32 unicast_queue_cfg[4];
100 + /* Assign the buffer number to the group 0 by default. */
101 + reg = PPE_AC_GRP_CFG_TBL_ADDR;
102 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
103 + group_cfg, ARRAY_SIZE(group_cfg));
105 + goto qm_config_fail;
107 + PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);
109 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
110 + group_cfg, ARRAY_SIZE(group_cfg));
112 + goto qm_config_fail;
114 + queue_cfg = ipq9574_ppe_qm_queue_config;
115 + queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);
116 + for (i = 0; i < queue_cfg_count; i++) {
117 + queue_id = queue_cfg[i].queue_start;
119 + /* Configure threshold for dropping packet from unicast queue
120 + * and multicast queue, which belong to the different queue ID.
122 + while (queue_id <= queue_cfg[i].queue_end) {
123 + if (queue_id < PPE_AC_UNI_QUEUE_CFG_TBL_NUM) {
124 + reg = PPE_AC_UNI_QUEUE_CFG_TBL_ADDR +
125 + PPE_AC_UNI_QUEUE_CFG_TBL_INC * queue_id;
127 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
129 + ARRAY_SIZE(unicast_queue_cfg));
131 + goto qm_config_fail;
133 + PPE_AC_UNI_QUEUE_SET_EN(unicast_queue_cfg, true);
134 + PPE_AC_UNI_QUEUE_SET_GRP_ID(unicast_queue_cfg, 0);
135 + PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(unicast_queue_cfg,
136 + queue_cfg[i].prealloc_buf);
137 + PPE_AC_UNI_QUEUE_SET_DYNAMIC(unicast_queue_cfg,
138 + queue_cfg[i].dynamic);
139 + PPE_AC_UNI_QUEUE_SET_WEIGHT(unicast_queue_cfg,
140 + queue_cfg[i].weight);
141 + PPE_AC_UNI_QUEUE_SET_THRESHOLD(unicast_queue_cfg,
142 + queue_cfg[i].ceil);
143 + PPE_AC_UNI_QUEUE_SET_GRN_RESUME(unicast_queue_cfg,
144 + queue_cfg[i].resume_offset);
146 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
148 + ARRAY_SIZE(unicast_queue_cfg));
150 + goto qm_config_fail;
152 + reg = PPE_AC_MUL_QUEUE_CFG_TBL_ADDR +
153 + PPE_AC_MUL_QUEUE_CFG_TBL_INC * queue_id;
155 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
156 + multicast_queue_cfg,
157 + ARRAY_SIZE(multicast_queue_cfg));
159 + goto qm_config_fail;
161 + PPE_AC_MUL_QUEUE_SET_EN(multicast_queue_cfg, true);
162 + PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(multicast_queue_cfg, 0);
163 + PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(multicast_queue_cfg,
164 + queue_cfg[i].prealloc_buf);
165 + PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(multicast_queue_cfg,
166 + queue_cfg[i].ceil);
167 + PPE_AC_MUL_QUEUE_SET_GRN_RESUME(multicast_queue_cfg,
168 + queue_cfg[i].resume_offset);
170 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
171 + multicast_queue_cfg,
172 + ARRAY_SIZE(multicast_queue_cfg));
174 + goto qm_config_fail;
177 + /* Enable enqueue */
178 + reg = PPE_ENQ_OPR_TBL_ADDR + PPE_ENQ_OPR_TBL_INC * queue_id;
179 + ret = regmap_update_bits(ppe_dev->regmap, reg,
180 + PPE_ENQ_OPR_TBL_ENQ_DISABLE,
181 + FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
183 + goto qm_config_fail;
185 + /* Enable dequeue */
186 + reg = PPE_DEQ_OPR_TBL_ADDR + PPE_DEQ_OPR_TBL_INC * queue_id;
187 + ret = regmap_update_bits(ppe_dev->regmap, reg,
188 + PPE_DEQ_OPR_TBL_DEQ_DISABLE,
189 + FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
191 + goto qm_config_fail;
197 + /* Enable queue counter for all PPE hardware queues. */
198 + ret = regmap_update_bits(ppe_dev->regmap, PPE_EG_BRIDGE_CONFIG_ADDR,
199 + PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN,
200 + PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN);
202 + goto qm_config_fail;
207 + dev_err(ppe_dev->dev, "PPE QM config error %d\n", ret);
211 int ppe_hw_config(struct ppe_device *ppe_dev)
213 - return ppe_config_bm(ppe_dev);
216 + ret = ppe_config_bm(ppe_dev);
220 + return ppe_config_qm(ppe_dev);
222 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
223 index bf25e0acc0f6..0bc13979e5e2 100644
224 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
225 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
227 * BM port (0-7) is matched to EDMA port 0, BM port (8-13) is matched
228 * to PPE physical port 1-6, BM port 14 is matched to EIP.
230 +#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044
231 +#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
233 +#define PPE_DEQ_OPR_TBL_ADDR 0x430000
234 +#define PPE_DEQ_OPR_TBL_NUM 300
235 +#define PPE_DEQ_OPR_TBL_INC 0x10
236 +#define PPE_DEQ_OPR_TBL_DEQ_DISABLE BIT(0)
238 #define PPE_BM_PORT_FC_MODE_ADDR 0x600100
239 #define PPE_BM_PORT_FC_MODE_INC 0x4
240 #define PPE_BM_PORT_FC_MODE_EN BIT(0)
242 #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \
243 u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
245 +/* PPE unicast queue (0-255) configurations. */
246 +#define PPE_AC_UNI_QUEUE_CFG_TBL_ADDR 0x848000
247 +#define PPE_AC_UNI_QUEUE_CFG_TBL_NUM 256
248 +#define PPE_AC_UNI_QUEUE_CFG_TBL_INC 0x10
249 +#define PPE_AC_UNI_QUEUE_CFG_W0_EN BIT(0)
250 +#define PPE_AC_UNI_QUEUE_CFG_W0_WRED_EN BIT(1)
251 +#define PPE_AC_UNI_QUEUE_CFG_W0_FC_EN BIT(2)
252 +#define PPE_AC_UNI_QUEUE_CFG_W0_COLOR_AWARE BIT(3)
253 +#define PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID GENMASK(5, 4)
254 +#define PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT GENMASK(16, 6)
255 +#define PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC BIT(17)
256 +#define PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT GENMASK(20, 18)
257 +#define PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD GENMASK(31, 21)
258 +#define PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME GENMASK(23, 13)
260 +#define PPE_AC_UNI_QUEUE_SET_EN(tbl_cfg, value) \
261 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_EN)
262 +#define PPE_AC_UNI_QUEUE_SET_GRP_ID(tbl_cfg, value) \
263 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID)
264 +#define PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(tbl_cfg, value) \
265 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT)
266 +#define PPE_AC_UNI_QUEUE_SET_DYNAMIC(tbl_cfg, value) \
267 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC)
268 +#define PPE_AC_UNI_QUEUE_SET_WEIGHT(tbl_cfg, value) \
269 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT)
270 +#define PPE_AC_UNI_QUEUE_SET_THRESHOLD(tbl_cfg, value) \
271 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD)
272 +#define PPE_AC_UNI_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
273 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x3, value, PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME)
275 +/* PPE multicast queue (256-299) configurations. */
276 +#define PPE_AC_MUL_QUEUE_CFG_TBL_ADDR 0x84a000
277 +#define PPE_AC_MUL_QUEUE_CFG_TBL_NUM 44
278 +#define PPE_AC_MUL_QUEUE_CFG_TBL_INC 0x10
279 +#define PPE_AC_MUL_QUEUE_CFG_W0_EN BIT(0)
280 +#define PPE_AC_MUL_QUEUE_CFG_W0_FC_EN BIT(1)
281 +#define PPE_AC_MUL_QUEUE_CFG_W0_COLOR_AWARE BIT(2)
282 +#define PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID GENMASK(4, 3)
283 +#define PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT GENMASK(15, 5)
284 +#define PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD GENMASK(26, 16)
285 +#define PPE_AC_MUL_QUEUE_CFG_W2_RESUME GENMASK(17, 7)
287 +#define PPE_AC_MUL_QUEUE_SET_EN(tbl_cfg, value) \
288 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_EN)
289 +#define PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(tbl_cfg, value) \
290 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID)
291 +#define PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(tbl_cfg, value) \
292 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT)
293 +#define PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(tbl_cfg, value) \
294 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD)
295 +#define PPE_AC_MUL_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
296 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x2, value, PPE_AC_MUL_QUEUE_CFG_W2_RESUME)
298 +/* PPE admission control group (0-3) configurations */
299 +#define PPE_AC_GRP_CFG_TBL_ADDR 0x84c000
300 +#define PPE_AC_GRP_CFG_TBL_NUM 0x4
301 +#define PPE_AC_GRP_CFG_TBL_INC 0x10
302 +#define PPE_AC_GRP_W0_AC_EN BIT(0)
303 +#define PPE_AC_GRP_W0_AC_FC_EN BIT(1)
304 +#define PPE_AC_GRP_W0_COLOR_AWARE BIT(2)
305 +#define PPE_AC_GRP_W0_THRESHOLD_LOW GENMASK(31, 25)
306 +#define PPE_AC_GRP_W1_THRESHOLD_HIGH GENMASK(3, 0)
307 +#define PPE_AC_GRP_W1_BUF_LIMIT GENMASK(14, 4)
308 +#define PPE_AC_GRP_W2_RESUME_GRN GENMASK(15, 5)
309 +#define PPE_AC_GRP_W2_PRE_ALLOC GENMASK(26, 16)
311 +#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \
312 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
314 +#define PPE_ENQ_OPR_TBL_ADDR 0x85c000
315 +#define PPE_ENQ_OPR_TBL_NUM 300
316 +#define PPE_ENQ_OPR_TBL_INC 0x10
317 +#define PPE_ENQ_OPR_TBL_ENQ_DISABLE BIT(0)