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