Skip to content

Commit 5a56083

Browse files
Jakub Kicinskidavem330
authored andcommitted
nfp: NSP backend for link configuration operations
Add NSP backend for upcoming link configuration operations. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 85eb97d commit 5a56083

File tree

3 files changed

+179
-14
lines changed

3 files changed

+179
-14
lines changed

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ static const struct {
101101
int code;
102102
const char *msg;
103103
} nsp_errors[] = {
104-
{ 0, "success" } /* placeholder to avoid warnings */
104+
{ 6010, "could not map to phy for port" },
105+
{ 6011, "not an allowed rate/lanes for port" },
106+
{ 6012, "not an allowed rate/lanes for port" },
107+
{ 6013, "high/low error, change other port first" },
108+
{ 6014, "config not found in flash" },
105109
};
106110

107111
struct nfp_nsp {

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,17 @@ struct nfp_eth_table {
134134
struct nfp_eth_table *nfp_eth_read_ports(struct nfp_cpp *cpp);
135135
struct nfp_eth_table *
136136
__nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp);
137+
137138
int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable);
139+
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx,
140+
bool configed);
138141

139142
struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx);
140143
int nfp_eth_config_commit_end(struct nfp_nsp *nsp);
141144
void nfp_eth_config_cleanup_end(struct nfp_nsp *nsp);
142145

146+
int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode);
147+
int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int speed);
148+
int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes);
149+
143150
#endif

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c

Lines changed: 167 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
#define NSP_ETH_PORT_LANES_MASK cpu_to_le64(NSP_ETH_PORT_LANES)
6060

61+
#define NSP_ETH_STATE_CONFIGURED BIT_ULL(0)
6162
#define NSP_ETH_STATE_ENABLED BIT_ULL(1)
6263
#define NSP_ETH_STATE_TX_ENABLED BIT_ULL(2)
6364
#define NSP_ETH_STATE_RX_ENABLED BIT_ULL(3)
@@ -67,9 +68,13 @@
6768
#define NSP_ETH_STATE_OVRD_CHNG BIT_ULL(22)
6869
#define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23)
6970

71+
#define NSP_ETH_CTRL_CONFIGURED BIT_ULL(0)
7072
#define NSP_ETH_CTRL_ENABLED BIT_ULL(1)
7173
#define NSP_ETH_CTRL_TX_ENABLED BIT_ULL(2)
7274
#define NSP_ETH_CTRL_RX_ENABLED BIT_ULL(3)
75+
#define NSP_ETH_CTRL_SET_RATE BIT_ULL(4)
76+
#define NSP_ETH_CTRL_SET_LANES BIT_ULL(5)
77+
#define NSP_ETH_CTRL_SET_ANEG BIT_ULL(6)
7378

7479
enum nfp_eth_raw {
7580
NSP_ETH_RAW_PORT = 0,
@@ -100,21 +105,38 @@ union eth_table_entry {
100105
__le64 raw[NSP_ETH_NUM_RAW];
101106
};
102107

103-
static unsigned int nfp_eth_rate(enum nfp_eth_rate rate)
108+
static const struct {
109+
enum nfp_eth_rate rate;
110+
unsigned int speed;
111+
} nsp_eth_rate_tbl[] = {
112+
{ RATE_INVALID, 0, },
113+
{ RATE_10M, SPEED_10, },
114+
{ RATE_100M, SPEED_100, },
115+
{ RATE_1G, SPEED_1000, },
116+
{ RATE_10G, SPEED_10000, },
117+
{ RATE_25G, SPEED_25000, },
118+
};
119+
120+
static unsigned int nfp_eth_rate2speed(enum nfp_eth_rate rate)
104121
{
105-
unsigned int rate_xlate[] = {
106-
[RATE_INVALID] = 0,
107-
[RATE_10M] = SPEED_10,
108-
[RATE_100M] = SPEED_100,
109-
[RATE_1G] = SPEED_1000,
110-
[RATE_10G] = SPEED_10000,
111-
[RATE_25G] = SPEED_25000,
112-
};
122+
int i;
113123

114-
if (rate >= ARRAY_SIZE(rate_xlate))
115-
return 0;
124+
for (i = 0; i < ARRAY_SIZE(nsp_eth_rate_tbl); i++)
125+
if (nsp_eth_rate_tbl[i].rate == rate)
126+
return nsp_eth_rate_tbl[i].speed;
127+
128+
return 0;
129+
}
130+
131+
static unsigned int nfp_eth_speed2rate(unsigned int speed)
132+
{
133+
int i;
134+
135+
for (i = 0; i < ARRAY_SIZE(nsp_eth_rate_tbl); i++)
136+
if (nsp_eth_rate_tbl[i].speed == speed)
137+
return nsp_eth_rate_tbl[i].rate;
116138

117-
return rate_xlate[rate];
139+
return RATE_INVALID;
118140
}
119141

120142
static void nfp_eth_copy_mac_reverse(u8 *dst, const u8 *src)
@@ -145,7 +167,7 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,
145167
dst->tx_enabled = FIELD_GET(NSP_ETH_STATE_TX_ENABLED, state);
146168
dst->rx_enabled = FIELD_GET(NSP_ETH_STATE_RX_ENABLED, state);
147169

148-
rate = nfp_eth_rate(FIELD_GET(NSP_ETH_STATE_RATE, state));
170+
rate = nfp_eth_rate2speed(FIELD_GET(NSP_ETH_STATE_RATE, state));
149171
dst->speed = dst->lanes * rate;
150172

151173
dst->interface = FIELD_GET(NSP_ETH_STATE_INTERFACE, state);
@@ -392,3 +414,135 @@ int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable)
392414

393415
return nfp_eth_config_commit_end(nsp);
394416
}
417+
418+
/**
419+
* nfp_eth_set_configured() - set PHY module configured control bit
420+
* @cpp: NFP CPP handle
421+
* @idx: NFP chip-wide port index
422+
* @configed: Desired state
423+
*
424+
* Set the ifup/ifdown state on the PHY.
425+
*
426+
* Return: 0 or -ERRNO.
427+
*/
428+
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, bool configed)
429+
{
430+
union eth_table_entry *entries;
431+
struct nfp_nsp *nsp;
432+
u64 reg;
433+
434+
nsp = nfp_eth_config_start(cpp, idx);
435+
if (IS_ERR(nsp))
436+
return PTR_ERR(nsp);
437+
438+
entries = nfp_nsp_config_entries(nsp);
439+
440+
/* Check if we are already in requested state */
441+
reg = le64_to_cpu(entries[idx].state);
442+
if (configed != FIELD_GET(NSP_ETH_STATE_CONFIGURED, reg)) {
443+
reg = le64_to_cpu(entries[idx].control);
444+
reg &= ~NSP_ETH_CTRL_CONFIGURED;
445+
reg |= FIELD_PREP(NSP_ETH_CTRL_CONFIGURED, configed);
446+
entries[idx].control = cpu_to_le64(reg);
447+
448+
nfp_nsp_config_set_modified(nsp, true);
449+
}
450+
451+
return nfp_eth_config_commit_end(nsp);
452+
}
453+
454+
/* Force inline, FIELD_* macroes require masks to be compilation-time known */
455+
static __always_inline int
456+
nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int raw_idx,
457+
const u64 mask, unsigned int val, const u64 ctrl_bit)
458+
{
459+
union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
460+
unsigned int idx = nfp_nsp_config_idx(nsp);
461+
u64 reg;
462+
463+
/* Note: set features were added in ABI 0.14 but the error
464+
* codes were initially not populated correctly.
465+
*/
466+
if (nfp_nsp_get_abi_ver_minor(nsp) < 17) {
467+
nfp_err(nfp_nsp_cpp(nsp),
468+
"set operations not supported, please update flash\n");
469+
return -EOPNOTSUPP;
470+
}
471+
472+
/* Check if we are already in requested state */
473+
reg = le64_to_cpu(entries[idx].raw[raw_idx]);
474+
if (val == FIELD_GET(mask, reg))
475+
return 0;
476+
477+
reg &= ~mask;
478+
reg |= FIELD_PREP(mask, val);
479+
entries[idx].raw[raw_idx] = cpu_to_le64(reg);
480+
481+
entries[idx].control |= cpu_to_le64(ctrl_bit);
482+
483+
nfp_nsp_config_set_modified(nsp, true);
484+
485+
return 0;
486+
}
487+
488+
/**
489+
* __nfp_eth_set_aneg() - set PHY autonegotiation control bit
490+
* @nsp: NFP NSP handle returned from nfp_eth_config_start()
491+
* @mode: Desired autonegotiation mode
492+
*
493+
* Allow/disallow PHY module to advertise/perform autonegotiation.
494+
* Will write to hwinfo overrides in the flash (persistent config).
495+
*
496+
* Return: 0 or -ERRNO.
497+
*/
498+
int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
499+
{
500+
return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_STATE,
501+
NSP_ETH_STATE_ANEG, mode,
502+
NSP_ETH_CTRL_SET_ANEG);
503+
}
504+
505+
/**
506+
* __nfp_eth_set_speed() - set interface speed/rate
507+
* @nsp: NFP NSP handle returned from nfp_eth_config_start()
508+
* @speed: Desired speed (per lane)
509+
*
510+
* Set lane speed. Provided @speed value should be subport speed divided
511+
* by number of lanes this subport is spanning (i.e. 10000 for 40G, 25000 for
512+
* 50G, etc.)
513+
* Will write to hwinfo overrides in the flash (persistent config).
514+
*
515+
* Return: 0 or -ERRNO.
516+
*/
517+
int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int speed)
518+
{
519+
enum nfp_eth_rate rate;
520+
521+
rate = nfp_eth_speed2rate(speed);
522+
if (rate == RATE_INVALID) {
523+
nfp_warn(nfp_nsp_cpp(nsp),
524+
"could not find matching lane rate for speed %u\n",
525+
speed);
526+
return -EINVAL;
527+
}
528+
529+
return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_STATE,
530+
NSP_ETH_STATE_RATE, rate,
531+
NSP_ETH_CTRL_SET_RATE);
532+
}
533+
534+
/**
535+
* __nfp_eth_set_split() - set interface lane split
536+
* @nsp: NFP NSP handle returned from nfp_eth_config_start()
537+
* @lanes: Desired lanes per port
538+
*
539+
* Set number of lanes in the port.
540+
* Will write to hwinfo overrides in the flash (persistent config).
541+
*
542+
* Return: 0 or -ERRNO.
543+
*/
544+
int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes)
545+
{
546+
return nfp_eth_set_bit_config(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
547+
lanes, NSP_ETH_CTRL_SET_LANES);
548+
}

0 commit comments

Comments
 (0)