1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
7 #include <rte_common.h>
8 #include <rte_byteorder.h>
11 #include "nfp6000/nfp6000.h"
13 #define GENMASK_ULL(h, l) \
14 (((~0ULL) - (1ULL << (l)) + 1) & \
15 (~0ULL >> (64 - 1 - (h))))
17 #define __bf_shf(x) (__builtin_ffsll(x) - 1)
19 #define FIELD_GET(_mask, _reg) \
21 typeof(_mask) _x = (_mask); \
22 (typeof(_x))(((_reg) & (_x)) >> __bf_shf(_x)); \
25 #define FIELD_FIT(_mask, _val) \
27 typeof(_mask) _x = (_mask); \
28 !((((typeof(_x))_val) << __bf_shf(_x)) & ~(_x)); \
31 #define FIELD_PREP(_mask, _val) \
33 typeof(_mask) _x = (_mask); \
34 ((typeof(_x))(_val) << __bf_shf(_x)) & (_x); \
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))
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)
49 #define NSP_ETH_PORT_LANES_MASK rte_cpu_to_le_64(NSP_ETH_PORT_LANES)
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)
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)
71 /* Which connector port. */
75 #define PORT_FIBRE 0x03
78 #define PORT_NONE 0xef
79 #define PORT_OTHER 0xff
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
113 union eth_table_entry
{
121 uint64_t raw
[NSP_ETH_NUM_RAW
];
124 static const struct {
125 enum nfp_eth_rate rate
;
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
, },
137 nfp_eth_rate2speed(enum nfp_eth_rate rate
)
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
;
149 nfp_eth_speed2rate(unsigned int speed
)
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
;
161 nfp_eth_copy_mac_reverse(uint8_t *dst
, const uint8_t *src
)
165 for (i
= 0; i
< (int)ETH_ALEN
; i
++)
166 dst
[ETH_ALEN
- i
- 1] = src
[i
];
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
)
175 uint64_t port
, state
;
177 port
= rte_le_to_cpu_64(src
->port
);
178 state
= rte_le_to_cpu_64(src
->state
);
180 dst
->eth_index
= FIELD_GET(NSP_ETH_PORT_INDEX
, port
);
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
);
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
);
190 rate
= nfp_eth_rate2speed(FIELD_GET(NSP_ETH_STATE_RATE
, state
));
191 dst
->speed
= dst
->lanes
* rate
;
193 dst
->interface
= FIELD_GET(NSP_ETH_STATE_INTERFACE
, state
);
194 dst
->media
= FIELD_GET(NSP_ETH_STATE_MEDIA
, state
);
196 nfp_eth_copy_mac_reverse(dst
->mac_addr
, src
->mac_addr
);
198 dst
->label_port
= FIELD_GET(NSP_ETH_PORT_PHYLABEL
, port
);
199 dst
->label_subport
= FIELD_GET(NSP_ETH_PORT_LABEL
, port
);
201 if (nfp_nsp_get_abi_ver_minor(nsp
) < 17)
204 dst
->override_changed
= FIELD_GET(NSP_ETH_STATE_OVRD_CHNG
, state
);
205 dst
->aneg
= FIELD_GET(NSP_ETH_STATE_ANEG
, state
);
207 if (nfp_nsp_get_abi_ver_minor(nsp
) < 22)
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
;
217 dst
->fec
= 1 << FIELD_GET(NSP_ETH_STATE_FEC
, state
);
221 nfp_eth_calc_port_geometry(struct nfp_eth_table
*table
)
225 for (i
= 0; i
< table
->count
; i
++) {
226 table
->max_index
= RTE_MAX(table
->max_index
,
227 table
->ports
[i
].index
);
229 for (j
= 0; j
< table
->count
; j
++) {
230 if (table
->ports
[i
].label_port
!=
231 table
->ports
[j
].label_port
)
233 table
->ports
[i
].port_lanes
+= table
->ports
[j
].lanes
;
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
);
243 table
->ports
[i
].is_split
= 1;
249 nfp_eth_calc_port_type(struct nfp_eth_table_port
*entry
)
251 if (entry
->interface
== NFP_INTERFACE_NONE
) {
252 entry
->port_type
= PORT_NONE
;
256 if (entry
->media
== NFP_MEDIA_FIBRE
)
257 entry
->port_type
= PORT_FIBRE
;
259 entry
->port_type
= PORT_DA
;
262 static struct nfp_eth_table
*
263 __nfp_eth_read_ports(struct nfp_nsp
*nsp
)
265 union eth_table_entry
*entries
;
266 struct nfp_eth_table
*table
;
268 int i
, j
, ret
, cnt
= 0;
270 entries
= malloc(NSP_ETH_TABLE_SIZE
);
274 memset(entries
, 0, NSP_ETH_TABLE_SIZE
);
275 ret
= nfp_nsp_read_eth_table(nsp
, entries
, NSP_ETH_TABLE_SIZE
);
277 printf("reading port table failed %d\n", ret
);
281 for (i
= 0; i
< NSP_ETH_MAX_COUNT
; i
++)
282 if (entries
[i
].port
& NSP_ETH_PORT_LANES_MASK
)
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
289 if (ret
&& ret
!= cnt
) {
290 printf("table entry count (%d) unmatch entries present (%d)\n",
295 table_sz
= sizeof(*table
) + sizeof(struct nfp_eth_table_port
) * cnt
;
296 table
= malloc(table_sz
);
300 memset(table
, 0, table_sz
);
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
,
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
]);
321 * nfp_eth_read_ports() - retrieve port information
322 * @cpp: NFP CPP handle
324 * Read the port information from the device. Returned structure should
325 * be freed with kfree() once no longer needed.
327 * Return: populated ETH table or NULL on error.
329 struct nfp_eth_table
*
330 nfp_eth_read_ports(struct nfp_cpp
*cpp
)
332 struct nfp_eth_table
*ret
;
335 nsp
= nfp_nsp_open(cpp
);
339 ret
= __nfp_eth_read_ports(nsp
);
346 nfp_eth_config_start(struct nfp_cpp
*cpp
, unsigned int idx
)
348 union eth_table_entry
*entries
;
352 entries
= malloc(NSP_ETH_TABLE_SIZE
);
356 memset(entries
, 0, NSP_ETH_TABLE_SIZE
);
357 nsp
= nfp_nsp_open(cpp
);
363 ret
= nfp_nsp_read_eth_table(nsp
, entries
, NSP_ETH_TABLE_SIZE
);
365 printf("reading port table failed %d\n", ret
);
369 if (!(entries
[idx
].port
& NSP_ETH_PORT_LANES_MASK
)) {
370 printf("trying to set port state on disabled port %d\n", idx
);
374 nfp_nsp_config_set_state(nsp
, entries
, idx
);
384 nfp_eth_config_cleanup_end(struct nfp_nsp
*nsp
)
386 union eth_table_entry
*entries
= nfp_nsp_config_entries(nsp
);
388 nfp_nsp_config_set_modified(nsp
, 0);
389 nfp_nsp_config_clear_state(nsp
);
395 * nfp_eth_config_commit_end() - perform recorded configuration changes
396 * @nsp: NFP NSP handle returned from nfp_eth_config_start()
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
404 * 0 - configuration successful;
405 * 1 - no changes were needed;
406 * -ERRNO - configuration failed.
409 nfp_eth_config_commit_end(struct nfp_nsp
*nsp
)
411 union eth_table_entry
*entries
= nfp_nsp_config_entries(nsp
);
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;
419 nfp_eth_config_cleanup_end(nsp
);
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
430 * Enable or disable PHY module (this usually means setting the TX lanes
434 * 0 - configuration successful;
435 * 1 - no changes were needed;
436 * -ERRNO - configuration failed.
439 nfp_eth_set_mod_enable(struct nfp_cpp
*cpp
, unsigned int idx
, int enable
)
441 union eth_table_entry
*entries
;
445 nsp
= nfp_eth_config_start(cpp
, idx
);
449 entries
= nfp_nsp_config_entries(nsp
);
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
);
459 nfp_nsp_config_set_modified(nsp
, 1);
462 return nfp_eth_config_commit_end(nsp
);
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
471 * Set the ifup/ifdown state on the PHY.
474 * 0 - configuration successful;
475 * 1 - no changes were needed;
476 * -ERRNO - configuration failed.
479 nfp_eth_set_configured(struct nfp_cpp
*cpp
, unsigned int idx
, int configed
)
481 union eth_table_entry
*entries
;
485 nsp
= nfp_eth_config_start(cpp
, idx
);
490 * Older ABI versions did support this feature, however this has only
491 * been reliable since ABI 20.
493 if (nfp_nsp_get_abi_ver_minor(nsp
) < 20) {
494 nfp_eth_config_cleanup_end(nsp
);
498 entries
= nfp_nsp_config_entries(nsp
);
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
);
508 nfp_nsp_config_set_modified(nsp
, 1);
511 return nfp_eth_config_commit_end(nsp
);
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
)
519 union eth_table_entry
*entries
= nfp_nsp_config_entries(nsp
);
520 unsigned int idx
= nfp_nsp_config_idx(nsp
);
524 * Note: set features were added in ABI 0.14 but the error
525 * codes were initially not populated correctly.
527 if (nfp_nsp_get_abi_ver_minor(nsp
) < 17) {
528 printf("set operations not supported, please update flash\n");
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
)
538 reg
|= (val
<< shift
) & mask
;
539 entries
[idx
].raw
[raw_idx
] = rte_cpu_to_le_64(reg
);
541 entries
[idx
].control
|= rte_cpu_to_le_64(ctrl_bit
);
543 nfp_nsp_config_set_modified(nsp
, 1);
548 #define NFP_ETH_SET_BIT_CONFIG(nsp, raw_idx, mask, val, ctrl_bit) \
550 typeof(mask) _x = (mask); \
551 nfp_eth_set_bit_config(nsp, raw_idx, _x, __bf_shf(_x), \
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
560 * Allow/disallow PHY module to advertise/perform autonegotiation.
561 * Will write to hwinfo overrides in the flash (persistent config).
563 * Return: 0 or -ERRNO.
566 __nfp_eth_set_aneg(struct nfp_nsp
*nsp
, enum nfp_eth_aneg mode
)
568 return NFP_ETH_SET_BIT_CONFIG(nsp
, NSP_ETH_RAW_STATE
,
569 NSP_ETH_STATE_ANEG
, mode
,
570 NSP_ETH_CTRL_SET_ANEG
);
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
578 * Set the PHY module forward error correction mode.
579 * Will write to hwinfo overrides in the flash (persistent config).
581 * Return: 0 or -ERRNO.
584 __nfp_eth_set_fec(struct nfp_nsp
*nsp
, enum nfp_eth_fec mode
)
586 return NFP_ETH_SET_BIT_CONFIG(nsp
, NSP_ETH_RAW_STATE
,
587 NSP_ETH_STATE_FEC
, mode
,
588 NSP_ETH_CTRL_SET_FEC
);
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
598 * 0 - configuration successful;
599 * 1 - no changes were needed;
600 * -ERRNO - configuration failed.
603 nfp_eth_set_fec(struct nfp_cpp
*cpp
, unsigned int idx
, enum nfp_eth_fec mode
)
608 nsp
= nfp_eth_config_start(cpp
, idx
);
612 err
= __nfp_eth_set_fec(nsp
, mode
);
614 nfp_eth_config_cleanup_end(nsp
);
618 return nfp_eth_config_commit_end(nsp
);
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)
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
629 * Will write to hwinfo overrides in the flash (persistent config).
631 * Return: 0 or -ERRNO.
634 __nfp_eth_set_speed(struct nfp_nsp
*nsp
, unsigned int speed
)
636 enum nfp_eth_rate rate
;
638 rate
= nfp_eth_speed2rate(speed
);
639 if (rate
== RATE_INVALID
) {
640 printf("could not find matching lane rate for speed %u\n",
645 return NFP_ETH_SET_BIT_CONFIG(nsp
, NSP_ETH_RAW_STATE
,
646 NSP_ETH_STATE_RATE
, rate
,
647 NSP_ETH_CTRL_SET_RATE
);
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
655 * Set number of lanes in the port.
656 * Will write to hwinfo overrides in the flash (persistent config).
658 * Return: 0 or -ERRNO.
661 __nfp_eth_set_split(struct nfp_nsp
*nsp
, unsigned int lanes
)
663 return NFP_ETH_SET_BIT_CONFIG(nsp
, NSP_ETH_RAW_PORT
, NSP_ETH_PORT_LANES
,
664 lanes
, NSP_ETH_CTRL_SET_LANES
);