aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 00:50:08 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:58:17 -0500
commit177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97 (patch)
treea6e5e9949f388d48ac20c4efbb2811762ac5f9d4 /drivers/net/sfc/falcon.c
parent356eebb2b3af24cc701823f1e025f04eef333239 (diff)
sfc: Add support for sub-10G speeds
The SFC4000 has a separate MAC for use at sub-10G speeds. Introduce an efx_mac_operations structure with implementations for the two MACs. Switch between the MACs as necessary. PHY settings are independent of the MAC, so add get_settings() and set_settings() to efx_phy_operations. Also add macs field to indicate which MACs the PHY is connected to. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/falcon.c')
-rw-r--r--drivers/net/sfc/falcon.c179
1 files changed, 141 insertions, 38 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 448bba9eed09..f09eded40fba 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1168,6 +1168,19 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
1168 falcon_generate_event(channel, &test_event); 1168 falcon_generate_event(channel, &test_event);
1169} 1169}
1170 1170
1171void falcon_sim_phy_event(struct efx_nic *efx)
1172{
1173 efx_qword_t phy_event;
1174
1175 EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE);
1176 if (EFX_IS10G(efx))
1177 EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1);
1178 else
1179 EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1);
1180
1181 falcon_generate_event(&efx->channel[0], &phy_event);
1182}
1183
1171/************************************************************************** 1184/**************************************************************************
1172 * 1185 *
1173 * Flush handling 1186 * Flush handling
@@ -1839,40 +1852,61 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
1839 * 1852 *
1840 ************************************************************************** 1853 **************************************************************************
1841 */ 1854 */
1842void falcon_drain_tx_fifo(struct efx_nic *efx) 1855
1856static int falcon_reset_macs(struct efx_nic *efx)
1843{ 1857{
1844 efx_oword_t temp; 1858 efx_oword_t reg;
1845 int count; 1859 int count;
1846 1860
1847 if ((falcon_rev(efx) < FALCON_REV_B0) || 1861 if (falcon_rev(efx) < FALCON_REV_B0) {
1848 (efx->loopback_mode != LOOPBACK_NONE)) 1862 /* It's not safe to use GLB_CTL_REG to reset the
1849 return; 1863 * macs, so instead use the internal MAC resets
1864 */
1865 if (!EFX_IS10G(efx)) {
1866 EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1);
1867 falcon_write(efx, &reg, GM_CFG1_REG);
1868 udelay(1000);
1869
1870 EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0);
1871 falcon_write(efx, &reg, GM_CFG1_REG);
1872 udelay(1000);
1873 return 0;
1874 } else {
1875 EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
1876 falcon_write(efx, &reg, XM_GLB_CFG_REG);
1877
1878 for (count = 0; count < 10000; count++) {
1879 falcon_read(efx, &reg, XM_GLB_CFG_REG);
1880 if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
1881 return 0;
1882 udelay(10);
1883 }
1850 1884
1851 falcon_read(efx, &temp, MAC0_CTRL_REG_KER); 1885 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
1852 /* There is no point in draining more than once */ 1886 return -ETIMEDOUT;
1853 if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) 1887 }
1854 return; 1888 }
1855 1889
1856 /* MAC stats will fail whilst the TX fifo is draining. Serialise 1890 /* MAC stats will fail whilst the TX fifo is draining. Serialise
1857 * the drain sequence with the statistics fetch */ 1891 * the drain sequence with the statistics fetch */
1858 spin_lock(&efx->stats_lock); 1892 spin_lock(&efx->stats_lock);
1859 1893
1860 EFX_SET_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0, 1); 1894 falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
1861 falcon_write(efx, &temp, MAC0_CTRL_REG_KER); 1895 EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
1896 falcon_write(efx, &reg, MAC0_CTRL_REG_KER);
1862 1897
1863 /* Reset the MAC and EM block. */ 1898 falcon_read(efx, &reg, GLB_CTL_REG_KER);
1864 falcon_read(efx, &temp, GLB_CTL_REG_KER); 1899 EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1);
1865 EFX_SET_OWORD_FIELD(temp, RST_XGTX, 1); 1900 EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1);
1866 EFX_SET_OWORD_FIELD(temp, RST_XGRX, 1); 1901 EFX_SET_OWORD_FIELD(reg, RST_EM, 1);
1867 EFX_SET_OWORD_FIELD(temp, RST_EM, 1); 1902 falcon_write(efx, &reg, GLB_CTL_REG_KER);
1868 falcon_write(efx, &temp, GLB_CTL_REG_KER);
1869 1903
1870 count = 0; 1904 count = 0;
1871 while (1) { 1905 while (1) {
1872 falcon_read(efx, &temp, GLB_CTL_REG_KER); 1906 falcon_read(efx, &reg, GLB_CTL_REG_KER);
1873 if (!EFX_OWORD_FIELD(temp, RST_XGTX) && 1907 if (!EFX_OWORD_FIELD(reg, RST_XGTX) &&
1874 !EFX_OWORD_FIELD(temp, RST_XGRX) && 1908 !EFX_OWORD_FIELD(reg, RST_XGRX) &&
1875 !EFX_OWORD_FIELD(temp, RST_EM)) { 1909 !EFX_OWORD_FIELD(reg, RST_EM)) {
1876 EFX_LOG(efx, "Completed MAC reset after %d loops\n", 1910 EFX_LOG(efx, "Completed MAC reset after %d loops\n",
1877 count); 1911 count);
1878 break; 1912 break;
@@ -1889,21 +1923,39 @@ void falcon_drain_tx_fifo(struct efx_nic *efx)
1889 1923
1890 /* If we've reset the EM block and the link is up, then 1924 /* If we've reset the EM block and the link is up, then
1891 * we'll have to kick the XAUI link so the PHY can recover */ 1925 * we'll have to kick the XAUI link so the PHY can recover */
1892 if (efx->link_up && EFX_WORKAROUND_5147(efx)) 1926 if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
1893 falcon_reset_xaui(efx); 1927 falcon_reset_xaui(efx);
1928
1929 return 0;
1930}
1931
1932void falcon_drain_tx_fifo(struct efx_nic *efx)
1933{
1934 efx_oword_t reg;
1935
1936 if ((falcon_rev(efx) < FALCON_REV_B0) ||
1937 (efx->loopback_mode != LOOPBACK_NONE))
1938 return;
1939
1940 falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
1941 /* There is no point in draining more than once */
1942 if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0))
1943 return;
1944
1945 falcon_reset_macs(efx);
1894} 1946}
1895 1947
1896void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) 1948void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
1897{ 1949{
1898 efx_oword_t temp; 1950 efx_oword_t reg;
1899 1951
1900 if (falcon_rev(efx) < FALCON_REV_B0) 1952 if (falcon_rev(efx) < FALCON_REV_B0)
1901 return; 1953 return;
1902 1954
1903 /* Isolate the MAC -> RX */ 1955 /* Isolate the MAC -> RX */
1904 falcon_read(efx, &temp, RX_CFG_REG_KER); 1956 falcon_read(efx, &reg, RX_CFG_REG_KER);
1905 EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 0); 1957 EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0);
1906 falcon_write(efx, &temp, RX_CFG_REG_KER); 1958 falcon_write(efx, &reg, RX_CFG_REG_KER);
1907 1959
1908 if (!efx->link_up) 1960 if (!efx->link_up)
1909 falcon_drain_tx_fifo(efx); 1961 falcon_drain_tx_fifo(efx);
@@ -2030,7 +2082,8 @@ static int falcon_gmii_wait(struct efx_nic *efx)
2030 efx_dword_t md_stat; 2082 efx_dword_t md_stat;
2031 int count; 2083 int count;
2032 2084
2033 for (count = 0; count < 1000; count++) { /* wait upto 10ms */ 2085 /* wait upto 50ms - taken max from datasheet */
2086 for (count = 0; count < 5000; count++) {
2034 falcon_readl(efx, &md_stat, MD_STAT_REG_KER); 2087 falcon_readl(efx, &md_stat, MD_STAT_REG_KER);
2035 if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { 2088 if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) {
2036 if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || 2089 if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 ||
@@ -2206,10 +2259,59 @@ static int falcon_probe_phy(struct efx_nic *efx)
2206 return -1; 2259 return -1;
2207 } 2260 }
2208 2261
2209 efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; 2262 if (efx->phy_op->macs & EFX_XMAC)
2263 efx->loopback_modes |= ((1 << LOOPBACK_XGMII) |
2264 (1 << LOOPBACK_XGXS) |
2265 (1 << LOOPBACK_XAUI));
2266 if (efx->phy_op->macs & EFX_GMAC)
2267 efx->loopback_modes |= (1 << LOOPBACK_GMAC);
2268 efx->loopback_modes |= efx->phy_op->loopbacks;
2269
2210 return 0; 2270 return 0;
2211} 2271}
2212 2272
2273int falcon_switch_mac(struct efx_nic *efx)
2274{
2275 struct efx_mac_operations *old_mac_op = efx->mac_op;
2276 efx_oword_t nic_stat;
2277 unsigned strap_val;
2278
2279 /* Internal loopbacks override the phy speed setting */
2280 if (efx->loopback_mode == LOOPBACK_GMAC) {
2281 efx->link_speed = 1000;
2282 efx->link_fd = true;
2283 } else if (LOOPBACK_INTERNAL(efx)) {
2284 efx->link_speed = 10000;
2285 efx->link_fd = true;
2286 }
2287
2288 efx->mac_op = (EFX_IS10G(efx) ?
2289 &falcon_xmac_operations : &falcon_gmac_operations);
2290 if (old_mac_op == efx->mac_op)
2291 return 0;
2292
2293 WARN_ON(!mutex_is_locked(&efx->mac_lock));
2294
2295 /* Not all macs support a mac-level link state */
2296 efx->mac_up = true;
2297
2298 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2299 strap_val = EFX_IS10G(efx) ? 5 : 3;
2300 if (falcon_rev(efx) >= FALCON_REV_B0) {
2301 EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1);
2302 EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val);
2303 falcon_write(efx, &nic_stat, NIC_STAT_REG);
2304 } else {
2305 /* Falcon A1 does not support 1G/10G speed switching
2306 * and must not be used with a PHY that does. */
2307 BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
2308 }
2309
2310
2311 EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
2312 return falcon_reset_macs(efx);
2313}
2314
2213/* This call is responsible for hooking in the MAC and PHY operations */ 2315/* This call is responsible for hooking in the MAC and PHY operations */
2214int falcon_probe_port(struct efx_nic *efx) 2316int falcon_probe_port(struct efx_nic *efx)
2215{ 2317{
@@ -2362,6 +2464,10 @@ static struct {
2362 EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, 2464 EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
2363 { DP_CTRL_REG, 2465 { DP_CTRL_REG,
2364 EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, 2466 EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
2467 { GM_CFG2_REG,
2468 EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) },
2469 { GMF_CFG0_REG,
2470 EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) },
2365 { XM_GLB_CFG_REG, 2471 { XM_GLB_CFG_REG,
2366 EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, 2472 EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) },
2367 { XM_TX_CFG_REG, 2473 { XM_TX_CFG_REG,
@@ -2687,6 +2793,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
2687static int falcon_probe_nic_variant(struct efx_nic *efx) 2793static int falcon_probe_nic_variant(struct efx_nic *efx)
2688{ 2794{
2689 efx_oword_t altera_build; 2795 efx_oword_t altera_build;
2796 efx_oword_t nic_stat;
2690 2797
2691 falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); 2798 falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER);
2692 if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { 2799 if (EFX_OWORD_FIELD(altera_build, VER_ALL)) {
@@ -2694,27 +2801,20 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
2694 return -ENODEV; 2801 return -ENODEV;
2695 } 2802 }
2696 2803
2804 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2805
2697 switch (falcon_rev(efx)) { 2806 switch (falcon_rev(efx)) {
2698 case FALCON_REV_A0: 2807 case FALCON_REV_A0:
2699 case 0xff: 2808 case 0xff:
2700 EFX_ERR(efx, "Falcon rev A0 not supported\n"); 2809 EFX_ERR(efx, "Falcon rev A0 not supported\n");
2701 return -ENODEV; 2810 return -ENODEV;
2702 2811
2703 case FALCON_REV_A1:{ 2812 case FALCON_REV_A1:
2704 efx_oword_t nic_stat;
2705
2706 falcon_read(efx, &nic_stat, NIC_STAT_REG);
2707
2708 if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { 2813 if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) {
2709 EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); 2814 EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n");
2710 return -ENODEV; 2815 return -ENODEV;
2711 } 2816 }
2712 if (!EFX_OWORD_FIELD(nic_stat, STRAP_10G)) {
2713 EFX_ERR(efx, "1G mode not supported\n");
2714 return -ENODEV;
2715 }
2716 break; 2817 break;
2717 }
2718 2818
2719 case FALCON_REV_B0: 2819 case FALCON_REV_B0:
2720 break; 2820 break;
@@ -2724,6 +2824,9 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
2724 return -ENODEV; 2824 return -ENODEV;
2725 } 2825 }
2726 2826
2827 /* Initial assumed speed */
2828 efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000;
2829
2727 return 0; 2830 return 0;
2728} 2831}
2729 2832