xref: /linux/drivers/net/ethernet/broadcom/bnge/bnge_link.c (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2026 Broadcom.
3 
4 #include <linux/linkmode.h>
5 
6 #include "bnge.h"
7 #include "bnge_link.h"
8 #include "bnge_hwrm_lib.h"
9 
10 enum bnge_media_type {
11 	BNGE_MEDIA_UNKNOWN = 0,
12 	BNGE_MEDIA_CR,
13 	BNGE_MEDIA_SR,
14 	BNGE_MEDIA_LR_ER_FR,
15 	BNGE_MEDIA_KR,
16 	__BNGE_MEDIA_END,
17 };
18 
19 static const enum bnge_media_type bnge_phy_types[] = {
20 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR4] = BNGE_MEDIA_CR,
21 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR4] = BNGE_MEDIA_SR,
22 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR4] = BNGE_MEDIA_LR_ER_FR,
23 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER4] = BNGE_MEDIA_LR_ER_FR,
24 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR10] = BNGE_MEDIA_SR,
25 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR4] = BNGE_MEDIA_CR,
26 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR4] = BNGE_MEDIA_SR,
27 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR4] = BNGE_MEDIA_LR_ER_FR,
28 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER4] = BNGE_MEDIA_LR_ER_FR,
29 	[PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASECR] = BNGE_MEDIA_CR,
30 	[PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASESR] = BNGE_MEDIA_SR,
31 	[PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASELR] = BNGE_MEDIA_LR_ER_FR,
32 	[PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASEER] = BNGE_MEDIA_LR_ER_FR,
33 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR2] = BNGE_MEDIA_CR,
34 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR2] = BNGE_MEDIA_SR,
35 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR2] = BNGE_MEDIA_LR_ER_FR,
36 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER2] = BNGE_MEDIA_LR_ER_FR,
37 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR] = BNGE_MEDIA_CR,
38 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR] = BNGE_MEDIA_SR,
39 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR] = BNGE_MEDIA_LR_ER_FR,
40 	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER] = BNGE_MEDIA_LR_ER_FR,
41 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR2] = BNGE_MEDIA_CR,
42 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR2] = BNGE_MEDIA_SR,
43 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR2] = BNGE_MEDIA_LR_ER_FR,
44 	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER2] = BNGE_MEDIA_LR_ER_FR,
45 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR8] = BNGE_MEDIA_CR,
46 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR8] = BNGE_MEDIA_SR,
47 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR8] = BNGE_MEDIA_LR_ER_FR,
48 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER8] = BNGE_MEDIA_LR_ER_FR,
49 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR4] = BNGE_MEDIA_CR,
50 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR4] = BNGE_MEDIA_SR,
51 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR4] = BNGE_MEDIA_LR_ER_FR,
52 	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4] = BNGE_MEDIA_LR_ER_FR,
53 };
54 
55 static u32 bnge_fw_to_ethtool_speed(u16 fw_link_speed)
56 {
57 	switch (fw_link_speed) {
58 	case BNGE_LINK_SPEED_50GB:
59 	case BNGE_LINK_SPEED_50GB_PAM4:
60 		return SPEED_50000;
61 	case BNGE_LINK_SPEED_100GB:
62 	case BNGE_LINK_SPEED_100GB_PAM4:
63 	case BNGE_LINK_SPEED_100GB_PAM4_112:
64 		return SPEED_100000;
65 	case BNGE_LINK_SPEED_200GB:
66 	case BNGE_LINK_SPEED_200GB_PAM4:
67 	case BNGE_LINK_SPEED_200GB_PAM4_112:
68 		return SPEED_200000;
69 	case BNGE_LINK_SPEED_400GB:
70 	case BNGE_LINK_SPEED_400GB_PAM4:
71 	case BNGE_LINK_SPEED_400GB_PAM4_112:
72 		return SPEED_400000;
73 	case BNGE_LINK_SPEED_800GB:
74 	case BNGE_LINK_SPEED_800GB_PAM4_112:
75 		return SPEED_800000;
76 	default:
77 		return SPEED_UNKNOWN;
78 	}
79 }
80 
81 static void bnge_set_auto_speed(struct bnge_net *bn)
82 {
83 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
84 	struct bnge_link_info *link_info;
85 
86 	link_info = &bn->bd->link_info;
87 	elink_info->advertising = link_info->auto_link_speeds2;
88 }
89 
90 static void bnge_set_force_speed(struct bnge_net *bn)
91 {
92 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
93 	struct bnge_link_info *link_info;
94 
95 	link_info = &bn->bd->link_info;
96 	elink_info->req_link_speed = link_info->force_link_speed2;
97 	switch (elink_info->req_link_speed) {
98 	case BNGE_LINK_SPEED_50GB_PAM4:
99 	case BNGE_LINK_SPEED_100GB_PAM4:
100 	case BNGE_LINK_SPEED_200GB_PAM4:
101 	case BNGE_LINK_SPEED_400GB_PAM4:
102 		elink_info->req_signal_mode = BNGE_SIG_MODE_PAM4;
103 		break;
104 	case BNGE_LINK_SPEED_100GB_PAM4_112:
105 	case BNGE_LINK_SPEED_200GB_PAM4_112:
106 	case BNGE_LINK_SPEED_400GB_PAM4_112:
107 	case BNGE_LINK_SPEED_800GB_PAM4_112:
108 		elink_info->req_signal_mode = BNGE_SIG_MODE_PAM4_112;
109 		break;
110 	default:
111 		elink_info->req_signal_mode = BNGE_SIG_MODE_NRZ;
112 		break;
113 	}
114 }
115 
116 void bnge_init_ethtool_link_settings(struct bnge_net *bn)
117 {
118 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
119 	struct bnge_link_info *link_info;
120 	struct bnge_dev *bd = bn->bd;
121 
122 	link_info = &bd->link_info;
123 
124 	if (BNGE_AUTO_MODE(link_info->auto_mode)) {
125 		elink_info->autoneg = BNGE_AUTONEG_SPEED;
126 		if (link_info->auto_pause_setting &
127 		    PORT_PHY_QCFG_RESP_AUTO_PAUSE_AUTONEG_PAUSE)
128 			elink_info->autoneg |= BNGE_AUTONEG_FLOW_CTRL;
129 		bnge_set_auto_speed(bn);
130 	} else {
131 		elink_info->autoneg = 0;
132 		elink_info->advertising = 0;
133 		bnge_set_force_speed(bn);
134 		elink_info->req_duplex = link_info->duplex_setting;
135 	}
136 	if (elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL)
137 		elink_info->req_flow_ctrl =
138 			link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH;
139 	else
140 		elink_info->req_flow_ctrl = link_info->force_pause_setting;
141 }
142 
143 int bnge_probe_phy(struct bnge_net *bn, bool fw_dflt)
144 {
145 	struct bnge_dev *bd = bn->bd;
146 	int rc;
147 
148 	bd->phy_flags = 0;
149 	rc = bnge_hwrm_phy_qcaps(bd);
150 	if (rc) {
151 		netdev_err(bn->netdev,
152 			   "Probe PHY can't get PHY qcaps (rc: %d)\n", rc);
153 		return rc;
154 	}
155 	if (bd->phy_flags & BNGE_PHY_FL_NO_FCS)
156 		bn->netdev->priv_flags |= IFF_SUPP_NOFCS;
157 	else
158 		bn->netdev->priv_flags &= ~IFF_SUPP_NOFCS;
159 	if (!fw_dflt)
160 		return 0;
161 
162 	rc = bnge_update_link(bn, false);
163 	if (rc) {
164 		netdev_err(bn->netdev, "Probe PHY can't update link (rc: %d)\n",
165 			   rc);
166 		return rc;
167 	}
168 	bnge_init_ethtool_link_settings(bn);
169 
170 	return 0;
171 }
172 
173 void bnge_hwrm_set_link_common(struct bnge_net *bn,
174 			       struct hwrm_port_phy_cfg_input *req)
175 {
176 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
177 
178 	if (elink_info->autoneg & BNGE_AUTONEG_SPEED) {
179 		req->auto_mode |= PORT_PHY_CFG_REQ_AUTO_MODE_SPEED_MASK;
180 		req->enables |= cpu_to_le32(BNGE_PHY_AUTO_SPEEDS2_MASK);
181 		req->auto_link_speeds2_mask =
182 			cpu_to_le16(elink_info->advertising);
183 		req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE);
184 		req->flags |= cpu_to_le32(BNGE_PHY_FLAGS_RESTART_AUTO);
185 	} else {
186 		req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE);
187 		req->force_link_speeds2 =
188 			cpu_to_le16(elink_info->req_link_speed);
189 		req->enables |=
190 			cpu_to_le32(BNGE_PHY_FLAGS_ENA_FORCE_SPEEDS2);
191 		netif_info(bn, link, bn->netdev,
192 			   "Forcing FW speed2: %d\n",
193 			   (u32)elink_info->req_link_speed);
194 	}
195 
196 	/* tell FW that the setting takes effect immediately */
197 	req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_RESET_PHY);
198 }
199 
200 static bool bnge_auto_speed_updated(struct bnge_net *bn)
201 {
202 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
203 	struct bnge_link_info *link_info = &bn->bd->link_info;
204 
205 	return elink_info->advertising != link_info->auto_link_speeds2;
206 }
207 
208 void bnge_hwrm_set_pause_common(struct bnge_net *bn,
209 				struct hwrm_port_phy_cfg_input *req)
210 {
211 	if (bn->eth_link_info.autoneg & BNGE_AUTONEG_FLOW_CTRL) {
212 		req->auto_pause = PORT_PHY_CFG_REQ_AUTO_PAUSE_AUTONEG_PAUSE;
213 		if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_RX)
214 			req->auto_pause |= PORT_PHY_CFG_REQ_AUTO_PAUSE_RX;
215 		if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_TX)
216 			req->auto_pause |= PORT_PHY_CFG_REQ_AUTO_PAUSE_TX;
217 		req->enables |=
218 			cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE);
219 	} else {
220 		if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_RX)
221 			req->force_pause |= PORT_PHY_CFG_REQ_FORCE_PAUSE_RX;
222 		if (bn->eth_link_info.req_flow_ctrl & BNGE_LINK_PAUSE_TX)
223 			req->force_pause |= PORT_PHY_CFG_REQ_FORCE_PAUSE_TX;
224 		req->enables |=
225 			cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_FORCE_PAUSE);
226 		req->auto_pause = req->force_pause;
227 		req->enables |=
228 			cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_PAUSE);
229 	}
230 }
231 
232 static bool bnge_force_speed_updated(struct bnge_net *bn)
233 {
234 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
235 	struct bnge_link_info *link_info = &bn->bd->link_info;
236 
237 	return elink_info->req_link_speed != link_info->force_link_speed2;
238 }
239 
240 int bnge_update_phy_setting(struct bnge_net *bn)
241 {
242 	struct bnge_ethtool_link_info *elink_info;
243 	struct bnge_link_info *link_info;
244 	struct bnge_dev *bd = bn->bd;
245 	bool update_pause = false;
246 	bool update_link = false;
247 	bool hw_pause_autoneg;
248 	bool pause_autoneg;
249 	int rc;
250 
251 	link_info = &bd->link_info;
252 	elink_info = &bn->eth_link_info;
253 	rc = bnge_update_link(bn, true);
254 	if (rc) {
255 		netdev_err(bn->netdev, "failed to update link (rc: %d)\n",
256 			   rc);
257 		return rc;
258 	}
259 
260 	pause_autoneg = !!(elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL);
261 	hw_pause_autoneg = !!(link_info->auto_pause_setting &
262 			      PORT_PHY_QCFG_RESP_AUTO_PAUSE_AUTONEG_PAUSE);
263 
264 	/* Check if pause autonegotiation state has changed */
265 	if (pause_autoneg != hw_pause_autoneg) {
266 		update_pause = true;
267 	} else if (pause_autoneg) {
268 		/* If pause autoneg is enabled, check if the
269 		 * requested RX/TX bits changed
270 		 */
271 		if ((link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH) !=
272 		    elink_info->req_flow_ctrl)
273 			update_pause = true;
274 	} else {
275 		/* If pause autoneg is disabled, check if the
276 		 * forced RX/TX bits changed
277 		 */
278 		if (link_info->force_pause_setting != elink_info->req_flow_ctrl)
279 			update_pause = true;
280 	}
281 
282 	/* Force update if link change is requested */
283 	if (elink_info->force_link_chng)
284 		update_pause = true;
285 
286 	/* Check if link speed or duplex settings have changed */
287 	if (!(elink_info->autoneg & BNGE_AUTONEG_SPEED)) {
288 		if (BNGE_AUTO_MODE(link_info->auto_mode) ||
289 		    bnge_force_speed_updated(bn) ||
290 		    elink_info->req_duplex != link_info->duplex_setting)
291 			update_link = true;
292 	} else {
293 		if (link_info->auto_mode == BNGE_LINK_AUTO_NONE ||
294 		    bnge_auto_speed_updated(bn))
295 			update_link = true;
296 	}
297 
298 	/* The last close may have shut down the link, so need to call
299 	 * PHY_CFG to bring it back up.
300 	 */
301 	if (!BNGE_LINK_IS_UP(bd))
302 		update_link = true;
303 
304 	if (update_link)
305 		rc = bnge_hwrm_set_link_setting(bn, update_pause);
306 	else if (update_pause)
307 		rc = bnge_hwrm_set_pause(bn);
308 
309 	if (rc) {
310 		netdev_err(bn->netdev,
311 			   "failed to update PHY setting (rc: %d)\n", rc);
312 		return rc;
313 	}
314 
315 	return 0;
316 }
317 
318 void bnge_get_port_module_status(struct bnge_net *bn)
319 {
320 	struct hwrm_port_phy_qcfg_output *resp;
321 	struct bnge_link_info *link_info;
322 	struct bnge_dev *bd = bn->bd;
323 	u8 module_status;
324 
325 	link_info = &bd->link_info;
326 	resp = &link_info->phy_qcfg_resp;
327 
328 	if (bnge_update_link(bn, true))
329 		return;
330 
331 	module_status = link_info->module_status;
332 	switch (module_status) {
333 	case PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX:
334 	case PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN:
335 	case PORT_PHY_QCFG_RESP_MODULE_STATUS_WARNINGMSG:
336 		netdev_warn(bn->netdev,
337 			    "Unqualified SFP+ module detected on port %d\n",
338 			    bd->pf.port_id);
339 		netdev_warn(bn->netdev, "Module part number %.*s\n",
340 			    (int)sizeof(resp->phy_vendor_partnumber),
341 			    resp->phy_vendor_partnumber);
342 		if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_DISABLETX)
343 			netdev_warn(bn->netdev, "TX is disabled\n");
344 		if (module_status == PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN)
345 			netdev_warn(bn->netdev, "SFP+ module is shut down\n");
346 		break;
347 	}
348 }
349 
350 static void bnge_set_default_adv_speeds(struct bnge_net *bn)
351 {
352 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
353 	struct bnge_link_info *link_info = &bn->bd->link_info;
354 
355 	elink_info->advertising = link_info->support_auto_speeds2;
356 }
357 
358 static bool bnge_support_dropped(u16 advertising, u16 supported)
359 {
360 	return (advertising & ~supported) != 0;
361 }
362 
363 bool bnge_support_speed_dropped(struct bnge_net *bn)
364 {
365 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
366 	struct bnge_link_info *link_info = &bn->bd->link_info;
367 
368 	/* Check if any advertised speeds are no longer supported. The caller
369 	 * holds the netdev instance lock, so we can modify link_info settings.
370 	 */
371 	if (bnge_support_dropped(elink_info->advertising,
372 				 link_info->support_auto_speeds2)) {
373 		elink_info->advertising = link_info->support_auto_speeds2;
374 		return true;
375 	}
376 	return false;
377 }
378 
379 static char *bnge_report_fec(struct bnge_link_info *link_info)
380 {
381 	u8 active_fec = link_info->active_fec_sig_mode &
382 			PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK;
383 
384 	switch (active_fec) {
385 	default:
386 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE:
387 		return "None";
388 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE:
389 		return "Clause 74 BaseR";
390 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE:
391 		return "Clause 91 RS(528,514)";
392 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE:
393 		return "Clause 91 RS544_1XN";
394 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE:
395 		return "Clause 91 RS(544,514)";
396 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE:
397 		return "Clause 91 RS272_1XN";
398 	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE:
399 		return "Clause 91 RS(272,257)";
400 	}
401 }
402 
403 void bnge_report_link(struct bnge_dev *bd)
404 {
405 	if (BNGE_LINK_IS_UP(bd)) {
406 		const char *signal = "";
407 		const char *flow_ctrl;
408 		const char *duplex;
409 		u32 speed;
410 		u16 fec;
411 
412 		netif_carrier_on(bd->netdev);
413 		speed = bnge_fw_to_ethtool_speed(bd->link_info.link_speed);
414 		if (speed == SPEED_UNKNOWN) {
415 			netdev_info(bd->netdev,
416 				    "NIC Link is Up, speed unknown\n");
417 			return;
418 		}
419 		if (bd->link_info.duplex == BNGE_LINK_DUPLEX_FULL)
420 			duplex = "full";
421 		else
422 			duplex = "half";
423 		if (bd->link_info.pause == BNGE_LINK_PAUSE_BOTH)
424 			flow_ctrl = "ON - receive & transmit";
425 		else if (bd->link_info.pause == BNGE_LINK_PAUSE_TX)
426 			flow_ctrl = "ON - transmit";
427 		else if (bd->link_info.pause == BNGE_LINK_PAUSE_RX)
428 			flow_ctrl = "ON - receive";
429 		else
430 			flow_ctrl = "none";
431 		if (bd->link_info.phy_qcfg_resp.option_flags &
432 		    PORT_PHY_QCFG_RESP_OPTION_FLAGS_SIGNAL_MODE_KNOWN) {
433 			u8 sig_mode = bd->link_info.active_fec_sig_mode &
434 				      PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK;
435 			switch (sig_mode) {
436 			case PORT_PHY_QCFG_RESP_SIGNAL_MODE_NRZ:
437 				signal = "(NRZ) ";
438 				break;
439 			case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4:
440 				signal = "(PAM4 56Gbps) ";
441 				break;
442 			case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4_112:
443 				signal = "(PAM4 112Gbps) ";
444 				break;
445 			default:
446 				break;
447 			}
448 		}
449 		netdev_info(bd->netdev, "NIC Link is Up, %u Mbps %s%s duplex, Flow control: %s\n",
450 			    speed, signal, duplex, flow_ctrl);
451 		fec = bd->link_info.fec_cfg;
452 		if (!(fec & PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED))
453 			netdev_info(bd->netdev, "FEC autoneg %s encoding: %s\n",
454 				    (fec & BNGE_FEC_AUTONEG) ? "on" : "off",
455 				    bnge_report_fec(&bd->link_info));
456 	} else {
457 		netif_carrier_off(bd->netdev);
458 		netdev_info(bd->netdev, "NIC Link is Down\n");
459 	}
460 }
461 
462 static void bnge_get_ethtool_modes(struct bnge_net *bn,
463 				   struct ethtool_link_ksettings *lk_ksettings)
464 {
465 	struct bnge_ethtool_link_info *elink_info;
466 	struct bnge_link_info *link_info;
467 	struct bnge_dev *bd = bn->bd;
468 
469 	elink_info = &bn->eth_link_info;
470 	link_info = &bd->link_info;
471 
472 	if (!(bd->phy_flags & BNGE_PHY_FL_NO_PAUSE)) {
473 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
474 				 lk_ksettings->link_modes.supported);
475 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
476 				 lk_ksettings->link_modes.supported);
477 	}
478 
479 	if (link_info->support_auto_speeds2)
480 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
481 				 lk_ksettings->link_modes.supported);
482 
483 	if (~elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL)
484 		return;
485 
486 	if (link_info->auto_pause_setting & BNGE_LINK_PAUSE_RX)
487 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
488 				 lk_ksettings->link_modes.advertising);
489 	if (hweight8(link_info->auto_pause_setting & BNGE_LINK_PAUSE_BOTH) == 1)
490 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
491 				 lk_ksettings->link_modes.advertising);
492 	if (link_info->lp_pause & BNGE_LINK_PAUSE_RX)
493 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
494 				 lk_ksettings->link_modes.lp_advertising);
495 	if (hweight8(link_info->lp_pause & BNGE_LINK_PAUSE_BOTH) == 1)
496 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
497 				 lk_ksettings->link_modes.lp_advertising);
498 }
499 
500 u32 bnge_get_link(struct net_device *dev)
501 {
502 	struct bnge_net *bn = netdev_priv(dev);
503 
504 	return BNGE_LINK_IS_UP(bn->bd);
505 }
506 
507 static enum bnge_media_type
508 bnge_get_media(struct bnge_link_info *link_info)
509 {
510 	switch (link_info->media_type) {
511 	case PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC:
512 		return BNGE_MEDIA_CR;
513 	default:
514 		if (link_info->phy_type < ARRAY_SIZE(bnge_phy_types))
515 			return bnge_phy_types[link_info->phy_type];
516 		return BNGE_MEDIA_UNKNOWN;
517 	}
518 }
519 
520 enum bnge_link_speed_indices {
521 	BNGE_LINK_SPEED_UNKNOWN = 0,
522 	BNGE_LINK_SPEED_50GB_IDX,
523 	BNGE_LINK_SPEED_100GB_IDX,
524 	BNGE_LINK_SPEED_200GB_IDX,
525 	BNGE_LINK_SPEED_400GB_IDX,
526 	BNGE_LINK_SPEED_800GB_IDX,
527 	__BNGE_LINK_SPEED_END
528 };
529 
530 static enum bnge_link_speed_indices bnge_fw_speed_idx(u16 speed)
531 {
532 	switch (speed) {
533 	case BNGE_LINK_SPEED_50GB:
534 	case BNGE_LINK_SPEED_50GB_PAM4:
535 		return BNGE_LINK_SPEED_50GB_IDX;
536 	case BNGE_LINK_SPEED_100GB:
537 	case BNGE_LINK_SPEED_100GB_PAM4:
538 	case BNGE_LINK_SPEED_100GB_PAM4_112:
539 		return BNGE_LINK_SPEED_100GB_IDX;
540 	case BNGE_LINK_SPEED_200GB:
541 	case BNGE_LINK_SPEED_200GB_PAM4:
542 	case BNGE_LINK_SPEED_200GB_PAM4_112:
543 		return BNGE_LINK_SPEED_200GB_IDX;
544 	case BNGE_LINK_SPEED_400GB:
545 	case BNGE_LINK_SPEED_400GB_PAM4:
546 	case BNGE_LINK_SPEED_400GB_PAM4_112:
547 		return BNGE_LINK_SPEED_400GB_IDX;
548 	case BNGE_LINK_SPEED_800GB:
549 	case BNGE_LINK_SPEED_800GB_PAM4_112:
550 		return BNGE_LINK_SPEED_800GB_IDX;
551 	default:
552 		return BNGE_LINK_SPEED_UNKNOWN;
553 	}
554 }
555 
556 /* Compile-time link mode mapping table.
557  * Indexed by [speed_idx][sig_mode][media].
558  */
559 #define BNGE_LINK_M(speed, sig, media, lm)	\
560 	[BNGE_LINK_SPEED_##speed##_IDX]	\
561 	[BNGE_SIG_MODE_##sig]		\
562 	[BNGE_MEDIA_##media] = ETHTOOL_LINK_MODE_##lm##_Full_BIT
563 
564 static const enum ethtool_link_mode_bit_indices
565 bnge_link_modes[__BNGE_LINK_SPEED_END]
566 	       [BNGE_SIG_MODE_MAX]
567 	       [__BNGE_MEDIA_END] = {
568 	/* 50GB PAM4 */
569 	BNGE_LINK_M(50GB,  PAM4, CR,        50000baseCR),
570 	BNGE_LINK_M(50GB,  PAM4, SR,        50000baseSR),
571 	BNGE_LINK_M(50GB,  PAM4, LR_ER_FR,  50000baseLR_ER_FR),
572 	BNGE_LINK_M(50GB,  PAM4, KR,        50000baseKR),
573 
574 	/* 100GB NRZ */
575 	BNGE_LINK_M(100GB, NRZ,  CR,        100000baseCR4),
576 	BNGE_LINK_M(100GB, NRZ,  SR,        100000baseSR4),
577 	BNGE_LINK_M(100GB, NRZ,  LR_ER_FR,  100000baseLR4_ER4),
578 	BNGE_LINK_M(100GB, NRZ,  KR,        100000baseKR4),
579 
580 	/* 100GB PAM4 */
581 	BNGE_LINK_M(100GB, PAM4, CR,        100000baseCR2),
582 	BNGE_LINK_M(100GB, PAM4, SR,        100000baseSR2),
583 	BNGE_LINK_M(100GB, PAM4, LR_ER_FR,  100000baseLR2_ER2_FR2),
584 	BNGE_LINK_M(100GB, PAM4, KR,        100000baseKR2),
585 
586 	/* 100GB PAM4_112 */
587 	BNGE_LINK_M(100GB, PAM4_112, CR,        100000baseCR),
588 	BNGE_LINK_M(100GB, PAM4_112, SR,        100000baseSR),
589 	BNGE_LINK_M(100GB, PAM4_112, LR_ER_FR,  100000baseLR_ER_FR),
590 	BNGE_LINK_M(100GB, PAM4_112, KR,        100000baseKR),
591 
592 	/* 200GB PAM4 */
593 	BNGE_LINK_M(200GB, PAM4, CR,        200000baseCR4),
594 	BNGE_LINK_M(200GB, PAM4, SR,        200000baseSR4),
595 	BNGE_LINK_M(200GB, PAM4, LR_ER_FR,  200000baseLR4_ER4_FR4),
596 	BNGE_LINK_M(200GB, PAM4, KR,        200000baseKR4),
597 
598 	/* 200GB PAM4_112 */
599 	BNGE_LINK_M(200GB, PAM4_112, CR,        200000baseCR2),
600 	BNGE_LINK_M(200GB, PAM4_112, SR,        200000baseSR2),
601 	BNGE_LINK_M(200GB, PAM4_112, LR_ER_FR,  200000baseLR2_ER2_FR2),
602 	BNGE_LINK_M(200GB, PAM4_112, KR,        200000baseKR2),
603 
604 	/* 400GB PAM4 */
605 	BNGE_LINK_M(400GB, PAM4, CR,        400000baseCR8),
606 	BNGE_LINK_M(400GB, PAM4, SR,        400000baseSR8),
607 	BNGE_LINK_M(400GB, PAM4, LR_ER_FR,  400000baseLR8_ER8_FR8),
608 	BNGE_LINK_M(400GB, PAM4, KR,        400000baseKR8),
609 
610 	/* 400GB PAM4_112 */
611 	BNGE_LINK_M(400GB, PAM4_112, CR,        400000baseCR4),
612 	BNGE_LINK_M(400GB, PAM4_112, SR,        400000baseSR4),
613 	BNGE_LINK_M(400GB, PAM4_112, LR_ER_FR,  400000baseLR4_ER4_FR4),
614 	BNGE_LINK_M(400GB, PAM4_112, KR,        400000baseKR4),
615 
616 	/* 800GB PAM4_112 */
617 	BNGE_LINK_M(800GB, PAM4_112, CR,        800000baseCR8),
618 	BNGE_LINK_M(800GB, PAM4_112, SR,        800000baseSR8),
619 	BNGE_LINK_M(800GB, PAM4_112, KR,        800000baseKR8),
620 };
621 
622 #define BNGE_LINK_MODE_UNKNOWN -1
623 
624 static enum ethtool_link_mode_bit_indices
625 bnge_get_link_mode(struct bnge_net *bn)
626 {
627 	enum ethtool_link_mode_bit_indices link_mode;
628 	struct bnge_ethtool_link_info *elink_info;
629 	enum bnge_link_speed_indices speed;
630 	struct bnge_link_info *link_info;
631 	struct bnge_dev *bd = bn->bd;
632 	enum bnge_media_type media;
633 	u8 sig_mode;
634 
635 	elink_info = &bn->eth_link_info;
636 	link_info = &bd->link_info;
637 
638 	if (link_info->phy_link_status != BNGE_LINK_LINK)
639 		return BNGE_LINK_MODE_UNKNOWN;
640 
641 	media = bnge_get_media(link_info);
642 	if (BNGE_AUTO_MODE(link_info->auto_mode)) {
643 		speed = bnge_fw_speed_idx(link_info->link_speed);
644 		sig_mode = link_info->active_fec_sig_mode &
645 			PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK;
646 	} else {
647 		speed = bnge_fw_speed_idx(elink_info->req_link_speed);
648 		sig_mode = elink_info->req_signal_mode;
649 	}
650 	if (sig_mode >= BNGE_SIG_MODE_MAX)
651 		return BNGE_LINK_MODE_UNKNOWN;
652 
653 	/* Since ETHTOOL_LINK_MODE_10baseT_Half_BIT is defined as 0 and
654 	 * not actually supported, the zeroes in this map can be safely
655 	 * used to represent unknown link modes.
656 	 */
657 	link_mode = bnge_link_modes[speed][sig_mode][media];
658 	if (!link_mode)
659 		return BNGE_LINK_MODE_UNKNOWN;
660 
661 	return link_mode;
662 }
663 
664 static const u16 bnge_nrz_speeds2_masks[__BNGE_LINK_SPEED_END] = {
665 	[BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB,
666 };
667 
668 static const u16 bnge_pam4_speeds2_masks[__BNGE_LINK_SPEED_END] = {
669 	[BNGE_LINK_SPEED_50GB_IDX] = BNGE_LINK_SPEEDS2_MSK_50GB_PAM4,
670 	[BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB_PAM4,
671 	[BNGE_LINK_SPEED_200GB_IDX] = BNGE_LINK_SPEEDS2_MSK_200GB_PAM4,
672 	[BNGE_LINK_SPEED_400GB_IDX] = BNGE_LINK_SPEEDS2_MSK_400GB_PAM4,
673 };
674 
675 static const u16 bnge_pam4_112_speeds2_masks[__BNGE_LINK_SPEED_END] = {
676 	[BNGE_LINK_SPEED_100GB_IDX] = BNGE_LINK_SPEEDS2_MSK_100GB_PAM4_112,
677 	[BNGE_LINK_SPEED_200GB_IDX] = BNGE_LINK_SPEEDS2_MSK_200GB_PAM4_112,
678 	[BNGE_LINK_SPEED_400GB_IDX] = BNGE_LINK_SPEEDS2_MSK_400GB_PAM4_112,
679 	[BNGE_LINK_SPEED_800GB_IDX] = BNGE_LINK_SPEEDS2_MSK_800GB_PAM4_112,
680 };
681 
682 static enum bnge_link_speed_indices
683 bnge_encoding_speed_idx(u8 sig_mode, u16 speed_msk)
684 {
685 	const u16 *speeds;
686 	int idx, len;
687 
688 	switch (sig_mode) {
689 	case BNGE_SIG_MODE_NRZ:
690 		speeds = bnge_nrz_speeds2_masks;
691 		len = ARRAY_SIZE(bnge_nrz_speeds2_masks);
692 		break;
693 	case BNGE_SIG_MODE_PAM4:
694 		speeds = bnge_pam4_speeds2_masks;
695 		len = ARRAY_SIZE(bnge_pam4_speeds2_masks);
696 		break;
697 	case BNGE_SIG_MODE_PAM4_112:
698 		speeds = bnge_pam4_112_speeds2_masks;
699 		len = ARRAY_SIZE(bnge_pam4_112_speeds2_masks);
700 		break;
701 	default:
702 		return BNGE_LINK_SPEED_UNKNOWN;
703 	}
704 
705 	for (idx = 0; idx < len; idx++) {
706 		if (speeds[idx] == speed_msk)
707 			return idx;
708 	}
709 
710 	return BNGE_LINK_SPEED_UNKNOWN;
711 }
712 
713 #define BNGE_FW_SPEED_MSK_BITS 16
714 
715 static void
716 __bnge_get_ethtool_speeds(unsigned long fw_mask, enum bnge_media_type media,
717 			  u8 sig_mode, unsigned long *et_mask)
718 {
719 	enum ethtool_link_mode_bit_indices link_mode;
720 	enum bnge_link_speed_indices speed;
721 	u8 bit;
722 
723 	for_each_set_bit(bit, &fw_mask, BNGE_FW_SPEED_MSK_BITS) {
724 		speed = bnge_encoding_speed_idx(sig_mode, 1 << bit);
725 		if (!speed)
726 			continue;
727 
728 		link_mode = bnge_link_modes[speed][sig_mode][media];
729 		if (!link_mode)
730 			continue;
731 
732 		linkmode_set_bit(link_mode, et_mask);
733 	}
734 }
735 
736 static void
737 bnge_get_ethtool_speeds(unsigned long fw_mask, enum bnge_media_type media,
738 			u8 sig_mode, unsigned long *et_mask)
739 {
740 	if (media) {
741 		__bnge_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask);
742 		return;
743 	}
744 
745 	/* list speeds for all media if unknown */
746 	for (media = 1; media < __BNGE_MEDIA_END; media++)
747 		__bnge_get_ethtool_speeds(fw_mask, media, sig_mode, et_mask);
748 }
749 
750 static void
751 bnge_get_all_ethtool_support_speeds(struct bnge_dev *bd,
752 				    enum bnge_media_type media,
753 				    struct ethtool_link_ksettings *lk_ksettings)
754 {
755 	u16 sp = bd->link_info.support_speeds2;
756 
757 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ,
758 				lk_ksettings->link_modes.supported);
759 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4,
760 				lk_ksettings->link_modes.supported);
761 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112,
762 				lk_ksettings->link_modes.supported);
763 }
764 
765 static void
766 bnge_get_all_ethtool_adv_speeds(struct bnge_net *bn,
767 				enum bnge_media_type media,
768 				struct ethtool_link_ksettings *lk_ksettings)
769 {
770 	u16 sp = bn->eth_link_info.advertising;
771 
772 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ,
773 				lk_ksettings->link_modes.advertising);
774 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4,
775 				lk_ksettings->link_modes.advertising);
776 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112,
777 				lk_ksettings->link_modes.advertising);
778 }
779 
780 static void
781 bnge_get_all_ethtool_lp_speeds(struct bnge_dev *bd,
782 			       enum bnge_media_type media,
783 			       struct ethtool_link_ksettings *lk_ksettings)
784 {
785 	u16 sp = bd->link_info.lp_auto_link_speeds;
786 
787 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_NRZ,
788 				lk_ksettings->link_modes.lp_advertising);
789 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4,
790 				lk_ksettings->link_modes.lp_advertising);
791 	bnge_get_ethtool_speeds(sp, media, BNGE_SIG_MODE_PAM4_112,
792 				lk_ksettings->link_modes.lp_advertising);
793 }
794 
795 static void bnge_update_speed(u32 *delta, bool installed_media, u16 *speeds,
796 			      u16 speed_msk, const unsigned long *et_mask,
797 			      enum ethtool_link_mode_bit_indices mode)
798 {
799 	bool mode_desired = linkmode_test_bit(mode, et_mask);
800 
801 	if (!mode || !mode_desired)
802 		return;
803 
804 	/* installed media takes priority; for non-installed media, only allow
805 	 * one change per fw_speed bit (many to one mapping).
806 	 */
807 	if (installed_media || !(*delta & speed_msk)) {
808 		*speeds |= speed_msk;
809 		*delta |= speed_msk;
810 	}
811 }
812 
813 static void bnge_set_ethtool_speeds(struct bnge_net *bn,
814 				    const unsigned long *et_mask)
815 {
816 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
817 	enum bnge_media_type media;
818 	u32 delta_pam4_112 = 0;
819 	u32 delta_pam4 = 0;
820 	u32 delta_nrz = 0;
821 	int i, m;
822 
823 	elink_info->advertising = 0;
824 
825 	media = bnge_get_media(&bn->bd->link_info);
826 	for (i = 1; i < __BNGE_LINK_SPEED_END; i++) {
827 		/* accept any legal media from user */
828 		for (m = 1; m < __BNGE_MEDIA_END; m++) {
829 			bnge_update_speed(&delta_nrz, m == media,
830 					  &elink_info->advertising,
831 					  bnge_nrz_speeds2_masks[i], et_mask,
832 					  bnge_link_modes[i][BNGE_SIG_MODE_NRZ][m]);
833 			bnge_update_speed(&delta_pam4, m == media,
834 					  &elink_info->advertising,
835 					  bnge_pam4_speeds2_masks[i], et_mask,
836 					  bnge_link_modes[i][BNGE_SIG_MODE_PAM4][m]);
837 			bnge_update_speed(&delta_pam4_112, m == media,
838 					  &elink_info->advertising,
839 					  bnge_pam4_112_speeds2_masks[i],
840 					  et_mask,
841 					  bnge_link_modes[i][BNGE_SIG_MODE_PAM4_112][m]);
842 		}
843 	}
844 }
845 
846 static void
847 bnge_fw_to_ethtool_advertised_fec(struct bnge_link_info *link_info,
848 				  struct ethtool_link_ksettings *lk_ksettings)
849 {
850 	u16 fec_cfg = link_info->fec_cfg;
851 
852 	if ((fec_cfg & BNGE_FEC_NONE) || !(fec_cfg & BNGE_FEC_AUTONEG)) {
853 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
854 				 lk_ksettings->link_modes.advertising);
855 		return;
856 	}
857 	if (fec_cfg & BNGE_FEC_ENC_BASE_R)
858 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
859 				 lk_ksettings->link_modes.advertising);
860 	if (fec_cfg & BNGE_FEC_ENC_RS)
861 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
862 				 lk_ksettings->link_modes.advertising);
863 	if (fec_cfg & BNGE_FEC_ENC_LLRS)
864 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
865 				 lk_ksettings->link_modes.advertising);
866 }
867 
868 static void
869 bnge_fw_to_ethtool_support_fec(struct bnge_link_info *link_info,
870 			       struct ethtool_link_ksettings *lk_ksettings)
871 {
872 	u16 fec_cfg = link_info->fec_cfg;
873 
874 	if (fec_cfg & BNGE_FEC_NONE) {
875 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
876 				 lk_ksettings->link_modes.supported);
877 		return;
878 	}
879 	if (fec_cfg & BNGE_FEC_ENC_BASE_R_CAP)
880 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
881 				 lk_ksettings->link_modes.supported);
882 	if (fec_cfg & BNGE_FEC_ENC_RS_CAP)
883 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
884 				 lk_ksettings->link_modes.supported);
885 	if (fec_cfg & BNGE_FEC_ENC_LLRS_CAP)
886 		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
887 				 lk_ksettings->link_modes.supported);
888 }
889 
890 static void bnge_get_default_speeds(struct bnge_net *bn,
891 				    struct ethtool_link_ksettings *lk_ksettings)
892 {
893 	struct bnge_ethtool_link_info *elink_info = &bn->eth_link_info;
894 	struct ethtool_link_settings *base = &lk_ksettings->base;
895 	struct bnge_link_info *link_info;
896 	struct bnge_dev *bd = bn->bd;
897 
898 	link_info = &bd->link_info;
899 
900 	if (link_info->link_state == BNGE_LINK_STATE_UP) {
901 		base->speed = bnge_fw_to_ethtool_speed(link_info->link_speed);
902 		base->duplex = DUPLEX_HALF;
903 		if (link_info->duplex & BNGE_LINK_DUPLEX_FULL)
904 			base->duplex = DUPLEX_FULL;
905 		lk_ksettings->lanes = link_info->active_lanes;
906 	} else if (!elink_info->autoneg) {
907 		base->speed =
908 			bnge_fw_to_ethtool_speed(elink_info->req_link_speed);
909 		base->duplex = DUPLEX_HALF;
910 		if (elink_info->req_duplex == BNGE_LINK_DUPLEX_FULL)
911 			base->duplex = DUPLEX_FULL;
912 	}
913 }
914 
915 int bnge_get_link_ksettings(struct net_device *dev,
916 			    struct ethtool_link_ksettings *lk_ksettings)
917 {
918 	struct ethtool_link_settings *base = &lk_ksettings->base;
919 	enum ethtool_link_mode_bit_indices link_mode;
920 	struct bnge_net *bn = netdev_priv(dev);
921 	struct bnge_link_info *link_info;
922 	struct bnge_dev *bd = bn->bd;
923 	enum bnge_media_type media;
924 
925 	ethtool_link_ksettings_zero_link_mode(lk_ksettings, lp_advertising);
926 	ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising);
927 	ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported);
928 	base->duplex = DUPLEX_UNKNOWN;
929 	base->speed = SPEED_UNKNOWN;
930 	link_info = &bd->link_info;
931 
932 	bnge_get_ethtool_modes(bn, lk_ksettings);
933 	media = bnge_get_media(link_info);
934 	bnge_get_all_ethtool_support_speeds(bd, media, lk_ksettings);
935 	bnge_fw_to_ethtool_support_fec(link_info, lk_ksettings);
936 	link_mode = bnge_get_link_mode(bn);
937 	if (link_mode != BNGE_LINK_MODE_UNKNOWN)
938 		ethtool_params_from_link_mode(lk_ksettings, link_mode);
939 	else
940 		bnge_get_default_speeds(bn, lk_ksettings);
941 
942 	if (bn->eth_link_info.autoneg) {
943 		bnge_fw_to_ethtool_advertised_fec(link_info, lk_ksettings);
944 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
945 				 lk_ksettings->link_modes.advertising);
946 		base->autoneg = AUTONEG_ENABLE;
947 		bnge_get_all_ethtool_adv_speeds(bn, media, lk_ksettings);
948 		if (link_info->phy_link_status == BNGE_LINK_LINK)
949 			bnge_get_all_ethtool_lp_speeds(bd, media, lk_ksettings);
950 	} else {
951 		base->autoneg = AUTONEG_DISABLE;
952 	}
953 
954 	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
955 			 lk_ksettings->link_modes.supported);
956 	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
957 			 lk_ksettings->link_modes.advertising);
958 
959 	if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC)
960 		base->port = PORT_DA;
961 	else
962 		base->port = PORT_FIBRE;
963 	base->phy_address = link_info->phy_addr;
964 
965 	return 0;
966 }
967 
968 static bool bnge_lanes_match(u32 user_lanes, u32 supported_lanes)
969 {
970 	/* 0 means lanes unspecified (auto) */
971 	return !user_lanes || user_lanes == supported_lanes;
972 }
973 
974 static int
975 bnge_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 user_lanes)
976 {
977 	struct bnge_ethtool_link_info *elink_info;
978 	struct bnge_net *bn = netdev_priv(dev);
979 	u8 sig_mode = BNGE_SIG_MODE_NRZ;
980 	u16 support_spds2;
981 	u16 fw_speed = 0;
982 
983 	elink_info = &bn->eth_link_info;
984 	support_spds2 = bn->bd->link_info.support_speeds2;
985 
986 	switch (ethtool_speed) {
987 	case SPEED_50000:
988 		if (bnge_lanes_match(user_lanes, 1) &&
989 		    (support_spds2 & BNGE_LINK_SPEEDS2_MSK_50GB_PAM4)) {
990 			fw_speed = BNGE_LINK_SPEED_50GB_PAM4;
991 			sig_mode = BNGE_SIG_MODE_PAM4;
992 		}
993 		break;
994 	case SPEED_100000:
995 		if (bnge_lanes_match(user_lanes, 4) &&
996 		    (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB)) {
997 			fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB;
998 		} else if (bnge_lanes_match(user_lanes, 2) &&
999 			   (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB_PAM4)) {
1000 			fw_speed = BNGE_LINK_SPEED_100GB_PAM4;
1001 			sig_mode = BNGE_SIG_MODE_PAM4;
1002 		} else if (bnge_lanes_match(user_lanes, 1) &&
1003 			   (support_spds2 & BNGE_LINK_SPEEDS2_MSK_100GB_PAM4_112)) {
1004 			fw_speed = BNGE_LINK_SPEED_100GB_PAM4_112;
1005 			sig_mode = BNGE_SIG_MODE_PAM4_112;
1006 		}
1007 		break;
1008 	case SPEED_200000:
1009 		if (bnge_lanes_match(user_lanes, 4) &&
1010 		    (support_spds2 & BNGE_LINK_SPEEDS2_MSK_200GB_PAM4)) {
1011 			fw_speed = BNGE_LINK_SPEED_200GB_PAM4;
1012 			sig_mode = BNGE_SIG_MODE_PAM4;
1013 		} else if (bnge_lanes_match(user_lanes, 2) &&
1014 			   (support_spds2 & BNGE_LINK_SPEEDS2_MSK_200GB_PAM4_112)) {
1015 			fw_speed = BNGE_LINK_SPEED_200GB_PAM4_112;
1016 			sig_mode = BNGE_SIG_MODE_PAM4_112;
1017 		}
1018 		break;
1019 	case SPEED_400000:
1020 		if (bnge_lanes_match(user_lanes, 8) &&
1021 		    (support_spds2 & BNGE_LINK_SPEEDS2_MSK_400GB_PAM4)) {
1022 			fw_speed = BNGE_LINK_SPEED_400GB_PAM4;
1023 			sig_mode = BNGE_SIG_MODE_PAM4;
1024 		} else if (bnge_lanes_match(user_lanes, 4) &&
1025 			   (support_spds2 & BNGE_LINK_SPEEDS2_MSK_400GB_PAM4_112)) {
1026 			fw_speed = BNGE_LINK_SPEED_400GB_PAM4_112;
1027 			sig_mode = BNGE_SIG_MODE_PAM4_112;
1028 		}
1029 		break;
1030 	case SPEED_800000:
1031 		if (bnge_lanes_match(user_lanes, 8) &&
1032 		    (support_spds2 & BNGE_LINK_SPEEDS2_MSK_800GB_PAM4_112)) {
1033 			fw_speed = BNGE_LINK_SPEED_800GB_PAM4_112;
1034 			sig_mode = BNGE_SIG_MODE_PAM4_112;
1035 		}
1036 		break;
1037 	default:
1038 		break;
1039 	}
1040 
1041 	if (!fw_speed) {
1042 		if (user_lanes)
1043 			netdev_err(dev, "unsupported speed or number of lanes!\n");
1044 		else
1045 			netdev_err(dev, "unsupported speed!\n");
1046 		return -EINVAL;
1047 	}
1048 
1049 	if (elink_info->req_link_speed == fw_speed &&
1050 	    elink_info->req_signal_mode == sig_mode &&
1051 	    elink_info->autoneg == 0)
1052 		return -EALREADY;
1053 
1054 	elink_info->req_link_speed = fw_speed;
1055 	elink_info->req_signal_mode = sig_mode;
1056 	elink_info->req_duplex = BNGE_LINK_DUPLEX_FULL;
1057 	elink_info->autoneg = 0;
1058 	elink_info->advertising = 0;
1059 
1060 	return 0;
1061 }
1062 
1063 int bnge_set_link_ksettings(struct net_device *dev,
1064 			    const struct ethtool_link_ksettings *lk_ksettings)
1065 {
1066 	const struct ethtool_link_settings *base = &lk_ksettings->base;
1067 	struct bnge_ethtool_link_info old_elink_info;
1068 	struct bnge_ethtool_link_info *elink_info;
1069 	struct bnge_net *bn = netdev_priv(dev);
1070 	struct bnge_dev *bd = bn->bd;
1071 	bool set_pause = false;
1072 	int rc = 0;
1073 
1074 	if (!BNGE_PHY_CFG_ABLE(bd))
1075 		return -EOPNOTSUPP;
1076 
1077 	elink_info = &bn->eth_link_info;
1078 	old_elink_info = *elink_info;
1079 
1080 	if (base->autoneg == AUTONEG_ENABLE) {
1081 		bnge_set_ethtool_speeds(bn,
1082 					lk_ksettings->link_modes.advertising);
1083 		elink_info->autoneg |= BNGE_AUTONEG_SPEED;
1084 		if (!elink_info->advertising)
1085 			bnge_set_default_adv_speeds(bn);
1086 		/* any change to autoneg will cause link change, therefore the
1087 		 * driver should put back the original pause setting in autoneg
1088 		 */
1089 		if (!(bd->phy_flags & BNGE_PHY_FL_NO_PAUSE))
1090 			set_pause = true;
1091 	} else {
1092 		if (base->duplex == DUPLEX_HALF) {
1093 			netdev_err(dev, "HALF DUPLEX is not supported!\n");
1094 			rc = -EINVAL;
1095 			goto set_setting_exit;
1096 		}
1097 		rc = bnge_force_link_speed(dev, base->speed,
1098 					   lk_ksettings->lanes);
1099 		if (rc) {
1100 			if (rc == -EALREADY)
1101 				rc = 0;
1102 			goto set_setting_exit;
1103 		}
1104 	}
1105 
1106 	if (netif_running(dev)) {
1107 		rc = bnge_hwrm_set_link_setting(bn, set_pause);
1108 		if (rc)
1109 			*elink_info = old_elink_info;
1110 	}
1111 
1112 set_setting_exit:
1113 	return rc;
1114 }
1115 
1116 void bnge_link_async_event_process(struct bnge_net *bn, u16 event_id)
1117 {
1118 	switch (event_id) {
1119 	case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
1120 		set_bit(BNGE_LINK_SPEED_CHNG_SP_EVENT, &bn->sp_event);
1121 		break;
1122 	case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
1123 	case ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE:
1124 		set_bit(BNGE_LINK_CFG_CHANGE_SP_EVENT, &bn->sp_event);
1125 		break;
1126 	case ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
1127 		set_bit(BNGE_LINK_CHNG_SP_EVENT, &bn->sp_event);
1128 		break;
1129 	default:
1130 		break;
1131 	}
1132 }
1133