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