New upstream version 18.08
[deb_dpdk.git] / drivers / net / nfp / nfpcore / nfp_nsp_eth.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Netronome Systems, Inc.
3  * All rights reserved.
4  */
5
6 #include <stdio.h>
7 #include <rte_common.h>
8 #include <rte_byteorder.h>
9 #include "nfp_cpp.h"
10 #include "nfp_nsp.h"
11 #include "nfp6000/nfp6000.h"
12
13 #define GENMASK_ULL(h, l) \
14         (((~0ULL) - (1ULL << (l)) + 1) & \
15          (~0ULL >> (64 - 1 - (h))))
16
17 #define __bf_shf(x) (__builtin_ffsll(x) - 1)
18
19 #define FIELD_GET(_mask, _reg)                                          \
20         (__extension__ ({ \
21                 typeof(_mask) _x = (_mask); \
22                 (typeof(_x))(((_reg) & (_x)) >> __bf_shf(_x));  \
23         }))
24
25 #define FIELD_FIT(_mask, _val)                                          \
26         (__extension__ ({ \
27                 typeof(_mask) _x = (_mask); \
28                 !((((typeof(_x))_val) << __bf_shf(_x)) & ~(_x)); \
29         }))
30
31 #define FIELD_PREP(_mask, _val)                                         \
32         (__extension__ ({ \
33                 typeof(_mask) _x = (_mask); \
34                 ((typeof(_x))(_val) << __bf_shf(_x)) & (_x);    \
35         }))
36
37 #define NSP_ETH_NBI_PORT_COUNT          24
38 #define NSP_ETH_MAX_COUNT               (2 * NSP_ETH_NBI_PORT_COUNT)
39 #define NSP_ETH_TABLE_SIZE              (NSP_ETH_MAX_COUNT *            \
40                                          sizeof(union eth_table_entry))
41
42 #define NSP_ETH_PORT_LANES              GENMASK_ULL(3, 0)
43 #define NSP_ETH_PORT_INDEX              GENMASK_ULL(15, 8)
44 #define NSP_ETH_PORT_LABEL              GENMASK_ULL(53, 48)
45 #define NSP_ETH_PORT_PHYLABEL           GENMASK_ULL(59, 54)
46 #define NSP_ETH_PORT_FEC_SUPP_BASER     BIT_ULL(60)
47 #define NSP_ETH_PORT_FEC_SUPP_RS        BIT_ULL(61)
48
49 #define NSP_ETH_PORT_LANES_MASK         rte_cpu_to_le_64(NSP_ETH_PORT_LANES)
50
51 #define NSP_ETH_STATE_CONFIGURED        BIT_ULL(0)
52 #define NSP_ETH_STATE_ENABLED           BIT_ULL(1)
53 #define NSP_ETH_STATE_TX_ENABLED        BIT_ULL(2)
54 #define NSP_ETH_STATE_RX_ENABLED        BIT_ULL(3)
55 #define NSP_ETH_STATE_RATE              GENMASK_ULL(11, 8)
56 #define NSP_ETH_STATE_INTERFACE         GENMASK_ULL(19, 12)
57 #define NSP_ETH_STATE_MEDIA             GENMASK_ULL(21, 20)
58 #define NSP_ETH_STATE_OVRD_CHNG         BIT_ULL(22)
59 #define NSP_ETH_STATE_ANEG              GENMASK_ULL(25, 23)
60 #define NSP_ETH_STATE_FEC               GENMASK_ULL(27, 26)
61
62 #define NSP_ETH_CTRL_CONFIGURED         BIT_ULL(0)
63 #define NSP_ETH_CTRL_ENABLED            BIT_ULL(1)
64 #define NSP_ETH_CTRL_TX_ENABLED         BIT_ULL(2)
65 #define NSP_ETH_CTRL_RX_ENABLED         BIT_ULL(3)
66 #define NSP_ETH_CTRL_SET_RATE           BIT_ULL(4)
67 #define NSP_ETH_CTRL_SET_LANES          BIT_ULL(5)
68 #define NSP_ETH_CTRL_SET_ANEG           BIT_ULL(6)
69 #define NSP_ETH_CTRL_SET_FEC            BIT_ULL(7)
70
71 /* Which connector port. */
72 #define PORT_TP                 0x00
73 #define PORT_AUI                0x01
74 #define PORT_MII                0x02
75 #define PORT_FIBRE              0x03
76 #define PORT_BNC                0x04
77 #define PORT_DA                 0x05
78 #define PORT_NONE               0xef
79 #define PORT_OTHER              0xff
80
81 #define SPEED_10                10
82 #define SPEED_100               100
83 #define SPEED_1000              1000
84 #define SPEED_2500              2500
85 #define SPEED_5000              5000
86 #define SPEED_10000             10000
87 #define SPEED_14000             14000
88 #define SPEED_20000             20000
89 #define SPEED_25000             25000
90 #define SPEED_40000             40000
91 #define SPEED_50000             50000
92 #define SPEED_56000             56000
93 #define SPEED_100000            100000
94
95 enum nfp_eth_raw {
96         NSP_ETH_RAW_PORT = 0,
97         NSP_ETH_RAW_STATE,
98         NSP_ETH_RAW_MAC,
99         NSP_ETH_RAW_CONTROL,
100
101         NSP_ETH_NUM_RAW
102 };
103
104 enum nfp_eth_rate {
105         RATE_INVALID = 0,
106         RATE_10M,
107         RATE_100M,
108         RATE_1G,
109         RATE_10G,
110         RATE_25G,
111 };
112
113 union eth_table_entry {
114         struct {
115                 uint64_t port;
116                 uint64_t state;
117                 uint8_t mac_addr[6];
118                 uint8_t resv[2];
119                 uint64_t control;
120         };
121         uint64_t raw[NSP_ETH_NUM_RAW];
122 };
123
124 static const struct {
125         enum nfp_eth_rate rate;
126         unsigned int speed;
127 } nsp_eth_rate_tbl[] = {
128         { RATE_INVALID, 0, },
129         { RATE_10M,     SPEED_10, },
130         { RATE_100M,    SPEED_100, },
131         { RATE_1G,      SPEED_1000, },
132         { RATE_10G,     SPEED_10000, },
133         { RATE_25G,     SPEED_25000, },
134 };
135
136 static unsigned int
137 nfp_eth_rate2speed(enum nfp_eth_rate rate)
138 {
139         int i;
140
141         for (i = 0; i < (int)ARRAY_SIZE(nsp_eth_rate_tbl); i++)
142                 if (nsp_eth_rate_tbl[i].rate == rate)
143                         return nsp_eth_rate_tbl[i].speed;
144
145         return 0;
146 }
147
148 static unsigned int
149 nfp_eth_speed2rate(unsigned int speed)
150 {
151         int i;
152
153         for (i = 0; i < (int)ARRAY_SIZE(nsp_eth_rate_tbl); i++)
154                 if (nsp_eth_rate_tbl[i].speed == speed)
155                         return nsp_eth_rate_tbl[i].rate;
156
157         return RATE_INVALID;
158 }
159
160 static void
161 nfp_eth_copy_mac_reverse(uint8_t *dst, const uint8_t *src)
162 {
163         int i;
164
165         for (i = 0; i < (int)ETH_ALEN; i++)
166                 dst[ETH_ALEN - i - 1] = src[i];
167 }
168
169 static void
170 nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,
171                        unsigned int index, struct nfp_eth_table_port *dst)
172 {
173         unsigned int rate;
174         unsigned int fec;
175         uint64_t port, state;
176
177         port = rte_le_to_cpu_64(src->port);
178         state = rte_le_to_cpu_64(src->state);
179
180         dst->eth_index = FIELD_GET(NSP_ETH_PORT_INDEX, port);
181         dst->index = index;
182         dst->nbi = index / NSP_ETH_NBI_PORT_COUNT;
183         dst->base = index % NSP_ETH_NBI_PORT_COUNT;
184         dst->lanes = FIELD_GET(NSP_ETH_PORT_LANES, port);
185
186         dst->enabled = FIELD_GET(NSP_ETH_STATE_ENABLED, state);
187         dst->tx_enabled = FIELD_GET(NSP_ETH_STATE_TX_ENABLED, state);
188         dst->rx_enabled = FIELD_GET(NSP_ETH_STATE_RX_ENABLED, state);
189
190         rate = nfp_eth_rate2speed(FIELD_GET(NSP_ETH_STATE_RATE, state));
191         dst->speed = dst->lanes * rate;
192
193         dst->interface = FIELD_GET(NSP_ETH_STATE_INTERFACE, state);
194         dst->media = FIELD_GET(NSP_ETH_STATE_MEDIA, state);
195
196         nfp_eth_copy_mac_reverse(dst->mac_addr, src->mac_addr);
197
198         dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
199         dst->label_subport = FIELD_GET(NSP_ETH_PORT_LABEL, port);
200
201         if (nfp_nsp_get_abi_ver_minor(nsp) < 17)
202                 return;
203
204         dst->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
205         dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, state);
206
207         if (nfp_nsp_get_abi_ver_minor(nsp) < 22)
208                 return;
209
210         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_BASER, port);
211         dst->fec_modes_supported |= fec << NFP_FEC_BASER_BIT;
212         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_RS, port);
213         dst->fec_modes_supported |= fec << NFP_FEC_REED_SOLOMON_BIT;
214         if (dst->fec_modes_supported)
215                 dst->fec_modes_supported |= NFP_FEC_AUTO | NFP_FEC_DISABLED;
216
217         dst->fec = 1 << FIELD_GET(NSP_ETH_STATE_FEC, state);
218 }
219
220 static void
221 nfp_eth_calc_port_geometry(struct nfp_eth_table *table)
222 {
223         unsigned int i, j;
224
225         for (i = 0; i < table->count; i++) {
226                 table->max_index = RTE_MAX(table->max_index,
227                                            table->ports[i].index);
228
229                 for (j = 0; j < table->count; j++) {
230                         if (table->ports[i].label_port !=
231                             table->ports[j].label_port)
232                                 continue;
233                         table->ports[i].port_lanes += table->ports[j].lanes;
234
235                         if (i == j)
236                                 continue;
237                         if (table->ports[i].label_subport ==
238                             table->ports[j].label_subport)
239                                 printf("Port %d subport %d is a duplicate\n",
240                                          table->ports[i].label_port,
241                                          table->ports[i].label_subport);
242
243                         table->ports[i].is_split = 1;
244                 }
245         }
246 }
247
248 static void
249 nfp_eth_calc_port_type(struct nfp_eth_table_port *entry)
250 {
251         if (entry->interface == NFP_INTERFACE_NONE) {
252                 entry->port_type = PORT_NONE;
253                 return;
254         }
255
256         if (entry->media == NFP_MEDIA_FIBRE)
257                 entry->port_type = PORT_FIBRE;
258         else
259                 entry->port_type = PORT_DA;
260 }
261
262 static struct nfp_eth_table *
263 __nfp_eth_read_ports(struct nfp_nsp *nsp)
264 {
265         union eth_table_entry *entries;
266         struct nfp_eth_table *table;
267         uint32_t table_sz;
268         int i, j, ret, cnt = 0;
269
270         entries = malloc(NSP_ETH_TABLE_SIZE);
271         if (!entries)
272                 return NULL;
273
274         memset(entries, 0, NSP_ETH_TABLE_SIZE);
275         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
276         if (ret < 0) {
277                 printf("reading port table failed %d\n", ret);
278                 goto err;
279         }
280
281         for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
282                 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
283                         cnt++;
284
285         /* Some versions of flash will give us 0 instead of port count. For
286          * those that give a port count, verify it against the value calculated
287          * above.
288          */
289         if (ret && ret != cnt) {
290                 printf("table entry count (%d) unmatch entries present (%d)\n",
291                        ret, cnt);
292                 goto err;
293         }
294
295         table_sz = sizeof(*table) + sizeof(struct nfp_eth_table_port) * cnt;
296         table = malloc(table_sz);
297         if (!table)
298                 goto err;
299
300         memset(table, 0, table_sz);
301         table->count = cnt;
302         for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++)
303                 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
304                         nfp_eth_port_translate(nsp, &entries[i], i,
305                                                &table->ports[j++]);
306
307         nfp_eth_calc_port_geometry(table);
308         for (i = 0; i < (int)table->count; i++)
309                 nfp_eth_calc_port_type(&table->ports[i]);
310
311         free(entries);
312
313         return table;
314
315 err:
316         free(entries);
317         return NULL;
318 }
319
320 /*
321  * nfp_eth_read_ports() - retrieve port information
322  * @cpp:        NFP CPP handle
323  *
324  * Read the port information from the device.  Returned structure should
325  * be freed with kfree() once no longer needed.
326  *
327  * Return: populated ETH table or NULL on error.
328  */
329 struct nfp_eth_table *
330 nfp_eth_read_ports(struct nfp_cpp *cpp)
331 {
332         struct nfp_eth_table *ret;
333         struct nfp_nsp *nsp;
334
335         nsp = nfp_nsp_open(cpp);
336         if (!nsp)
337                 return NULL;
338
339         ret = __nfp_eth_read_ports(nsp);
340         nfp_nsp_close(nsp);
341
342         return ret;
343 }
344
345 struct nfp_nsp *
346 nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx)
347 {
348         union eth_table_entry *entries;
349         struct nfp_nsp *nsp;
350         int ret;
351
352         entries = malloc(NSP_ETH_TABLE_SIZE);
353         if (!entries)
354                 return NULL;
355
356         memset(entries, 0, NSP_ETH_TABLE_SIZE);
357         nsp = nfp_nsp_open(cpp);
358         if (!nsp) {
359                 free(entries);
360                 return nsp;
361         }
362
363         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
364         if (ret < 0) {
365                 printf("reading port table failed %d\n", ret);
366                 goto err;
367         }
368
369         if (!(entries[idx].port & NSP_ETH_PORT_LANES_MASK)) {
370                 printf("trying to set port state on disabled port %d\n", idx);
371                 goto err;
372         }
373
374         nfp_nsp_config_set_state(nsp, entries, idx);
375         return nsp;
376
377 err:
378         nfp_nsp_close(nsp);
379         free(entries);
380         return NULL;
381 }
382
383 void
384 nfp_eth_config_cleanup_end(struct nfp_nsp *nsp)
385 {
386         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
387
388         nfp_nsp_config_set_modified(nsp, 0);
389         nfp_nsp_config_clear_state(nsp);
390         nfp_nsp_close(nsp);
391         free(entries);
392 }
393
394 /*
395  * nfp_eth_config_commit_end() - perform recorded configuration changes
396  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
397  *
398  * Perform the configuration which was requested with __nfp_eth_set_*()
399  * helpers and recorded in @nsp state.  If device was already configured
400  * as requested or no __nfp_eth_set_*() operations were made no NSP command
401  * will be performed.
402  *
403  * Return:
404  * 0 - configuration successful;
405  * 1 - no changes were needed;
406  * -ERRNO - configuration failed.
407  */
408 int
409 nfp_eth_config_commit_end(struct nfp_nsp *nsp)
410 {
411         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
412         int ret = 1;
413
414         if (nfp_nsp_config_modified(nsp)) {
415                 ret = nfp_nsp_write_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
416                 ret = ret < 0 ? ret : 0;
417         }
418
419         nfp_eth_config_cleanup_end(nsp);
420
421         return ret;
422 }
423
424 /*
425  * nfp_eth_set_mod_enable() - set PHY module enable control bit
426  * @cpp:        NFP CPP handle
427  * @idx:        NFP chip-wide port index
428  * @enable:     Desired state
429  *
430  * Enable or disable PHY module (this usually means setting the TX lanes
431  * disable bits).
432  *
433  * Return:
434  * 0 - configuration successful;
435  * 1 - no changes were needed;
436  * -ERRNO - configuration failed.
437  */
438 int
439 nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, int enable)
440 {
441         union eth_table_entry *entries;
442         struct nfp_nsp *nsp;
443         uint64_t reg;
444
445         nsp = nfp_eth_config_start(cpp, idx);
446         if (!nsp)
447                 return -1;
448
449         entries = nfp_nsp_config_entries(nsp);
450
451         /* Check if we are already in requested state */
452         reg = rte_le_to_cpu_64(entries[idx].state);
453         if (enable != (int)FIELD_GET(NSP_ETH_CTRL_ENABLED, reg)) {
454                 reg = rte_le_to_cpu_64(entries[idx].control);
455                 reg &= ~NSP_ETH_CTRL_ENABLED;
456                 reg |= FIELD_PREP(NSP_ETH_CTRL_ENABLED, enable);
457                 entries[idx].control = rte_cpu_to_le_64(reg);
458
459                 nfp_nsp_config_set_modified(nsp, 1);
460         }
461
462         return nfp_eth_config_commit_end(nsp);
463 }
464
465 /*
466  * nfp_eth_set_configured() - set PHY module configured control bit
467  * @cpp:        NFP CPP handle
468  * @idx:        NFP chip-wide port index
469  * @configed:   Desired state
470  *
471  * Set the ifup/ifdown state on the PHY.
472  *
473  * Return:
474  * 0 - configuration successful;
475  * 1 - no changes were needed;
476  * -ERRNO - configuration failed.
477  */
478 int
479 nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, int configed)
480 {
481         union eth_table_entry *entries;
482         struct nfp_nsp *nsp;
483         uint64_t reg;
484
485         nsp = nfp_eth_config_start(cpp, idx);
486         if (!nsp)
487                 return -EIO;
488
489         /*
490          * Older ABI versions did support this feature, however this has only
491          * been reliable since ABI 20.
492          */
493         if (nfp_nsp_get_abi_ver_minor(nsp) < 20) {
494                 nfp_eth_config_cleanup_end(nsp);
495                 return -EOPNOTSUPP;
496         }
497
498         entries = nfp_nsp_config_entries(nsp);
499
500         /* Check if we are already in requested state */
501         reg = rte_le_to_cpu_64(entries[idx].state);
502         if (configed != (int)FIELD_GET(NSP_ETH_STATE_CONFIGURED, reg)) {
503                 reg = rte_le_to_cpu_64(entries[idx].control);
504                 reg &= ~NSP_ETH_CTRL_CONFIGURED;
505                 reg |= FIELD_PREP(NSP_ETH_CTRL_CONFIGURED, configed);
506                 entries[idx].control = rte_cpu_to_le_64(reg);
507
508                 nfp_nsp_config_set_modified(nsp, 1);
509         }
510
511         return nfp_eth_config_commit_end(nsp);
512 }
513
514 static int
515 nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int raw_idx,
516                        const uint64_t mask, const unsigned int shift,
517                        unsigned int val, const uint64_t ctrl_bit)
518 {
519         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
520         unsigned int idx = nfp_nsp_config_idx(nsp);
521         uint64_t reg;
522
523         /*
524          * Note: set features were added in ABI 0.14 but the error
525          *       codes were initially not populated correctly.
526          */
527         if (nfp_nsp_get_abi_ver_minor(nsp) < 17) {
528                 printf("set operations not supported, please update flash\n");
529                 return -EOPNOTSUPP;
530         }
531
532         /* Check if we are already in requested state */
533         reg = rte_le_to_cpu_64(entries[idx].raw[raw_idx]);
534         if (val == (reg & mask) >> shift)
535                 return 0;
536
537         reg &= ~mask;
538         reg |= (val << shift) & mask;
539         entries[idx].raw[raw_idx] = rte_cpu_to_le_64(reg);
540
541         entries[idx].control |= rte_cpu_to_le_64(ctrl_bit);
542
543         nfp_nsp_config_set_modified(nsp, 1);
544
545         return 0;
546 }
547
548 #define NFP_ETH_SET_BIT_CONFIG(nsp, raw_idx, mask, val, ctrl_bit)       \
549         (__extension__ ({ \
550                 typeof(mask) _x = (mask); \
551                 nfp_eth_set_bit_config(nsp, raw_idx, _x, __bf_shf(_x), \
552                                        val, ctrl_bit);                  \
553         }))
554
555 /*
556  * __nfp_eth_set_aneg() - set PHY autonegotiation control bit
557  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
558  * @mode:       Desired autonegotiation mode
559  *
560  * Allow/disallow PHY module to advertise/perform autonegotiation.
561  * Will write to hwinfo overrides in the flash (persistent config).
562  *
563  * Return: 0 or -ERRNO.
564  */
565 int
566 __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
567 {
568         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
569                                       NSP_ETH_STATE_ANEG, mode,
570                                       NSP_ETH_CTRL_SET_ANEG);
571 }
572
573 /*
574  * __nfp_eth_set_fec() - set PHY forward error correction control bit
575  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
576  * @mode:       Desired fec mode
577  *
578  * Set the PHY module forward error correction mode.
579  * Will write to hwinfo overrides in the flash (persistent config).
580  *
581  * Return: 0 or -ERRNO.
582  */
583 static int
584 __nfp_eth_set_fec(struct nfp_nsp *nsp, enum nfp_eth_fec mode)
585 {
586         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
587                                       NSP_ETH_STATE_FEC, mode,
588                                       NSP_ETH_CTRL_SET_FEC);
589 }
590
591 /*
592  * nfp_eth_set_fec() - set PHY forward error correction control mode
593  * @cpp:        NFP CPP handle
594  * @idx:        NFP chip-wide port index
595  * @mode:       Desired fec mode
596  *
597  * Return:
598  * 0 - configuration successful;
599  * 1 - no changes were needed;
600  * -ERRNO - configuration failed.
601  */
602 int
603 nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode)
604 {
605         struct nfp_nsp *nsp;
606         int err;
607
608         nsp = nfp_eth_config_start(cpp, idx);
609         if (!nsp)
610                 return -EIO;
611
612         err = __nfp_eth_set_fec(nsp, mode);
613         if (err) {
614                 nfp_eth_config_cleanup_end(nsp);
615                 return err;
616         }
617
618         return nfp_eth_config_commit_end(nsp);
619 }
620
621 /*
622  * __nfp_eth_set_speed() - set interface speed/rate
623  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
624  * @speed:      Desired speed (per lane)
625  *
626  * Set lane speed.  Provided @speed value should be subport speed divided
627  * by number of lanes this subport is spanning (i.e. 10000 for 40G, 25000 for
628  * 50G, etc.)
629  * Will write to hwinfo overrides in the flash (persistent config).
630  *
631  * Return: 0 or -ERRNO.
632  */
633 int
634 __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int speed)
635 {
636         enum nfp_eth_rate rate;
637
638         rate = nfp_eth_speed2rate(speed);
639         if (rate == RATE_INVALID) {
640                 printf("could not find matching lane rate for speed %u\n",
641                          speed);
642                 return -EINVAL;
643         }
644
645         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
646                                       NSP_ETH_STATE_RATE, rate,
647                                       NSP_ETH_CTRL_SET_RATE);
648 }
649
650 /*
651  * __nfp_eth_set_split() - set interface lane split
652  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
653  * @lanes:      Desired lanes per port
654  *
655  * Set number of lanes in the port.
656  * Will write to hwinfo overrides in the flash (persistent config).
657  *
658  * Return: 0 or -ERRNO.
659  */
660 int
661 __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes)
662 {
663         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
664                                       lanes, NSP_ETH_CTRL_SET_LANES);
665 }