1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Ethernet driver
3 *
4 * Copyright (C) 2023 Marvell.
5 *
6 */
7 #include <linux/netdevice.h>
8 #include <linux/etherdevice.h>
9 #include <linux/inetdevice.h>
10 #include <linux/bitfield.h>
11
12 #include "otx2_common.h"
13 #include "cn10k.h"
14 #include "qos.h"
15
16 #define OTX2_QOS_QID_INNER 0xFFFFU
17 #define OTX2_QOS_QID_NONE 0xFFFEU
18 #define OTX2_QOS_ROOT_CLASSID 0xFFFFFFFF
19 #define OTX2_QOS_CLASS_NONE 0
20 #define OTX2_QOS_DEFAULT_PRIO 0xF
21 #define OTX2_QOS_INVALID_SQ 0xFFFF
22 #define OTX2_QOS_INVALID_TXSCHQ_IDX 0xFFFF
23 #define CN10K_MAX_RR_WEIGHT GENMASK_ULL(13, 0)
24 #define OTX2_MAX_RR_QUANTUM GENMASK_ULL(23, 0)
25
otx2_qos_update_tx_netdev_queues(struct otx2_nic * pfvf)26 static void otx2_qos_update_tx_netdev_queues(struct otx2_nic *pfvf)
27 {
28 struct otx2_hw *hw = &pfvf->hw;
29 int tx_queues, qos_txqs, err;
30
31 qos_txqs = bitmap_weight(pfvf->qos.qos_sq_bmap,
32 OTX2_QOS_MAX_LEAF_NODES);
33
34 tx_queues = hw->tx_queues + qos_txqs;
35
36 err = netif_set_real_num_tx_queues(pfvf->netdev, tx_queues);
37 if (err) {
38 netdev_err(pfvf->netdev,
39 "Failed to set no of Tx queues: %d\n", tx_queues);
40 return;
41 }
42 }
43
otx2_qos_get_regaddr(struct otx2_qos_node * node,struct nix_txschq_config * cfg,int index)44 static void otx2_qos_get_regaddr(struct otx2_qos_node *node,
45 struct nix_txschq_config *cfg,
46 int index)
47 {
48 if (node->level == NIX_TXSCH_LVL_SMQ) {
49 cfg->reg[index++] = NIX_AF_MDQX_PARENT(node->schq);
50 cfg->reg[index++] = NIX_AF_MDQX_SCHEDULE(node->schq);
51 cfg->reg[index++] = NIX_AF_MDQX_PIR(node->schq);
52 cfg->reg[index] = NIX_AF_MDQX_CIR(node->schq);
53 } else if (node->level == NIX_TXSCH_LVL_TL4) {
54 cfg->reg[index++] = NIX_AF_TL4X_PARENT(node->schq);
55 cfg->reg[index++] = NIX_AF_TL4X_SCHEDULE(node->schq);
56 cfg->reg[index++] = NIX_AF_TL4X_PIR(node->schq);
57 cfg->reg[index] = NIX_AF_TL4X_CIR(node->schq);
58 } else if (node->level == NIX_TXSCH_LVL_TL3) {
59 cfg->reg[index++] = NIX_AF_TL3X_PARENT(node->schq);
60 cfg->reg[index++] = NIX_AF_TL3X_SCHEDULE(node->schq);
61 cfg->reg[index++] = NIX_AF_TL3X_PIR(node->schq);
62 cfg->reg[index] = NIX_AF_TL3X_CIR(node->schq);
63 } else if (node->level == NIX_TXSCH_LVL_TL2) {
64 cfg->reg[index++] = NIX_AF_TL2X_PARENT(node->schq);
65 cfg->reg[index++] = NIX_AF_TL2X_SCHEDULE(node->schq);
66 cfg->reg[index++] = NIX_AF_TL2X_PIR(node->schq);
67 cfg->reg[index] = NIX_AF_TL2X_CIR(node->schq);
68 }
69 }
70
otx2_qos_quantum_to_dwrr_weight(struct otx2_nic * pfvf,u32 quantum)71 static int otx2_qos_quantum_to_dwrr_weight(struct otx2_nic *pfvf, u32 quantum)
72 {
73 u32 weight;
74
75 weight = quantum / pfvf->hw.dwrr_mtu;
76 if (quantum % pfvf->hw.dwrr_mtu)
77 weight += 1;
78
79 return weight;
80 }
81
otx2_config_sched_shaping(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct nix_txschq_config * cfg,int * num_regs)82 static void otx2_config_sched_shaping(struct otx2_nic *pfvf,
83 struct otx2_qos_node *node,
84 struct nix_txschq_config *cfg,
85 int *num_regs)
86 {
87 u32 rr_weight;
88 u32 quantum;
89 u64 maxrate;
90
91 otx2_qos_get_regaddr(node, cfg, *num_regs);
92
93 /* configure parent txschq */
94 cfg->regval[*num_regs] = node->parent->schq << 16;
95 (*num_regs)++;
96
97 /* configure prio/quantum */
98 if (node->qid == OTX2_QOS_QID_NONE) {
99 cfg->regval[*num_regs] = node->prio << 24 |
100 mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen);
101 (*num_regs)++;
102 return;
103 }
104
105 /* configure priority/quantum */
106 if (node->is_static) {
107 cfg->regval[*num_regs] =
108 (node->schq - node->parent->prio_anchor) << 24;
109 } else {
110 quantum = node->quantum ?
111 node->quantum : pfvf->tx_max_pktlen;
112 rr_weight = otx2_qos_quantum_to_dwrr_weight(pfvf, quantum);
113 cfg->regval[*num_regs] = node->parent->child_dwrr_prio << 24 |
114 rr_weight;
115 }
116 (*num_regs)++;
117
118 /* configure PIR */
119 maxrate = (node->rate > node->ceil) ? node->rate : node->ceil;
120
121 cfg->regval[*num_regs] =
122 otx2_get_txschq_rate_regval(pfvf, maxrate, 65536);
123 (*num_regs)++;
124
125 /* Don't configure CIR when both CIR+PIR not supported
126 * On 96xx, CIR + PIR + RED_ALGO=STALL causes deadlock
127 */
128 if (!test_bit(QOS_CIR_PIR_SUPPORT, &pfvf->hw.cap_flag))
129 return;
130
131 cfg->regval[*num_regs] =
132 otx2_get_txschq_rate_regval(pfvf, node->rate, 65536);
133 (*num_regs)++;
134 }
135
__otx2_qos_txschq_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct nix_txschq_config * cfg)136 static void __otx2_qos_txschq_cfg(struct otx2_nic *pfvf,
137 struct otx2_qos_node *node,
138 struct nix_txschq_config *cfg)
139 {
140 struct otx2_hw *hw = &pfvf->hw;
141 int num_regs = 0;
142 u8 level;
143
144 level = node->level;
145
146 /* program txschq registers */
147 if (level == NIX_TXSCH_LVL_SMQ) {
148 cfg->reg[num_regs] = NIX_AF_SMQX_CFG(node->schq);
149 cfg->regval[num_regs] = ((u64)pfvf->tx_max_pktlen << 8) |
150 OTX2_MIN_MTU;
151 cfg->regval[num_regs] |= (0x20ULL << 51) | (0x80ULL << 39) |
152 (0x2ULL << 36);
153 num_regs++;
154
155 otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
156 } else if (level == NIX_TXSCH_LVL_TL4) {
157 otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
158 } else if (level == NIX_TXSCH_LVL_TL3) {
159 /* configure link cfg */
160 if (level == pfvf->qos.link_cfg_lvl) {
161 cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
162 cfg->regval[num_regs] = BIT_ULL(13) | BIT_ULL(12);
163 num_regs++;
164 }
165
166 otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
167 } else if (level == NIX_TXSCH_LVL_TL2) {
168 /* configure parent txschq */
169 cfg->reg[num_regs] = NIX_AF_TL2X_PARENT(node->schq);
170 cfg->regval[num_regs] = (u64)hw->tx_link << 16;
171 num_regs++;
172
173 /* configure link cfg */
174 if (level == pfvf->qos.link_cfg_lvl) {
175 cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
176 cfg->regval[num_regs] = BIT_ULL(13) | BIT_ULL(12);
177 num_regs++;
178 }
179
180 /* check if node is root */
181 if (node->qid == OTX2_QOS_QID_INNER && !node->parent) {
182 cfg->reg[num_regs] = NIX_AF_TL2X_SCHEDULE(node->schq);
183 cfg->regval[num_regs] = (u64)hw->txschq_aggr_lvl_rr_prio << 24 |
184 mtu_to_dwrr_weight(pfvf,
185 pfvf->tx_max_pktlen);
186 num_regs++;
187 goto txschq_cfg_out;
188 }
189
190 otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
191 }
192
193 txschq_cfg_out:
194 cfg->num_regs = num_regs;
195 }
196
otx2_qos_txschq_set_parent_topology(struct otx2_nic * pfvf,struct otx2_qos_node * parent)197 static int otx2_qos_txschq_set_parent_topology(struct otx2_nic *pfvf,
198 struct otx2_qos_node *parent)
199 {
200 struct mbox *mbox = &pfvf->mbox;
201 struct nix_txschq_config *cfg;
202 int rc;
203
204 if (parent->level == NIX_TXSCH_LVL_MDQ)
205 return 0;
206
207 mutex_lock(&mbox->lock);
208
209 cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(&pfvf->mbox);
210 if (!cfg) {
211 mutex_unlock(&mbox->lock);
212 return -ENOMEM;
213 }
214
215 cfg->lvl = parent->level;
216
217 if (parent->level == NIX_TXSCH_LVL_TL4)
218 cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(parent->schq);
219 else if (parent->level == NIX_TXSCH_LVL_TL3)
220 cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(parent->schq);
221 else if (parent->level == NIX_TXSCH_LVL_TL2)
222 cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(parent->schq);
223 else if (parent->level == NIX_TXSCH_LVL_TL1)
224 cfg->reg[0] = NIX_AF_TL1X_TOPOLOGY(parent->schq);
225
226 cfg->regval[0] = (u64)parent->prio_anchor << 32;
227 cfg->regval[0] |= ((parent->child_dwrr_prio != OTX2_QOS_DEFAULT_PRIO) ?
228 parent->child_dwrr_prio : 0) << 1;
229 cfg->num_regs++;
230
231 rc = otx2_sync_mbox_msg(&pfvf->mbox);
232
233 mutex_unlock(&mbox->lock);
234
235 return rc;
236 }
237
otx2_qos_reset_schq_topology(struct otx2_nic * pfvf,u16 lvl,u16 schq)238 static int otx2_qos_reset_schq_topology(struct otx2_nic *pfvf, u16 lvl,
239 u16 schq)
240 {
241 struct mbox *mbox = &pfvf->mbox;
242 struct nix_txschq_config *cfg;
243 int rc;
244
245 if (lvl < NIX_TXSCH_LVL_TL4 || lvl >= NIX_TXSCH_LVL_TL1)
246 return 0;
247
248 mutex_lock(&mbox->lock);
249
250 cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);
251 if (!cfg) {
252 mutex_unlock(&mbox->lock);
253 return -ENOMEM;
254 }
255
256 cfg->lvl = lvl;
257 cfg->num_regs = 1;
258
259 if (lvl == NIX_TXSCH_LVL_TL4)
260 cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(schq);
261 else if (lvl == NIX_TXSCH_LVL_TL3)
262 cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(schq);
263 else if (lvl == NIX_TXSCH_LVL_TL2)
264 cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(schq);
265
266 cfg->regval[0] = 0;
267
268 rc = otx2_sync_mbox_msg(mbox);
269
270 mutex_unlock(&mbox->lock);
271
272 return rc;
273 }
274
otx2_qos_free_hw_schq(struct otx2_nic * pfvf,u16 lvl,u16 schq)275 static void otx2_qos_free_hw_schq(struct otx2_nic *pfvf, u16 lvl, u16 schq)
276 {
277 int err;
278
279 err = otx2_qos_reset_schq_topology(pfvf, lvl, schq);
280 if (err)
281 netdev_warn(pfvf->netdev,
282 "QoS: failed to reset topology for schq %u at level %u: %d\n",
283 schq, lvl, err);
284
285 otx2_txschq_free_one(pfvf, lvl, schq);
286 }
287
otx2_qos_free_hw_node_schq(struct otx2_nic * pfvf,struct otx2_qos_node * parent)288 static void otx2_qos_free_hw_node_schq(struct otx2_nic *pfvf,
289 struct otx2_qos_node *parent)
290 {
291 struct otx2_qos_node *node;
292
293 list_for_each_entry_reverse(node, &parent->child_schq_list, list)
294 otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
295 }
296
otx2_qos_free_hw_node(struct otx2_nic * pfvf,struct otx2_qos_node * parent)297 static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
298 struct otx2_qos_node *parent)
299 {
300 struct otx2_qos_node *node, *tmp;
301
302 list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
303 otx2_qos_free_hw_node(pfvf, node);
304 otx2_qos_free_hw_node_schq(pfvf, node);
305 otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
306 }
307 }
308
otx2_qos_free_hw_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node)309 static void otx2_qos_free_hw_cfg(struct otx2_nic *pfvf,
310 struct otx2_qos_node *node)
311 {
312 mutex_lock(&pfvf->qos.qos_lock);
313
314 /* free child node hw mappings */
315 otx2_qos_free_hw_node(pfvf, node);
316 otx2_qos_free_hw_node_schq(pfvf, node);
317
318 /* free node hw mappings */
319 otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
320
321 mutex_unlock(&pfvf->qos.qos_lock);
322 }
323
otx2_qos_sw_node_delete(struct otx2_nic * pfvf,struct otx2_qos_node * node)324 static void otx2_qos_sw_node_delete(struct otx2_nic *pfvf,
325 struct otx2_qos_node *node)
326 {
327 hash_del_rcu(&node->hlist);
328
329 if (node->qid != OTX2_QOS_QID_INNER && node->qid != OTX2_QOS_QID_NONE) {
330 __clear_bit(node->qid, pfvf->qos.qos_sq_bmap);
331 otx2_qos_update_tx_netdev_queues(pfvf);
332 }
333
334 list_del(&node->list);
335 kfree(node);
336 }
337
otx2_qos_free_sw_node_schq(struct otx2_nic * pfvf,struct otx2_qos_node * parent)338 static void otx2_qos_free_sw_node_schq(struct otx2_nic *pfvf,
339 struct otx2_qos_node *parent)
340 {
341 struct otx2_qos_node *node, *tmp;
342
343 list_for_each_entry_safe(node, tmp, &parent->child_schq_list, list) {
344 list_del(&node->list);
345 kfree(node);
346 }
347 }
348
__otx2_qos_free_sw_node(struct otx2_nic * pfvf,struct otx2_qos_node * parent)349 static void __otx2_qos_free_sw_node(struct otx2_nic *pfvf,
350 struct otx2_qos_node *parent)
351 {
352 struct otx2_qos_node *node, *tmp;
353
354 list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
355 __otx2_qos_free_sw_node(pfvf, node);
356 otx2_qos_free_sw_node_schq(pfvf, node);
357 otx2_qos_sw_node_delete(pfvf, node);
358 }
359 }
360
otx2_qos_free_sw_node(struct otx2_nic * pfvf,struct otx2_qos_node * node)361 static void otx2_qos_free_sw_node(struct otx2_nic *pfvf,
362 struct otx2_qos_node *node)
363 {
364 mutex_lock(&pfvf->qos.qos_lock);
365
366 __otx2_qos_free_sw_node(pfvf, node);
367 otx2_qos_free_sw_node_schq(pfvf, node);
368 otx2_qos_sw_node_delete(pfvf, node);
369
370 mutex_unlock(&pfvf->qos.qos_lock);
371 }
372
otx2_qos_destroy_node(struct otx2_nic * pfvf,struct otx2_qos_node * node)373 static void otx2_qos_destroy_node(struct otx2_nic *pfvf,
374 struct otx2_qos_node *node)
375 {
376 otx2_qos_free_hw_cfg(pfvf, node);
377 otx2_qos_free_sw_node(pfvf, node);
378 }
379
otx2_qos_fill_cfg_schq(struct otx2_qos_node * parent,struct otx2_qos_cfg * cfg)380 static void otx2_qos_fill_cfg_schq(struct otx2_qos_node *parent,
381 struct otx2_qos_cfg *cfg)
382 {
383 struct otx2_qos_node *node;
384
385 list_for_each_entry(node, &parent->child_schq_list, list)
386 cfg->schq[node->level]++;
387 }
388
otx2_qos_fill_cfg_tl(struct otx2_qos_node * parent,struct otx2_qos_cfg * cfg)389 static void otx2_qos_fill_cfg_tl(struct otx2_qos_node *parent,
390 struct otx2_qos_cfg *cfg)
391 {
392 struct otx2_qos_node *node;
393
394 list_for_each_entry(node, &parent->child_list, list) {
395 otx2_qos_fill_cfg_tl(node, cfg);
396 otx2_qos_fill_cfg_schq(node, cfg);
397 }
398
399 /* Assign the required number of transmit schedular queues under the
400 * given class
401 */
402 cfg->schq_contig[parent->level - 1] += parent->child_dwrr_cnt +
403 parent->max_static_prio + 1;
404 }
405
otx2_qos_prepare_txschq_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * parent,struct otx2_qos_cfg * cfg)406 static void otx2_qos_prepare_txschq_cfg(struct otx2_nic *pfvf,
407 struct otx2_qos_node *parent,
408 struct otx2_qos_cfg *cfg)
409 {
410 mutex_lock(&pfvf->qos.qos_lock);
411 otx2_qos_fill_cfg_tl(parent, cfg);
412 mutex_unlock(&pfvf->qos.qos_lock);
413 }
414
otx2_qos_read_txschq_cfg_schq(struct otx2_qos_node * parent,struct otx2_qos_cfg * cfg)415 static void otx2_qos_read_txschq_cfg_schq(struct otx2_qos_node *parent,
416 struct otx2_qos_cfg *cfg)
417 {
418 struct otx2_qos_node *node;
419 int cnt;
420
421 list_for_each_entry(node, &parent->child_schq_list, list) {
422 cnt = cfg->dwrr_node_pos[node->level];
423 cfg->schq_list[node->level][cnt] = node->schq;
424 cfg->schq[node->level]++;
425 cfg->dwrr_node_pos[node->level]++;
426 }
427 }
428
otx2_qos_read_txschq_cfg_tl(struct otx2_qos_node * parent,struct otx2_qos_cfg * cfg)429 static void otx2_qos_read_txschq_cfg_tl(struct otx2_qos_node *parent,
430 struct otx2_qos_cfg *cfg)
431 {
432 struct otx2_qos_node *node;
433 int cnt;
434
435 list_for_each_entry(node, &parent->child_list, list) {
436 otx2_qos_read_txschq_cfg_tl(node, cfg);
437 cnt = cfg->static_node_pos[node->level];
438 cfg->schq_contig_list[node->level][cnt] = node->schq;
439 cfg->schq_index_used[node->level][cnt] = true;
440 cfg->schq_contig[node->level]++;
441 cfg->static_node_pos[node->level]++;
442 otx2_qos_read_txschq_cfg_schq(node, cfg);
443 }
444 }
445
otx2_qos_read_txschq_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)446 static void otx2_qos_read_txschq_cfg(struct otx2_nic *pfvf,
447 struct otx2_qos_node *node,
448 struct otx2_qos_cfg *cfg)
449 {
450 mutex_lock(&pfvf->qos.qos_lock);
451 otx2_qos_read_txschq_cfg_tl(node, cfg);
452 mutex_unlock(&pfvf->qos.qos_lock);
453 }
454
455 static struct otx2_qos_node *
otx2_qos_alloc_root(struct otx2_nic * pfvf)456 otx2_qos_alloc_root(struct otx2_nic *pfvf)
457 {
458 struct otx2_qos_node *node;
459
460 node = kzalloc_obj(*node);
461 if (!node)
462 return ERR_PTR(-ENOMEM);
463
464 node->parent = NULL;
465 if (!is_otx2_vf(pfvf->pcifunc)) {
466 node->level = NIX_TXSCH_LVL_TL1;
467 } else {
468 node->level = NIX_TXSCH_LVL_TL2;
469 node->child_dwrr_prio = OTX2_QOS_DEFAULT_PRIO;
470 }
471
472 WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
473 node->classid = OTX2_QOS_ROOT_CLASSID;
474
475 hash_add_rcu(pfvf->qos.qos_hlist, &node->hlist, node->classid);
476 list_add_tail(&node->list, &pfvf->qos.qos_tree);
477 INIT_LIST_HEAD(&node->child_list);
478 INIT_LIST_HEAD(&node->child_schq_list);
479
480 return node;
481 }
482
otx2_qos_add_child_node(struct otx2_qos_node * parent,struct otx2_qos_node * node)483 static int otx2_qos_add_child_node(struct otx2_qos_node *parent,
484 struct otx2_qos_node *node)
485 {
486 struct list_head *head = &parent->child_list;
487 struct otx2_qos_node *tmp_node;
488 struct list_head *tmp;
489
490 if (node->prio > parent->max_static_prio)
491 parent->max_static_prio = node->prio;
492
493 for (tmp = head->next; tmp != head; tmp = tmp->next) {
494 tmp_node = list_entry(tmp, struct otx2_qos_node, list);
495 if (tmp_node->prio == node->prio &&
496 tmp_node->is_static)
497 return -EEXIST;
498 if (tmp_node->prio > node->prio) {
499 list_add_tail(&node->list, tmp);
500 return 0;
501 }
502 }
503
504 list_add_tail(&node->list, head);
505 return 0;
506 }
507
otx2_qos_alloc_txschq_node(struct otx2_nic * pfvf,struct otx2_qos_node * node)508 static int otx2_qos_alloc_txschq_node(struct otx2_nic *pfvf,
509 struct otx2_qos_node *node)
510 {
511 struct otx2_qos_node *txschq_node, *parent, *tmp;
512 int lvl;
513
514 parent = node;
515 for (lvl = node->level - 1; lvl >= NIX_TXSCH_LVL_MDQ; lvl--) {
516 txschq_node = kzalloc_obj(*txschq_node);
517 if (!txschq_node)
518 goto err_out;
519
520 txschq_node->parent = parent;
521 txschq_node->level = lvl;
522 txschq_node->classid = OTX2_QOS_CLASS_NONE;
523 WRITE_ONCE(txschq_node->qid, OTX2_QOS_QID_NONE);
524 txschq_node->rate = 0;
525 txschq_node->ceil = 0;
526 txschq_node->prio = 0;
527 txschq_node->quantum = 0;
528 txschq_node->is_static = true;
529 txschq_node->child_dwrr_prio = OTX2_QOS_DEFAULT_PRIO;
530 txschq_node->txschq_idx = OTX2_QOS_INVALID_TXSCHQ_IDX;
531
532 mutex_lock(&pfvf->qos.qos_lock);
533 list_add_tail(&txschq_node->list, &node->child_schq_list);
534 mutex_unlock(&pfvf->qos.qos_lock);
535
536 INIT_LIST_HEAD(&txschq_node->child_list);
537 INIT_LIST_HEAD(&txschq_node->child_schq_list);
538 parent = txschq_node;
539 }
540
541 return 0;
542
543 err_out:
544 list_for_each_entry_safe(txschq_node, tmp, &node->child_schq_list,
545 list) {
546 list_del(&txschq_node->list);
547 kfree(txschq_node);
548 }
549 return -ENOMEM;
550 }
551
552 static struct otx2_qos_node *
otx2_qos_sw_create_leaf_node(struct otx2_nic * pfvf,struct otx2_qos_node * parent,u16 classid,u32 prio,u64 rate,u64 ceil,u32 quantum,u16 qid,bool static_cfg)553 otx2_qos_sw_create_leaf_node(struct otx2_nic *pfvf,
554 struct otx2_qos_node *parent,
555 u16 classid, u32 prio, u64 rate, u64 ceil,
556 u32 quantum, u16 qid, bool static_cfg)
557 {
558 struct otx2_qos_node *node;
559 int err;
560
561 node = kzalloc_obj(*node);
562 if (!node)
563 return ERR_PTR(-ENOMEM);
564
565 node->parent = parent;
566 node->level = parent->level - 1;
567 node->classid = classid;
568 WRITE_ONCE(node->qid, qid);
569
570 node->rate = otx2_convert_rate(rate);
571 node->ceil = otx2_convert_rate(ceil);
572 node->prio = prio;
573 node->quantum = quantum;
574 node->is_static = static_cfg;
575 node->child_dwrr_prio = OTX2_QOS_DEFAULT_PRIO;
576 node->txschq_idx = OTX2_QOS_INVALID_TXSCHQ_IDX;
577
578 __set_bit(qid, pfvf->qos.qos_sq_bmap);
579
580 hash_add_rcu(pfvf->qos.qos_hlist, &node->hlist, classid);
581
582 mutex_lock(&pfvf->qos.qos_lock);
583 err = otx2_qos_add_child_node(parent, node);
584 if (err) {
585 mutex_unlock(&pfvf->qos.qos_lock);
586 return ERR_PTR(err);
587 }
588 mutex_unlock(&pfvf->qos.qos_lock);
589
590 INIT_LIST_HEAD(&node->child_list);
591 INIT_LIST_HEAD(&node->child_schq_list);
592
593 err = otx2_qos_alloc_txschq_node(pfvf, node);
594 if (err) {
595 otx2_qos_sw_node_delete(pfvf, node);
596 return ERR_PTR(-ENOMEM);
597 }
598
599 return node;
600 }
601
602 static struct otx2_qos_node
otx2_sw_node_find_by_qid(struct otx2_nic * pfvf,u16 qid)603 *otx2_sw_node_find_by_qid(struct otx2_nic *pfvf, u16 qid)
604 {
605 struct otx2_qos_node *node = NULL;
606 int bkt;
607
608 hash_for_each(pfvf->qos.qos_hlist, bkt, node, hlist) {
609 if (node->qid == qid)
610 break;
611 }
612
613 return node;
614 }
615
616 static struct otx2_qos_node *
otx2_sw_node_find(struct otx2_nic * pfvf,u32 classid)617 otx2_sw_node_find(struct otx2_nic *pfvf, u32 classid)
618 {
619 struct otx2_qos_node *node = NULL;
620
621 hash_for_each_possible(pfvf->qos.qos_hlist, node, hlist, classid) {
622 if (node->classid == classid)
623 break;
624 }
625
626 return node;
627 }
628
629 static struct otx2_qos_node *
otx2_sw_node_find_rcu(struct otx2_nic * pfvf,u32 classid)630 otx2_sw_node_find_rcu(struct otx2_nic *pfvf, u32 classid)
631 {
632 struct otx2_qos_node *node = NULL;
633
634 hash_for_each_possible_rcu(pfvf->qos.qos_hlist, node, hlist, classid) {
635 if (node->classid == classid)
636 break;
637 }
638
639 return node;
640 }
641
otx2_get_txq_by_classid(struct otx2_nic * pfvf,u16 classid)642 int otx2_get_txq_by_classid(struct otx2_nic *pfvf, u16 classid)
643 {
644 struct otx2_qos_node *node;
645 u16 qid;
646 int res;
647
648 node = otx2_sw_node_find_rcu(pfvf, classid);
649 if (!node) {
650 res = -ENOENT;
651 goto out;
652 }
653 qid = READ_ONCE(node->qid);
654 if (qid == OTX2_QOS_QID_INNER) {
655 res = -EINVAL;
656 goto out;
657 }
658 res = pfvf->hw.tx_queues + qid;
659 out:
660 return res;
661 }
662
663 static int
otx2_qos_txschq_config(struct otx2_nic * pfvf,struct otx2_qos_node * node)664 otx2_qos_txschq_config(struct otx2_nic *pfvf, struct otx2_qos_node *node)
665 {
666 struct mbox *mbox = &pfvf->mbox;
667 struct nix_txschq_config *req;
668 int rc;
669
670 mutex_lock(&mbox->lock);
671
672 req = otx2_mbox_alloc_msg_nix_txschq_cfg(&pfvf->mbox);
673 if (!req) {
674 mutex_unlock(&mbox->lock);
675 return -ENOMEM;
676 }
677
678 req->lvl = node->level;
679 __otx2_qos_txschq_cfg(pfvf, node, req);
680
681 rc = otx2_sync_mbox_msg(&pfvf->mbox);
682
683 mutex_unlock(&mbox->lock);
684
685 return rc;
686 }
687
otx2_qos_txschq_alloc(struct otx2_nic * pfvf,struct otx2_qos_cfg * cfg)688 static int otx2_qos_txschq_alloc(struct otx2_nic *pfvf,
689 struct otx2_qos_cfg *cfg)
690 {
691 struct nix_txsch_alloc_req *req;
692 struct nix_txsch_alloc_rsp *rsp;
693 struct mbox *mbox = &pfvf->mbox;
694 int lvl, rc, schq;
695
696 mutex_lock(&mbox->lock);
697 req = otx2_mbox_alloc_msg_nix_txsch_alloc(&pfvf->mbox);
698 if (!req) {
699 mutex_unlock(&mbox->lock);
700 return -ENOMEM;
701 }
702
703 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
704 req->schq[lvl] = cfg->schq[lvl];
705 req->schq_contig[lvl] = cfg->schq_contig[lvl];
706 }
707
708 rc = otx2_sync_mbox_msg(&pfvf->mbox);
709 if (rc) {
710 mutex_unlock(&mbox->lock);
711 return rc;
712 }
713
714 rsp = (struct nix_txsch_alloc_rsp *)
715 otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
716
717 if (IS_ERR(rsp)) {
718 rc = PTR_ERR(rsp);
719 goto out;
720 }
721
722 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
723 for (schq = 0; schq < rsp->schq_contig[lvl]; schq++) {
724 cfg->schq_contig_list[lvl][schq] =
725 rsp->schq_contig_list[lvl][schq];
726 }
727 }
728
729 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
730 for (schq = 0; schq < rsp->schq[lvl]; schq++) {
731 cfg->schq_list[lvl][schq] =
732 rsp->schq_list[lvl][schq];
733 }
734 }
735
736 pfvf->qos.link_cfg_lvl = rsp->link_cfg_lvl;
737 pfvf->hw.txschq_aggr_lvl_rr_prio = rsp->aggr_lvl_rr_prio;
738
739 out:
740 mutex_unlock(&mbox->lock);
741 return rc;
742 }
743
otx2_qos_free_unused_txschq(struct otx2_nic * pfvf,struct otx2_qos_cfg * cfg)744 static void otx2_qos_free_unused_txschq(struct otx2_nic *pfvf,
745 struct otx2_qos_cfg *cfg)
746 {
747 int lvl, idx, schq;
748
749 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
750 for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
751 if (!cfg->schq_index_used[lvl][idx]) {
752 schq = cfg->schq_contig_list[lvl][idx];
753 otx2_txschq_free_one(pfvf, lvl, schq);
754 }
755 }
756 }
757 }
758
otx2_qos_txschq_fill_cfg_schq(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)759 static void otx2_qos_txschq_fill_cfg_schq(struct otx2_nic *pfvf,
760 struct otx2_qos_node *node,
761 struct otx2_qos_cfg *cfg)
762 {
763 struct otx2_qos_node *tmp;
764 int cnt;
765
766 list_for_each_entry(tmp, &node->child_schq_list, list) {
767 cnt = cfg->dwrr_node_pos[tmp->level];
768 tmp->schq = cfg->schq_list[tmp->level][cnt];
769 cfg->dwrr_node_pos[tmp->level]++;
770 }
771 }
772
otx2_qos_txschq_fill_cfg_tl(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)773 static void otx2_qos_txschq_fill_cfg_tl(struct otx2_nic *pfvf,
774 struct otx2_qos_node *node,
775 struct otx2_qos_cfg *cfg)
776 {
777 struct otx2_qos_node *tmp;
778 int cnt;
779
780 list_for_each_entry(tmp, &node->child_list, list) {
781 otx2_qos_txschq_fill_cfg_tl(pfvf, tmp, cfg);
782 cnt = cfg->static_node_pos[tmp->level];
783 tmp->schq = cfg->schq_contig_list[tmp->level][tmp->txschq_idx];
784 cfg->schq_index_used[tmp->level][tmp->txschq_idx] = true;
785 if (cnt == 0)
786 node->prio_anchor =
787 cfg->schq_contig_list[tmp->level][0];
788 cfg->static_node_pos[tmp->level]++;
789 otx2_qos_txschq_fill_cfg_schq(pfvf, tmp, cfg);
790 }
791 }
792
otx2_qos_txschq_fill_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)793 static void otx2_qos_txschq_fill_cfg(struct otx2_nic *pfvf,
794 struct otx2_qos_node *node,
795 struct otx2_qos_cfg *cfg)
796 {
797 mutex_lock(&pfvf->qos.qos_lock);
798 otx2_qos_txschq_fill_cfg_tl(pfvf, node, cfg);
799 otx2_qos_txschq_fill_cfg_schq(pfvf, node, cfg);
800 otx2_qos_free_unused_txschq(pfvf, cfg);
801 mutex_unlock(&pfvf->qos.qos_lock);
802 }
803
__otx2_qos_assign_base_idx_tl(struct otx2_nic * pfvf,struct otx2_qos_node * tmp,unsigned long * child_idx_bmap,int child_cnt)804 static void __otx2_qos_assign_base_idx_tl(struct otx2_nic *pfvf,
805 struct otx2_qos_node *tmp,
806 unsigned long *child_idx_bmap,
807 int child_cnt)
808 {
809 int idx;
810
811 if (tmp->txschq_idx != OTX2_QOS_INVALID_TXSCHQ_IDX)
812 return;
813
814 /* assign static nodes 1:1 prio mapping first, then remaining nodes */
815 for (idx = 0; idx < child_cnt; idx++) {
816 if (tmp->is_static && tmp->prio == idx &&
817 !test_bit(idx, child_idx_bmap)) {
818 tmp->txschq_idx = idx;
819 set_bit(idx, child_idx_bmap);
820 return;
821 } else if (!tmp->is_static && idx >= tmp->prio &&
822 !test_bit(idx, child_idx_bmap)) {
823 tmp->txschq_idx = idx;
824 set_bit(idx, child_idx_bmap);
825 return;
826 }
827 }
828 }
829
otx2_qos_assign_base_idx_tl(struct otx2_nic * pfvf,struct otx2_qos_node * node)830 static int otx2_qos_assign_base_idx_tl(struct otx2_nic *pfvf,
831 struct otx2_qos_node *node)
832 {
833 unsigned long *child_idx_bmap;
834 struct otx2_qos_node *tmp;
835 int child_cnt;
836
837 list_for_each_entry(tmp, &node->child_list, list)
838 tmp->txschq_idx = OTX2_QOS_INVALID_TXSCHQ_IDX;
839
840 /* allocate child index array */
841 child_cnt = node->child_dwrr_cnt + node->max_static_prio + 1;
842 child_idx_bmap = kcalloc(BITS_TO_LONGS(child_cnt),
843 sizeof(unsigned long),
844 GFP_KERNEL);
845 if (!child_idx_bmap)
846 return -ENOMEM;
847
848 list_for_each_entry(tmp, &node->child_list, list)
849 otx2_qos_assign_base_idx_tl(pfvf, tmp);
850
851 /* assign base index of static priority children first */
852 list_for_each_entry(tmp, &node->child_list, list) {
853 if (!tmp->is_static)
854 continue;
855 __otx2_qos_assign_base_idx_tl(pfvf, tmp, child_idx_bmap,
856 child_cnt);
857 }
858
859 /* assign base index of dwrr priority children */
860 list_for_each_entry(tmp, &node->child_list, list)
861 __otx2_qos_assign_base_idx_tl(pfvf, tmp, child_idx_bmap,
862 child_cnt);
863
864 kfree(child_idx_bmap);
865
866 return 0;
867 }
868
otx2_qos_assign_base_idx(struct otx2_nic * pfvf,struct otx2_qos_node * node)869 static int otx2_qos_assign_base_idx(struct otx2_nic *pfvf,
870 struct otx2_qos_node *node)
871 {
872 int ret = 0;
873
874 mutex_lock(&pfvf->qos.qos_lock);
875 ret = otx2_qos_assign_base_idx_tl(pfvf, node);
876 mutex_unlock(&pfvf->qos.qos_lock);
877
878 return ret;
879 }
880
otx2_qos_txschq_push_cfg_schq(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)881 static int otx2_qos_txschq_push_cfg_schq(struct otx2_nic *pfvf,
882 struct otx2_qos_node *node,
883 struct otx2_qos_cfg *cfg)
884 {
885 struct otx2_qos_node *tmp;
886 int ret;
887
888 list_for_each_entry(tmp, &node->child_schq_list, list) {
889 ret = otx2_qos_txschq_config(pfvf, tmp);
890 if (ret)
891 return -EIO;
892 ret = otx2_qos_txschq_set_parent_topology(pfvf, tmp->parent);
893 if (ret)
894 return -EIO;
895 }
896
897 return 0;
898 }
899
otx2_qos_txschq_push_cfg_tl(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)900 static int otx2_qos_txschq_push_cfg_tl(struct otx2_nic *pfvf,
901 struct otx2_qos_node *node,
902 struct otx2_qos_cfg *cfg)
903 {
904 struct otx2_qos_node *tmp;
905 int ret;
906
907 list_for_each_entry(tmp, &node->child_list, list) {
908 ret = otx2_qos_txschq_push_cfg_tl(pfvf, tmp, cfg);
909 if (ret)
910 return -EIO;
911 ret = otx2_qos_txschq_config(pfvf, tmp);
912 if (ret)
913 return -EIO;
914 ret = otx2_qos_txschq_push_cfg_schq(pfvf, tmp, cfg);
915 if (ret)
916 return -EIO;
917 }
918
919 ret = otx2_qos_txschq_set_parent_topology(pfvf, node);
920 if (ret)
921 return -EIO;
922
923 return 0;
924 }
925
otx2_qos_txschq_push_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)926 static int otx2_qos_txschq_push_cfg(struct otx2_nic *pfvf,
927 struct otx2_qos_node *node,
928 struct otx2_qos_cfg *cfg)
929 {
930 int ret;
931
932 mutex_lock(&pfvf->qos.qos_lock);
933 ret = otx2_qos_txschq_push_cfg_tl(pfvf, node, cfg);
934 if (ret)
935 goto out;
936 ret = otx2_qos_txschq_push_cfg_schq(pfvf, node, cfg);
937 out:
938 mutex_unlock(&pfvf->qos.qos_lock);
939 return ret;
940 }
941
otx2_qos_txschq_update_config(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)942 static int otx2_qos_txschq_update_config(struct otx2_nic *pfvf,
943 struct otx2_qos_node *node,
944 struct otx2_qos_cfg *cfg)
945 {
946 otx2_qos_txschq_fill_cfg(pfvf, node, cfg);
947
948 return otx2_qos_txschq_push_cfg(pfvf, node, cfg);
949 }
950
otx2_qos_txschq_update_root_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * root,struct otx2_qos_cfg * cfg)951 static int otx2_qos_txschq_update_root_cfg(struct otx2_nic *pfvf,
952 struct otx2_qos_node *root,
953 struct otx2_qos_cfg *cfg)
954 {
955 root->schq = cfg->schq_list[root->level][0];
956 return otx2_qos_txschq_config(pfvf, root);
957 }
958
otx2_qos_free_cfg(struct otx2_nic * pfvf,struct otx2_qos_cfg * cfg)959 static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
960 {
961 int lvl, idx, schq;
962
963 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
964 for (idx = 0; idx < cfg->schq[lvl]; idx++) {
965 schq = cfg->schq_list[lvl][idx];
966 otx2_qos_free_hw_schq(pfvf, lvl, schq);
967 }
968 }
969
970 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
971 for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
972 if (cfg->schq_index_used[lvl][idx]) {
973 schq = cfg->schq_contig_list[lvl][idx];
974 otx2_qos_free_hw_schq(pfvf, lvl, schq);
975 }
976 }
977 }
978 }
979
otx2_qos_enadis_sq(struct otx2_nic * pfvf,struct otx2_qos_node * node,u16 qid)980 static void otx2_qos_enadis_sq(struct otx2_nic *pfvf,
981 struct otx2_qos_node *node,
982 u16 qid)
983 {
984 if (pfvf->qos.qid_to_sqmap[qid] != OTX2_QOS_INVALID_SQ)
985 otx2_qos_disable_sq(pfvf, qid);
986
987 pfvf->qos.qid_to_sqmap[qid] = node->schq;
988 otx2_qos_txschq_config(pfvf, node);
989 otx2_qos_enable_sq(pfvf, qid);
990 }
991
otx2_qos_update_smq_schq(struct otx2_nic * pfvf,struct otx2_qos_node * node,bool action)992 static void otx2_qos_update_smq_schq(struct otx2_nic *pfvf,
993 struct otx2_qos_node *node,
994 bool action)
995 {
996 struct otx2_qos_node *tmp;
997
998 if (node->qid == OTX2_QOS_QID_INNER)
999 return;
1000
1001 list_for_each_entry(tmp, &node->child_schq_list, list) {
1002 if (tmp->level == NIX_TXSCH_LVL_MDQ) {
1003 if (action == QOS_SMQ_FLUSH)
1004 otx2_smq_flush(pfvf, tmp->schq);
1005 else
1006 otx2_qos_enadis_sq(pfvf, tmp, node->qid);
1007 }
1008 }
1009 }
1010
__otx2_qos_update_smq(struct otx2_nic * pfvf,struct otx2_qos_node * node,bool action)1011 static void __otx2_qos_update_smq(struct otx2_nic *pfvf,
1012 struct otx2_qos_node *node,
1013 bool action)
1014 {
1015 struct otx2_qos_node *tmp;
1016
1017 list_for_each_entry(tmp, &node->child_list, list) {
1018 __otx2_qos_update_smq(pfvf, tmp, action);
1019 if (tmp->qid == OTX2_QOS_QID_INNER)
1020 continue;
1021 if (tmp->level == NIX_TXSCH_LVL_MDQ) {
1022 if (action == QOS_SMQ_FLUSH)
1023 otx2_smq_flush(pfvf, tmp->schq);
1024 else
1025 otx2_qos_enadis_sq(pfvf, tmp, tmp->qid);
1026 } else {
1027 otx2_qos_update_smq_schq(pfvf, tmp, action);
1028 }
1029 }
1030 }
1031
otx2_qos_update_smq(struct otx2_nic * pfvf,struct otx2_qos_node * node,bool action)1032 static void otx2_qos_update_smq(struct otx2_nic *pfvf,
1033 struct otx2_qos_node *node,
1034 bool action)
1035 {
1036 mutex_lock(&pfvf->qos.qos_lock);
1037 __otx2_qos_update_smq(pfvf, node, action);
1038 otx2_qos_update_smq_schq(pfvf, node, action);
1039 mutex_unlock(&pfvf->qos.qos_lock);
1040 }
1041
otx2_qos_push_txschq_cfg(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)1042 static int otx2_qos_push_txschq_cfg(struct otx2_nic *pfvf,
1043 struct otx2_qos_node *node,
1044 struct otx2_qos_cfg *cfg)
1045 {
1046 int ret;
1047
1048 ret = otx2_qos_txschq_alloc(pfvf, cfg);
1049 if (ret)
1050 return -ENOSPC;
1051
1052 ret = otx2_qos_assign_base_idx(pfvf, node);
1053 if (ret)
1054 return -ENOMEM;
1055
1056 if (!(pfvf->netdev->flags & IFF_UP)) {
1057 otx2_qos_txschq_fill_cfg(pfvf, node, cfg);
1058 return 0;
1059 }
1060
1061 ret = otx2_qos_txschq_update_config(pfvf, node, cfg);
1062 if (ret) {
1063 otx2_qos_free_cfg(pfvf, cfg);
1064 return -EIO;
1065 }
1066
1067 otx2_qos_update_smq(pfvf, node, QOS_CFG_SQ);
1068
1069 return 0;
1070 }
1071
otx2_qos_update_tree(struct otx2_nic * pfvf,struct otx2_qos_node * node,struct otx2_qos_cfg * cfg)1072 static int otx2_qos_update_tree(struct otx2_nic *pfvf,
1073 struct otx2_qos_node *node,
1074 struct otx2_qos_cfg *cfg)
1075 {
1076 otx2_qos_prepare_txschq_cfg(pfvf, node->parent, cfg);
1077 return otx2_qos_push_txschq_cfg(pfvf, node->parent, cfg);
1078 }
1079
otx2_qos_root_add(struct otx2_nic * pfvf,u16 htb_maj_id,u16 htb_defcls,struct netlink_ext_ack * extack)1080 static int otx2_qos_root_add(struct otx2_nic *pfvf, u16 htb_maj_id, u16 htb_defcls,
1081 struct netlink_ext_ack *extack)
1082 {
1083 struct otx2_qos_cfg *new_cfg;
1084 struct otx2_qos_node *root;
1085 int err;
1086
1087 netdev_dbg(pfvf->netdev,
1088 "TC_HTB_CREATE: handle=0x%x defcls=0x%x\n",
1089 htb_maj_id, htb_defcls);
1090
1091 root = otx2_qos_alloc_root(pfvf);
1092 if (IS_ERR(root)) {
1093 err = PTR_ERR(root);
1094 return err;
1095 }
1096
1097 /* allocate txschq queue */
1098 new_cfg = kzalloc_obj(*new_cfg);
1099 if (!new_cfg) {
1100 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1101 err = -ENOMEM;
1102 goto free_root_node;
1103 }
1104 /* allocate htb root node */
1105 new_cfg->schq[root->level] = 1;
1106 err = otx2_qos_txschq_alloc(pfvf, new_cfg);
1107 if (err) {
1108 NL_SET_ERR_MSG_MOD(extack, "Error allocating txschq");
1109 goto free_root_node;
1110 }
1111
1112 /* Update TL1 RR PRIO */
1113 if (root->level == NIX_TXSCH_LVL_TL1) {
1114 root->child_dwrr_prio = pfvf->hw.txschq_aggr_lvl_rr_prio;
1115 netdev_dbg(pfvf->netdev,
1116 "TL1 DWRR Priority %d\n", root->child_dwrr_prio);
1117 }
1118
1119 if (!(pfvf->netdev->flags & IFF_UP) ||
1120 root->level == NIX_TXSCH_LVL_TL1) {
1121 root->schq = new_cfg->schq_list[root->level][0];
1122 goto out;
1123 }
1124
1125 /* update the txschq configuration in hw */
1126 err = otx2_qos_txschq_update_root_cfg(pfvf, root, new_cfg);
1127 if (err) {
1128 NL_SET_ERR_MSG_MOD(extack,
1129 "Error updating txschq configuration");
1130 goto txschq_free;
1131 }
1132
1133 out:
1134 WRITE_ONCE(pfvf->qos.defcls, htb_defcls);
1135 /* Pairs with smp_load_acquire() in ndo_select_queue */
1136 smp_store_release(&pfvf->qos.maj_id, htb_maj_id);
1137 kfree(new_cfg);
1138 return 0;
1139
1140 txschq_free:
1141 otx2_qos_free_cfg(pfvf, new_cfg);
1142 free_root_node:
1143 kfree(new_cfg);
1144 otx2_qos_sw_node_delete(pfvf, root);
1145 return err;
1146 }
1147
otx2_qos_root_destroy(struct otx2_nic * pfvf)1148 static int otx2_qos_root_destroy(struct otx2_nic *pfvf)
1149 {
1150 struct otx2_qos_node *root;
1151
1152 netdev_dbg(pfvf->netdev, "TC_HTB_DESTROY\n");
1153
1154 /* find root node */
1155 root = otx2_sw_node_find(pfvf, OTX2_QOS_ROOT_CLASSID);
1156 if (!root)
1157 return -ENOENT;
1158
1159 /* free the hw mappings */
1160 otx2_qos_destroy_node(pfvf, root);
1161
1162 return 0;
1163 }
1164
otx2_qos_validate_quantum(struct otx2_nic * pfvf,u32 quantum)1165 static int otx2_qos_validate_quantum(struct otx2_nic *pfvf, u32 quantum)
1166 {
1167 u32 rr_weight = otx2_qos_quantum_to_dwrr_weight(pfvf, quantum);
1168 int err = 0;
1169
1170 /* Max Round robin weight supported by octeontx2 and CN10K
1171 * is different. Validate accordingly
1172 */
1173 if (is_dev_otx2(pfvf->pdev))
1174 err = (rr_weight > OTX2_MAX_RR_QUANTUM) ? -EINVAL : 0;
1175 else if (rr_weight > CN10K_MAX_RR_WEIGHT)
1176 err = -EINVAL;
1177
1178 return err;
1179 }
1180
otx2_qos_validate_dwrr_cfg(struct otx2_qos_node * parent,struct netlink_ext_ack * extack,struct otx2_nic * pfvf,u64 prio,u64 quantum)1181 static int otx2_qos_validate_dwrr_cfg(struct otx2_qos_node *parent,
1182 struct netlink_ext_ack *extack,
1183 struct otx2_nic *pfvf,
1184 u64 prio, u64 quantum)
1185 {
1186 int err;
1187
1188 err = otx2_qos_validate_quantum(pfvf, quantum);
1189 if (err) {
1190 NL_SET_ERR_MSG_MOD(extack, "Unsupported quantum value");
1191 return err;
1192 }
1193
1194 if (parent->child_dwrr_prio == OTX2_QOS_DEFAULT_PRIO) {
1195 parent->child_dwrr_prio = prio;
1196 } else if (prio != parent->child_dwrr_prio) {
1197 NL_SET_ERR_MSG_MOD(extack, "Only one DWRR group is allowed");
1198 return -EOPNOTSUPP;
1199 }
1200
1201 return 0;
1202 }
1203
otx2_qos_validate_configuration(struct otx2_qos_node * parent,struct netlink_ext_ack * extack,struct otx2_nic * pfvf,u64 prio,bool static_cfg)1204 static int otx2_qos_validate_configuration(struct otx2_qos_node *parent,
1205 struct netlink_ext_ack *extack,
1206 struct otx2_nic *pfvf,
1207 u64 prio, bool static_cfg)
1208 {
1209 if (prio == parent->child_dwrr_prio && static_cfg) {
1210 NL_SET_ERR_MSG_MOD(extack, "DWRR child group with same priority exists");
1211 return -EEXIST;
1212 }
1213
1214 if (static_cfg && test_bit(prio, parent->prio_bmap)) {
1215 NL_SET_ERR_MSG_MOD(extack,
1216 "Static priority child with same priority exists");
1217 return -EEXIST;
1218 }
1219
1220 return 0;
1221 }
1222
otx2_reset_dwrr_prio(struct otx2_qos_node * parent,u64 prio)1223 static void otx2_reset_dwrr_prio(struct otx2_qos_node *parent, u64 prio)
1224 {
1225 /* For PF, root node dwrr priority is static */
1226 if (parent->level == NIX_TXSCH_LVL_TL1)
1227 return;
1228
1229 if (parent->child_dwrr_prio != OTX2_QOS_DEFAULT_PRIO) {
1230 parent->child_dwrr_prio = OTX2_QOS_DEFAULT_PRIO;
1231 clear_bit(prio, parent->prio_bmap);
1232 }
1233 }
1234
is_qos_node_dwrr(struct otx2_qos_node * parent,struct otx2_nic * pfvf,u64 prio)1235 static bool is_qos_node_dwrr(struct otx2_qos_node *parent,
1236 struct otx2_nic *pfvf,
1237 u64 prio)
1238 {
1239 struct otx2_qos_node *node;
1240 bool ret = false;
1241
1242 if (parent->child_dwrr_prio == prio)
1243 return true;
1244
1245 mutex_lock(&pfvf->qos.qos_lock);
1246 list_for_each_entry(node, &parent->child_list, list) {
1247 if (prio == node->prio) {
1248 if (parent->child_dwrr_prio != OTX2_QOS_DEFAULT_PRIO &&
1249 parent->child_dwrr_prio != prio)
1250 continue;
1251
1252 if (otx2_qos_validate_quantum(pfvf, node->quantum)) {
1253 netdev_err(pfvf->netdev,
1254 "Unsupported quantum value for existing classid=0x%x quantum=%d prio=%d",
1255 node->classid, node->quantum,
1256 node->prio);
1257 break;
1258 }
1259 /* mark old node as dwrr */
1260 node->is_static = false;
1261 parent->child_dwrr_cnt++;
1262 parent->child_static_cnt--;
1263 ret = true;
1264 break;
1265 }
1266 }
1267 mutex_unlock(&pfvf->qos.qos_lock);
1268
1269 return ret;
1270 }
1271
otx2_qos_leaf_alloc_queue(struct otx2_nic * pfvf,u16 classid,u32 parent_classid,u64 rate,u64 ceil,u64 prio,u32 quantum,struct netlink_ext_ack * extack)1272 static int otx2_qos_leaf_alloc_queue(struct otx2_nic *pfvf, u16 classid,
1273 u32 parent_classid, u64 rate, u64 ceil,
1274 u64 prio, u32 quantum,
1275 struct netlink_ext_ack *extack)
1276 {
1277 struct otx2_qos_cfg *old_cfg, *new_cfg;
1278 struct otx2_qos_node *node, *parent;
1279 int qid, ret, err;
1280 bool static_cfg;
1281
1282 netdev_dbg(pfvf->netdev,
1283 "TC_HTB_LEAF_ALLOC_QUEUE: classid=0x%x parent_classid=0x%x rate=%lld ceil=%lld prio=%lld quantum=%d\n",
1284 classid, parent_classid, rate, ceil, prio, quantum);
1285
1286 if (prio > OTX2_QOS_MAX_PRIO) {
1287 NL_SET_ERR_MSG_MOD(extack, "Valid priority range 0 to 7");
1288 ret = -EOPNOTSUPP;
1289 goto out;
1290 }
1291
1292 if (!quantum || quantum > INT_MAX) {
1293 NL_SET_ERR_MSG_MOD(extack, "Invalid quantum, range 1 - 2147483647 bytes");
1294 ret = -EOPNOTSUPP;
1295 goto out;
1296 }
1297
1298 /* get parent node */
1299 parent = otx2_sw_node_find(pfvf, parent_classid);
1300 if (!parent) {
1301 NL_SET_ERR_MSG_MOD(extack, "parent node not found");
1302 ret = -ENOENT;
1303 goto out;
1304 }
1305 if (parent->level == NIX_TXSCH_LVL_MDQ) {
1306 NL_SET_ERR_MSG_MOD(extack, "HTB qos max levels reached");
1307 ret = -EOPNOTSUPP;
1308 goto out;
1309 }
1310
1311 static_cfg = !is_qos_node_dwrr(parent, pfvf, prio);
1312 ret = otx2_qos_validate_configuration(parent, extack, pfvf, prio,
1313 static_cfg);
1314 if (ret)
1315 goto out;
1316
1317 if (!static_cfg) {
1318 ret = otx2_qos_validate_dwrr_cfg(parent, extack, pfvf, prio,
1319 quantum);
1320 if (ret)
1321 goto out;
1322 }
1323
1324 if (static_cfg)
1325 parent->child_static_cnt++;
1326 else
1327 parent->child_dwrr_cnt++;
1328
1329 set_bit(prio, parent->prio_bmap);
1330
1331 /* read current txschq configuration */
1332 old_cfg = kzalloc_obj(*old_cfg);
1333 if (!old_cfg) {
1334 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1335 ret = -ENOMEM;
1336 goto reset_prio;
1337 }
1338 otx2_qos_read_txschq_cfg(pfvf, parent, old_cfg);
1339
1340 /* allocate a new sq */
1341 qid = otx2_qos_get_qid(pfvf);
1342 if (qid < 0) {
1343 NL_SET_ERR_MSG_MOD(extack, "Reached max supported QOS SQ's");
1344 ret = -ENOMEM;
1345 goto free_old_cfg;
1346 }
1347
1348 /* Actual SQ mapping will be updated after SMQ alloc */
1349 pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
1350
1351 /* allocate and initialize a new child node */
1352 node = otx2_qos_sw_create_leaf_node(pfvf, parent, classid, prio, rate,
1353 ceil, quantum, qid, static_cfg);
1354 if (IS_ERR(node)) {
1355 NL_SET_ERR_MSG_MOD(extack, "Unable to allocate leaf node");
1356 ret = PTR_ERR(node);
1357 goto free_old_cfg;
1358 }
1359
1360 /* push new txschq config to hw */
1361 new_cfg = kzalloc_obj(*new_cfg);
1362 if (!new_cfg) {
1363 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1364 ret = -ENOMEM;
1365 goto free_node;
1366 }
1367 ret = otx2_qos_update_tree(pfvf, node, new_cfg);
1368 if (ret) {
1369 NL_SET_ERR_MSG_MOD(extack, "HTB HW configuration error");
1370 kfree(new_cfg);
1371 otx2_qos_sw_node_delete(pfvf, node);
1372 /* restore the old qos tree */
1373 err = otx2_qos_txschq_update_config(pfvf, parent, old_cfg);
1374 if (err) {
1375 netdev_err(pfvf->netdev,
1376 "Failed to restore txcshq configuration");
1377 goto free_old_cfg;
1378 }
1379
1380 otx2_qos_update_smq(pfvf, parent, QOS_CFG_SQ);
1381 goto free_old_cfg;
1382 }
1383
1384 /* update tx_real_queues */
1385 otx2_qos_update_tx_netdev_queues(pfvf);
1386
1387 /* free new txschq config */
1388 kfree(new_cfg);
1389
1390 /* free old txschq config */
1391 otx2_qos_free_cfg(pfvf, old_cfg);
1392 kfree(old_cfg);
1393
1394 return pfvf->hw.tx_queues + qid;
1395
1396 free_node:
1397 otx2_qos_sw_node_delete(pfvf, node);
1398 free_old_cfg:
1399 kfree(old_cfg);
1400 reset_prio:
1401 if (static_cfg)
1402 parent->child_static_cnt--;
1403 else
1404 parent->child_dwrr_cnt--;
1405
1406 clear_bit(prio, parent->prio_bmap);
1407 out:
1408 return ret;
1409 }
1410
otx2_qos_leaf_to_inner(struct otx2_nic * pfvf,u16 classid,u16 child_classid,u64 rate,u64 ceil,u64 prio,u32 quantum,struct netlink_ext_ack * extack)1411 static int otx2_qos_leaf_to_inner(struct otx2_nic *pfvf, u16 classid,
1412 u16 child_classid, u64 rate, u64 ceil, u64 prio,
1413 u32 quantum, struct netlink_ext_ack *extack)
1414 {
1415 struct otx2_qos_cfg *old_cfg, *new_cfg;
1416 struct otx2_qos_node *node, *child;
1417 bool static_cfg;
1418 int ret, err;
1419 u16 qid;
1420
1421 netdev_dbg(pfvf->netdev,
1422 "TC_HTB_LEAF_TO_INNER classid %04x, child %04x, rate %llu, ceil %llu\n",
1423 classid, child_classid, rate, ceil);
1424
1425 if (prio > OTX2_QOS_MAX_PRIO) {
1426 NL_SET_ERR_MSG_MOD(extack, "Valid priority range 0 to 7");
1427 ret = -EOPNOTSUPP;
1428 goto out;
1429 }
1430
1431 if (!quantum || quantum > INT_MAX) {
1432 NL_SET_ERR_MSG_MOD(extack, "Invalid quantum, range 1 - 2147483647 bytes");
1433 ret = -EOPNOTSUPP;
1434 goto out;
1435 }
1436
1437 /* find node related to classid */
1438 node = otx2_sw_node_find(pfvf, classid);
1439 if (!node) {
1440 NL_SET_ERR_MSG_MOD(extack, "HTB node not found");
1441 ret = -ENOENT;
1442 goto out;
1443 }
1444 /* check max qos txschq level */
1445 if (node->level == NIX_TXSCH_LVL_MDQ) {
1446 NL_SET_ERR_MSG_MOD(extack, "HTB qos level not supported");
1447 ret = -EOPNOTSUPP;
1448 goto out;
1449 }
1450
1451 static_cfg = !is_qos_node_dwrr(node, pfvf, prio);
1452 if (!static_cfg) {
1453 ret = otx2_qos_validate_dwrr_cfg(node, extack, pfvf, prio,
1454 quantum);
1455 if (ret)
1456 goto out;
1457 }
1458
1459 if (static_cfg)
1460 node->child_static_cnt++;
1461 else
1462 node->child_dwrr_cnt++;
1463
1464 set_bit(prio, node->prio_bmap);
1465
1466 /* store the qid to assign to leaf node */
1467 qid = node->qid;
1468
1469 /* read current txschq configuration */
1470 old_cfg = kzalloc_obj(*old_cfg);
1471 if (!old_cfg) {
1472 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1473 ret = -ENOMEM;
1474 goto reset_prio;
1475 }
1476 otx2_qos_read_txschq_cfg(pfvf, node, old_cfg);
1477
1478 /* delete the txschq nodes allocated for this node */
1479 otx2_qos_disable_sq(pfvf, qid);
1480 otx2_qos_free_hw_node_schq(pfvf, node);
1481 otx2_qos_free_sw_node_schq(pfvf, node);
1482 pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
1483
1484 /* mark this node as htb inner node */
1485 WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
1486
1487 /* allocate and initialize a new child node */
1488 child = otx2_qos_sw_create_leaf_node(pfvf, node, child_classid,
1489 prio, rate, ceil, quantum,
1490 qid, static_cfg);
1491 if (IS_ERR(child)) {
1492 NL_SET_ERR_MSG_MOD(extack, "Unable to allocate leaf node");
1493 ret = PTR_ERR(child);
1494 goto free_old_cfg;
1495 }
1496
1497 /* push new txschq config to hw */
1498 new_cfg = kzalloc_obj(*new_cfg);
1499 if (!new_cfg) {
1500 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1501 ret = -ENOMEM;
1502 goto free_node;
1503 }
1504 ret = otx2_qos_update_tree(pfvf, child, new_cfg);
1505 if (ret) {
1506 NL_SET_ERR_MSG_MOD(extack, "HTB HW configuration error");
1507 kfree(new_cfg);
1508 otx2_qos_sw_node_delete(pfvf, child);
1509 /* restore the old qos tree */
1510 WRITE_ONCE(node->qid, qid);
1511 err = otx2_qos_alloc_txschq_node(pfvf, node);
1512 if (err) {
1513 netdev_err(pfvf->netdev,
1514 "Failed to restore old leaf node");
1515 goto free_old_cfg;
1516 }
1517 err = otx2_qos_txschq_update_config(pfvf, node, old_cfg);
1518 if (err) {
1519 netdev_err(pfvf->netdev,
1520 "Failed to restore txcshq configuration");
1521 goto free_old_cfg;
1522 }
1523 otx2_qos_update_smq(pfvf, node, QOS_CFG_SQ);
1524 goto free_old_cfg;
1525 }
1526
1527 /* free new txschq config */
1528 kfree(new_cfg);
1529
1530 /* free old txschq config */
1531 otx2_qos_free_cfg(pfvf, old_cfg);
1532 kfree(old_cfg);
1533
1534 return 0;
1535
1536 free_node:
1537 otx2_qos_sw_node_delete(pfvf, child);
1538 free_old_cfg:
1539 kfree(old_cfg);
1540 reset_prio:
1541 if (static_cfg)
1542 node->child_static_cnt--;
1543 else
1544 node->child_dwrr_cnt--;
1545 clear_bit(prio, node->prio_bmap);
1546 out:
1547 return ret;
1548 }
1549
otx2_qos_cur_leaf_nodes(struct otx2_nic * pfvf)1550 static int otx2_qos_cur_leaf_nodes(struct otx2_nic *pfvf)
1551 {
1552 int last = find_last_bit(pfvf->qos.qos_sq_bmap, pfvf->hw.tc_tx_queues);
1553
1554 return last == pfvf->hw.tc_tx_queues ? 0 : last + 1;
1555 }
1556
otx2_reset_qdisc(struct net_device * dev,u16 qid)1557 static void otx2_reset_qdisc(struct net_device *dev, u16 qid)
1558 {
1559 struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, qid);
1560 struct Qdisc *qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
1561
1562 if (!qdisc)
1563 return;
1564
1565 spin_lock_bh(qdisc_lock(qdisc));
1566 qdisc_reset(qdisc);
1567 spin_unlock_bh(qdisc_lock(qdisc));
1568 }
1569
otx2_cfg_smq(struct otx2_nic * pfvf,struct otx2_qos_node * node,int qid)1570 static void otx2_cfg_smq(struct otx2_nic *pfvf, struct otx2_qos_node *node,
1571 int qid)
1572 {
1573 struct otx2_qos_node *tmp;
1574
1575 list_for_each_entry(tmp, &node->child_schq_list, list)
1576 if (tmp->level == NIX_TXSCH_LVL_MDQ) {
1577 otx2_qos_txschq_config(pfvf, tmp);
1578 pfvf->qos.qid_to_sqmap[qid] = tmp->schq;
1579 }
1580 }
1581
otx2_qos_leaf_del(struct otx2_nic * pfvf,u16 * classid,struct netlink_ext_ack * extack)1582 static int otx2_qos_leaf_del(struct otx2_nic *pfvf, u16 *classid,
1583 struct netlink_ext_ack *extack)
1584 {
1585 struct otx2_qos_node *node, *parent;
1586 int dwrr_del_node = false;
1587 u16 qid, moved_qid;
1588 u64 prio;
1589
1590 netdev_dbg(pfvf->netdev, "TC_HTB_LEAF_DEL classid %04x\n", *classid);
1591
1592 /* find node related to classid */
1593 node = otx2_sw_node_find(pfvf, *classid);
1594 if (!node) {
1595 NL_SET_ERR_MSG_MOD(extack, "HTB node not found");
1596 return -ENOENT;
1597 }
1598 parent = node->parent;
1599 prio = node->prio;
1600 qid = node->qid;
1601
1602 if (!node->is_static)
1603 dwrr_del_node = true;
1604
1605 otx2_qos_disable_sq(pfvf, node->qid);
1606
1607 otx2_qos_destroy_node(pfvf, node);
1608 pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
1609
1610 if (dwrr_del_node) {
1611 parent->child_dwrr_cnt--;
1612 } else {
1613 parent->child_static_cnt--;
1614 clear_bit(prio, parent->prio_bmap);
1615 }
1616
1617 /* Reset DWRR priority if all dwrr nodes are deleted */
1618 if (!parent->child_dwrr_cnt)
1619 otx2_reset_dwrr_prio(parent, prio);
1620
1621 if (!parent->child_static_cnt)
1622 parent->max_static_prio = 0;
1623
1624 moved_qid = otx2_qos_cur_leaf_nodes(pfvf);
1625
1626 /* last node just deleted */
1627 if (moved_qid == 0 || moved_qid == qid)
1628 return 0;
1629
1630 moved_qid--;
1631
1632 node = otx2_sw_node_find_by_qid(pfvf, moved_qid);
1633 if (!node)
1634 return 0;
1635
1636 /* stop traffic to the old queue and disable
1637 * SQ associated with it
1638 */
1639 node->qid = OTX2_QOS_QID_INNER;
1640 __clear_bit(moved_qid, pfvf->qos.qos_sq_bmap);
1641 otx2_qos_disable_sq(pfvf, moved_qid);
1642
1643 otx2_reset_qdisc(pfvf->netdev, pfvf->hw.tx_queues + moved_qid);
1644
1645 /* enable SQ associated with qid and
1646 * update the node
1647 */
1648 otx2_cfg_smq(pfvf, node, qid);
1649
1650 otx2_qos_enable_sq(pfvf, qid);
1651 __set_bit(qid, pfvf->qos.qos_sq_bmap);
1652 node->qid = qid;
1653
1654 *classid = node->classid;
1655 return 0;
1656 }
1657
otx2_qos_leaf_del_last(struct otx2_nic * pfvf,u16 classid,bool force,struct netlink_ext_ack * extack)1658 static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force,
1659 struct netlink_ext_ack *extack)
1660 {
1661 struct otx2_qos_node *node, *parent;
1662 struct otx2_qos_cfg *new_cfg;
1663 int dwrr_del_node = false;
1664 u64 prio;
1665 int err;
1666 u16 qid;
1667
1668 netdev_dbg(pfvf->netdev,
1669 "TC_HTB_LEAF_DEL_LAST classid %04x\n", classid);
1670
1671 /* find node related to classid */
1672 node = otx2_sw_node_find(pfvf, classid);
1673 if (!node) {
1674 NL_SET_ERR_MSG_MOD(extack, "HTB node not found");
1675 return -ENOENT;
1676 }
1677
1678 /* save qid for use by parent */
1679 qid = node->qid;
1680 prio = node->prio;
1681
1682 parent = otx2_sw_node_find(pfvf, node->parent->classid);
1683 if (!parent) {
1684 NL_SET_ERR_MSG_MOD(extack, "parent node not found");
1685 return -ENOENT;
1686 }
1687
1688 if (!node->is_static)
1689 dwrr_del_node = true;
1690
1691 WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
1692 /* destroy the leaf node */
1693 otx2_qos_disable_sq(pfvf, qid);
1694 otx2_qos_destroy_node(pfvf, node);
1695 pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
1696
1697 if (dwrr_del_node) {
1698 parent->child_dwrr_cnt--;
1699 } else {
1700 parent->child_static_cnt--;
1701 clear_bit(prio, parent->prio_bmap);
1702 }
1703
1704 /* Reset DWRR priority if all dwrr nodes are deleted */
1705 if (!parent->child_dwrr_cnt)
1706 otx2_reset_dwrr_prio(parent, prio);
1707
1708 if (!parent->child_static_cnt)
1709 parent->max_static_prio = 0;
1710
1711 /* create downstream txschq entries to parent */
1712 err = otx2_qos_alloc_txschq_node(pfvf, parent);
1713 if (err) {
1714 NL_SET_ERR_MSG_MOD(extack, "HTB failed to create txsch configuration");
1715 return err;
1716 }
1717 WRITE_ONCE(parent->qid, qid);
1718 __set_bit(qid, pfvf->qos.qos_sq_bmap);
1719
1720 /* push new txschq config to hw */
1721 new_cfg = kzalloc_obj(*new_cfg);
1722 if (!new_cfg) {
1723 NL_SET_ERR_MSG_MOD(extack, "Memory allocation error");
1724 return -ENOMEM;
1725 }
1726 /* fill txschq cfg and push txschq cfg to hw */
1727 otx2_qos_fill_cfg_schq(parent, new_cfg);
1728 err = otx2_qos_push_txschq_cfg(pfvf, parent, new_cfg);
1729 if (err) {
1730 NL_SET_ERR_MSG_MOD(extack, "HTB HW configuration error");
1731 kfree(new_cfg);
1732 return err;
1733 }
1734 kfree(new_cfg);
1735
1736 return 0;
1737 }
1738
otx2_clean_qos_queues(struct otx2_nic * pfvf)1739 void otx2_clean_qos_queues(struct otx2_nic *pfvf)
1740 {
1741 struct otx2_qos_node *root;
1742
1743 root = otx2_sw_node_find(pfvf, OTX2_QOS_ROOT_CLASSID);
1744 if (!root)
1745 return;
1746
1747 otx2_qos_update_smq(pfvf, root, QOS_SMQ_FLUSH);
1748 }
1749
otx2_qos_config_txschq(struct otx2_nic * pfvf)1750 void otx2_qos_config_txschq(struct otx2_nic *pfvf)
1751 {
1752 struct otx2_qos_node *root;
1753 int err;
1754
1755 root = otx2_sw_node_find(pfvf, OTX2_QOS_ROOT_CLASSID);
1756 if (!root)
1757 return;
1758
1759 if (root->level != NIX_TXSCH_LVL_TL1) {
1760 err = otx2_qos_txschq_config(pfvf, root);
1761 if (err) {
1762 netdev_err(pfvf->netdev, "Error update txschq configuration\n");
1763 goto root_destroy;
1764 }
1765 }
1766
1767 err = otx2_qos_txschq_push_cfg_tl(pfvf, root, NULL);
1768 if (err) {
1769 netdev_err(pfvf->netdev, "Error update txschq configuration\n");
1770 goto root_destroy;
1771 }
1772
1773 otx2_qos_update_smq(pfvf, root, QOS_CFG_SQ);
1774 return;
1775
1776 root_destroy:
1777 netdev_err(pfvf->netdev, "Failed to update Scheduler/Shaping config in Hardware\n");
1778 /* Free resources allocated */
1779 otx2_qos_root_destroy(pfvf);
1780 }
1781
otx2_setup_tc_htb(struct net_device * ndev,struct tc_htb_qopt_offload * htb)1782 int otx2_setup_tc_htb(struct net_device *ndev, struct tc_htb_qopt_offload *htb)
1783 {
1784 struct otx2_nic *pfvf = netdev_priv(ndev);
1785 int res;
1786
1787 switch (htb->command) {
1788 case TC_HTB_CREATE:
1789 return otx2_qos_root_add(pfvf, htb->parent_classid,
1790 htb->classid, htb->extack);
1791 case TC_HTB_DESTROY:
1792 return otx2_qos_root_destroy(pfvf);
1793 case TC_HTB_LEAF_ALLOC_QUEUE:
1794 res = otx2_qos_leaf_alloc_queue(pfvf, htb->classid,
1795 htb->parent_classid,
1796 htb->rate, htb->ceil,
1797 htb->prio, htb->quantum,
1798 htb->extack);
1799 if (res < 0)
1800 return res;
1801 htb->qid = res;
1802 return 0;
1803 case TC_HTB_LEAF_TO_INNER:
1804 return otx2_qos_leaf_to_inner(pfvf, htb->parent_classid,
1805 htb->classid, htb->rate,
1806 htb->ceil, htb->prio,
1807 htb->quantum, htb->extack);
1808 case TC_HTB_LEAF_DEL:
1809 return otx2_qos_leaf_del(pfvf, &htb->classid, htb->extack);
1810 case TC_HTB_LEAF_DEL_LAST:
1811 case TC_HTB_LEAF_DEL_LAST_FORCE:
1812 return otx2_qos_leaf_del_last(pfvf, htb->classid,
1813 htb->command == TC_HTB_LEAF_DEL_LAST_FORCE,
1814 htb->extack);
1815 case TC_HTB_LEAF_QUERY_QUEUE:
1816 res = otx2_get_txq_by_classid(pfvf, htb->classid);
1817 htb->qid = res;
1818 return 0;
1819 case TC_HTB_NODE_MODIFY:
1820 fallthrough;
1821 default:
1822 return -EOPNOTSUPP;
1823 }
1824 }
1825