xref: /linux/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c (revision fab183d632628381b466a41479489541ac0e29a0)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2015 - 2025 Beijing WangXun Technology Co., Ltd. */
3 
4 #include <linux/phylink.h>
5 #include <linux/iopoll.h>
6 #include <linux/pci.h>
7 #include <linux/phy.h>
8 
9 #include "../libwx/wx_type.h"
10 #include "../libwx/wx_lib.h"
11 #include "../libwx/wx_ptp.h"
12 #include "../libwx/wx_hw.h"
13 #include "../libwx/wx_sriov.h"
14 #include "txgbe_type.h"
15 #include "txgbe_aml.h"
16 #include "txgbe_hw.h"
17 
txgbe_gpio_init_aml(struct wx * wx)18 void txgbe_gpio_init_aml(struct wx *wx)
19 {
20 	u32 status, mod_rst;
21 
22 	if (wx->mac.type == wx_mac_aml40)
23 		mod_rst = TXGBE_GPIOBIT_4;
24 	else
25 		mod_rst = TXGBE_GPIOBIT_2;
26 
27 	wr32(wx, WX_GPIO_INTTYPE_LEVEL, mod_rst);
28 	wr32(wx, WX_GPIO_INTEN, mod_rst);
29 
30 	status = rd32(wx, WX_GPIO_INTSTATUS);
31 	for (int i = 0; i < 6; i++) {
32 		if (status & BIT(i))
33 			wr32(wx, WX_GPIO_EOI, BIT(i));
34 	}
35 }
36 
txgbe_gpio_irq_handler_aml(int irq,void * data)37 irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
38 {
39 	struct txgbe *txgbe = data;
40 	struct wx *wx = txgbe->wx;
41 	u32 status, mod_rst;
42 
43 	if (wx->mac.type == wx_mac_aml40)
44 		mod_rst = TXGBE_GPIOBIT_4;
45 	else
46 		mod_rst = TXGBE_GPIOBIT_2;
47 
48 	wr32(wx, WX_GPIO_INTMASK, 0xFF);
49 	status = rd32(wx, WX_GPIO_INTSTATUS);
50 	if (status & mod_rst) {
51 		set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags);
52 		wr32(wx, WX_GPIO_EOI, mod_rst);
53 		wx_service_event_schedule(wx);
54 	}
55 
56 	wr32(wx, WX_GPIO_INTMASK, 0);
57 	return IRQ_HANDLED;
58 }
59 
txgbe_test_hostif(struct wx * wx)60 int txgbe_test_hostif(struct wx *wx)
61 {
62 	struct txgbe_hic_ephy_getlink buffer;
63 
64 	if (wx->mac.type == wx_mac_sp)
65 		return 0;
66 
67 	buffer.hdr.cmd = FW_PHY_GET_LINK_CMD;
68 	buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_getlink) -
69 			     sizeof(struct wx_hic_hdr);
70 	buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
71 
72 	return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
73 					 WX_HI_COMMAND_TIMEOUT, false);
74 }
75 
txgbe_read_eeprom_hostif(struct wx * wx,struct txgbe_hic_i2c_read * buffer,u32 length,u8 * data)76 int txgbe_read_eeprom_hostif(struct wx *wx,
77 			     struct txgbe_hic_i2c_read *buffer,
78 			     u32 length, u8 *data)
79 {
80 	u32 dword_len, offset, value, i;
81 	int err;
82 
83 	buffer->hdr.cmd = FW_READ_EEPROM_CMD;
84 	buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) -
85 			      sizeof(struct wx_hic_hdr);
86 	buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
87 
88 	err = wx_host_interface_command(wx, (u32 *)buffer,
89 					sizeof(struct txgbe_hic_i2c_read),
90 					WX_HI_COMMAND_TIMEOUT, false);
91 	if (err != 0)
92 		return err;
93 
94 	/* buffer length offset to read return data */
95 	offset = sizeof(struct txgbe_hic_i2c_read) >> 2;
96 	dword_len = round_up(length, 4) >> 2;
97 
98 	for (i = 0; i < dword_len; i++) {
99 		u32 copy_len = min_t(u32, 4, length - i * 4);
100 
101 		value = rd32a(wx, WX_FW2SW_MBOX, i + offset);
102 		le32_to_cpus(&value);
103 
104 		memcpy(data, &value, copy_len);
105 		data += copy_len;
106 	}
107 
108 	return 0;
109 }
110 
txgbe_identify_module_hostif(struct wx * wx,struct txgbe_hic_get_module_info * buffer)111 static int txgbe_identify_module_hostif(struct wx *wx,
112 					struct txgbe_hic_get_module_info *buffer)
113 {
114 	buffer->hdr.cmd = FW_GET_MODULE_INFO_CMD;
115 	buffer->hdr.buf_len = sizeof(struct txgbe_hic_get_module_info) -
116 			      sizeof(struct wx_hic_hdr);
117 	buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
118 
119 	return wx_host_interface_command(wx, (u32 *)buffer,
120 					 sizeof(struct txgbe_hic_get_module_info),
121 					 WX_HI_COMMAND_TIMEOUT, true);
122 }
123 
txgbe_set_phy_link_hostif(struct wx * wx,int speed,int autoneg,int duplex)124 static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int duplex)
125 {
126 	struct txgbe_hic_ephy_setlink buffer;
127 
128 	buffer.hdr.cmd = FW_PHY_SET_LINK_CMD;
129 	buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_setlink) -
130 			     sizeof(struct wx_hic_hdr);
131 	buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
132 
133 	switch (speed) {
134 	case SPEED_40000:
135 		buffer.speed = TXGBE_LINK_SPEED_40GB_FULL;
136 		break;
137 	case SPEED_25000:
138 		buffer.speed = TXGBE_LINK_SPEED_25GB_FULL;
139 		break;
140 	case SPEED_10000:
141 		buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
142 		break;
143 	default:
144 		buffer.speed = TXGBE_LINK_SPEED_UNKNOWN;
145 		break;
146 	}
147 
148 	buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
149 	buffer.autoneg = autoneg;
150 	buffer.duplex = duplex;
151 
152 	return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
153 					 WX_HI_COMMAND_TIMEOUT, false);
154 }
155 
txgbe_get_link_capabilities(struct wx * wx,int * speed,int * autoneg,int * duplex)156 static void txgbe_get_link_capabilities(struct wx *wx, int *speed,
157 					int *autoneg, int *duplex)
158 {
159 	struct txgbe *txgbe = wx->priv;
160 
161 	if (test_bit(PHY_INTERFACE_MODE_XLGMII, txgbe->link_interfaces))
162 		*speed = SPEED_40000;
163 	else if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->link_interfaces))
164 		*speed = SPEED_25000;
165 	else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->link_interfaces))
166 		*speed = SPEED_10000;
167 	else
168 		*speed = SPEED_UNKNOWN;
169 
170 	*autoneg = phylink_test(txgbe->advertising, Autoneg);
171 	*duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL;
172 }
173 
txgbe_get_mac_link(struct wx * wx,int * speed)174 static void txgbe_get_mac_link(struct wx *wx, int *speed)
175 {
176 	u32 status;
177 
178 	status = rd32(wx, TXGBE_CFG_PORT_ST);
179 	if (!(status & TXGBE_CFG_PORT_ST_LINK_UP))
180 		*speed = SPEED_UNKNOWN;
181 	else if (status & TXGBE_CFG_PORT_ST_LINK_AML_40G)
182 		*speed = SPEED_40000;
183 	else if (status & TXGBE_CFG_PORT_ST_LINK_AML_25G)
184 		*speed = SPEED_25000;
185 	else if (status & TXGBE_CFG_PORT_ST_LINK_AML_10G)
186 		*speed = SPEED_10000;
187 	else
188 		*speed = SPEED_UNKNOWN;
189 }
190 
txgbe_set_phy_link(struct wx * wx)191 void txgbe_set_phy_link(struct wx *wx)
192 {
193 	int speed, autoneg, duplex, err;
194 
195 	txgbe_get_link_capabilities(wx, &speed, &autoneg, &duplex);
196 
197 	err = txgbe_set_phy_link_hostif(wx, speed, autoneg, duplex);
198 	if (err)
199 		wx_err(wx, "Failed to setup link\n");
200 }
201 
txgbe_sfp_to_linkmodes(struct wx * wx,struct txgbe_sff_id * id)202 static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
203 {
204 	__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
205 	DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
206 	struct txgbe *txgbe = wx->priv;
207 
208 	if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) {
209 		txgbe->link_port = PORT_DA;
210 		phylink_set(modes, Autoneg);
211 		if (id->com_25g_code == TXGBE_SFF_25GBASECR_91FEC ||
212 		    id->com_25g_code == TXGBE_SFF_25GBASECR_74FEC ||
213 		    id->com_25g_code == TXGBE_SFF_25GBASECR_NOFEC) {
214 			phylink_set(modes, 25000baseCR_Full);
215 			phylink_set(modes, 10000baseCR_Full);
216 			__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
217 			__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
218 		} else {
219 			phylink_set(modes, 10000baseCR_Full);
220 			__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
221 		}
222 	} else if (id->cable_tech & TXGBE_SFF_DA_ACTIVE_CABLE) {
223 		txgbe->link_port = PORT_DA;
224 		phylink_set(modes, Autoneg);
225 		phylink_set(modes, 25000baseCR_Full);
226 		__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
227 	} else {
228 		if (id->com_25g_code == TXGBE_SFF_25GBASESR_CAPABLE ||
229 		    id->com_25g_code == TXGBE_SFF_25GBASEER_CAPABLE ||
230 		    id->com_25g_code == TXGBE_SFF_25GBASELR_CAPABLE) {
231 			txgbe->link_port = PORT_FIBRE;
232 			phylink_set(modes, 25000baseSR_Full);
233 			__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
234 		}
235 		if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
236 			txgbe->link_port = PORT_FIBRE;
237 			phylink_set(modes, 10000baseSR_Full);
238 			__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
239 		}
240 		if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
241 			txgbe->link_port = PORT_FIBRE;
242 			phylink_set(modes, 10000baseLR_Full);
243 			__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
244 		}
245 	}
246 
247 	if (phy_interface_empty(interfaces)) {
248 		wx_err(wx, "unsupported SFP module\n");
249 		return -EINVAL;
250 	}
251 
252 	phylink_set(modes, Pause);
253 	phylink_set(modes, Asym_Pause);
254 	phylink_set(modes, FIBRE);
255 
256 	if (!linkmode_equal(txgbe->link_support, modes)) {
257 		linkmode_copy(txgbe->link_support, modes);
258 		phy_interface_and(txgbe->link_interfaces,
259 				  wx->phylink_config.supported_interfaces,
260 				  interfaces);
261 		linkmode_copy(txgbe->advertising, modes);
262 
263 		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
264 	}
265 
266 	return 0;
267 }
268 
txgbe_qsfp_to_linkmodes(struct wx * wx,struct txgbe_sff_id * id)269 static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id)
270 {
271 	__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
272 	DECLARE_PHY_INTERFACE_MASK_ZERO(interfaces);
273 	struct txgbe *txgbe = wx->priv;
274 
275 	if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) {
276 		txgbe->link_port = PORT_DA;
277 		phylink_set(modes, Autoneg);
278 		phylink_set(modes, 40000baseCR4_Full);
279 		phylink_set(modes, 10000baseCR_Full);
280 		__set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces);
281 		__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
282 	}
283 	if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_SR4) {
284 		txgbe->link_port = PORT_FIBRE;
285 		phylink_set(modes, 40000baseSR4_Full);
286 		__set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces);
287 	}
288 	if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_LR4) {
289 		txgbe->link_port = PORT_FIBRE;
290 		phylink_set(modes, 40000baseLR4_Full);
291 		__set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces);
292 	}
293 	if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_ACTIVE) {
294 		txgbe->link_port = PORT_DA;
295 		phylink_set(modes, Autoneg);
296 		phylink_set(modes, 40000baseCR4_Full);
297 		__set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces);
298 	}
299 	if (id->transceiver_type & TXGBE_SFF_ETHERNET_RSRVD) {
300 		if (id->sff_opt1 & TXGBE_SFF_ETHERNET_100G_CR4) {
301 			txgbe->link_port = PORT_DA;
302 			phylink_set(modes, Autoneg);
303 			phylink_set(modes, 40000baseCR4_Full);
304 			phylink_set(modes, 25000baseCR_Full);
305 			phylink_set(modes, 10000baseCR_Full);
306 			__set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces);
307 			__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
308 			__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
309 		}
310 	}
311 
312 	if (phy_interface_empty(interfaces)) {
313 		wx_err(wx, "unsupported QSFP module\n");
314 		return -EINVAL;
315 	}
316 
317 	phylink_set(modes, Pause);
318 	phylink_set(modes, Asym_Pause);
319 	phylink_set(modes, FIBRE);
320 
321 	if (!linkmode_equal(txgbe->link_support, modes)) {
322 		linkmode_copy(txgbe->link_support, modes);
323 		phy_interface_and(txgbe->link_interfaces,
324 				  wx->phylink_config.supported_interfaces,
325 				  interfaces);
326 		linkmode_copy(txgbe->advertising, modes);
327 
328 		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
329 	}
330 
331 	return 0;
332 }
333 
txgbe_identify_module(struct wx * wx)334 int txgbe_identify_module(struct wx *wx)
335 {
336 	struct txgbe_hic_get_module_info buffer = { 0 };
337 	struct txgbe_sff_id *id;
338 	int err = 0;
339 	u32 mod_abs;
340 	u32 gpio;
341 
342 	if (wx->mac.type == wx_mac_aml40)
343 		mod_abs = TXGBE_GPIOBIT_4;
344 	else
345 		mod_abs = TXGBE_GPIOBIT_2;
346 
347 	gpio = rd32(wx, WX_GPIO_EXT);
348 	if (gpio & mod_abs)
349 		return -ENODEV;
350 
351 	err = txgbe_identify_module_hostif(wx, &buffer);
352 	if (err) {
353 		wx_err(wx, "Failed to identify module\n");
354 		return err;
355 	}
356 
357 	id = &buffer.id;
358 	if (id->identifier == TXGBE_SFF_IDENTIFIER_SFP)
359 		return txgbe_sfp_to_linkmodes(wx, id);
360 
361 	if (id->identifier == TXGBE_SFF_IDENTIFIER_QSFP ||
362 	    id->identifier == TXGBE_SFF_IDENTIFIER_QSFP_PLUS ||
363 	    id->identifier == TXGBE_SFF_IDENTIFIER_QSFP28)
364 		return txgbe_qsfp_to_linkmodes(wx, id);
365 
366 	wx_err(wx, "Invalid module\n");
367 	return -EINVAL;
368 }
369 
txgbe_setup_link(struct wx * wx)370 void txgbe_setup_link(struct wx *wx)
371 {
372 	struct txgbe *txgbe = wx->priv;
373 
374 	phy_interface_zero(txgbe->link_interfaces);
375 	linkmode_zero(txgbe->link_support);
376 
377 	set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags);
378 	wx_service_event_schedule(wx);
379 }
380 
txgbe_get_link_state(struct phylink_config * config,struct phylink_link_state * state)381 static void txgbe_get_link_state(struct phylink_config *config,
382 				 struct phylink_link_state *state)
383 {
384 	struct wx *wx = phylink_to_wx(config);
385 	int speed;
386 
387 	txgbe_get_mac_link(wx, &speed);
388 	state->link = speed != SPEED_UNKNOWN;
389 	state->speed = speed;
390 	state->duplex = state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
391 }
392 
txgbe_reconfig_mac(struct wx * wx)393 static void txgbe_reconfig_mac(struct wx *wx)
394 {
395 	u32 wdg, fc;
396 
397 	wdg = rd32(wx, WX_MAC_WDG_TIMEOUT);
398 	fc = rd32(wx, WX_MAC_RX_FLOW_CTRL);
399 
400 	wr32(wx, WX_MIS_RST, TXGBE_MIS_RST_MAC_RST(wx->bus.func));
401 	/* wait for MAC reset complete */
402 	usleep_range(1000, 1500);
403 
404 	wr32m(wx, TXGBE_MAC_MISC_CTL, TXGBE_MAC_MISC_CTL_LINK_STS_MOD,
405 	      TXGBE_MAC_MISC_CTL_LINK_BOTH);
406 	wx_reset_mac(wx);
407 
408 	wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
409 	wr32(wx, WX_MAC_RX_FLOW_CTRL, fc);
410 }
411 
txgbe_mac_link_up_aml(struct phylink_config * config,struct phy_device * phy,unsigned int mode,phy_interface_t interface,int speed,int duplex,bool tx_pause,bool rx_pause)412 static void txgbe_mac_link_up_aml(struct phylink_config *config,
413 				  struct phy_device *phy,
414 				  unsigned int mode,
415 				  phy_interface_t interface,
416 				  int speed, int duplex,
417 				  bool tx_pause, bool rx_pause)
418 {
419 	struct wx *wx = phylink_to_wx(config);
420 	u32 txcfg;
421 
422 	wx_fc_enable(wx, tx_pause, rx_pause);
423 
424 	txgbe_reconfig_mac(wx);
425 	txgbe_enable_sec_tx_path(wx);
426 
427 	txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
428 	txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
429 
430 	switch (speed) {
431 	case SPEED_40000:
432 		txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_40G;
433 		break;
434 	case SPEED_25000:
435 		txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
436 		break;
437 	case SPEED_10000:
438 		txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_10G;
439 		break;
440 	default:
441 		break;
442 	}
443 
444 	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
445 	wr32(wx, TXGBE_AML_MAC_TX_CFG, txcfg | TXGBE_AML_MAC_TX_CFG_TE);
446 
447 	wx->speed = speed;
448 	wx->last_rx_ptp_check = jiffies;
449 	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
450 		wx_ptp_reset_cyclecounter(wx);
451 	/* ping all the active vfs to let them know we are going up */
452 	wx_ping_all_vfs_with_link_status(wx, true);
453 }
454 
txgbe_mac_link_down_aml(struct phylink_config * config,unsigned int mode,phy_interface_t interface)455 static void txgbe_mac_link_down_aml(struct phylink_config *config,
456 				    unsigned int mode,
457 				    phy_interface_t interface)
458 {
459 	struct wx *wx = phylink_to_wx(config);
460 
461 	wr32m(wx, TXGBE_AML_MAC_TX_CFG, TXGBE_AML_MAC_TX_CFG_TE, 0);
462 	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
463 
464 	wx->speed = SPEED_UNKNOWN;
465 	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
466 		wx_ptp_reset_cyclecounter(wx);
467 	/* ping all the active vfs to let them know we are going down */
468 	wx_ping_all_vfs_with_link_status(wx, false);
469 }
470 
txgbe_mac_config_aml(struct phylink_config * config,unsigned int mode,const struct phylink_link_state * state)471 static void txgbe_mac_config_aml(struct phylink_config *config, unsigned int mode,
472 				 const struct phylink_link_state *state)
473 {
474 }
475 
476 static const struct phylink_mac_ops txgbe_mac_ops_aml = {
477 	.mac_config = txgbe_mac_config_aml,
478 	.mac_link_down = txgbe_mac_link_down_aml,
479 	.mac_link_up = txgbe_mac_link_up_aml,
480 };
481 
txgbe_phylink_init_aml(struct txgbe * txgbe)482 int txgbe_phylink_init_aml(struct txgbe *txgbe)
483 {
484 	struct phylink_link_state state;
485 	struct phylink_config *config;
486 	struct wx *wx = txgbe->wx;
487 	phy_interface_t phy_mode;
488 	struct phylink *phylink;
489 	int err;
490 
491 	config = &wx->phylink_config;
492 	config->dev = &wx->netdev->dev;
493 	config->type = PHYLINK_NETDEV;
494 	config->mac_capabilities = MAC_25000FD | MAC_10000FD |
495 				   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
496 	config->get_fixed_state = txgbe_get_link_state;
497 
498 	if (wx->mac.type == wx_mac_aml40) {
499 		config->mac_capabilities |= MAC_40000FD;
500 		phy_mode = PHY_INTERFACE_MODE_XLGMII;
501 		__set_bit(PHY_INTERFACE_MODE_XLGMII, config->supported_interfaces);
502 		state.speed = SPEED_40000;
503 		state.duplex = DUPLEX_FULL;
504 	} else {
505 		phy_mode = PHY_INTERFACE_MODE_25GBASER;
506 		state.speed = SPEED_25000;
507 		state.duplex = DUPLEX_FULL;
508 	}
509 
510 	__set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces);
511 	__set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces);
512 
513 	phylink = phylink_create(config, NULL, phy_mode, &txgbe_mac_ops_aml);
514 	if (IS_ERR(phylink))
515 		return PTR_ERR(phylink);
516 
517 	err = phylink_set_fixed_link(phylink, &state);
518 	if (err) {
519 		wx_err(wx, "Failed to set fixed link\n");
520 		phylink_destroy(phylink);
521 		return err;
522 	}
523 
524 	wx->phylink = phylink;
525 
526 	return 0;
527 }
528