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

sfc: Add support for Solarflare 10Xpress SFT9001

Add type codes for the new PHY and rename the SFX7101 type code.

Add definition of clause 22 extension MMD.

Adapt the 10Xpress SFX7101 code to support the SFT9001 as well.
Clean up register definitions.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ben Hutchings and committed by
David S. Miller
e6fa2eb7 766ca0fa

+464 -102
+3
drivers/net/sfc/enum.h
··· 58 58 #define LOOPBACK_INTERNAL(_efx) \ 59 59 (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx))) 60 60 61 + #define LOOPBACK_CHANGED(_from, _to, _mask) \ 62 + (!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask))) 63 + 61 64 #define LOOPBACK_OUT_OF(_from, _to, _mask) \ 62 65 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask))) 63 66
+3
drivers/net/sfc/ethtool.c
··· 219 219 struct efx_nic *efx = netdev_priv(net_dev); 220 220 int rc; 221 221 222 + if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg) 223 + return -EINVAL; 224 + 222 225 /* Falcon GMAC does not support 1000Mbps HD */ 223 226 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { 224 227 EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
+7 -3
drivers/net/sfc/falcon.c
··· 826 826 #endif 827 827 828 828 if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && 829 - efx->phy_type == PHY_TYPE_10XPRESS)) 829 + efx->phy_type == PHY_TYPE_SFX7101)) 830 830 tenxpress_crc_err(efx); 831 831 } 832 832 ··· 2245 2245 static int falcon_probe_phy(struct efx_nic *efx) 2246 2246 { 2247 2247 switch (efx->phy_type) { 2248 - case PHY_TYPE_10XPRESS: 2249 - efx->phy_op = &falcon_tenxpress_phy_ops; 2248 + case PHY_TYPE_SFX7101: 2249 + efx->phy_op = &falcon_sfx7101_phy_ops; 2250 + break; 2251 + case PHY_TYPE_SFT9001A: 2252 + case PHY_TYPE_SFT9001B: 2253 + efx->phy_op = &falcon_sft9001_phy_ops; 2250 2254 break; 2251 2255 case PHY_TYPE_XFP: 2252 2256 efx->phy_op = &falcon_xfp_phy_ops;
+8
drivers/net/sfc/mdio_10g.h
··· 33 33 #define MDIO_MMD_TC (6) 34 34 /* Auto negotiation */ 35 35 #define MDIO_MMD_AN (7) 36 + /* Clause 22 extension */ 37 + #define MDIO_MMD_C22EXT 29 36 38 37 39 /* Generic register locations */ 38 40 #define MDIO_MMDREG_CTRL1 (0) ··· 84 82 #define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) 85 83 #define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) 86 84 #define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) 85 + #define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT) 87 86 88 87 /* Bits in MMDREG_SPEED */ 89 88 #define MDIO_MMDREG_SPEED_10G_LBN 0 ··· 127 124 #define MDIO_PMAPMD_CTRL2_100_BT (0xe) 128 125 #define MDIO_PMAPMD_CTRL2_10_BT (0xf) 129 126 #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) 127 + 128 + /* PMA 10GBT registers */ 129 + #define MDIO_PMAPMD_10GBT_TXPWR (131) 130 + #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0) 131 + #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1) 130 132 131 133 /* PHY XGXS lane state */ 132 134 #define MDIO_PHYXS_LANE_STATE (0x18)
+3 -1
drivers/net/sfc/net_driver.h
··· 455 455 PHY_TYPE_NONE = 0, 456 456 PHY_TYPE_CX4_RTMR = 1, 457 457 PHY_TYPE_1G_ALASKA = 2, 458 - PHY_TYPE_10XPRESS = 3, 458 + PHY_TYPE_SFX7101 = 3, 459 459 PHY_TYPE_XFP = 4, 460 460 PHY_TYPE_PM8358 = 6, 461 + PHY_TYPE_SFT9001A = 8, 462 + PHY_TYPE_SFT9001B = 10, 461 463 PHY_TYPE_MAX /* Insert any new items before this */ 462 464 }; 463 465
+4 -3
drivers/net/sfc/phy.h
··· 1 1 /**************************************************************************** 2 2 * Driver for Solarflare Solarstorm network controllers and boards 3 - * Copyright 2007 Solarflare Communications Inc. 3 + * Copyright 2007-2008 Solarflare Communications Inc. 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify it 6 6 * under the terms of the GNU General Public License version 2 as published ··· 11 11 #define EFX_PHY_H 12 12 13 13 /**************************************************************************** 14 - * 10Xpress (SFX7101) PHY 14 + * 10Xpress (SFX7101 and SFT9001) PHYs 15 15 */ 16 - extern struct efx_phy_operations falcon_tenxpress_phy_ops; 16 + extern struct efx_phy_operations falcon_sfx7101_phy_ops; 17 + extern struct efx_phy_operations falcon_sft9001_phy_ops; 17 18 18 19 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); 19 20 extern void tenxpress_crc_err(struct efx_nic *efx);
+428 -94
drivers/net/sfc/tenxpress.c
··· 15 15 #include "phy.h" 16 16 #include "falcon_hwdefs.h" 17 17 #include "boards.h" 18 + #include "workarounds.h" 19 + #include "selftest.h" 18 20 19 - /* We expect these MMDs to be in the package */ 21 + /* We expect these MMDs to be in the package. SFT9001 also has a 22 + * clause 22 extension MMD, but since it doesn't have all the generic 23 + * MMD registers it is pointless to include it here. 24 + */ 20 25 #define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ 21 26 MDIO_MMDREG_DEVS_PCS | \ 22 27 MDIO_MMDREG_DEVS_PHYXS | \ 23 28 MDIO_MMDREG_DEVS_AN) 24 29 25 - #define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 26 - (1 << LOOPBACK_PCS) | \ 27 - (1 << LOOPBACK_PMAPMD) | \ 28 - (1 << LOOPBACK_NETWORK)) 30 + #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 31 + (1 << LOOPBACK_PCS) | \ 32 + (1 << LOOPBACK_PMAPMD) | \ 33 + (1 << LOOPBACK_NETWORK)) 34 + 35 + #define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \ 36 + (1 << LOOPBACK_PHYXS) | \ 37 + (1 << LOOPBACK_PCS) | \ 38 + (1 << LOOPBACK_PMAPMD) | \ 39 + (1 << LOOPBACK_NETWORK)) 29 40 30 41 /* We complain if we fail to see the link partner as 10G capable this many 31 42 * times in a row (must be > 1 as sampling the autoneg. registers is racy) 32 43 */ 33 44 #define MAX_BAD_LP_TRIES (5) 34 45 46 + /* LASI Control */ 47 + #define PMA_PMD_LASI_CTRL 36866 48 + #define PMA_PMD_LASI_STATUS 36869 49 + #define PMA_PMD_LS_ALARM_LBN 0 50 + #define PMA_PMD_LS_ALARM_WIDTH 1 51 + #define PMA_PMD_TX_ALARM_LBN 1 52 + #define PMA_PMD_TX_ALARM_WIDTH 1 53 + #define PMA_PMD_RX_ALARM_LBN 2 54 + #define PMA_PMD_RX_ALARM_WIDTH 1 55 + #define PMA_PMD_AN_ALARM_LBN 3 56 + #define PMA_PMD_AN_ALARM_WIDTH 1 57 + 35 58 /* Extended control register */ 36 - #define PMA_PMD_XCONTROL_REG 0xc000 37 - #define PMA_PMD_LNPGA_POWERDOWN_LBN 8 38 - #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 59 + #define PMA_PMD_XCONTROL_REG 49152 60 + #define PMA_PMD_EXT_GMII_EN_LBN 1 61 + #define PMA_PMD_EXT_GMII_EN_WIDTH 1 62 + #define PMA_PMD_EXT_CLK_OUT_LBN 2 63 + #define PMA_PMD_EXT_CLK_OUT_WIDTH 1 64 + #define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */ 65 + #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 66 + #define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */ 67 + #define PMA_PMD_EXT_CLK312_WIDTH 1 68 + #define PMA_PMD_EXT_LPOWER_LBN 12 69 + #define PMA_PMD_EXT_LPOWER_WIDTH 1 70 + #define PMA_PMD_EXT_SSR_LBN 15 71 + #define PMA_PMD_EXT_SSR_WIDTH 1 39 72 40 73 /* extended status register */ 41 - #define PMA_PMD_XSTATUS_REG 0xc001 74 + #define PMA_PMD_XSTATUS_REG 49153 42 75 #define PMA_PMD_XSTAT_FLP_LBN (12) 43 76 44 77 /* LED control register */ 45 - #define PMA_PMD_LED_CTRL_REG (0xc007) 78 + #define PMA_PMD_LED_CTRL_REG 49159 46 79 #define PMA_PMA_LED_ACTIVITY_LBN (3) 47 80 48 81 /* LED function override register */ 49 - #define PMA_PMD_LED_OVERR_REG (0xc009) 82 + #define PMA_PMD_LED_OVERR_REG 49161 50 83 /* Bit positions for different LEDs (there are more but not wired on SFE4001)*/ 51 84 #define PMA_PMD_LED_LINK_LBN (0) 52 85 #define PMA_PMD_LED_SPEED_LBN (2) ··· 96 63 /* Green and Amber under hardware control, Red off */ 97 64 #define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) 98 65 66 + #define PMA_PMD_SPEED_ENABLE_REG 49192 67 + #define PMA_PMD_100TX_ADV_LBN 1 68 + #define PMA_PMD_100TX_ADV_WIDTH 1 69 + #define PMA_PMD_1000T_ADV_LBN 2 70 + #define PMA_PMD_1000T_ADV_WIDTH 1 71 + #define PMA_PMD_10000T_ADV_LBN 3 72 + #define PMA_PMD_10000T_ADV_WIDTH 1 73 + #define PMA_PMD_SPEED_LBN 4 74 + #define PMA_PMD_SPEED_WIDTH 4 99 75 100 - /* Special Software reset register */ 101 - #define PMA_PMD_EXT_CTRL_REG 49152 102 - #define PMA_PMD_EXT_SSR_LBN 15 76 + /* Serdes control registers - SFT9001 only */ 77 + #define PMA_PMD_CSERDES_CTRL_REG 64258 78 + /* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */ 79 + #define PMA_PMD_CSERDES_DEFAULT 0x000f 103 80 104 - /* Misc register defines */ 105 - #define PCS_CLOCK_CTRL_REG 0xd801 81 + /* Misc register defines - SFX7101 only */ 82 + #define PCS_CLOCK_CTRL_REG 55297 106 83 #define PLL312_RST_N_LBN 2 107 84 108 - #define PCS_SOFT_RST2_REG 0xd806 85 + #define PCS_SOFT_RST2_REG 55302 109 86 #define SERDES_RST_N_LBN 13 110 87 #define XGXS_RST_N_LBN 12 111 88 112 - #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ 89 + #define PCS_TEST_SELECT_REG 55303 /* PRM 10.5.8 */ 113 90 #define CLK312_EN_LBN 3 114 91 115 92 /* PHYXS registers */ 93 + #define PHYXS_XCONTROL_REG 49152 94 + #define PHYXS_RESET_LBN 15 95 + #define PHYXS_RESET_WIDTH 1 96 + 116 97 #define PHYXS_TEST1 (49162) 117 98 #define LOOPBACK_NEAR_LBN (8) 118 99 #define LOOPBACK_NEAR_WIDTH (1) 119 100 101 + #define PCS_10GBASET_STAT1 32 102 + #define PCS_10GBASET_BLKLK_LBN 0 103 + #define PCS_10GBASET_BLKLK_WIDTH 1 104 + 120 105 /* Boot status register */ 121 - #define PCS_BOOT_STATUS_REG (0xd000) 106 + #define PCS_BOOT_STATUS_REG 53248 122 107 #define PCS_BOOT_FATAL_ERR_LBN (0) 123 108 #define PCS_BOOT_PROGRESS_LBN (1) 124 109 #define PCS_BOOT_PROGRESS_WIDTH (2) 125 110 #define PCS_BOOT_COMPLETE_LBN (3) 111 + 126 112 #define PCS_BOOT_MAX_DELAY (100) 127 113 #define PCS_BOOT_POLL_DELAY (10) 114 + 115 + /* 100M/1G PHY registers */ 116 + #define GPHY_XCONTROL_REG 49152 117 + #define GPHY_ISOLATE_LBN 10 118 + #define GPHY_ISOLATE_WIDTH 1 119 + #define GPHY_DUPLEX_LBN 8 120 + #define GPHY_DUPLEX_WIDTH 1 121 + #define GPHY_LOOPBACK_NEAR_LBN 14 122 + #define GPHY_LOOPBACK_NEAR_WIDTH 1 123 + 124 + #define C22EXT_STATUS_REG 49153 125 + #define C22EXT_STATUS_LINK_LBN 2 126 + #define C22EXT_STATUS_LINK_WIDTH 1 127 + 128 + #define C22EXT_MSTSLV_REG 49162 129 + #define C22EXT_MSTSLV_1000_HD_LBN 10 130 + #define C22EXT_MSTSLV_1000_HD_WIDTH 1 131 + #define C22EXT_MSTSLV_1000_FD_LBN 11 132 + #define C22EXT_MSTSLV_1000_FD_WIDTH 1 128 133 129 134 /* Time to wait between powering down the LNPGA and turning off the power 130 135 * rails */ ··· 186 115 if (phy_data != NULL) 187 116 atomic_inc(&phy_data->bad_crc_count); 188 117 } 118 + 119 + static ssize_t show_phy_short_reach(struct device *dev, 120 + struct device_attribute *attr, char *buf) 121 + { 122 + struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 123 + int reg; 124 + 125 + reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 126 + MDIO_PMAPMD_10GBT_TXPWR); 127 + return sprintf(buf, "%d\n", 128 + !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN))); 129 + } 130 + 131 + static ssize_t set_phy_short_reach(struct device *dev, 132 + struct device_attribute *attr, 133 + const char *buf, size_t count) 134 + { 135 + struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 136 + 137 + rtnl_lock(); 138 + mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 139 + MDIO_PMAPMD_10GBT_TXPWR, 140 + MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN, 141 + count != 0 && *buf != '0'); 142 + efx_reconfigure_port(efx); 143 + rtnl_unlock(); 144 + 145 + return count; 146 + } 147 + 148 + static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, 149 + set_phy_short_reach); 189 150 190 151 /* Check that the C166 has booted successfully */ 191 152 static int tenxpress_phy_check(struct efx_nic *efx) ··· 250 147 251 148 static int tenxpress_init(struct efx_nic *efx) 252 149 { 253 - int rc, reg; 150 + int phy_id = efx->mii.phy_id; 151 + int reg; 152 + int rc; 254 153 255 - /* Turn on the clock */ 256 - reg = (1 << CLK312_EN_LBN); 257 - mdio_clause45_write(efx, efx->mii.phy_id, 258 - MDIO_MMD_PCS, PCS_TEST_SELECT_REG, reg); 154 + if (efx->phy_type == PHY_TYPE_SFX7101) { 155 + /* Enable 312.5 MHz clock */ 156 + mdio_clause45_write(efx, phy_id, 157 + MDIO_MMD_PCS, PCS_TEST_SELECT_REG, 158 + 1 << CLK312_EN_LBN); 159 + } else { 160 + /* Enable 312.5 MHz clock and GMII */ 161 + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, 162 + PMA_PMD_XCONTROL_REG); 163 + reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | 164 + (1 << PMA_PMD_EXT_CLK_OUT_LBN) | 165 + (1 << PMA_PMD_EXT_CLK312_LBN)); 166 + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, 167 + PMA_PMD_XCONTROL_REG, reg); 168 + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, 169 + GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN, 170 + false); 171 + } 259 172 260 173 rc = tenxpress_phy_check(efx); 261 174 if (rc < 0) 262 175 return rc; 263 176 264 177 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ 265 - reg = mdio_clause45_read(efx, efx->mii.phy_id, 266 - MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG); 267 - reg |= (1 << PMA_PMA_LED_ACTIVITY_LBN); 268 - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 269 - PMA_PMD_LED_CTRL_REG, reg); 270 - 271 - reg = PMA_PMD_LED_DEFAULT; 272 - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 273 - PMA_PMD_LED_OVERR_REG, reg); 178 + if (efx->phy_type == PHY_TYPE_SFX7101) { 179 + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, 180 + PMA_PMD_LED_CTRL_REG, 181 + PMA_PMA_LED_ACTIVITY_LBN, 182 + true); 183 + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, 184 + PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT); 185 + } 274 186 275 187 return rc; 276 188 } ··· 301 183 efx->phy_data = phy_data; 302 184 phy_data->phy_mode = efx->phy_mode; 303 185 304 - rc = mdio_clause45_wait_reset_mmds(efx, 305 - TENXPRESS_REQUIRED_DEVS); 306 - if (rc < 0) 307 - goto fail; 186 + if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { 187 + if (efx->phy_type == PHY_TYPE_SFT9001A) { 188 + int reg; 189 + reg = mdio_clause45_read(efx, efx->mii.phy_id, 190 + MDIO_MMD_PMAPMD, 191 + PMA_PMD_XCONTROL_REG); 192 + reg |= (1 << PMA_PMD_EXT_SSR_LBN); 193 + mdio_clause45_write(efx, efx->mii.phy_id, 194 + MDIO_MMD_PMAPMD, 195 + PMA_PMD_XCONTROL_REG, reg); 196 + mdelay(200); 197 + } 308 198 309 - rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 310 - if (rc < 0) 311 - goto fail; 199 + rc = mdio_clause45_wait_reset_mmds(efx, 200 + TENXPRESS_REQUIRED_DEVS); 201 + if (rc < 0) 202 + goto fail; 203 + 204 + rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 205 + if (rc < 0) 206 + goto fail; 207 + } 312 208 313 209 rc = tenxpress_init(efx); 314 210 if (rc < 0) 315 211 goto fail; 316 212 213 + if (efx->phy_type == PHY_TYPE_SFT9001B) { 214 + rc = device_create_file(&efx->pci_dev->dev, 215 + &dev_attr_phy_short_reach); 216 + if (rc) 217 + goto fail; 218 + } 219 + 317 220 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ 318 221 319 - /* Let XGXS and SerDes out of reset and resets 10XPress */ 222 + /* Let XGXS and SerDes out of reset */ 320 223 falcon_reset_xaui(efx); 321 224 322 225 return 0; ··· 348 209 return rc; 349 210 } 350 211 212 + /* Perform a "special software reset" on the PHY. The caller is 213 + * responsible for saving and restoring the PHY hardware registers 214 + * properly, and masking/unmasking LASI */ 351 215 static int tenxpress_special_reset(struct efx_nic *efx) 352 216 { 353 217 int rc, reg; 354 218 355 219 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 356 220 * a special software reset can glitch the XGMAC sufficiently for stats 357 - * requests to fail. Since we don't ofen special_reset, just lock. */ 221 + * requests to fail. Since we don't often special_reset, just lock. */ 358 222 spin_lock(&efx->stats_lock); 359 223 360 224 /* Initiate reset */ 361 225 reg = mdio_clause45_read(efx, efx->mii.phy_id, 362 - MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG); 226 + MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); 363 227 reg |= (1 << PMA_PMD_EXT_SSR_LBN); 364 228 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 365 - PMA_PMD_EXT_CTRL_REG, reg); 229 + PMA_PMD_XCONTROL_REG, reg); 366 230 367 231 mdelay(200); 368 232 ··· 380 238 if (rc < 0) 381 239 goto unlock; 382 240 241 + /* Wait for the XGXS state machine to churn */ 242 + mdelay(10); 383 243 unlock: 384 244 spin_unlock(&efx->stats_lock); 385 245 return rc; 386 246 } 387 247 388 - static void tenxpress_check_bad_lp(struct efx_nic *efx, bool link_ok) 248 + static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) 389 249 { 390 250 struct tenxpress_phy_data *pd = efx->phy_data; 391 251 int phy_id = efx->mii.phy_id; ··· 432 288 } 433 289 } 434 290 435 - static bool tenxpress_link_ok(struct efx_nic *efx) 291 + static bool sfx7101_link_ok(struct efx_nic *efx) 436 292 { 437 - if (efx->loopback_mode == LOOPBACK_NONE) 438 - return mdio_clause45_links_ok(efx, MDIO_MMDREG_DEVS_AN); 439 - else 293 + return mdio_clause45_links_ok(efx, 294 + MDIO_MMDREG_DEVS_PMAPMD | 295 + MDIO_MMDREG_DEVS_PCS | 296 + MDIO_MMDREG_DEVS_PHYXS); 297 + } 298 + 299 + static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) 300 + { 301 + int phy_id = efx->mii.phy_id; 302 + u32 reg; 303 + 304 + if (efx->loopback_mode == LOOPBACK_GPHY) 305 + return true; 306 + else if (efx_phy_mode_disabled(efx->phy_mode)) 307 + return false; 308 + else if (efx->loopback_mode) 440 309 return mdio_clause45_links_ok(efx, 441 310 MDIO_MMDREG_DEVS_PMAPMD | 442 311 MDIO_MMDREG_DEVS_PCS | 443 312 MDIO_MMDREG_DEVS_PHYXS); 313 + 314 + /* We must use the same definition of link state as LASI, 315 + * otherwise we can miss a link state transition 316 + */ 317 + if (ecmd->speed == 10000) { 318 + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, 319 + PCS_10GBASET_STAT1); 320 + return reg & (1 << PCS_10GBASET_BLKLK_LBN); 321 + } else { 322 + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, 323 + C22EXT_STATUS_REG); 324 + return reg & (1 << C22EXT_STATUS_LINK_LBN); 325 + } 444 326 } 445 327 446 - static void tenxpress_phyxs_loopback(struct efx_nic *efx) 328 + static void tenxpress_ext_loopback(struct efx_nic *efx) 447 329 { 448 330 int phy_id = efx->mii.phy_id; 449 - int ctrl1, ctrl2; 450 331 451 - ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, 452 - PHYXS_TEST1); 453 - if (efx->loopback_mode == LOOPBACK_PHYXS) 454 - ctrl2 |= (1 << LOOPBACK_NEAR_LBN); 332 + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, 333 + PHYXS_TEST1, LOOPBACK_NEAR_LBN, 334 + efx->loopback_mode == LOOPBACK_PHYXS); 335 + if (efx->phy_type != PHY_TYPE_SFX7101) 336 + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, 337 + GPHY_XCONTROL_REG, 338 + GPHY_LOOPBACK_NEAR_LBN, 339 + efx->loopback_mode == LOOPBACK_GPHY); 340 + } 341 + 342 + static void tenxpress_low_power(struct efx_nic *efx) 343 + { 344 + int phy_id = efx->mii.phy_id; 345 + 346 + if (efx->phy_type == PHY_TYPE_SFX7101) 347 + mdio_clause45_set_mmds_lpower( 348 + efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), 349 + TENXPRESS_REQUIRED_DEVS); 455 350 else 456 - ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN); 457 - if (ctrl1 != ctrl2) 458 - mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, 459 - PHYXS_TEST1, ctrl2); 351 + mdio_clause45_set_flag( 352 + efx, phy_id, MDIO_MMD_PMAPMD, 353 + PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN, 354 + !!(efx->phy_mode & PHY_MODE_LOW_POWER)); 460 355 } 461 356 462 357 static void tenxpress_phy_reconfigure(struct efx_nic *efx) 463 358 { 464 359 struct tenxpress_phy_data *phy_data = efx->phy_data; 465 - bool loop_change = LOOPBACK_OUT_OF(phy_data, efx, 466 - TENXPRESS_LOOPBACKS); 360 + struct ethtool_cmd ecmd; 361 + bool phy_mode_change, loop_reset, loop_toggle, loopback; 467 362 468 - if (efx->phy_mode & PHY_MODE_SPECIAL) { 363 + if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 469 364 phy_data->phy_mode = efx->phy_mode; 470 365 return; 471 366 } 472 367 473 - /* When coming out of transmit disable, coming out of low power 474 - * mode, or moving out of any PHY internal loopback mode, 475 - * perform a special software reset */ 476 - if ((efx->phy_mode == PHY_MODE_NORMAL && 477 - phy_data->phy_mode != PHY_MODE_NORMAL) || 478 - loop_change) { 479 - tenxpress_special_reset(efx); 480 - falcon_reset_xaui(efx); 368 + tenxpress_low_power(efx); 369 + 370 + phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 371 + phy_data->phy_mode != PHY_MODE_NORMAL); 372 + loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks; 373 + loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks); 374 + loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || 375 + LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 376 + 377 + if (loop_reset || loop_toggle || loopback || phy_mode_change) { 378 + int rc; 379 + 380 + efx->phy_op->get_settings(efx, &ecmd); 381 + 382 + if (loop_reset || phy_mode_change) { 383 + tenxpress_special_reset(efx); 384 + 385 + /* Reset XAUI if we were in 10G, and are staying 386 + * in 10G. If we're moving into and out of 10G 387 + * then xaui will be reset anyway */ 388 + if (EFX_IS10G(efx)) 389 + falcon_reset_xaui(efx); 390 + } 391 + 392 + if (efx->phy_type != PHY_TYPE_SFX7101) { 393 + /* Only change autoneg once, on coming out or 394 + * going into loopback */ 395 + if (loop_toggle) 396 + ecmd.autoneg = !loopback; 397 + if (loopback) { 398 + ecmd.duplex = DUPLEX_FULL; 399 + if (efx->loopback_mode == LOOPBACK_GPHY) 400 + ecmd.speed = SPEED_1000; 401 + else 402 + ecmd.speed = SPEED_10000; 403 + } 404 + } 405 + 406 + rc = efx->phy_op->set_settings(efx, &ecmd); 407 + WARN_ON(rc); 481 408 } 482 409 483 410 mdio_clause45_transmit_disable(efx); 484 411 mdio_clause45_phy_reconfigure(efx); 485 - tenxpress_phyxs_loopback(efx); 412 + tenxpress_ext_loopback(efx); 486 413 487 414 phy_data->loopback_mode = efx->loopback_mode; 488 415 phy_data->phy_mode = efx->phy_mode; 489 - efx->link_up = tenxpress_link_ok(efx); 490 - efx->link_speed = 10000; 491 - efx->link_fd = true; 416 + 417 + if (efx->phy_type == PHY_TYPE_SFX7101) { 418 + efx->link_speed = 10000; 419 + efx->link_fd = true; 420 + efx->link_up = sfx7101_link_ok(efx); 421 + } else { 422 + efx->phy_op->get_settings(efx, &ecmd); 423 + efx->link_speed = ecmd.speed; 424 + efx->link_fd = ecmd.duplex == DUPLEX_FULL; 425 + efx->link_up = sft9001_link_ok(efx, &ecmd); 426 + } 492 427 efx->link_fc = mdio_clause45_get_pause(efx); 493 428 } 494 429 ··· 578 355 bool change = false, link_ok; 579 356 unsigned link_fc; 580 357 581 - link_ok = tenxpress_link_ok(efx); 582 - if (link_ok != efx->link_up) { 583 - change = true; 358 + if (efx->phy_type == PHY_TYPE_SFX7101) { 359 + link_ok = sfx7101_link_ok(efx); 360 + if (link_ok != efx->link_up) { 361 + change = true; 362 + } else { 363 + link_fc = mdio_clause45_get_pause(efx); 364 + if (link_fc != efx->link_fc) 365 + change = true; 366 + } 367 + sfx7101_check_bad_lp(efx, link_ok); 584 368 } else { 585 - link_fc = mdio_clause45_get_pause(efx); 586 - if (link_fc != efx->link_fc) 369 + u32 status = mdio_clause45_read(efx, efx->mii.phy_id, 370 + MDIO_MMD_PMAPMD, 371 + PMA_PMD_LASI_STATUS); 372 + if (status & (1 << PMA_PMD_LS_ALARM_LBN)) 587 373 change = true; 588 374 } 589 - tenxpress_check_bad_lp(efx, link_ok); 590 375 591 376 if (change) 592 377 falcon_sim_phy_event(efx); ··· 602 371 if (phy_data->phy_mode != PHY_MODE_NORMAL) 603 372 return; 604 373 605 - if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { 374 + if (EFX_WORKAROUND_10750(efx) && 375 + atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { 606 376 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); 607 377 falcon_reset_xaui(efx); 608 378 atomic_set(&phy_data->bad_crc_count, 0); ··· 614 382 { 615 383 int reg; 616 384 617 - /* Power down the LNPGA */ 618 - reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); 619 - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 620 - PMA_PMD_XCONTROL_REG, reg); 385 + if (efx->phy_type == PHY_TYPE_SFT9001B) { 386 + device_remove_file(&efx->pci_dev->dev, 387 + &dev_attr_phy_short_reach); 388 + } else { 389 + /* Power down the LNPGA */ 390 + reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); 391 + mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 392 + PMA_PMD_XCONTROL_REG, reg); 621 393 622 - /* Waiting here ensures that the board fini, which can turn off the 623 - * power to the PHY, won't get run until the LNPGA powerdown has been 624 - * given long enough to complete. */ 625 - schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ 394 + /* Waiting here ensures that the board fini, which can turn 395 + * off the power to the PHY, won't get run until the LNPGA 396 + * powerdown has been given long enough to complete. */ 397 + schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ 398 + } 626 399 627 400 kfree(efx->phy_data); 628 401 efx->phy_data = NULL; ··· 663 426 u32 lpa = 0; 664 427 int reg; 665 428 429 + if (efx->phy_type != PHY_TYPE_SFX7101) { 430 + reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, 431 + C22EXT_MSTSLV_REG); 432 + if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) 433 + lpa |= ADVERTISED_1000baseT_Half; 434 + if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) 435 + lpa |= ADVERTISED_1000baseT_Full; 436 + } 666 437 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); 667 438 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) 668 439 lpa |= ADVERTISED_10000baseT_Full; 669 440 return lpa; 670 441 } 671 442 672 - static void 673 - tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 443 + static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 674 444 { 675 445 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, 676 446 tenxpress_get_xnp_lpa(efx)); ··· 685 441 ecmd->advertising |= ADVERTISED_10000baseT_Full; 686 442 } 687 443 688 - struct efx_phy_operations falcon_tenxpress_phy_ops = { 444 + static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 445 + { 446 + int phy_id = efx->mii.phy_id; 447 + u32 xnp_adv = 0; 448 + int reg; 449 + 450 + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, 451 + PMA_PMD_SPEED_ENABLE_REG); 452 + if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN))) 453 + xnp_adv |= ADVERTISED_100baseT_Full; 454 + if (reg & (1 << PMA_PMD_1000T_ADV_LBN)) 455 + xnp_adv |= ADVERTISED_1000baseT_Full; 456 + if (reg & (1 << PMA_PMD_10000T_ADV_LBN)) 457 + xnp_adv |= ADVERTISED_10000baseT_Full; 458 + 459 + mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv, 460 + tenxpress_get_xnp_lpa(efx)); 461 + 462 + ecmd->supported |= (SUPPORTED_100baseT_Half | 463 + SUPPORTED_100baseT_Full | 464 + SUPPORTED_1000baseT_Full); 465 + 466 + /* Use the vendor defined C22ext register for duplex settings */ 467 + if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { 468 + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, 469 + GPHY_XCONTROL_REG); 470 + ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? 471 + DUPLEX_FULL : DUPLEX_HALF); 472 + } 473 + } 474 + 475 + static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 476 + { 477 + int phy_id = efx->mii.phy_id; 478 + int rc; 479 + 480 + rc = mdio_clause45_set_settings(efx, ecmd); 481 + if (rc) 482 + return rc; 483 + 484 + if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) 485 + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, 486 + GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN, 487 + ecmd->duplex == DUPLEX_FULL); 488 + 489 + return rc; 490 + } 491 + 492 + static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) 493 + { 494 + int phy = efx->mii.phy_id; 495 + int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, 496 + PMA_PMD_SPEED_ENABLE_REG); 497 + bool enabled; 498 + 499 + reg &= ~((1 << 2) | (1 << 3)); 500 + if (EFX_WORKAROUND_13204(efx) && 501 + (advertising & ADVERTISED_100baseT_Full)) 502 + reg |= 1 << PMA_PMD_100TX_ADV_LBN; 503 + if (advertising & ADVERTISED_1000baseT_Full) 504 + reg |= 1 << PMA_PMD_1000T_ADV_LBN; 505 + if (advertising & ADVERTISED_10000baseT_Full) 506 + reg |= 1 << PMA_PMD_10000T_ADV_LBN; 507 + mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD, 508 + PMA_PMD_SPEED_ENABLE_REG, reg); 509 + 510 + enabled = (advertising & 511 + (ADVERTISED_1000baseT_Half | 512 + ADVERTISED_1000baseT_Full | 513 + ADVERTISED_10000baseT_Full)); 514 + if (EFX_WORKAROUND_13204(efx)) 515 + enabled |= (advertising & ADVERTISED_100baseT_Full); 516 + return enabled; 517 + } 518 + 519 + struct efx_phy_operations falcon_sfx7101_phy_ops = { 689 520 .macs = EFX_XMAC, 690 521 .init = tenxpress_phy_init, 691 522 .reconfigure = tenxpress_phy_reconfigure, ··· 768 449 .fini = tenxpress_phy_fini, 769 450 .clear_interrupt = efx_port_dummy_op_void, 770 451 .test = tenxpress_phy_test, 771 - .get_settings = tenxpress_get_settings, 452 + .get_settings = sfx7101_get_settings, 772 453 .set_settings = mdio_clause45_set_settings, 773 454 .mmds = TENXPRESS_REQUIRED_DEVS, 774 - .loopbacks = TENXPRESS_LOOPBACKS, 455 + .loopbacks = SFX7101_LOOPBACKS, 456 + }; 457 + 458 + struct efx_phy_operations falcon_sft9001_phy_ops = { 459 + .macs = EFX_GMAC | EFX_XMAC, 460 + .init = tenxpress_phy_init, 461 + .reconfigure = tenxpress_phy_reconfigure, 462 + .poll = tenxpress_phy_poll, 463 + .fini = tenxpress_phy_fini, 464 + .clear_interrupt = efx_port_dummy_op_void, 465 + .test = tenxpress_phy_test, 466 + .get_settings = sft9001_get_settings, 467 + .set_settings = sft9001_set_settings, 468 + .set_xnp_advertise = sft9001_set_xnp_advertise, 469 + .mmds = TENXPRESS_REQUIRED_DEVS, 470 + .loopbacks = SFT9001_LOOPBACKS, 775 471 };
+8 -1
drivers/net/sfc/workarounds.h
··· 17 17 18 18 #define EFX_WORKAROUND_ALWAYS(efx) 1 19 19 #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) 20 + #define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101) 21 + #define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) 20 22 21 23 /* XAUI resets if link not detected */ 22 24 #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS ··· 29 27 /* TX pkt parser problem with <= 16 byte TXes */ 30 28 #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS 31 29 /* Low rate CRC errors require XAUI reset */ 32 - #define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS 30 + #define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101 33 31 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor 34 32 * or a PCIe error (bug 11028) */ 35 33 #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS ··· 52 50 #define EFX_WORKAROUND_7803 EFX_WORKAROUND_FALCON_A 53 51 /* Leak overlength packets rather than free */ 54 52 #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A 53 + 54 + /* Need to send XNP pages for 100BaseT */ 55 + #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A 56 + /* Need to keep AN enabled */ 57 + #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A 55 58 56 59 #endif /* EFX_WORKAROUNDS_H */