hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
....@@ -1,39 +1,10 @@
1
-/*
2
- * Copyright (C) 2017 Netronome Systems, Inc.
3
- *
4
- * This software is dual licensed under the GNU General License Version 2,
5
- * June 1991 as shown in the file COPYING in the top-level directory of this
6
- * source tree or the BSD 2-Clause License provided below. You have the
7
- * option to license this software under the complete terms of either license.
8
- *
9
- * The BSD 2-Clause License:
10
- *
11
- * Redistribution and use in source and binary forms, with or
12
- * without modification, are permitted provided that the following
13
- * conditions are met:
14
- *
15
- * 1. Redistributions of source code must retain the above
16
- * copyright notice, this list of conditions and the following
17
- * disclaimer.
18
- *
19
- * 2. Redistributions in binary form must reproduce the above
20
- * copyright notice, this list of conditions and the following
21
- * disclaimer in the documentation and/or other materials
22
- * provided with the distribution.
23
- *
24
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- * SOFTWARE.
32
- */
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #include <linux/rtnetlink.h>
355 #include <net/devlink.h>
366
7
+#include "nfpcore/nfp.h"
378 #include "nfpcore/nfp_nsp.h"
389 #include "nfp_app.h"
3910 #include "nfp_main.h"
....@@ -99,9 +70,6 @@
9970 unsigned int lanes;
10071 int ret;
10172
102
- if (count < 2)
103
- return -EINVAL;
104
-
10573 mutex_lock(&pf->lock);
10674
10775 rtnl_lock();
....@@ -110,7 +78,7 @@
11078 if (ret)
11179 goto out;
11280
113
- if (eth_port.is_split || eth_port.port_lanes % count) {
81
+ if (eth_port.port_lanes % count) {
11482 ret = -EINVAL;
11583 goto out;
11684 }
....@@ -173,7 +141,8 @@
173141 static int
174142 nfp_devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
175143 u16 pool_index,
176
- u32 size, enum devlink_sb_threshold_type threshold_type)
144
+ u32 size, enum devlink_sb_threshold_type threshold_type,
145
+ struct netlink_ext_ack *extack)
177146 {
178147 struct nfp_pf *pf = devlink_priv(devlink);
179148
....@@ -188,7 +157,8 @@
188157 return nfp_app_eswitch_mode_get(pf->app, mode);
189158 }
190159
191
-static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode)
160
+static int nfp_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
161
+ struct netlink_ext_ack *extack)
192162 {
193163 struct nfp_pf *pf = devlink_priv(devlink);
194164 int ret;
....@@ -200,6 +170,172 @@
200170 return ret;
201171 }
202172
173
+static const struct nfp_devlink_versions_simple {
174
+ const char *key;
175
+ const char *hwinfo;
176
+} nfp_devlink_versions_hwinfo[] = {
177
+ { DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, "assembly.partno", },
178
+ { DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, "assembly.revision", },
179
+ { DEVLINK_INFO_VERSION_GENERIC_BOARD_MANUFACTURE, "assembly.vendor", },
180
+ { "board.model", /* code name */ "assembly.model", },
181
+};
182
+
183
+static int
184
+nfp_devlink_versions_get_hwinfo(struct nfp_pf *pf, struct devlink_info_req *req)
185
+{
186
+ unsigned int i;
187
+ int err;
188
+
189
+ for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_hwinfo); i++) {
190
+ const struct nfp_devlink_versions_simple *info;
191
+ const char *val;
192
+
193
+ info = &nfp_devlink_versions_hwinfo[i];
194
+
195
+ val = nfp_hwinfo_lookup(pf->hwinfo, info->hwinfo);
196
+ if (!val)
197
+ continue;
198
+
199
+ err = devlink_info_version_fixed_put(req, info->key, val);
200
+ if (err)
201
+ return err;
202
+ }
203
+
204
+ return 0;
205
+}
206
+
207
+static const struct nfp_devlink_versions {
208
+ enum nfp_nsp_versions id;
209
+ const char *key;
210
+} nfp_devlink_versions_nsp[] = {
211
+ { NFP_VERSIONS_BUNDLE, DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, },
212
+ { NFP_VERSIONS_BSP, DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, },
213
+ { NFP_VERSIONS_CPLD, "fw.cpld", },
214
+ { NFP_VERSIONS_APP, DEVLINK_INFO_VERSION_GENERIC_FW_APP, },
215
+ { NFP_VERSIONS_UNDI, DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, },
216
+ { NFP_VERSIONS_NCSI, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, },
217
+ { NFP_VERSIONS_CFGR, "chip.init", },
218
+};
219
+
220
+static int
221
+nfp_devlink_versions_get_nsp(struct devlink_info_req *req, bool flash,
222
+ const u8 *buf, unsigned int size)
223
+{
224
+ unsigned int i;
225
+ int err;
226
+
227
+ for (i = 0; i < ARRAY_SIZE(nfp_devlink_versions_nsp); i++) {
228
+ const struct nfp_devlink_versions *info;
229
+ const char *version;
230
+
231
+ info = &nfp_devlink_versions_nsp[i];
232
+
233
+ version = nfp_nsp_versions_get(info->id, flash, buf, size);
234
+ if (IS_ERR(version)) {
235
+ if (PTR_ERR(version) == -ENOENT)
236
+ continue;
237
+ else
238
+ return PTR_ERR(version);
239
+ }
240
+
241
+ if (flash)
242
+ err = devlink_info_version_stored_put(req, info->key,
243
+ version);
244
+ else
245
+ err = devlink_info_version_running_put(req, info->key,
246
+ version);
247
+ if (err)
248
+ return err;
249
+ }
250
+
251
+ return 0;
252
+}
253
+
254
+static int
255
+nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
256
+ struct netlink_ext_ack *extack)
257
+{
258
+ struct nfp_pf *pf = devlink_priv(devlink);
259
+ const char *sn, *vendor, *part;
260
+ struct nfp_nsp *nsp;
261
+ char *buf = NULL;
262
+ int err;
263
+
264
+ err = devlink_info_driver_name_put(req, "nfp");
265
+ if (err)
266
+ return err;
267
+
268
+ vendor = nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor");
269
+ part = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno");
270
+ sn = nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial");
271
+ if (vendor && part && sn) {
272
+ char *buf;
273
+
274
+ buf = kmalloc(strlen(vendor) + strlen(part) + strlen(sn) + 1,
275
+ GFP_KERNEL);
276
+ if (!buf)
277
+ return -ENOMEM;
278
+
279
+ buf[0] = '\0';
280
+ strcat(buf, vendor);
281
+ strcat(buf, part);
282
+ strcat(buf, sn);
283
+
284
+ err = devlink_info_serial_number_put(req, buf);
285
+ kfree(buf);
286
+ if (err)
287
+ return err;
288
+ }
289
+
290
+ nsp = nfp_nsp_open(pf->cpp);
291
+ if (IS_ERR(nsp)) {
292
+ NL_SET_ERR_MSG_MOD(extack, "can't access NSP");
293
+ return PTR_ERR(nsp);
294
+ }
295
+
296
+ if (nfp_nsp_has_versions(nsp)) {
297
+ buf = kzalloc(NFP_NSP_VERSION_BUFSZ, GFP_KERNEL);
298
+ if (!buf) {
299
+ err = -ENOMEM;
300
+ goto err_close_nsp;
301
+ }
302
+
303
+ err = nfp_nsp_versions(nsp, buf, NFP_NSP_VERSION_BUFSZ);
304
+ if (err)
305
+ goto err_free_buf;
306
+
307
+ err = nfp_devlink_versions_get_nsp(req, false,
308
+ buf, NFP_NSP_VERSION_BUFSZ);
309
+ if (err)
310
+ goto err_free_buf;
311
+
312
+ err = nfp_devlink_versions_get_nsp(req, true,
313
+ buf, NFP_NSP_VERSION_BUFSZ);
314
+ if (err)
315
+ goto err_free_buf;
316
+
317
+ kfree(buf);
318
+ }
319
+
320
+ nfp_nsp_close(nsp);
321
+
322
+ return nfp_devlink_versions_get_hwinfo(pf, req);
323
+
324
+err_free_buf:
325
+ kfree(buf);
326
+err_close_nsp:
327
+ nfp_nsp_close(nsp);
328
+ return err;
329
+}
330
+
331
+static int
332
+nfp_devlink_flash_update(struct devlink *devlink,
333
+ struct devlink_flash_update_params *params,
334
+ struct netlink_ext_ack *extack)
335
+{
336
+ return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack);
337
+}
338
+
203339 const struct devlink_ops nfp_devlink_ops = {
204340 .port_split = nfp_devlink_port_split,
205341 .port_unsplit = nfp_devlink_port_unsplit,
....@@ -207,12 +343,17 @@
207343 .sb_pool_set = nfp_devlink_sb_pool_set,
208344 .eswitch_mode_get = nfp_devlink_eswitch_mode_get,
209345 .eswitch_mode_set = nfp_devlink_eswitch_mode_set,
346
+ .info_get = nfp_devlink_info_get,
347
+ .flash_update = nfp_devlink_flash_update,
210348 };
211349
212350 int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
213351 {
352
+ struct devlink_port_attrs attrs = {};
214353 struct nfp_eth_table_port eth_port;
215354 struct devlink *devlink;
355
+ const u8 *serial;
356
+ int serial_len;
216357 int ret;
217358
218359 rtnl_lock();
....@@ -221,10 +362,16 @@
221362 if (ret)
222363 return ret;
223364
224
- devlink_port_type_eth_set(&port->dl_port, port->netdev);
225
- devlink_port_attrs_set(&port->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
226
- eth_port.label_port, eth_port.is_split,
227
- eth_port.label_subport);
365
+ attrs.split = eth_port.is_split;
366
+ attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
367
+ attrs.lanes = eth_port.port_lanes;
368
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
369
+ attrs.phys.port_number = eth_port.label_port;
370
+ attrs.phys.split_subport_number = eth_port.label_subport;
371
+ serial_len = nfp_cpp_serial(port->app->cpp, &serial);
372
+ memcpy(attrs.switch_id.id, serial, serial_len);
373
+ attrs.switch_id.id_len = serial_len;
374
+ devlink_port_attrs_set(&port->dl_port, &attrs);
228375
229376 devlink = priv_to_devlink(app->pf);
230377
....@@ -235,3 +382,24 @@
235382 {
236383 devlink_port_unregister(&port->dl_port);
237384 }
385
+
386
+void nfp_devlink_port_type_eth_set(struct nfp_port *port)
387
+{
388
+ devlink_port_type_eth_set(&port->dl_port, port->netdev);
389
+}
390
+
391
+void nfp_devlink_port_type_clear(struct nfp_port *port)
392
+{
393
+ devlink_port_type_clear(&port->dl_port);
394
+}
395
+
396
+struct devlink_port *nfp_devlink_get_devlink_port(struct net_device *netdev)
397
+{
398
+ struct nfp_port *port;
399
+
400
+ port = nfp_port_from_netdev(netdev);
401
+ if (!port)
402
+ return NULL;
403
+
404
+ return &port->dl_port;
405
+}