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