xref: /linux/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c (revision e78f70bad29c5ae1e1076698b690b15794e9b81e)
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 
18 void txgbe_gpio_init_aml(struct wx *wx)
19 {
20 	u32 status;
21 
22 	wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
23 	wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3);
24 
25 	status = rd32(wx, WX_GPIO_INTSTATUS);
26 	for (int i = 0; i < 6; i++) {
27 		if (status & BIT(i))
28 			wr32(wx, WX_GPIO_EOI, BIT(i));
29 	}
30 }
31 
32 irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data)
33 {
34 	struct txgbe *txgbe = data;
35 	struct wx *wx = txgbe->wx;
36 	u32 status;
37 
38 	wr32(wx, WX_GPIO_INTMASK, 0xFF);
39 	status = rd32(wx, WX_GPIO_INTSTATUS);
40 	if (status & TXGBE_GPIOBIT_2) {
41 		set_bit(WX_FLAG_NEED_SFP_RESET, wx->flags);
42 		wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2);
43 		wx_service_event_schedule(wx);
44 	}
45 	if (status & TXGBE_GPIOBIT_3) {
46 		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
47 		wx_service_event_schedule(wx);
48 		wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_3);
49 	}
50 
51 	wr32(wx, WX_GPIO_INTMASK, 0);
52 	return IRQ_HANDLED;
53 }
54 
55 int txgbe_test_hostif(struct wx *wx)
56 {
57 	struct txgbe_hic_ephy_getlink buffer;
58 
59 	if (wx->mac.type != wx_mac_aml)
60 		return 0;
61 
62 	buffer.hdr.cmd = FW_PHY_GET_LINK_CMD;
63 	buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_getlink) -
64 			     sizeof(struct wx_hic_hdr);
65 	buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
66 
67 	return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
68 					WX_HI_COMMAND_TIMEOUT, true);
69 }
70 
71 static int txgbe_identify_sfp_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer)
72 {
73 	buffer->hdr.cmd = FW_READ_SFP_INFO_CMD;
74 	buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) -
75 			      sizeof(struct wx_hic_hdr);
76 	buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
77 
78 	return wx_host_interface_command(wx, (u32 *)buffer,
79 					 sizeof(struct txgbe_hic_i2c_read),
80 					 WX_HI_COMMAND_TIMEOUT, true);
81 }
82 
83 static int txgbe_set_phy_link_hostif(struct wx *wx, int speed, int autoneg, int duplex)
84 {
85 	struct txgbe_hic_ephy_setlink buffer;
86 
87 	buffer.hdr.cmd = FW_PHY_SET_LINK_CMD;
88 	buffer.hdr.buf_len = sizeof(struct txgbe_hic_ephy_setlink) -
89 			     sizeof(struct wx_hic_hdr);
90 	buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
91 
92 	switch (speed) {
93 	case SPEED_25000:
94 		buffer.speed = TXGBE_LINK_SPEED_25GB_FULL;
95 		break;
96 	case SPEED_10000:
97 		buffer.speed = TXGBE_LINK_SPEED_10GB_FULL;
98 		break;
99 	}
100 
101 	buffer.fec_mode = TXGBE_PHY_FEC_AUTO;
102 	buffer.autoneg = autoneg;
103 	buffer.duplex = duplex;
104 
105 	return wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
106 					 WX_HI_COMMAND_TIMEOUT, true);
107 }
108 
109 static void txgbe_get_link_capabilities(struct wx *wx)
110 {
111 	struct txgbe *txgbe = wx->priv;
112 
113 	if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces))
114 		wx->adv_speed = SPEED_25000;
115 	else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces))
116 		wx->adv_speed = SPEED_10000;
117 	else
118 		wx->adv_speed = SPEED_UNKNOWN;
119 
120 	wx->adv_duplex = wx->adv_speed == SPEED_UNKNOWN ?
121 			 DUPLEX_HALF : DUPLEX_FULL;
122 }
123 
124 static void txgbe_get_phy_link(struct wx *wx, int *speed)
125 {
126 	u32 status;
127 
128 	status = rd32(wx, TXGBE_CFG_PORT_ST);
129 	if (!(status & TXGBE_CFG_PORT_ST_LINK_UP))
130 		*speed = SPEED_UNKNOWN;
131 	else if (status & TXGBE_CFG_PORT_ST_LINK_AML_25G)
132 		*speed = SPEED_25000;
133 	else if (status & TXGBE_CFG_PORT_ST_LINK_AML_10G)
134 		*speed = SPEED_10000;
135 	else
136 		*speed = SPEED_UNKNOWN;
137 }
138 
139 int txgbe_set_phy_link(struct wx *wx)
140 {
141 	int speed, err;
142 	u32 gpio;
143 
144 	/* Check RX signal */
145 	gpio = rd32(wx, WX_GPIO_EXT);
146 	if (gpio & TXGBE_GPIOBIT_3)
147 		return -ENODEV;
148 
149 	txgbe_get_link_capabilities(wx);
150 	if (wx->adv_speed == SPEED_UNKNOWN)
151 		return -ENODEV;
152 
153 	txgbe_get_phy_link(wx, &speed);
154 	if (speed == wx->adv_speed)
155 		return 0;
156 
157 	err = txgbe_set_phy_link_hostif(wx, wx->adv_speed, 0, wx->adv_duplex);
158 	if (err) {
159 		wx_err(wx, "Failed to setup link\n");
160 		return err;
161 	}
162 
163 	return 0;
164 }
165 
166 static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id)
167 {
168 	__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
169 	DECLARE_PHY_INTERFACE_MASK(interfaces);
170 	struct txgbe *txgbe = wx->priv;
171 
172 	if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE |
173 				TXGBE_SFF_25GBASEER_CAPABLE |
174 				TXGBE_SFF_25GBASELR_CAPABLE)) {
175 		phylink_set(modes, 25000baseSR_Full);
176 		__set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces);
177 	}
178 	if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) {
179 		phylink_set(modes, 10000baseSR_Full);
180 		__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
181 	}
182 	if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) {
183 		phylink_set(modes, 10000baseLR_Full);
184 		__set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces);
185 	}
186 
187 	if (phy_interface_empty(interfaces)) {
188 		wx_err(wx, "unsupported SFP module\n");
189 		return -EINVAL;
190 	}
191 
192 	phylink_set(modes, Pause);
193 	phylink_set(modes, Asym_Pause);
194 	phylink_set(modes, FIBRE);
195 	txgbe->link_port = PORT_FIBRE;
196 
197 	if (!linkmode_equal(txgbe->sfp_support, modes)) {
198 		linkmode_copy(txgbe->sfp_support, modes);
199 		phy_interface_and(txgbe->sfp_interfaces,
200 				  wx->phylink_config.supported_interfaces,
201 				  interfaces);
202 		linkmode_copy(txgbe->advertising, modes);
203 
204 		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
205 	}
206 
207 	return 0;
208 }
209 
210 int txgbe_identify_sfp(struct wx *wx)
211 {
212 	struct txgbe_hic_i2c_read buffer;
213 	struct txgbe_sfp_id *id;
214 	int err = 0;
215 	u32 gpio;
216 
217 	gpio = rd32(wx, WX_GPIO_EXT);
218 	if (gpio & TXGBE_GPIOBIT_2)
219 		return -ENODEV;
220 
221 	err = txgbe_identify_sfp_hostif(wx, &buffer);
222 	if (err) {
223 		wx_err(wx, "Failed to identify SFP module\n");
224 		return err;
225 	}
226 
227 	id = &buffer.id;
228 	if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP) {
229 		wx_err(wx, "Invalid SFP module\n");
230 		return -ENODEV;
231 	}
232 
233 	err = txgbe_sfp_to_linkmodes(wx, id);
234 	if (err)
235 		return err;
236 
237 	if (gpio & TXGBE_GPIOBIT_3)
238 		set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags);
239 
240 	return 0;
241 }
242 
243 void txgbe_setup_link(struct wx *wx)
244 {
245 	struct txgbe *txgbe = wx->priv;
246 
247 	phy_interface_zero(txgbe->sfp_interfaces);
248 	linkmode_zero(txgbe->sfp_support);
249 
250 	txgbe_identify_sfp(wx);
251 }
252 
253 static void txgbe_get_link_state(struct phylink_config *config,
254 				 struct phylink_link_state *state)
255 {
256 	struct wx *wx = phylink_to_wx(config);
257 	int speed;
258 
259 	txgbe_get_phy_link(wx, &speed);
260 	state->link = speed != SPEED_UNKNOWN;
261 	state->speed = speed;
262 	state->duplex = state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
263 }
264 
265 static void txgbe_reconfig_mac(struct wx *wx)
266 {
267 	u32 wdg, fc;
268 
269 	wdg = rd32(wx, WX_MAC_WDG_TIMEOUT);
270 	fc = rd32(wx, WX_MAC_RX_FLOW_CTRL);
271 
272 	wr32(wx, WX_MIS_RST, TXGBE_MIS_RST_MAC_RST(wx->bus.func));
273 	/* wait for MAC reset complete */
274 	usleep_range(1000, 1500);
275 
276 	wr32m(wx, TXGBE_MAC_MISC_CTL, TXGBE_MAC_MISC_CTL_LINK_STS_MOD,
277 	      TXGBE_MAC_MISC_CTL_LINK_BOTH);
278 	wx_reset_mac(wx);
279 
280 	wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
281 	wr32(wx, WX_MAC_RX_FLOW_CTRL, fc);
282 }
283 
284 static void txgbe_mac_link_up_aml(struct phylink_config *config,
285 				  struct phy_device *phy,
286 				  unsigned int mode,
287 				  phy_interface_t interface,
288 				  int speed, int duplex,
289 				  bool tx_pause, bool rx_pause)
290 {
291 	struct wx *wx = phylink_to_wx(config);
292 	u32 txcfg;
293 
294 	wx_fc_enable(wx, tx_pause, rx_pause);
295 
296 	txgbe_reconfig_mac(wx);
297 
298 	txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
299 	txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
300 
301 	switch (speed) {
302 	case SPEED_25000:
303 		txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
304 		break;
305 	case SPEED_10000:
306 		txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_10G;
307 		break;
308 	default:
309 		break;
310 	}
311 
312 	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
313 	wr32(wx, TXGBE_AML_MAC_TX_CFG, txcfg | TXGBE_AML_MAC_TX_CFG_TE);
314 
315 	wx->speed = speed;
316 	wx->last_rx_ptp_check = jiffies;
317 	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
318 		wx_ptp_reset_cyclecounter(wx);
319 	/* ping all the active vfs to let them know we are going up */
320 	wx_ping_all_vfs_with_link_status(wx, true);
321 }
322 
323 static void txgbe_mac_link_down_aml(struct phylink_config *config,
324 				    unsigned int mode,
325 				    phy_interface_t interface)
326 {
327 	struct wx *wx = phylink_to_wx(config);
328 
329 	wr32m(wx, TXGBE_AML_MAC_TX_CFG, TXGBE_AML_MAC_TX_CFG_TE, 0);
330 	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
331 
332 	wx->speed = SPEED_UNKNOWN;
333 	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
334 		wx_ptp_reset_cyclecounter(wx);
335 	/* ping all the active vfs to let them know we are going down */
336 	wx_ping_all_vfs_with_link_status(wx, false);
337 }
338 
339 static void txgbe_mac_config_aml(struct phylink_config *config, unsigned int mode,
340 				 const struct phylink_link_state *state)
341 {
342 }
343 
344 static const struct phylink_mac_ops txgbe_mac_ops_aml = {
345 	.mac_config = txgbe_mac_config_aml,
346 	.mac_link_down = txgbe_mac_link_down_aml,
347 	.mac_link_up = txgbe_mac_link_up_aml,
348 };
349 
350 int txgbe_phylink_init_aml(struct txgbe *txgbe)
351 {
352 	struct phylink_link_state state;
353 	struct phylink_config *config;
354 	struct wx *wx = txgbe->wx;
355 	phy_interface_t phy_mode;
356 	struct phylink *phylink;
357 	int err;
358 
359 	config = &wx->phylink_config;
360 	config->dev = &wx->netdev->dev;
361 	config->type = PHYLINK_NETDEV;
362 	config->mac_capabilities = MAC_25000FD | MAC_10000FD |
363 				   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
364 	config->get_fixed_state = txgbe_get_link_state;
365 
366 	phy_mode = PHY_INTERFACE_MODE_25GBASER;
367 	__set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces);
368 	__set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces);
369 
370 	phylink = phylink_create(config, NULL, phy_mode, &txgbe_mac_ops_aml);
371 	if (IS_ERR(phylink))
372 		return PTR_ERR(phylink);
373 
374 	state.speed = SPEED_25000;
375 	state.duplex = DUPLEX_FULL;
376 	err = phylink_set_fixed_link(phylink, &state);
377 	if (err) {
378 		wx_err(wx, "Failed to set fixed link\n");
379 		return err;
380 	}
381 
382 	wx->phylink = phylink;
383 
384 	return 0;
385 }
386