Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'txgbe-support-more-modules'

Jiawen Wu says:

====================
TXGBE support more modules

Support CR modules for 25G devices and QSFP modules for 40G devices. And
implement .get_module_eeprom_by_page() to get module info.

v1: https://lore.kernel.org/all/20251112055841.22984-1-jiawenwu@trustnetic.com/
====================

Link: https://patch.msgid.link/20251118080259.24676-1-jiawenwu@trustnetic.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+292 -98
-12
drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
··· 240 240 { 241 241 struct wx *wx = netdev_priv(netdev); 242 242 243 - if (wx->mac.type == wx_mac_aml40) 244 - return -EOPNOTSUPP; 245 - 246 243 return phylink_ethtool_nway_reset(wx->phylink); 247 244 } 248 245 EXPORT_SYMBOL(wx_nway_reset); ··· 258 261 { 259 262 struct wx *wx = netdev_priv(netdev); 260 263 261 - if (wx->mac.type == wx_mac_aml40) 262 - return -EOPNOTSUPP; 263 - 264 264 return phylink_ethtool_ksettings_set(wx->phylink, cmd); 265 265 } 266 266 EXPORT_SYMBOL(wx_set_link_ksettings); ··· 267 273 { 268 274 struct wx *wx = netdev_priv(netdev); 269 275 270 - if (wx->mac.type == wx_mac_aml40) 271 - return; 272 - 273 276 phylink_ethtool_get_pauseparam(wx->phylink, pause); 274 277 } 275 278 EXPORT_SYMBOL(wx_get_pauseparam); ··· 275 284 struct ethtool_pauseparam *pause) 276 285 { 277 286 struct wx *wx = netdev_priv(netdev); 278 - 279 - if (wx->mac.type == wx_mac_aml40) 280 - return -EOPNOTSUPP; 281 287 282 288 return phylink_ethtool_set_pauseparam(wx->phylink, pause); 283 289 }
+1 -1
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 1249 1249 WX_FLAG_RX_HWTSTAMP_IN_REGISTER, 1250 1250 WX_FLAG_PTP_PPS_ENABLED, 1251 1251 WX_FLAG_NEED_LINK_CONFIG, 1252 - WX_FLAG_NEED_SFP_RESET, 1252 + WX_FLAG_NEED_MODULE_RESET, 1253 1253 WX_FLAG_NEED_UPDATE_LINK, 1254 1254 WX_FLAG_NEED_DO_RESET, 1255 1255 WX_FLAG_RX_MERGE_ENABLED,
+215 -49
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c
··· 17 17 18 18 void txgbe_gpio_init_aml(struct wx *wx) 19 19 { 20 - u32 status; 20 + u32 status, mod_rst; 21 21 22 - wr32(wx, WX_GPIO_INTTYPE_LEVEL, TXGBE_GPIOBIT_2); 23 - wr32(wx, WX_GPIO_INTEN, TXGBE_GPIOBIT_2); 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); 24 29 25 30 status = rd32(wx, WX_GPIO_INTSTATUS); 26 31 for (int i = 0; i < 6; i++) { ··· 38 33 { 39 34 struct txgbe *txgbe = data; 40 35 struct wx *wx = txgbe->wx; 41 - u32 status; 36 + u32 status, mod_rst; 37 + 38 + if (wx->mac.type == wx_mac_aml40) 39 + mod_rst = TXGBE_GPIOBIT_4; 40 + else 41 + mod_rst = TXGBE_GPIOBIT_2; 42 42 43 43 wr32(wx, WX_GPIO_INTMASK, 0xFF); 44 44 status = rd32(wx, WX_GPIO_INTSTATUS); 45 - if (status & TXGBE_GPIOBIT_2) { 46 - set_bit(WX_FLAG_NEED_SFP_RESET, wx->flags); 47 - wr32(wx, WX_GPIO_EOI, TXGBE_GPIOBIT_2); 45 + if (status & mod_rst) { 46 + set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags); 47 + wr32(wx, WX_GPIO_EOI, mod_rst); 48 48 wx_service_event_schedule(wx); 49 49 } 50 50 ··· 61 51 { 62 52 struct txgbe_hic_ephy_getlink buffer; 63 53 64 - if (wx->mac.type != wx_mac_aml) 54 + if (wx->mac.type == wx_mac_sp) 65 55 return 0; 66 56 67 57 buffer.hdr.cmd = FW_PHY_GET_LINK_CMD; ··· 73 63 WX_HI_COMMAND_TIMEOUT, true); 74 64 } 75 65 76 - static int txgbe_identify_sfp_hostif(struct wx *wx, struct txgbe_hic_i2c_read *buffer) 66 + int txgbe_read_eeprom_hostif(struct wx *wx, 67 + struct txgbe_hic_i2c_read *buffer, 68 + u32 length, u8 *data) 77 69 { 78 - buffer->hdr.cmd = FW_READ_SFP_INFO_CMD; 70 + u32 dword_len, offset, value, i; 71 + int err; 72 + 73 + buffer->hdr.cmd = FW_READ_EEPROM_CMD; 79 74 buffer->hdr.buf_len = sizeof(struct txgbe_hic_i2c_read) - 80 75 sizeof(struct wx_hic_hdr); 81 76 buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 82 77 78 + err = wx_host_interface_command(wx, (u32 *)buffer, 79 + sizeof(struct txgbe_hic_i2c_read), 80 + WX_HI_COMMAND_TIMEOUT, false); 81 + if (err != 0) 82 + return err; 83 + 84 + /* buffer length offset to read return data */ 85 + offset = sizeof(struct txgbe_hic_i2c_read) >> 2; 86 + dword_len = round_up(length, 4) >> 2; 87 + 88 + for (i = 0; i < dword_len; i++) { 89 + value = rd32a(wx, WX_FW2SW_MBOX, i + offset); 90 + le32_to_cpus(&value); 91 + 92 + memcpy(data, &value, 4); 93 + data += 4; 94 + } 95 + 96 + return 0; 97 + } 98 + 99 + static int txgbe_identify_module_hostif(struct wx *wx, 100 + struct txgbe_hic_get_module_info *buffer) 101 + { 102 + buffer->hdr.cmd = FW_GET_MODULE_INFO_CMD; 103 + buffer->hdr.buf_len = sizeof(struct txgbe_hic_get_module_info) - 104 + sizeof(struct wx_hic_hdr); 105 + buffer->hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 106 + 83 107 return wx_host_interface_command(wx, (u32 *)buffer, 84 - sizeof(struct txgbe_hic_i2c_read), 108 + sizeof(struct txgbe_hic_get_module_info), 85 109 WX_HI_COMMAND_TIMEOUT, true); 86 110 } 87 111 ··· 129 85 buffer.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; 130 86 131 87 switch (speed) { 88 + case SPEED_40000: 89 + buffer.speed = TXGBE_LINK_SPEED_40GB_FULL; 90 + break; 132 91 case SPEED_25000: 133 92 buffer.speed = TXGBE_LINK_SPEED_25GB_FULL; 134 93 break; ··· 151 104 WX_HI_COMMAND_TIMEOUT, true); 152 105 } 153 106 154 - static void txgbe_get_link_capabilities(struct wx *wx, int *speed, int *duplex) 107 + static void txgbe_get_link_capabilities(struct wx *wx, int *speed, 108 + int *autoneg, int *duplex) 155 109 { 156 110 struct txgbe *txgbe = wx->priv; 157 111 158 - if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->sfp_interfaces)) 112 + if (test_bit(PHY_INTERFACE_MODE_XLGMII, txgbe->link_interfaces)) 113 + *speed = SPEED_40000; 114 + else if (test_bit(PHY_INTERFACE_MODE_25GBASER, txgbe->link_interfaces)) 159 115 *speed = SPEED_25000; 160 - else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->sfp_interfaces)) 116 + else if (test_bit(PHY_INTERFACE_MODE_10GBASER, txgbe->link_interfaces)) 161 117 *speed = SPEED_10000; 162 118 else 163 119 *speed = SPEED_UNKNOWN; 164 120 121 + *autoneg = phylink_test(txgbe->advertising, Autoneg); 165 122 *duplex = *speed == SPEED_UNKNOWN ? DUPLEX_HALF : DUPLEX_FULL; 166 123 } 167 124 ··· 176 125 status = rd32(wx, TXGBE_CFG_PORT_ST); 177 126 if (!(status & TXGBE_CFG_PORT_ST_LINK_UP)) 178 127 *speed = SPEED_UNKNOWN; 128 + else if (status & TXGBE_CFG_PORT_ST_LINK_AML_40G) 129 + *speed = SPEED_40000; 179 130 else if (status & TXGBE_CFG_PORT_ST_LINK_AML_25G) 180 131 *speed = SPEED_25000; 181 132 else if (status & TXGBE_CFG_PORT_ST_LINK_AML_10G) ··· 188 135 189 136 int txgbe_set_phy_link(struct wx *wx) 190 137 { 191 - int speed, duplex, err; 138 + int speed, autoneg, duplex, err; 192 139 193 - txgbe_get_link_capabilities(wx, &speed, &duplex); 140 + txgbe_get_link_capabilities(wx, &speed, &autoneg, &duplex); 194 141 195 - err = txgbe_set_phy_link_hostif(wx, speed, 0, duplex); 142 + err = txgbe_set_phy_link_hostif(wx, speed, autoneg, duplex); 196 143 if (err) { 197 144 wx_err(wx, "Failed to setup link\n"); 198 145 return err; ··· 201 148 return 0; 202 149 } 203 150 204 - static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sfp_id *id) 151 + static int txgbe_sfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id) 205 152 { 206 153 __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, }; 207 154 DECLARE_PHY_INTERFACE_MASK(interfaces); 208 155 struct txgbe *txgbe = wx->priv; 209 156 210 - if (id->com_25g_code & (TXGBE_SFF_25GBASESR_CAPABLE | 211 - TXGBE_SFF_25GBASEER_CAPABLE | 212 - TXGBE_SFF_25GBASELR_CAPABLE)) { 213 - phylink_set(modes, 25000baseSR_Full); 157 + if (id->cable_tech & TXGBE_SFF_DA_PASSIVE_CABLE) { 158 + txgbe->link_port = PORT_DA; 159 + phylink_set(modes, Autoneg); 160 + if (id->com_25g_code == TXGBE_SFF_25GBASECR_91FEC || 161 + id->com_25g_code == TXGBE_SFF_25GBASECR_74FEC || 162 + id->com_25g_code == TXGBE_SFF_25GBASECR_NOFEC) { 163 + phylink_set(modes, 25000baseCR_Full); 164 + phylink_set(modes, 10000baseCR_Full); 165 + __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); 166 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 167 + } else { 168 + phylink_set(modes, 10000baseCR_Full); 169 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 170 + } 171 + } else if (id->cable_tech & TXGBE_SFF_DA_ACTIVE_CABLE) { 172 + txgbe->link_port = PORT_DA; 173 + phylink_set(modes, Autoneg); 174 + phylink_set(modes, 25000baseCR_Full); 214 175 __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); 215 - } 216 - if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) { 217 - phylink_set(modes, 10000baseSR_Full); 218 - __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 219 - } 220 - if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) { 221 - phylink_set(modes, 10000baseLR_Full); 222 - __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 176 + } else { 177 + if (id->com_25g_code == TXGBE_SFF_25GBASESR_CAPABLE || 178 + id->com_25g_code == TXGBE_SFF_25GBASEER_CAPABLE || 179 + id->com_25g_code == TXGBE_SFF_25GBASELR_CAPABLE) { 180 + txgbe->link_port = PORT_FIBRE; 181 + phylink_set(modes, 25000baseSR_Full); 182 + __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); 183 + } 184 + if (id->com_10g_code & TXGBE_SFF_10GBASESR_CAPABLE) { 185 + txgbe->link_port = PORT_FIBRE; 186 + phylink_set(modes, 10000baseSR_Full); 187 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 188 + } 189 + if (id->com_10g_code & TXGBE_SFF_10GBASELR_CAPABLE) { 190 + txgbe->link_port = PORT_FIBRE; 191 + phylink_set(modes, 10000baseLR_Full); 192 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 193 + } 223 194 } 224 195 225 196 if (phy_interface_empty(interfaces)) { ··· 254 177 phylink_set(modes, Pause); 255 178 phylink_set(modes, Asym_Pause); 256 179 phylink_set(modes, FIBRE); 257 - txgbe->link_port = PORT_FIBRE; 258 180 259 - if (!linkmode_equal(txgbe->sfp_support, modes)) { 260 - linkmode_copy(txgbe->sfp_support, modes); 261 - phy_interface_and(txgbe->sfp_interfaces, 181 + if (!linkmode_equal(txgbe->link_support, modes)) { 182 + linkmode_copy(txgbe->link_support, modes); 183 + phy_interface_and(txgbe->link_interfaces, 262 184 wx->phylink_config.supported_interfaces, 263 185 interfaces); 264 186 linkmode_copy(txgbe->advertising, modes); ··· 268 192 return 0; 269 193 } 270 194 271 - int txgbe_identify_sfp(struct wx *wx) 195 + static int txgbe_qsfp_to_linkmodes(struct wx *wx, struct txgbe_sff_id *id) 272 196 { 273 - struct txgbe_hic_i2c_read buffer; 274 - struct txgbe_sfp_id *id; 197 + __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, }; 198 + DECLARE_PHY_INTERFACE_MASK(interfaces); 199 + struct txgbe *txgbe = wx->priv; 200 + 201 + if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) { 202 + txgbe->link_port = PORT_DA; 203 + phylink_set(modes, Autoneg); 204 + phylink_set(modes, 40000baseCR4_Full); 205 + phylink_set(modes, 10000baseCR_Full); 206 + __set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces); 207 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 208 + } 209 + if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_SR4) { 210 + txgbe->link_port = PORT_FIBRE; 211 + phylink_set(modes, 40000baseSR4_Full); 212 + __set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces); 213 + } 214 + if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_LR4) { 215 + txgbe->link_port = PORT_FIBRE; 216 + phylink_set(modes, 40000baseLR4_Full); 217 + __set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces); 218 + } 219 + if (id->transceiver_type & TXGBE_SFF_ETHERNET_40G_ACTIVE) { 220 + txgbe->link_port = PORT_DA; 221 + phylink_set(modes, Autoneg); 222 + phylink_set(modes, 40000baseCR4_Full); 223 + __set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces); 224 + } 225 + if (id->transceiver_type & TXGBE_SFF_ETHERNET_RSRVD) { 226 + if (id->sff_opt1 & TXGBE_SFF_ETHERNET_100G_CR4) { 227 + txgbe->link_port = PORT_DA; 228 + phylink_set(modes, Autoneg); 229 + phylink_set(modes, 40000baseCR4_Full); 230 + phylink_set(modes, 25000baseCR_Full); 231 + phylink_set(modes, 10000baseCR_Full); 232 + __set_bit(PHY_INTERFACE_MODE_XLGMII, interfaces); 233 + __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); 234 + __set_bit(PHY_INTERFACE_MODE_10GBASER, interfaces); 235 + } 236 + } 237 + 238 + if (phy_interface_empty(interfaces)) { 239 + wx_err(wx, "unsupported QSFP module\n"); 240 + return -EINVAL; 241 + } 242 + 243 + phylink_set(modes, Pause); 244 + phylink_set(modes, Asym_Pause); 245 + phylink_set(modes, FIBRE); 246 + 247 + if (!linkmode_equal(txgbe->link_support, modes)) { 248 + linkmode_copy(txgbe->link_support, modes); 249 + phy_interface_and(txgbe->link_interfaces, 250 + wx->phylink_config.supported_interfaces, 251 + interfaces); 252 + linkmode_copy(txgbe->advertising, modes); 253 + 254 + set_bit(WX_FLAG_NEED_LINK_CONFIG, wx->flags); 255 + } 256 + 257 + return 0; 258 + } 259 + 260 + int txgbe_identify_module(struct wx *wx) 261 + { 262 + struct txgbe_hic_get_module_info buffer; 263 + struct txgbe_sff_id *id; 275 264 int err = 0; 265 + u32 mod_abs; 276 266 u32 gpio; 277 267 268 + if (wx->mac.type == wx_mac_aml40) 269 + mod_abs = TXGBE_GPIOBIT_4; 270 + else 271 + mod_abs = TXGBE_GPIOBIT_2; 272 + 278 273 gpio = rd32(wx, WX_GPIO_EXT); 279 - if (gpio & TXGBE_GPIOBIT_2) 274 + if (gpio & mod_abs) 280 275 return -ENODEV; 281 276 282 - err = txgbe_identify_sfp_hostif(wx, &buffer); 277 + err = txgbe_identify_module_hostif(wx, &buffer); 283 278 if (err) { 284 - wx_err(wx, "Failed to identify SFP module\n"); 279 + wx_err(wx, "Failed to identify module\n"); 285 280 return err; 286 281 } 287 282 288 283 id = &buffer.id; 289 - if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP) { 290 - wx_err(wx, "Invalid SFP module\n"); 284 + if (id->identifier != TXGBE_SFF_IDENTIFIER_SFP && 285 + id->identifier != TXGBE_SFF_IDENTIFIER_QSFP && 286 + id->identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS && 287 + id->identifier != TXGBE_SFF_IDENTIFIER_QSFP28) { 288 + wx_err(wx, "Invalid module\n"); 291 289 return -ENODEV; 292 290 } 293 291 294 - return txgbe_sfp_to_linkmodes(wx, id); 292 + if (id->transceiver_type == 0xFF) 293 + return txgbe_sfp_to_linkmodes(wx, id); 294 + 295 + return txgbe_qsfp_to_linkmodes(wx, id); 295 296 } 296 297 297 298 void txgbe_setup_link(struct wx *wx) 298 299 { 299 300 struct txgbe *txgbe = wx->priv; 300 301 301 - phy_interface_zero(txgbe->sfp_interfaces); 302 - linkmode_zero(txgbe->sfp_support); 302 + phy_interface_zero(txgbe->link_interfaces); 303 + linkmode_zero(txgbe->link_support); 303 304 304 - txgbe_identify_sfp(wx); 305 + set_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags); 306 + wx_service_event_schedule(wx); 305 307 } 306 308 307 309 static void txgbe_get_link_state(struct phylink_config *config, ··· 432 278 txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK; 433 279 434 280 switch (speed) { 281 + case SPEED_40000: 282 + txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_40G; 283 + break; 435 284 case SPEED_25000: 436 285 txcfg |= TXGBE_AML_MAC_TX_CFG_SPEED_25G; 437 286 break; ··· 499 342 MAC_SYM_PAUSE | MAC_ASYM_PAUSE; 500 343 config->get_fixed_state = txgbe_get_link_state; 501 344 502 - phy_mode = PHY_INTERFACE_MODE_25GBASER; 345 + if (wx->mac.type == wx_mac_aml40) { 346 + config->mac_capabilities |= MAC_40000FD; 347 + phy_mode = PHY_INTERFACE_MODE_XLGMII; 348 + __set_bit(PHY_INTERFACE_MODE_XLGMII, config->supported_interfaces); 349 + state.speed = SPEED_40000; 350 + state.duplex = DUPLEX_FULL; 351 + } else { 352 + phy_mode = PHY_INTERFACE_MODE_25GBASER; 353 + state.speed = SPEED_25000; 354 + state.duplex = DUPLEX_FULL; 355 + } 356 + 503 357 __set_bit(PHY_INTERFACE_MODE_25GBASER, config->supported_interfaces); 504 358 __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces); 505 359 ··· 518 350 if (IS_ERR(phylink)) 519 351 return PTR_ERR(phylink); 520 352 521 - state.speed = SPEED_25000; 522 - state.duplex = DUPLEX_FULL; 523 353 err = phylink_set_fixed_link(phylink, &state); 524 354 if (err) { 525 355 wx_err(wx, "Failed to set fixed link\n");
+4 -1
drivers/net/ethernet/wangxun/txgbe/txgbe_aml.h
··· 7 7 void txgbe_gpio_init_aml(struct wx *wx); 8 8 irqreturn_t txgbe_gpio_irq_handler_aml(int irq, void *data); 9 9 int txgbe_test_hostif(struct wx *wx); 10 + int txgbe_read_eeprom_hostif(struct wx *wx, 11 + struct txgbe_hic_i2c_read *buffer, 12 + u32 length, u8 *data); 10 13 int txgbe_set_phy_link(struct wx *wx); 11 - int txgbe_identify_sfp(struct wx *wx); 14 + int txgbe_identify_module(struct wx *wx); 12 15 void txgbe_setup_link(struct wx *wx); 13 16 int txgbe_phylink_init_aml(struct txgbe *txgbe); 14 17
+33 -5
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
··· 10 10 #include "../libwx/wx_lib.h" 11 11 #include "txgbe_type.h" 12 12 #include "txgbe_fdir.h" 13 + #include "txgbe_aml.h" 13 14 #include "txgbe_ethtool.h" 14 15 15 16 int txgbe_get_link_ksettings(struct net_device *netdev, ··· 20 19 struct txgbe *txgbe = wx->priv; 21 20 int err; 22 21 23 - if (wx->mac.type == wx_mac_aml40) 24 - return -EOPNOTSUPP; 25 - 26 22 err = wx_get_link_ksettings(netdev, cmd); 27 23 if (err) 28 24 return err; ··· 28 30 return 0; 29 31 30 32 cmd->base.port = txgbe->link_port; 31 - cmd->base.autoneg = AUTONEG_DISABLE; 32 - linkmode_copy(cmd->link_modes.supported, txgbe->sfp_support); 33 + cmd->base.autoneg = phylink_test(txgbe->advertising, Autoneg) ? 34 + AUTONEG_ENABLE : AUTONEG_DISABLE; 35 + linkmode_copy(cmd->link_modes.supported, txgbe->link_support); 33 36 linkmode_copy(cmd->link_modes.advertising, txgbe->advertising); 34 37 35 38 return 0; ··· 535 536 return ret; 536 537 } 537 538 539 + static int 540 + txgbe_get_module_eeprom_by_page(struct net_device *netdev, 541 + const struct ethtool_module_eeprom *page_data, 542 + struct netlink_ext_ack *extack) 543 + { 544 + struct wx *wx = netdev_priv(netdev); 545 + struct txgbe_hic_i2c_read buffer; 546 + int err; 547 + 548 + if (!test_bit(WX_FLAG_SWFW_RING, wx->flags)) 549 + return -EOPNOTSUPP; 550 + 551 + buffer.length = cpu_to_be32(page_data->length); 552 + buffer.offset = cpu_to_be32(page_data->offset); 553 + buffer.page = page_data->page; 554 + buffer.bank = page_data->bank; 555 + buffer.i2c_address = page_data->i2c_address; 556 + 557 + err = txgbe_read_eeprom_hostif(wx, &buffer, page_data->length, 558 + page_data->data); 559 + if (err) { 560 + wx_err(wx, "Failed to read module EEPROM\n"); 561 + return err; 562 + } 563 + 564 + return page_data->length; 565 + } 566 + 538 567 static const struct ethtool_ops txgbe_ethtool_ops = { 539 568 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 540 569 ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | ··· 597 570 .set_msglevel = wx_set_msglevel, 598 571 .get_ts_info = wx_get_ts_info, 599 572 .get_ts_stats = wx_get_ptp_stats, 573 + .get_module_eeprom_by_page = txgbe_get_module_eeprom_by_page, 600 574 }; 601 575 602 576 void txgbe_set_ethtool_ops(struct net_device *netdev)
+2 -8
drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
··· 23 23 { 24 24 u32 misc_ien = TXGBE_PX_MISC_IEN_MASK; 25 25 26 - if (wx->mac.type == wx_mac_aml) { 26 + if (wx->mac.type != wx_mac_sp) { 27 27 misc_ien |= TXGBE_PX_MISC_GPIO; 28 28 txgbe_gpio_init_aml(wx); 29 29 } ··· 201 201 202 202 void txgbe_free_misc_irq(struct txgbe *txgbe) 203 203 { 204 - if (txgbe->wx->mac.type == wx_mac_aml40) 205 - return; 206 - 207 - if (txgbe->wx->mac.type == wx_mac_aml) 204 + if (txgbe->wx->mac.type != wx_mac_sp) 208 205 free_irq(txgbe->gpio_irq, txgbe); 209 206 210 207 free_irq(txgbe->link_irq, txgbe); ··· 215 218 unsigned long flags = IRQF_ONESHOT; 216 219 struct wx *wx = txgbe->wx; 217 220 int hwirq, err; 218 - 219 - if (wx->mac.type == wx_mac_aml40) 220 - goto skip_sp_irq; 221 221 222 222 txgbe->misc.nirqs = TXGBE_IRQ_MAX; 223 223 txgbe->misc.domain = irq_domain_create_simple(NULL, txgbe->misc.nirqs, 0,
+9 -14
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
··· 89 89 return physfns; 90 90 } 91 91 92 - static void txgbe_sfp_detection_subtask(struct wx *wx) 92 + static void txgbe_module_detection_subtask(struct wx *wx) 93 93 { 94 94 int err; 95 95 96 - if (!test_bit(WX_FLAG_NEED_SFP_RESET, wx->flags)) 96 + if (!test_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags)) 97 97 return; 98 98 99 - /* wait for SFP module ready */ 99 + /* wait for SFF module ready */ 100 100 msleep(200); 101 101 102 - err = txgbe_identify_sfp(wx); 102 + err = txgbe_identify_module(wx); 103 103 if (err) 104 104 return; 105 105 106 - clear_bit(WX_FLAG_NEED_SFP_RESET, wx->flags); 106 + clear_bit(WX_FLAG_NEED_MODULE_RESET, wx->flags); 107 107 } 108 108 109 109 static void txgbe_link_config_subtask(struct wx *wx) ··· 128 128 { 129 129 struct wx *wx = container_of(work, struct wx, service_task); 130 130 131 - txgbe_sfp_detection_subtask(wx); 131 + txgbe_module_detection_subtask(wx); 132 132 txgbe_link_config_subtask(wx); 133 133 134 134 wx_service_event_complete(wx); ··· 144 144 static void txgbe_up_complete(struct wx *wx) 145 145 { 146 146 struct net_device *netdev = wx->netdev; 147 - u32 reg; 148 147 149 148 wx_control_hw(wx, true); 150 149 wx_configure_vectors(wx); ··· 154 155 155 156 switch (wx->mac.type) { 156 157 case wx_mac_aml40: 157 - reg = rd32(wx, TXGBE_AML_MAC_TX_CFG); 158 - reg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK; 159 - reg |= TXGBE_AML_MAC_TX_CFG_SPEED_40G; 160 - wr32(wx, WX_MAC_TX_CFG, reg); 161 - txgbe_enable_sec_tx_path(wx); 162 - netif_carrier_on(wx->netdev); 158 + txgbe_setup_link(wx); 159 + phylink_start(wx->phylink); 163 160 break; 164 161 case wx_mac_aml: 165 162 /* Enable TX laser */ ··· 271 276 272 277 switch (wx->mac.type) { 273 278 case wx_mac_aml40: 274 - netif_carrier_off(wx->netdev); 279 + phylink_stop(wx->phylink); 275 280 break; 276 281 case wx_mac_aml: 277 282 phylink_stop(wx->phylink);
-2
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
··· 579 579 580 580 switch (wx->mac.type) { 581 581 case wx_mac_aml40: 582 - return 0; 583 582 case wx_mac_aml: 584 583 return txgbe_phylink_init_aml(txgbe); 585 584 case wx_mac_sp: ··· 652 653 { 653 654 switch (txgbe->wx->mac.type) { 654 655 case wx_mac_aml40: 655 - return; 656 656 case wx_mac_aml: 657 657 phylink_destroy(txgbe->wx->phylink); 658 658 return;
+28 -6
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
··· 98 98 /* Port cfg registers */ 99 99 #define TXGBE_CFG_PORT_ST 0x14404 100 100 #define TXGBE_CFG_PORT_ST_LINK_UP BIT(0) 101 + #define TXGBE_CFG_PORT_ST_LINK_AML_40G BIT(2) 101 102 #define TXGBE_CFG_PORT_ST_LINK_AML_25G BIT(3) 102 103 #define TXGBE_CFG_PORT_ST_LINK_AML_10G BIT(4) 103 104 #define TXGBE_CFG_VXLAN 0x14410 ··· 318 317 #define TXGBE_LINK_SPEED_UNKNOWN 0 319 318 #define TXGBE_LINK_SPEED_10GB_FULL 4 320 319 #define TXGBE_LINK_SPEED_25GB_FULL 0x10 320 + #define TXGBE_LINK_SPEED_40GB_FULL 0x20 321 321 322 322 #define TXGBE_SFF_IDENTIFIER_SFP 0x3 323 + #define TXGBE_SFF_IDENTIFIER_QSFP 0xC 324 + #define TXGBE_SFF_IDENTIFIER_QSFP_PLUS 0xD 325 + #define TXGBE_SFF_IDENTIFIER_QSFP28 0x11 323 326 #define TXGBE_SFF_DA_PASSIVE_CABLE 0x4 324 327 #define TXGBE_SFF_DA_ACTIVE_CABLE 0x8 325 328 #define TXGBE_SFF_DA_SPEC_ACTIVE_LIMIT 0x4 ··· 336 331 #define TXGBE_SFF_25GBASECR_91FEC 0xB 337 332 #define TXGBE_SFF_25GBASECR_74FEC 0xC 338 333 #define TXGBE_SFF_25GBASECR_NOFEC 0xD 334 + #define TXGBE_SFF_ETHERNET_RSRVD BIT(7) 335 + #define TXGBE_SFF_ETHERNET_40G_CR4 BIT(3) 336 + #define TXGBE_SFF_ETHERNET_40G_SR4 BIT(2) 337 + #define TXGBE_SFF_ETHERNET_40G_LR4 BIT(1) 338 + #define TXGBE_SFF_ETHERNET_40G_ACTIVE BIT(0) 339 + #define TXGBE_SFF_ETHERNET_100G_CR4 0xB 339 340 340 341 #define TXGBE_PHY_FEC_RS BIT(0) 341 342 #define TXGBE_PHY_FEC_BASER BIT(1) ··· 352 341 353 342 #define FW_PHY_GET_LINK_CMD 0xC0 354 343 #define FW_PHY_SET_LINK_CMD 0xC1 355 - #define FW_READ_SFP_INFO_CMD 0xC5 344 + #define FW_GET_MODULE_INFO_CMD 0xC5 345 + #define FW_READ_EEPROM_CMD 0xC6 356 346 357 - struct txgbe_sfp_id { 347 + struct txgbe_sff_id { 358 348 u8 identifier; /* A0H 0x00 */ 359 349 u8 com_1g_code; /* A0H 0x06 */ 360 350 u8 com_10g_code; /* A0H 0x03 */ ··· 370 358 u8 reserved[5]; 371 359 }; 372 360 373 - struct txgbe_hic_i2c_read { 361 + struct txgbe_hic_get_module_info { 374 362 struct wx_hic_hdr hdr; 375 - struct txgbe_sfp_id id; 363 + struct txgbe_sff_id id; 376 364 }; 377 365 378 366 struct txgbe_hic_ephy_setlink { ··· 393 381 u8 power; 394 382 u8 fec_mode; 395 383 u8 resv[6]; 384 + }; 385 + 386 + struct txgbe_hic_i2c_read { 387 + struct wx_hic_hdr hdr; 388 + __be32 offset; 389 + __be32 length; 390 + u8 page; 391 + u8 bank; 392 + u8 i2c_address; 393 + u8 resv; 396 394 }; 397 395 398 396 #define NODE_PROP(_NAME, _PROP) \ ··· 473 451 int fdir_filter_count; 474 452 spinlock_t fdir_perfect_lock; /* spinlock for FDIR */ 475 453 476 - DECLARE_PHY_INTERFACE_MASK(sfp_interfaces); 477 - __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); 454 + DECLARE_PHY_INTERFACE_MASK(link_interfaces); 455 + __ETHTOOL_DECLARE_LINK_MODE_MASK(link_support); 478 456 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); 479 457 u8 link_port; 480 458 };