forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/net/ethernet/netronome/nfp/abm/ctrl.c
....@@ -1,38 +1,9 @@
1
-// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
-/*
3
- * Copyright (C) 2018 Netronome Systems, Inc.
4
- *
5
- * This software is dual licensed under the GNU General License Version 2,
6
- * June 1991 as shown in the file COPYING in the top-level directory of this
7
- * source tree or the BSD 2-Clause License provided below. You have the
8
- * option to license this software under the complete terms of either license.
9
- *
10
- * The BSD 2-Clause License:
11
- *
12
- * Redistribution and use in source and binary forms, with or
13
- * without modification, are permitted provided that the following
14
- * conditions are met:
15
- *
16
- * 1. Redistributions of source code must retain the above
17
- * copyright notice, this list of conditions and the following
18
- * disclaimer.
19
- *
20
- * 2. Redistributions in binary form must reproduce the above
21
- * copyright notice, this list of conditions and the following
22
- * disclaimer in the documentation and/or other materials
23
- * provided with the distribution.
24
- *
25
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
- * SOFTWARE.
33
- */
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
+/* Copyright (C) 2018 Netronome Systems, Inc. */
343
4
+#include <linux/bitops.h>
355 #include <linux/kernel.h>
6
+#include <linux/log2.h>
367
378 #include "../nfpcore/nfp_cpp.h"
389 #include "../nfpcore/nfp_nffw.h"
....@@ -42,47 +13,58 @@
4213 #include "../nfp_net.h"
4314 #include "main.h"
4415
45
-#define NFP_QLVL_SYM_NAME "_abi_nfd_out_q_lvls_%u"
16
+#define NFP_NUM_PRIOS_SYM_NAME "_abi_pci_dscp_num_prio_%u"
17
+#define NFP_NUM_BANDS_SYM_NAME "_abi_pci_dscp_num_band_%u"
18
+#define NFP_ACT_MASK_SYM_NAME "_abi_nfd_out_q_actions_%u"
19
+
20
+#define NFP_RED_SUPPORT_SYM_NAME "_abi_nfd_out_red_offload_%u"
21
+
22
+#define NFP_QLVL_SYM_NAME "_abi_nfd_out_q_lvls_%u%s"
4623 #define NFP_QLVL_STRIDE 16
4724 #define NFP_QLVL_BLOG_BYTES 0
4825 #define NFP_QLVL_BLOG_PKTS 4
4926 #define NFP_QLVL_THRS 8
27
+#define NFP_QLVL_ACT 12
5028
51
-#define NFP_QMSTAT_SYM_NAME "_abi_nfdqm%u_stats"
29
+#define NFP_QMSTAT_SYM_NAME "_abi_nfdqm%u_stats%s"
5230 #define NFP_QMSTAT_STRIDE 32
5331 #define NFP_QMSTAT_NON_STO 0
5432 #define NFP_QMSTAT_STO 8
5533 #define NFP_QMSTAT_DROP 16
5634 #define NFP_QMSTAT_ECN 24
5735
58
-static unsigned long long
59
-nfp_abm_q_lvl_thrs(struct nfp_abm_link *alink, unsigned int queue)
60
-{
61
- return alink->abm->q_lvls->addr +
62
- (alink->queue_base + queue) * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
63
-}
36
+#define NFP_Q_STAT_SYM_NAME "_abi_nfd_rxq_stats%u%s"
37
+#define NFP_Q_STAT_STRIDE 16
38
+#define NFP_Q_STAT_PKTS 0
39
+#define NFP_Q_STAT_BYTES 8
40
+
41
+#define NFP_NET_ABM_MBOX_CMD NFP_NET_CFG_MBOX_SIMPLE_CMD
42
+#define NFP_NET_ABM_MBOX_RET NFP_NET_CFG_MBOX_SIMPLE_RET
43
+#define NFP_NET_ABM_MBOX_DATALEN NFP_NET_CFG_MBOX_SIMPLE_VAL
44
+#define NFP_NET_ABM_MBOX_RESERVED (NFP_NET_CFG_MBOX_SIMPLE_VAL + 4)
45
+#define NFP_NET_ABM_MBOX_DATA (NFP_NET_CFG_MBOX_SIMPLE_VAL + 8)
6446
6547 static int
6648 nfp_abm_ctrl_stat(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
67
- unsigned int stride, unsigned int offset, unsigned int i,
68
- bool is_u64, u64 *res)
49
+ unsigned int stride, unsigned int offset, unsigned int band,
50
+ unsigned int queue, bool is_u64, u64 *res)
6951 {
7052 struct nfp_cpp *cpp = alink->abm->app->cpp;
71
- u32 val32, mur;
72
- u64 val, addr;
53
+ u64 val, sym_offset;
54
+ unsigned int qid;
55
+ u32 val32;
7356 int err;
7457
75
- mur = NFP_CPP_ATOMIC_RD(sym->target, sym->domain);
58
+ qid = band * NFP_NET_MAX_RX_RINGS + alink->queue_base + queue;
7659
77
- addr = sym->addr + (alink->queue_base + i) * stride + offset;
60
+ sym_offset = qid * stride + offset;
7861 if (is_u64)
79
- err = nfp_cpp_readq(cpp, mur, addr, &val);
62
+ err = __nfp_rtsym_readq(cpp, sym, 3, 0, sym_offset, &val);
8063 else
81
- err = nfp_cpp_readl(cpp, mur, addr, &val32);
64
+ err = __nfp_rtsym_readl(cpp, sym, 3, 0, sym_offset, &val32);
8265 if (err) {
83
- nfp_err(cpp,
84
- "RED offload reading stat failed on vNIC %d queue %d\n",
85
- alink->id, i);
66
+ nfp_err(cpp, "RED offload reading stat failed on vNIC %d band %d queue %d (+ %d)\n",
67
+ alink->id, band, queue, alink->queue_base);
8668 return err;
8769 }
8870
....@@ -90,176 +72,179 @@
9072 return 0;
9173 }
9274
93
-static int
94
-nfp_abm_ctrl_stat_all(struct nfp_abm_link *alink, const struct nfp_rtsym *sym,
95
- unsigned int stride, unsigned int offset, bool is_u64,
96
- u64 *res)
75
+int __nfp_abm_ctrl_set_q_lvl(struct nfp_abm *abm, unsigned int id, u32 val)
9776 {
98
- u64 val, sum = 0;
99
- unsigned int i;
77
+ struct nfp_cpp *cpp = abm->app->cpp;
78
+ u64 sym_offset;
10079 int err;
10180
102
- for (i = 0; i < alink->vnic->max_rx_rings; i++) {
103
- err = nfp_abm_ctrl_stat(alink, sym, stride, offset, i,
104
- is_u64, &val);
105
- if (err)
106
- return err;
107
- sum += val;
108
- }
81
+ __clear_bit(id, abm->threshold_undef);
82
+ if (abm->thresholds[id] == val)
83
+ return 0;
10984
110
- *res = sum;
111
- return 0;
112
-}
113
-
114
-int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int i, u32 val)
115
-{
116
- struct nfp_cpp *cpp = alink->abm->app->cpp;
117
- u32 muw;
118
- int err;
119
-
120
- muw = NFP_CPP_ATOMIC_WR(alink->abm->q_lvls->target,
121
- alink->abm->q_lvls->domain);
122
-
123
- err = nfp_cpp_writel(cpp, muw, nfp_abm_q_lvl_thrs(alink, i), val);
85
+ sym_offset = id * NFP_QLVL_STRIDE + NFP_QLVL_THRS;
86
+ err = __nfp_rtsym_writel(cpp, abm->q_lvls, 4, 0, sym_offset, val);
12487 if (err) {
125
- nfp_err(cpp, "RED offload setting level failed on vNIC %d queue %d\n",
126
- alink->id, i);
88
+ nfp_err(cpp,
89
+ "RED offload setting level failed on subqueue %d\n",
90
+ id);
12791 return err;
12892 }
12993
94
+ abm->thresholds[id] = val;
13095 return 0;
13196 }
13297
133
-int nfp_abm_ctrl_set_all_q_lvls(struct nfp_abm_link *alink, u32 val)
98
+int nfp_abm_ctrl_set_q_lvl(struct nfp_abm_link *alink, unsigned int band,
99
+ unsigned int queue, u32 val)
134100 {
135
- int i, err;
101
+ unsigned int threshold;
136102
137
- for (i = 0; i < alink->vnic->max_rx_rings; i++) {
138
- err = nfp_abm_ctrl_set_q_lvl(alink, i, val);
139
- if (err)
140
- return err;
103
+ threshold = band * NFP_NET_MAX_RX_RINGS + alink->queue_base + queue;
104
+
105
+ return __nfp_abm_ctrl_set_q_lvl(alink->abm, threshold, val);
106
+}
107
+
108
+int __nfp_abm_ctrl_set_q_act(struct nfp_abm *abm, unsigned int id,
109
+ enum nfp_abm_q_action act)
110
+{
111
+ struct nfp_cpp *cpp = abm->app->cpp;
112
+ u64 sym_offset;
113
+ int err;
114
+
115
+ if (abm->actions[id] == act)
116
+ return 0;
117
+
118
+ sym_offset = id * NFP_QLVL_STRIDE + NFP_QLVL_ACT;
119
+ err = __nfp_rtsym_writel(cpp, abm->q_lvls, 4, 0, sym_offset, act);
120
+ if (err) {
121
+ nfp_err(cpp,
122
+ "RED offload setting action failed on subqueue %d\n",
123
+ id);
124
+ return err;
141125 }
142126
127
+ abm->actions[id] = act;
143128 return 0;
144129 }
145130
146
-u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int i)
131
+int nfp_abm_ctrl_set_q_act(struct nfp_abm_link *alink, unsigned int band,
132
+ unsigned int queue, enum nfp_abm_q_action act)
147133 {
148
- u64 val;
134
+ unsigned int qid;
149135
150
- if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats, NFP_QMSTAT_STRIDE,
151
- NFP_QMSTAT_NON_STO, i, true, &val))
152
- return 0;
153
- return val;
136
+ qid = band * NFP_NET_MAX_RX_RINGS + alink->queue_base + queue;
137
+
138
+ return __nfp_abm_ctrl_set_q_act(alink->abm, qid, act);
154139 }
155140
156
-u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int i)
141
+u64 nfp_abm_ctrl_stat_non_sto(struct nfp_abm_link *alink, unsigned int queue)
157142 {
158
- u64 val;
143
+ unsigned int band;
144
+ u64 val, sum = 0;
159145
160
- if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats, NFP_QMSTAT_STRIDE,
161
- NFP_QMSTAT_STO, i, true, &val))
162
- return 0;
163
- return val;
146
+ for (band = 0; band < alink->abm->num_bands; band++) {
147
+ if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
148
+ NFP_QMSTAT_STRIDE, NFP_QMSTAT_NON_STO,
149
+ band, queue, true, &val))
150
+ return 0;
151
+ sum += val;
152
+ }
153
+
154
+ return sum;
164155 }
165156
166
-int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink, unsigned int i,
167
- struct nfp_alink_stats *stats)
157
+u64 nfp_abm_ctrl_stat_sto(struct nfp_abm_link *alink, unsigned int queue)
158
+{
159
+ unsigned int band;
160
+ u64 val, sum = 0;
161
+
162
+ for (band = 0; band < alink->abm->num_bands; band++) {
163
+ if (nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
164
+ NFP_QMSTAT_STRIDE, NFP_QMSTAT_STO,
165
+ band, queue, true, &val))
166
+ return 0;
167
+ sum += val;
168
+ }
169
+
170
+ return sum;
171
+}
172
+
173
+static int
174
+nfp_abm_ctrl_stat_basic(struct nfp_abm_link *alink, unsigned int band,
175
+ unsigned int queue, unsigned int off, u64 *val)
176
+{
177
+ if (!nfp_abm_has_prio(alink->abm)) {
178
+ if (!band) {
179
+ unsigned int id = alink->queue_base + queue;
180
+
181
+ *val = nn_readq(alink->vnic,
182
+ NFP_NET_CFG_RXR_STATS(id) + off);
183
+ } else {
184
+ *val = 0;
185
+ }
186
+
187
+ return 0;
188
+ } else {
189
+ return nfp_abm_ctrl_stat(alink, alink->abm->q_stats,
190
+ NFP_Q_STAT_STRIDE, off, band, queue,
191
+ true, val);
192
+ }
193
+}
194
+
195
+int nfp_abm_ctrl_read_q_stats(struct nfp_abm_link *alink, unsigned int band,
196
+ unsigned int queue, struct nfp_alink_stats *stats)
168197 {
169198 int err;
170199
171
- stats->tx_pkts = nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i));
172
- stats->tx_bytes = nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i) + 8);
200
+ err = nfp_abm_ctrl_stat_basic(alink, band, queue, NFP_Q_STAT_PKTS,
201
+ &stats->tx_pkts);
202
+ if (err)
203
+ return err;
173204
174
- err = nfp_abm_ctrl_stat(alink, alink->abm->q_lvls,
175
- NFP_QLVL_STRIDE, NFP_QLVL_BLOG_BYTES,
176
- i, false, &stats->backlog_bytes);
205
+ err = nfp_abm_ctrl_stat_basic(alink, band, queue, NFP_Q_STAT_BYTES,
206
+ &stats->tx_bytes);
207
+ if (err)
208
+ return err;
209
+
210
+ err = nfp_abm_ctrl_stat(alink, alink->abm->q_lvls, NFP_QLVL_STRIDE,
211
+ NFP_QLVL_BLOG_BYTES, band, queue, false,
212
+ &stats->backlog_bytes);
177213 if (err)
178214 return err;
179215
180216 err = nfp_abm_ctrl_stat(alink, alink->abm->q_lvls,
181217 NFP_QLVL_STRIDE, NFP_QLVL_BLOG_PKTS,
182
- i, false, &stats->backlog_pkts);
218
+ band, queue, false, &stats->backlog_pkts);
183219 if (err)
184220 return err;
185221
186222 err = nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
187223 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
188
- i, true, &stats->drops);
224
+ band, queue, true, &stats->drops);
189225 if (err)
190226 return err;
191227
192228 return nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
193229 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
194
- i, true, &stats->overlimits);
230
+ band, queue, true, &stats->overlimits);
195231 }
196232
197
-int nfp_abm_ctrl_read_stats(struct nfp_abm_link *alink,
198
- struct nfp_alink_stats *stats)
199
-{
200
- u64 pkts = 0, bytes = 0;
201
- int i, err;
202
-
203
- for (i = 0; i < alink->vnic->max_rx_rings; i++) {
204
- pkts += nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i));
205
- bytes += nn_readq(alink->vnic, NFP_NET_CFG_RXR_STATS(i) + 8);
206
- }
207
- stats->tx_pkts = pkts;
208
- stats->tx_bytes = bytes;
209
-
210
- err = nfp_abm_ctrl_stat_all(alink, alink->abm->q_lvls,
211
- NFP_QLVL_STRIDE, NFP_QLVL_BLOG_BYTES,
212
- false, &stats->backlog_bytes);
213
- if (err)
214
- return err;
215
-
216
- err = nfp_abm_ctrl_stat_all(alink, alink->abm->q_lvls,
217
- NFP_QLVL_STRIDE, NFP_QLVL_BLOG_PKTS,
218
- false, &stats->backlog_pkts);
219
- if (err)
220
- return err;
221
-
222
- err = nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
223
- NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
224
- true, &stats->drops);
225
- if (err)
226
- return err;
227
-
228
- return nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
229
- NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
230
- true, &stats->overlimits);
231
-}
232
-
233
-int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink, unsigned int i,
233
+int nfp_abm_ctrl_read_q_xstats(struct nfp_abm_link *alink,
234
+ unsigned int band, unsigned int queue,
234235 struct nfp_alink_xstats *xstats)
235236 {
236237 int err;
237238
238239 err = nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
239240 NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
240
- i, true, &xstats->pdrop);
241
+ band, queue, true, &xstats->pdrop);
241242 if (err)
242243 return err;
243244
244245 return nfp_abm_ctrl_stat(alink, alink->abm->qm_stats,
245246 NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
246
- i, true, &xstats->ecn_marked);
247
-}
248
-
249
-int nfp_abm_ctrl_read_xstats(struct nfp_abm_link *alink,
250
- struct nfp_alink_xstats *xstats)
251
-{
252
- int err;
253
-
254
- err = nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
255
- NFP_QMSTAT_STRIDE, NFP_QMSTAT_DROP,
256
- true, &xstats->pdrop);
257
- if (err)
258
- return err;
259
-
260
- return nfp_abm_ctrl_stat_all(alink, alink->abm->qm_stats,
261
- NFP_QMSTAT_STRIDE, NFP_QMSTAT_ECN,
262
- true, &xstats->ecn_marked);
247
+ band, queue, true, &xstats->ecn_marked);
263248 }
264249
265250 int nfp_abm_ctrl_qm_enable(struct nfp_abm *abm)
....@@ -274,10 +259,68 @@
274259 NULL, 0, NULL, 0);
275260 }
276261
277
-void nfp_abm_ctrl_read_params(struct nfp_abm_link *alink)
262
+int nfp_abm_ctrl_prio_map_update(struct nfp_abm_link *alink, u32 *packed)
263
+{
264
+ const u32 cmd = NFP_NET_CFG_MBOX_CMD_PCI_DSCP_PRIOMAP_SET;
265
+ struct nfp_net *nn = alink->vnic;
266
+ unsigned int i;
267
+ int err;
268
+
269
+ err = nfp_net_mbox_lock(nn, alink->abm->prio_map_len);
270
+ if (err)
271
+ return err;
272
+
273
+ /* Write data_len and wipe reserved */
274
+ nn_writeq(nn, nn->tlv_caps.mbox_off + NFP_NET_ABM_MBOX_DATALEN,
275
+ alink->abm->prio_map_len);
276
+
277
+ for (i = 0; i < alink->abm->prio_map_len; i += sizeof(u32))
278
+ nn_writel(nn, nn->tlv_caps.mbox_off + NFP_NET_ABM_MBOX_DATA + i,
279
+ packed[i / sizeof(u32)]);
280
+
281
+ err = nfp_net_mbox_reconfig_and_unlock(nn, cmd);
282
+ if (err)
283
+ nfp_err(alink->abm->app->cpp,
284
+ "setting DSCP -> VQ map failed with error %d\n", err);
285
+ return err;
286
+}
287
+
288
+static int nfp_abm_ctrl_prio_check_params(struct nfp_abm_link *alink)
289
+{
290
+ struct nfp_abm *abm = alink->abm;
291
+ struct nfp_net *nn = alink->vnic;
292
+ unsigned int min_mbox_sz;
293
+
294
+ if (!nfp_abm_has_prio(alink->abm))
295
+ return 0;
296
+
297
+ min_mbox_sz = NFP_NET_ABM_MBOX_DATA + alink->abm->prio_map_len;
298
+ if (nn->tlv_caps.mbox_len < min_mbox_sz) {
299
+ nfp_err(abm->app->pf->cpp, "vNIC mailbox too small for prio offload: %u, need: %u\n",
300
+ nn->tlv_caps.mbox_len, min_mbox_sz);
301
+ return -EINVAL;
302
+ }
303
+
304
+ return 0;
305
+}
306
+
307
+int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink)
278308 {
279309 alink->queue_base = nn_readl(alink->vnic, NFP_NET_CFG_START_RXQ);
280310 alink->queue_base /= alink->vnic->stride_rx;
311
+
312
+ return nfp_abm_ctrl_prio_check_params(alink);
313
+}
314
+
315
+static unsigned int nfp_abm_ctrl_prio_map_size(struct nfp_abm *abm)
316
+{
317
+ unsigned int size;
318
+
319
+ size = roundup_pow_of_two(order_base_2(abm->num_bands));
320
+ size = DIV_ROUND_UP(size * abm->num_prios, BITS_PER_BYTE);
321
+ size = round_up(size, sizeof(u32));
322
+
323
+ return size;
281324 }
282325
283326 static const struct nfp_rtsym *
....@@ -290,10 +333,10 @@
290333 nfp_err(pf->cpp, "Symbol '%s' not found\n", name);
291334 return ERR_PTR(-ENOENT);
292335 }
293
- if (sym->size != size) {
336
+ if (nfp_rtsym_size(sym) != size) {
294337 nfp_err(pf->cpp,
295338 "Symbol '%s' wrong size: expected %u got %llu\n",
296
- name, size, sym->size);
339
+ name, size, nfp_rtsym_size(sym));
297340 return ERR_PTR(-EINVAL);
298341 }
299342
....@@ -301,33 +344,86 @@
301344 }
302345
303346 static const struct nfp_rtsym *
304
-nfp_abm_ctrl_find_q_rtsym(struct nfp_pf *pf, const char *name,
305
- unsigned int size)
347
+nfp_abm_ctrl_find_q_rtsym(struct nfp_abm *abm, const char *name_fmt,
348
+ size_t size)
306349 {
307
- return nfp_abm_ctrl_find_rtsym(pf, name, size * NFP_NET_MAX_RX_RINGS);
350
+ char pf_symbol[64];
351
+
352
+ size = array3_size(size, abm->num_bands, NFP_NET_MAX_RX_RINGS);
353
+ snprintf(pf_symbol, sizeof(pf_symbol), name_fmt,
354
+ abm->pf_id, nfp_abm_has_prio(abm) ? "_per_band" : "");
355
+
356
+ return nfp_abm_ctrl_find_rtsym(abm->app->pf, pf_symbol, size);
308357 }
309358
310359 int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm)
311360 {
312361 struct nfp_pf *pf = abm->app->pf;
313362 const struct nfp_rtsym *sym;
314
- unsigned int pf_id;
315
- char pf_symbol[64];
363
+ int res;
316364
317
- pf_id = nfp_cppcore_pcie_unit(pf->cpp);
318
- abm->pf_id = pf_id;
365
+ abm->pf_id = nfp_cppcore_pcie_unit(pf->cpp);
319366
320
- snprintf(pf_symbol, sizeof(pf_symbol), NFP_QLVL_SYM_NAME, pf_id);
321
- sym = nfp_abm_ctrl_find_q_rtsym(pf, pf_symbol, NFP_QLVL_STRIDE);
367
+ /* Check if Qdisc offloads are supported */
368
+ res = nfp_pf_rtsym_read_optional(pf, NFP_RED_SUPPORT_SYM_NAME, 1);
369
+ if (res < 0)
370
+ return res;
371
+ abm->red_support = res;
372
+
373
+ /* Read count of prios and prio bands */
374
+ res = nfp_pf_rtsym_read_optional(pf, NFP_NUM_BANDS_SYM_NAME, 1);
375
+ if (res < 0)
376
+ return res;
377
+ abm->num_bands = res;
378
+
379
+ res = nfp_pf_rtsym_read_optional(pf, NFP_NUM_PRIOS_SYM_NAME, 1);
380
+ if (res < 0)
381
+ return res;
382
+ abm->num_prios = res;
383
+
384
+ /* Read available actions */
385
+ res = nfp_pf_rtsym_read_optional(pf, NFP_ACT_MASK_SYM_NAME,
386
+ BIT(NFP_ABM_ACT_MARK_DROP));
387
+ if (res < 0)
388
+ return res;
389
+ abm->action_mask = res;
390
+
391
+ abm->prio_map_len = nfp_abm_ctrl_prio_map_size(abm);
392
+ abm->dscp_mask = GENMASK(7, 8 - order_base_2(abm->num_prios));
393
+
394
+ /* Check values are sane, U16_MAX is arbitrarily chosen as max */
395
+ if (!is_power_of_2(abm->num_bands) || !is_power_of_2(abm->num_prios) ||
396
+ abm->num_bands > U16_MAX || abm->num_prios > U16_MAX ||
397
+ (abm->num_bands == 1) != (abm->num_prios == 1)) {
398
+ nfp_err(pf->cpp,
399
+ "invalid priomap description num bands: %u and num prios: %u\n",
400
+ abm->num_bands, abm->num_prios);
401
+ return -EINVAL;
402
+ }
403
+
404
+ /* Find level and stat symbols */
405
+ if (!abm->red_support)
406
+ return 0;
407
+
408
+ sym = nfp_abm_ctrl_find_q_rtsym(abm, NFP_QLVL_SYM_NAME,
409
+ NFP_QLVL_STRIDE);
322410 if (IS_ERR(sym))
323411 return PTR_ERR(sym);
324412 abm->q_lvls = sym;
325413
326
- snprintf(pf_symbol, sizeof(pf_symbol), NFP_QMSTAT_SYM_NAME, pf_id);
327
- sym = nfp_abm_ctrl_find_q_rtsym(pf, pf_symbol, NFP_QMSTAT_STRIDE);
414
+ sym = nfp_abm_ctrl_find_q_rtsym(abm, NFP_QMSTAT_SYM_NAME,
415
+ NFP_QMSTAT_STRIDE);
328416 if (IS_ERR(sym))
329417 return PTR_ERR(sym);
330418 abm->qm_stats = sym;
331419
420
+ if (nfp_abm_has_prio(abm)) {
421
+ sym = nfp_abm_ctrl_find_q_rtsym(abm, NFP_Q_STAT_SYM_NAME,
422
+ NFP_Q_STAT_STRIDE);
423
+ if (IS_ERR(sym))
424
+ return PTR_ERR(sym);
425
+ abm->q_stats = sym;
426
+ }
427
+
332428 return 0;
333429 }