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