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;
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
txgbe_gpio_irq_handler_aml(int irq,void * data)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
txgbe_test_hostif(struct wx * wx)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
txgbe_identify_sfp_hostif(struct wx * wx,struct txgbe_hic_i2c_read * buffer)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
txgbe_set_phy_link_hostif(struct wx * wx,int speed,int autoneg,int duplex)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
txgbe_get_link_capabilities(struct wx * wx)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
txgbe_get_phy_link(struct wx * wx,int * speed)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
txgbe_set_phy_link(struct wx * wx)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
txgbe_sfp_to_linkmodes(struct wx * wx,struct txgbe_sfp_id * id)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
txgbe_identify_sfp(struct wx * wx)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
txgbe_setup_link(struct wx * wx)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
txgbe_get_link_state(struct phylink_config * config,struct phylink_link_state * state)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
txgbe_reconfig_mac(struct wx * wx)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
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)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 txgbe_enable_sec_tx_path(wx);
298
299 txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
300 txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
301
302 switch (speed) {
303 case SPEED_25000:
304 txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G;
305 break;
306 case SPEED_10000:
307 txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_10G;
308 break;
309 default:
310 break;
311 }
312
313 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
314 wr32(wx, TXGBE_AML_MAC_TX_CFG, txcfg | TXGBE_AML_MAC_TX_CFG_TE);
315
316 wx->speed = speed;
317 wx->last_rx_ptp_check = jiffies;
318 if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
319 wx_ptp_reset_cyclecounter(wx);
320 /* ping all the active vfs to let them know we are going up */
321 wx_ping_all_vfs_with_link_status(wx, true);
322 }
323
txgbe_mac_link_down_aml(struct phylink_config * config,unsigned int mode,phy_interface_t interface)324 static void txgbe_mac_link_down_aml(struct phylink_config *config,
325 unsigned int mode,
326 phy_interface_t interface)
327 {
328 struct wx *wx = phylink_to_wx(config);
329
330 wr32m(wx, TXGBE_AML_MAC_TX_CFG, TXGBE_AML_MAC_TX_CFG_TE, 0);
331 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
332
333 wx->speed = SPEED_UNKNOWN;
334 if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
335 wx_ptp_reset_cyclecounter(wx);
336 /* ping all the active vfs to let them know we are going down */
337 wx_ping_all_vfs_with_link_status(wx, false);
338 }
339
txgbe_mac_config_aml(struct phylink_config * config,unsigned int mode,const struct phylink_link_state * state)340 static void txgbe_mac_config_aml(struct phylink_config *config, unsigned int mode,
341 const struct phylink_link_state *state)
342 {
343 }
344
345 static const struct phylink_mac_ops txgbe_mac_ops_aml = {
346 .mac_config = txgbe_mac_config_aml,
347 .mac_link_down = txgbe_mac_link_down_aml,
348 .mac_link_up = txgbe_mac_link_up_aml,
349 };
350
txgbe_phylink_init_aml(struct txgbe * txgbe)351 int txgbe_phylink_init_aml(struct txgbe *txgbe)
352 {
353 struct phylink_link_state state;
354 struct phylink_config *config;
355 struct wx *wx = txgbe->wx;
356 phy_interface_t phy_mode;
357 struct phylink *phylink;
358 int err;
359
360 config = &wx->phylink_config;
361 config->dev = &wx->netdev->dev;
362 config->type = PHYLINK_NETDEV;
363 config->mac_capabilities = MAC_25000FD | MAC_10000FD |
364 MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
365 config->get_fixed_state = txgbe_get_link_state;
366
367 phy_mode = PHY_INTERFACE_MODE_25GBASER;
368 __set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces);
369 __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces);
370
371 phylink = phylink_create(config, NULL, phy_mode, &txgbe_mac_ops_aml);
372 if (IS_ERR(phylink))
373 return PTR_ERR(phylink);
374
375 state.speed = SPEED_25000;
376 state.duplex = DUPLEX_FULL;
377 err = phylink_set_fixed_link(phylink, &state);
378 if (err) {
379 wx_err(wx, "Failed to set fixed link\n");
380 return err;
381 }
382
383 wx->phylink = phylink;
384
385 return 0;
386 }
387