forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/net/ethernet/netronome/nfp/abm/main.c
....@@ -1,46 +1,14 @@
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
354 #include <linux/bitfield.h>
5
+#include <linux/bitmap.h>
366 #include <linux/etherdevice.h>
377 #include <linux/lockdep.h>
388 #include <linux/netdevice.h>
399 #include <linux/rcupdate.h>
10
+#include <linux/rtnetlink.h>
4011 #include <linux/slab.h>
41
-#include <net/pkt_cls.h>
42
-#include <net/pkt_sched.h>
43
-#include <net/red.h>
4412
4513 #include "../nfpcore/nfp.h"
4614 #include "../nfpcore/nfp_cpp.h"
....@@ -59,269 +27,6 @@
5927 }
6028
6129 static int
62
-__nfp_abm_reset_root(struct net_device *netdev, struct nfp_abm_link *alink,
63
- u32 handle, unsigned int qs, u32 init_val)
64
-{
65
- struct nfp_port *port = nfp_port_from_netdev(netdev);
66
- int ret;
67
-
68
- ret = nfp_abm_ctrl_set_all_q_lvls(alink, init_val);
69
- memset(alink->qdiscs, 0, sizeof(*alink->qdiscs) * alink->num_qdiscs);
70
-
71
- alink->parent = handle;
72
- alink->num_qdiscs = qs;
73
- port->tc_offload_cnt = qs;
74
-
75
- return ret;
76
-}
77
-
78
-static void
79
-nfp_abm_reset_root(struct net_device *netdev, struct nfp_abm_link *alink,
80
- u32 handle, unsigned int qs)
81
-{
82
- __nfp_abm_reset_root(netdev, alink, handle, qs, ~0);
83
-}
84
-
85
-static int
86
-nfp_abm_red_find(struct nfp_abm_link *alink, struct tc_red_qopt_offload *opt)
87
-{
88
- unsigned int i = TC_H_MIN(opt->parent) - 1;
89
-
90
- if (opt->parent == TC_H_ROOT)
91
- i = 0;
92
- else if (TC_H_MAJ(alink->parent) == TC_H_MAJ(opt->parent))
93
- i = TC_H_MIN(opt->parent) - 1;
94
- else
95
- return -EOPNOTSUPP;
96
-
97
- if (i >= alink->num_qdiscs || opt->handle != alink->qdiscs[i].handle)
98
- return -EOPNOTSUPP;
99
-
100
- return i;
101
-}
102
-
103
-static void
104
-nfp_abm_red_destroy(struct net_device *netdev, struct nfp_abm_link *alink,
105
- u32 handle)
106
-{
107
- unsigned int i;
108
-
109
- for (i = 0; i < alink->num_qdiscs; i++)
110
- if (handle == alink->qdiscs[i].handle)
111
- break;
112
- if (i == alink->num_qdiscs)
113
- return;
114
-
115
- if (alink->parent == TC_H_ROOT) {
116
- nfp_abm_reset_root(netdev, alink, TC_H_ROOT, 0);
117
- } else {
118
- nfp_abm_ctrl_set_q_lvl(alink, i, ~0);
119
- memset(&alink->qdiscs[i], 0, sizeof(*alink->qdiscs));
120
- }
121
-}
122
-
123
-static int
124
-nfp_abm_red_replace(struct net_device *netdev, struct nfp_abm_link *alink,
125
- struct tc_red_qopt_offload *opt)
126
-{
127
- bool existing;
128
- int i, err;
129
-
130
- i = nfp_abm_red_find(alink, opt);
131
- existing = i >= 0;
132
-
133
- if (opt->set.min != opt->set.max || !opt->set.is_ecn) {
134
- nfp_warn(alink->abm->app->cpp,
135
- "RED offload failed - unsupported parameters\n");
136
- err = -EINVAL;
137
- goto err_destroy;
138
- }
139
-
140
- if (existing) {
141
- if (alink->parent == TC_H_ROOT)
142
- err = nfp_abm_ctrl_set_all_q_lvls(alink, opt->set.min);
143
- else
144
- err = nfp_abm_ctrl_set_q_lvl(alink, i, opt->set.min);
145
- if (err)
146
- goto err_destroy;
147
- return 0;
148
- }
149
-
150
- if (opt->parent == TC_H_ROOT) {
151
- i = 0;
152
- err = __nfp_abm_reset_root(netdev, alink, TC_H_ROOT, 1,
153
- opt->set.min);
154
- } else if (TC_H_MAJ(alink->parent) == TC_H_MAJ(opt->parent)) {
155
- i = TC_H_MIN(opt->parent) - 1;
156
- err = nfp_abm_ctrl_set_q_lvl(alink, i, opt->set.min);
157
- } else {
158
- return -EINVAL;
159
- }
160
- /* Set the handle to try full clean up, in case IO failed */
161
- alink->qdiscs[i].handle = opt->handle;
162
- if (err)
163
- goto err_destroy;
164
-
165
- if (opt->parent == TC_H_ROOT)
166
- err = nfp_abm_ctrl_read_stats(alink, &alink->qdiscs[i].stats);
167
- else
168
- err = nfp_abm_ctrl_read_q_stats(alink, i,
169
- &alink->qdiscs[i].stats);
170
- if (err)
171
- goto err_destroy;
172
-
173
- if (opt->parent == TC_H_ROOT)
174
- err = nfp_abm_ctrl_read_xstats(alink,
175
- &alink->qdiscs[i].xstats);
176
- else
177
- err = nfp_abm_ctrl_read_q_xstats(alink, i,
178
- &alink->qdiscs[i].xstats);
179
- if (err)
180
- goto err_destroy;
181
-
182
- alink->qdiscs[i].stats.backlog_pkts = 0;
183
- alink->qdiscs[i].stats.backlog_bytes = 0;
184
-
185
- return 0;
186
-err_destroy:
187
- /* If the qdisc keeps on living, but we can't offload undo changes */
188
- if (existing) {
189
- opt->set.qstats->qlen -= alink->qdiscs[i].stats.backlog_pkts;
190
- opt->set.qstats->backlog -=
191
- alink->qdiscs[i].stats.backlog_bytes;
192
- }
193
- nfp_abm_red_destroy(netdev, alink, opt->handle);
194
-
195
- return err;
196
-}
197
-
198
-static void
199
-nfp_abm_update_stats(struct nfp_alink_stats *new, struct nfp_alink_stats *old,
200
- struct tc_qopt_offload_stats *stats)
201
-{
202
- _bstats_update(stats->bstats, new->tx_bytes - old->tx_bytes,
203
- new->tx_pkts - old->tx_pkts);
204
- stats->qstats->qlen += new->backlog_pkts - old->backlog_pkts;
205
- stats->qstats->backlog += new->backlog_bytes - old->backlog_bytes;
206
- stats->qstats->overlimits += new->overlimits - old->overlimits;
207
- stats->qstats->drops += new->drops - old->drops;
208
-}
209
-
210
-static int
211
-nfp_abm_red_stats(struct nfp_abm_link *alink, struct tc_red_qopt_offload *opt)
212
-{
213
- struct nfp_alink_stats *prev_stats;
214
- struct nfp_alink_stats stats;
215
- int i, err;
216
-
217
- i = nfp_abm_red_find(alink, opt);
218
- if (i < 0)
219
- return i;
220
- prev_stats = &alink->qdiscs[i].stats;
221
-
222
- if (alink->parent == TC_H_ROOT)
223
- err = nfp_abm_ctrl_read_stats(alink, &stats);
224
- else
225
- err = nfp_abm_ctrl_read_q_stats(alink, i, &stats);
226
- if (err)
227
- return err;
228
-
229
- nfp_abm_update_stats(&stats, prev_stats, &opt->stats);
230
-
231
- *prev_stats = stats;
232
-
233
- return 0;
234
-}
235
-
236
-static int
237
-nfp_abm_red_xstats(struct nfp_abm_link *alink, struct tc_red_qopt_offload *opt)
238
-{
239
- struct nfp_alink_xstats *prev_xstats;
240
- struct nfp_alink_xstats xstats;
241
- int i, err;
242
-
243
- i = nfp_abm_red_find(alink, opt);
244
- if (i < 0)
245
- return i;
246
- prev_xstats = &alink->qdiscs[i].xstats;
247
-
248
- if (alink->parent == TC_H_ROOT)
249
- err = nfp_abm_ctrl_read_xstats(alink, &xstats);
250
- else
251
- err = nfp_abm_ctrl_read_q_xstats(alink, i, &xstats);
252
- if (err)
253
- return err;
254
-
255
- opt->xstats->forced_mark += xstats.ecn_marked - prev_xstats->ecn_marked;
256
- opt->xstats->pdrop += xstats.pdrop - prev_xstats->pdrop;
257
-
258
- *prev_xstats = xstats;
259
-
260
- return 0;
261
-}
262
-
263
-static int
264
-nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink,
265
- struct tc_red_qopt_offload *opt)
266
-{
267
- switch (opt->command) {
268
- case TC_RED_REPLACE:
269
- return nfp_abm_red_replace(netdev, alink, opt);
270
- case TC_RED_DESTROY:
271
- nfp_abm_red_destroy(netdev, alink, opt->handle);
272
- return 0;
273
- case TC_RED_STATS:
274
- return nfp_abm_red_stats(alink, opt);
275
- case TC_RED_XSTATS:
276
- return nfp_abm_red_xstats(alink, opt);
277
- default:
278
- return -EOPNOTSUPP;
279
- }
280
-}
281
-
282
-static int
283
-nfp_abm_mq_stats(struct nfp_abm_link *alink, struct tc_mq_qopt_offload *opt)
284
-{
285
- struct nfp_alink_stats stats;
286
- unsigned int i;
287
- int err;
288
-
289
- for (i = 0; i < alink->num_qdiscs; i++) {
290
- if (alink->qdiscs[i].handle == TC_H_UNSPEC)
291
- continue;
292
-
293
- err = nfp_abm_ctrl_read_q_stats(alink, i, &stats);
294
- if (err)
295
- return err;
296
-
297
- nfp_abm_update_stats(&stats, &alink->qdiscs[i].stats,
298
- &opt->stats);
299
- }
300
-
301
- return 0;
302
-}
303
-
304
-static int
305
-nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
306
- struct tc_mq_qopt_offload *opt)
307
-{
308
- switch (opt->command) {
309
- case TC_MQ_CREATE:
310
- nfp_abm_reset_root(netdev, alink, opt->handle,
311
- alink->total_queues);
312
- return 0;
313
- case TC_MQ_DESTROY:
314
- if (opt->handle == alink->parent)
315
- nfp_abm_reset_root(netdev, alink, TC_H_ROOT, 0);
316
- return 0;
317
- case TC_MQ_STATS:
318
- return nfp_abm_mq_stats(alink, opt);
319
- default:
320
- return -EOPNOTSUPP;
321
- }
322
-}
323
-
324
-static int
32530 nfp_abm_setup_tc(struct nfp_app *app, struct net_device *netdev,
32631 enum tc_setup_type type, void *type_data)
32732 {
....@@ -333,16 +38,23 @@
33338 return -EOPNOTSUPP;
33439
33540 switch (type) {
41
+ case TC_SETUP_ROOT_QDISC:
42
+ return nfp_abm_setup_root(netdev, repr->app_priv, type_data);
33643 case TC_SETUP_QDISC_MQ:
33744 return nfp_abm_setup_tc_mq(netdev, repr->app_priv, type_data);
33845 case TC_SETUP_QDISC_RED:
33946 return nfp_abm_setup_tc_red(netdev, repr->app_priv, type_data);
47
+ case TC_SETUP_QDISC_GRED:
48
+ return nfp_abm_setup_tc_gred(netdev, repr->app_priv, type_data);
49
+ case TC_SETUP_BLOCK:
50
+ return nfp_abm_setup_cls_block(netdev, repr, type_data);
34051 default:
34152 return -EOPNOTSUPP;
34253 }
34354 }
34455
345
-static struct net_device *nfp_abm_repr_get(struct nfp_app *app, u32 port_id)
56
+static struct net_device *
57
+nfp_abm_repr_get(struct nfp_app *app, u32 port_id, bool *redir_egress)
34658 {
34759 enum nfp_repr_type rtype;
34860 struct nfp_reprs *reprs;
....@@ -415,7 +127,9 @@
415127
416128 reprs = nfp_reprs_get_locked(app, rtype);
417129 WARN(nfp_repr_get_locked(app, reprs, alink->id), "duplicate repr");
130
+ rtnl_lock();
418131 rcu_assign_pointer(reprs->reprs[alink->id], netdev);
132
+ rtnl_unlock();
419133
420134 nfp_info(app->cpp, "%s Port %d Representor(%s) created\n",
421135 ptype == NFP_PORT_PF_PORT ? "PCIe" : "Phys",
....@@ -441,7 +155,9 @@
441155 netdev = nfp_repr_get_locked(app, reprs, alink->id);
442156 if (!netdev)
443157 return;
158
+ rtnl_lock();
444159 rcu_assign_pointer(reprs->reprs[alink->id], NULL);
160
+ rtnl_unlock();
445161 synchronize_rcu();
446162 /* Cast to make sure nfp_repr_clean_and_free() takes a nfp_repr */
447163 nfp_repr_clean_and_free((struct nfp_repr *)netdev_priv(netdev));
....@@ -492,6 +208,9 @@
492208 struct nfp_net *nn;
493209 int err;
494210
211
+ if (!abm->red_support)
212
+ return -EOPNOTSUPP;
213
+
495214 err = nfp_abm_ctrl_qm_enable(abm);
496215 if (err)
497216 return err;
....@@ -540,8 +259,9 @@
540259 {
541260 struct nfp_eth_table_port *eth_port = &pf->eth_tbl->ports[id];
542261 u8 mac_addr[ETH_ALEN];
543
- const char *mac_str;
544
- char name[32];
262
+ struct nfp_nsp *nsp;
263
+ char hwinfo[32];
264
+ int err;
545265
546266 if (id > pf->eth_tbl->count) {
547267 nfp_warn(pf->cpp, "No entry for persistent MAC address\n");
....@@ -549,22 +269,38 @@
549269 return;
550270 }
551271
552
- snprintf(name, sizeof(name), "eth%u.mac.pf%u",
272
+ snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac.pf%u",
553273 eth_port->eth_index, abm->pf_id);
554274
555
- mac_str = nfp_hwinfo_lookup(pf->hwinfo, name);
556
- if (!mac_str) {
557
- nfp_warn(pf->cpp, "Can't lookup persistent MAC address (%s)\n",
558
- name);
275
+ nsp = nfp_nsp_open(pf->cpp);
276
+ if (IS_ERR(nsp)) {
277
+ nfp_warn(pf->cpp, "Failed to access the NSP for persistent MAC address: %ld\n",
278
+ PTR_ERR(nsp));
559279 eth_hw_addr_random(nn->dp.netdev);
560280 return;
561281 }
562282
563
- if (sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
283
+ if (!nfp_nsp_has_hwinfo_lookup(nsp)) {
284
+ nfp_warn(pf->cpp, "NSP doesn't support PF MAC generation\n");
285
+ eth_hw_addr_random(nn->dp.netdev);
286
+ nfp_nsp_close(nsp);
287
+ return;
288
+ }
289
+
290
+ err = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
291
+ nfp_nsp_close(nsp);
292
+ if (err) {
293
+ nfp_warn(pf->cpp, "Reading persistent MAC address failed: %d\n",
294
+ err);
295
+ eth_hw_addr_random(nn->dp.netdev);
296
+ return;
297
+ }
298
+
299
+ if (sscanf(hwinfo, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
564300 &mac_addr[0], &mac_addr[1], &mac_addr[2],
565301 &mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
566302 nfp_warn(pf->cpp, "Can't parse persistent MAC address (%s)\n",
567
- mac_str);
303
+ hwinfo);
568304 eth_hw_addr_random(nn->dp.netdev);
569305 return;
570306 }
....@@ -588,11 +324,16 @@
588324 alink->abm = abm;
589325 alink->vnic = nn;
590326 alink->id = id;
591
- alink->parent = TC_H_ROOT;
592327 alink->total_queues = alink->vnic->max_rx_rings;
593
- alink->qdiscs = kvcalloc(alink->total_queues, sizeof(*alink->qdiscs),
594
- GFP_KERNEL);
595
- if (!alink->qdiscs) {
328
+
329
+ INIT_LIST_HEAD(&alink->dscp_map);
330
+
331
+ err = nfp_abm_ctrl_read_params(alink);
332
+ if (err)
333
+ goto err_free_alink;
334
+
335
+ alink->prio_map = kzalloc(abm->prio_map_len, GFP_KERNEL);
336
+ if (!alink->prio_map) {
596337 err = -ENOMEM;
597338 goto err_free_alink;
598339 }
....@@ -602,17 +343,17 @@
602343 */
603344 err = nfp_eth_set_configured(app->cpp, eth_port->index, true);
604345 if (err < 0)
605
- goto err_free_qdiscs;
346
+ goto err_free_priomap;
606347
607348 netif_keep_dst(nn->dp.netdev);
608349
609350 nfp_abm_vnic_set_mac(app->pf, abm, nn, id);
610
- nfp_abm_ctrl_read_params(alink);
351
+ INIT_RADIX_TREE(&alink->qdiscs, GFP_KERNEL);
611352
612353 return 0;
613354
614
-err_free_qdiscs:
615
- kvfree(alink->qdiscs);
355
+err_free_priomap:
356
+ kfree(alink->prio_map);
616357 err_free_alink:
617358 kfree(alink);
618359 return err;
....@@ -623,8 +364,18 @@
623364 struct nfp_abm_link *alink = nn->app_priv;
624365
625366 nfp_abm_kill_reprs(alink->abm, alink);
626
- kvfree(alink->qdiscs);
367
+ WARN(!radix_tree_empty(&alink->qdiscs), "left over qdiscs\n");
368
+ kfree(alink->prio_map);
627369 kfree(alink);
370
+}
371
+
372
+static int nfp_abm_vnic_init(struct nfp_app *app, struct nfp_net *nn)
373
+{
374
+ struct nfp_abm_link *alink = nn->app_priv;
375
+
376
+ if (nfp_abm_has_prio(alink->abm))
377
+ return nfp_abm_ctrl_prio_map_update(alink, alink->prio_map);
378
+ return 0;
628379 }
629380
630381 static u64 *
....@@ -674,6 +425,21 @@
674425 return data;
675426 }
676427
428
+static int nfp_abm_fw_init_reset(struct nfp_abm *abm)
429
+{
430
+ unsigned int i;
431
+
432
+ if (!abm->red_support)
433
+ return 0;
434
+
435
+ for (i = 0; i < abm->num_bands * NFP_NET_MAX_RX_RINGS; i++) {
436
+ __nfp_abm_ctrl_set_q_lvl(abm, i, NFP_ABM_LVL_INFINITY);
437
+ __nfp_abm_ctrl_set_q_act(abm, i, NFP_ABM_ACT_DROP);
438
+ }
439
+
440
+ return nfp_abm_ctrl_qm_disable(abm);
441
+}
442
+
677443 static int nfp_abm_init(struct nfp_app *app)
678444 {
679445 struct nfp_pf *pf = app->pf;
....@@ -705,15 +471,31 @@
705471 if (err)
706472 goto err_free_abm;
707473
708
- /* We start in legacy mode, make sure advanced queuing is disabled */
709
- err = nfp_abm_ctrl_qm_disable(abm);
710
- if (err)
474
+ err = -ENOMEM;
475
+ abm->num_thresholds = array_size(abm->num_bands, NFP_NET_MAX_RX_RINGS);
476
+ abm->threshold_undef = bitmap_zalloc(abm->num_thresholds, GFP_KERNEL);
477
+ if (!abm->threshold_undef)
711478 goto err_free_abm;
479
+
480
+ abm->thresholds = kvcalloc(abm->num_thresholds,
481
+ sizeof(*abm->thresholds), GFP_KERNEL);
482
+ if (!abm->thresholds)
483
+ goto err_free_thresh_umap;
484
+
485
+ abm->actions = kvcalloc(abm->num_thresholds, sizeof(*abm->actions),
486
+ GFP_KERNEL);
487
+ if (!abm->actions)
488
+ goto err_free_thresh;
489
+
490
+ /* We start in legacy mode, make sure advanced queuing is disabled */
491
+ err = nfp_abm_fw_init_reset(abm);
492
+ if (err)
493
+ goto err_free_act;
712494
713495 err = -ENOMEM;
714496 reprs = nfp_reprs_alloc(pf->max_data_vnics);
715497 if (!reprs)
716
- goto err_free_abm;
498
+ goto err_free_act;
717499 RCU_INIT_POINTER(app->reprs[NFP_REPR_TYPE_PHYS_PORT], reprs);
718500
719501 reprs = nfp_reprs_alloc(pf->max_data_vnics);
....@@ -725,6 +507,12 @@
725507
726508 err_free_phys:
727509 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
510
+err_free_act:
511
+ kvfree(abm->actions);
512
+err_free_thresh:
513
+ kvfree(abm->thresholds);
514
+err_free_thresh_umap:
515
+ bitmap_free(abm->threshold_undef);
728516 err_free_abm:
729517 kfree(abm);
730518 app->priv = NULL;
....@@ -738,6 +526,9 @@
738526 nfp_abm_eswitch_clean_up(abm);
739527 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
740528 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
529
+ bitmap_free(abm->threshold_undef);
530
+ kvfree(abm->actions);
531
+ kvfree(abm->thresholds);
741532 kfree(abm);
742533 app->priv = NULL;
743534 }
....@@ -751,6 +542,7 @@
751542
752543 .vnic_alloc = nfp_abm_vnic_alloc,
753544 .vnic_free = nfp_abm_vnic_free,
545
+ .vnic_init = nfp_abm_vnic_init,
754546
755547 .port_get_stats = nfp_abm_port_get_stats,
756548 .port_get_stats_count = nfp_abm_port_get_stats_count,
....@@ -761,5 +553,5 @@
761553 .eswitch_mode_get = nfp_abm_eswitch_mode_get,
762554 .eswitch_mode_set = nfp_abm_eswitch_mode_set,
763555
764
- .repr_get = nfp_abm_repr_get,
556
+ .dev_get = nfp_abm_repr_get,
765557 };