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 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
22 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
23 @@ -43,6 +43,27 @@ struct ppe_bm_port_config {
28 + * struct ppe_qm_queue_config - PPE queue config.
29 + * @queue_start: PPE start of queue ID.
30 + * @queue_end: PPE end of queue ID.
31 + * @prealloc_buf: Queue dedicated buffer number.
32 + * @ceil: Ceil to start drop packet from queue.
33 + * @weight: Weight value.
34 + * @resume_offset: Resume offset from the threshold.
35 + * @dynamic: Threshold value is decided dynamically or statically.
38 +struct ppe_qm_queue_config {
39 + unsigned int queue_start;
40 + unsigned int queue_end;
41 + unsigned int prealloc_buf;
43 + unsigned int weight;
44 + unsigned int resume_offset;
48 static int ipq9574_ppe_bm_group_config = 1550;
49 static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
51 @@ -91,6 +112,31 @@ static struct ppe_bm_port_config ipq9574
55 +/* Default QM group settings for IPQ9754. */
56 +static int ipq9574_ppe_qm_group_config = 2000;
58 +/* Default QM settings for unicast and multicast queues for IPQ9754. */
59 +static struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
66 + .resume_offset = 36,
75 + .resume_offset = 36,
80 static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
81 struct ppe_bm_port_config port_cfg)
83 @@ -175,7 +221,135 @@ bm_config_fail:
87 +/* Configure PPE hardware queue depth, which is decided by the threshold
90 +static int ppe_config_qm(struct ppe_device *ppe_dev)
92 + struct ppe_qm_queue_config *queue_cfg;
93 + int ret, i, queue_id, queue_cfg_count;
94 + u32 reg, multicast_queue_cfg[5];
95 + u32 unicast_queue_cfg[4];
98 + /* Assign the buffer number to the group 0 by default. */
99 + reg = PPE_AC_GRP_CFG_TBL_ADDR;
100 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
101 + group_cfg, ARRAY_SIZE(group_cfg));
103 + goto qm_config_fail;
105 + PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);
107 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
108 + group_cfg, ARRAY_SIZE(group_cfg));
110 + goto qm_config_fail;
112 + queue_cfg = ipq9574_ppe_qm_queue_config;
113 + queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);
114 + for (i = 0; i < queue_cfg_count; i++) {
115 + queue_id = queue_cfg[i].queue_start;
117 + /* Configure threshold for dropping packet from unicast queue
118 + * and multicast queue, which belong to the different queue ID.
120 + while (queue_id <= queue_cfg[i].queue_end) {
121 + if (queue_id < PPE_AC_UNI_QUEUE_CFG_TBL_NUM) {
122 + reg = PPE_AC_UNI_QUEUE_CFG_TBL_ADDR +
123 + PPE_AC_UNI_QUEUE_CFG_TBL_INC * queue_id;
125 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
127 + ARRAY_SIZE(unicast_queue_cfg));
129 + goto qm_config_fail;
131 + PPE_AC_UNI_QUEUE_SET_EN(unicast_queue_cfg, true);
132 + PPE_AC_UNI_QUEUE_SET_GRP_ID(unicast_queue_cfg, 0);
133 + PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(unicast_queue_cfg,
134 + queue_cfg[i].prealloc_buf);
135 + PPE_AC_UNI_QUEUE_SET_DYNAMIC(unicast_queue_cfg,
136 + queue_cfg[i].dynamic);
137 + PPE_AC_UNI_QUEUE_SET_WEIGHT(unicast_queue_cfg,
138 + queue_cfg[i].weight);
139 + PPE_AC_UNI_QUEUE_SET_THRESHOLD(unicast_queue_cfg,
140 + queue_cfg[i].ceil);
141 + PPE_AC_UNI_QUEUE_SET_GRN_RESUME(unicast_queue_cfg,
142 + queue_cfg[i].resume_offset);
144 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
146 + ARRAY_SIZE(unicast_queue_cfg));
148 + goto qm_config_fail;
150 + reg = PPE_AC_MUL_QUEUE_CFG_TBL_ADDR +
151 + PPE_AC_MUL_QUEUE_CFG_TBL_INC * queue_id;
153 + ret = regmap_bulk_read(ppe_dev->regmap, reg,
154 + multicast_queue_cfg,
155 + ARRAY_SIZE(multicast_queue_cfg));
157 + goto qm_config_fail;
159 + PPE_AC_MUL_QUEUE_SET_EN(multicast_queue_cfg, true);
160 + PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(multicast_queue_cfg, 0);
161 + PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(multicast_queue_cfg,
162 + queue_cfg[i].prealloc_buf);
163 + PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(multicast_queue_cfg,
164 + queue_cfg[i].ceil);
165 + PPE_AC_MUL_QUEUE_SET_GRN_RESUME(multicast_queue_cfg,
166 + queue_cfg[i].resume_offset);
168 + ret = regmap_bulk_write(ppe_dev->regmap, reg,
169 + multicast_queue_cfg,
170 + ARRAY_SIZE(multicast_queue_cfg));
172 + goto qm_config_fail;
175 + /* Enable enqueue */
176 + reg = PPE_ENQ_OPR_TBL_ADDR + PPE_ENQ_OPR_TBL_INC * queue_id;
177 + ret = regmap_update_bits(ppe_dev->regmap, reg,
178 + PPE_ENQ_OPR_TBL_ENQ_DISABLE,
179 + FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
181 + goto qm_config_fail;
183 + /* Enable dequeue */
184 + reg = PPE_DEQ_OPR_TBL_ADDR + PPE_DEQ_OPR_TBL_INC * queue_id;
185 + ret = regmap_update_bits(ppe_dev->regmap, reg,
186 + PPE_DEQ_OPR_TBL_DEQ_DISABLE,
187 + FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
189 + goto qm_config_fail;
195 + /* Enable queue counter for all PPE hardware queues. */
196 + ret = regmap_update_bits(ppe_dev->regmap, PPE_EG_BRIDGE_CONFIG_ADDR,
197 + PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN,
198 + PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN);
200 + goto qm_config_fail;
205 + dev_err(ppe_dev->dev, "PPE QM config error %d\n", ret);
209 int ppe_hw_config(struct ppe_device *ppe_dev)
211 - return ppe_config_bm(ppe_dev);
214 + ret = ppe_config_bm(ppe_dev);
218 + return ppe_config_qm(ppe_dev);
220 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
221 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
223 * BM port (0-7) is matched to EDMA port 0, BM port (8-13) is matched
224 * to PPE physical port 1-6, BM port 14 is matched to EIP.
226 +#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044
227 +#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
229 +#define PPE_DEQ_OPR_TBL_ADDR 0x430000
230 +#define PPE_DEQ_OPR_TBL_NUM 300
231 +#define PPE_DEQ_OPR_TBL_INC 0x10
232 +#define PPE_DEQ_OPR_TBL_DEQ_DISABLE BIT(0)
234 #define PPE_BM_PORT_FC_MODE_ADDR 0x600100
235 #define PPE_BM_PORT_FC_MODE_INC 0x4
236 #define PPE_BM_PORT_FC_MODE_EN BIT(0)
238 #define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \
239 u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
241 +/* PPE unicast queue (0-255) configurations. */
242 +#define PPE_AC_UNI_QUEUE_CFG_TBL_ADDR 0x848000
243 +#define PPE_AC_UNI_QUEUE_CFG_TBL_NUM 256
244 +#define PPE_AC_UNI_QUEUE_CFG_TBL_INC 0x10
245 +#define PPE_AC_UNI_QUEUE_CFG_W0_EN BIT(0)
246 +#define PPE_AC_UNI_QUEUE_CFG_W0_WRED_EN BIT(1)
247 +#define PPE_AC_UNI_QUEUE_CFG_W0_FC_EN BIT(2)
248 +#define PPE_AC_UNI_QUEUE_CFG_W0_COLOR_AWARE BIT(3)
249 +#define PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID GENMASK(5, 4)
250 +#define PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT GENMASK(16, 6)
251 +#define PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC BIT(17)
252 +#define PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT GENMASK(20, 18)
253 +#define PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD GENMASK(31, 21)
254 +#define PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME GENMASK(23, 13)
256 +#define PPE_AC_UNI_QUEUE_SET_EN(tbl_cfg, value) \
257 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_EN)
258 +#define PPE_AC_UNI_QUEUE_SET_GRP_ID(tbl_cfg, value) \
259 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID)
260 +#define PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(tbl_cfg, value) \
261 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT)
262 +#define PPE_AC_UNI_QUEUE_SET_DYNAMIC(tbl_cfg, value) \
263 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC)
264 +#define PPE_AC_UNI_QUEUE_SET_WEIGHT(tbl_cfg, value) \
265 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT)
266 +#define PPE_AC_UNI_QUEUE_SET_THRESHOLD(tbl_cfg, value) \
267 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD)
268 +#define PPE_AC_UNI_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
269 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x3, value, PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME)
271 +/* PPE multicast queue (256-299) configurations. */
272 +#define PPE_AC_MUL_QUEUE_CFG_TBL_ADDR 0x84a000
273 +#define PPE_AC_MUL_QUEUE_CFG_TBL_NUM 44
274 +#define PPE_AC_MUL_QUEUE_CFG_TBL_INC 0x10
275 +#define PPE_AC_MUL_QUEUE_CFG_W0_EN BIT(0)
276 +#define PPE_AC_MUL_QUEUE_CFG_W0_FC_EN BIT(1)
277 +#define PPE_AC_MUL_QUEUE_CFG_W0_COLOR_AWARE BIT(2)
278 +#define PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID GENMASK(4, 3)
279 +#define PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT GENMASK(15, 5)
280 +#define PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD GENMASK(26, 16)
281 +#define PPE_AC_MUL_QUEUE_CFG_W2_RESUME GENMASK(17, 7)
283 +#define PPE_AC_MUL_QUEUE_SET_EN(tbl_cfg, value) \
284 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_EN)
285 +#define PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(tbl_cfg, value) \
286 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID)
287 +#define PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(tbl_cfg, value) \
288 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT)
289 +#define PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(tbl_cfg, value) \
290 + u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD)
291 +#define PPE_AC_MUL_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
292 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x2, value, PPE_AC_MUL_QUEUE_CFG_W2_RESUME)
294 +/* PPE admission control group (0-3) configurations */
295 +#define PPE_AC_GRP_CFG_TBL_ADDR 0x84c000
296 +#define PPE_AC_GRP_CFG_TBL_NUM 0x4
297 +#define PPE_AC_GRP_CFG_TBL_INC 0x10
298 +#define PPE_AC_GRP_W0_AC_EN BIT(0)
299 +#define PPE_AC_GRP_W0_AC_FC_EN BIT(1)
300 +#define PPE_AC_GRP_W0_COLOR_AWARE BIT(2)
301 +#define PPE_AC_GRP_W0_THRESHOLD_LOW GENMASK(31, 25)
302 +#define PPE_AC_GRP_W1_THRESHOLD_HIGH GENMASK(3, 0)
303 +#define PPE_AC_GRP_W1_BUF_LIMIT GENMASK(14, 4)
304 +#define PPE_AC_GRP_W2_RESUME_GRN GENMASK(15, 5)
305 +#define PPE_AC_GRP_W2_PRE_ALLOC GENMASK(26, 16)
307 +#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \
308 + u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
310 +#define PPE_ENQ_OPR_TBL_ADDR 0x85c000
311 +#define PPE_ENQ_OPR_TBL_NUM 300
312 +#define PPE_ENQ_OPR_TBL_INC 0x10
313 +#define PPE_ENQ_OPR_TBL_ENQ_DISABLE BIT(0)