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

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>

authored by

Ben Hutchings and committed by
David S. Miller
177dfcd8 356eebb2

+700 -322
+2 -2
drivers/net/sfc/Makefile
··· 1 - sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ 2 - selftest.o ethtool.o xfp_phy.o \ 1 + sfc-y += efx.o falcon.o tx.o rx.o falcon_gmac.o \ 2 + falcon_xmac.o selftest.o ethtool.o xfp_phy.o \ 3 3 mdio_10g.o tenxpress.o boards.o sfe4001.o 4 4 sfc-$(CONFIG_SFC_MTD) += mtd.o 5 5
+43 -19
drivers/net/sfc/efx.c
··· 27 27 #include "efx.h" 28 28 #include "mdio_10g.h" 29 29 #include "falcon.h" 30 - #include "mac.h" 31 30 32 31 #define EFX_MAX_MTU (9 * 1024) 33 32 ··· 574 575 netif_addr_unlock_bh(efx->net_dev); 575 576 } 576 577 577 - falcon_reconfigure_xmac(efx); 578 + falcon_deconfigure_mac_wrapper(efx); 579 + 580 + /* Reconfigure the PHY, disabling transmit in mac level loopback. */ 581 + if (LOOPBACK_INTERNAL(efx)) 582 + efx->phy_mode |= PHY_MODE_TX_DISABLED; 583 + else 584 + efx->phy_mode &= ~PHY_MODE_TX_DISABLED; 585 + efx->phy_op->reconfigure(efx); 586 + 587 + if (falcon_switch_mac(efx)) 588 + goto fail; 589 + 590 + efx->mac_op->reconfigure(efx); 578 591 579 592 /* Inform kernel of loss/gain of carrier */ 580 593 efx_link_status_changed(efx); 594 + return; 595 + 596 + fail: 597 + EFX_ERR(efx, "failed to reconfigure MAC\n"); 598 + efx->phy_op->fini(efx); 599 + efx->port_initialized = false; 581 600 } 582 601 583 602 /* Reinitialise the MAC to pick up new PHY settings, even if the port is ··· 665 648 666 649 EFX_LOG(efx, "init port\n"); 667 650 668 - /* Initialise the MAC and PHY */ 669 - rc = falcon_init_xmac(efx); 651 + rc = efx->phy_op->init(efx); 670 652 if (rc) 671 653 return rc; 654 + efx->phy_op->reconfigure(efx); 655 + 656 + mutex_lock(&efx->mac_lock); 657 + rc = falcon_switch_mac(efx); 658 + mutex_unlock(&efx->mac_lock); 659 + if (rc) 660 + goto fail; 661 + efx->mac_op->reconfigure(efx); 672 662 673 663 efx->port_initialized = true; 674 664 efx->stats_enabled = true; 675 - 676 - /* Reconfigure port to program MAC registers */ 677 - falcon_reconfigure_xmac(efx); 678 - 679 665 return 0; 666 + 667 + fail: 668 + efx->phy_op->fini(efx); 669 + return rc; 680 670 } 681 671 682 672 /* Allow efx_reconfigure_port() to be scheduled, and close the window ··· 726 702 if (!efx->port_initialized) 727 703 return; 728 704 729 - falcon_fini_xmac(efx); 705 + efx->phy_op->fini(efx); 730 706 efx->port_initialized = false; 731 707 732 708 efx->link_up = false; ··· 1203 1179 { 1204 1180 struct efx_nic *efx = container_of(data, struct efx_nic, 1205 1181 monitor_work.work); 1206 - int rc = 0; 1207 1182 1208 1183 EFX_TRACE(efx, "hardware monitor executing on CPU %d\n", 1209 1184 raw_smp_processor_id()); ··· 1218 1195 } 1219 1196 1220 1197 if (efx->port_enabled) 1221 - rc = falcon_check_xmac(efx); 1198 + efx->mac_op->check_hw(efx); 1222 1199 mutex_unlock(&efx->mac_lock); 1223 1200 1224 1201 queue_delayed_work(efx->workqueue, &efx->monitor_work, ··· 1354 1331 if (!spin_trylock(&efx->stats_lock)) 1355 1332 return stats; 1356 1333 if (efx->stats_enabled) { 1357 - falcon_update_stats_xmac(efx); 1334 + efx->mac_op->update_stats(efx); 1358 1335 falcon_update_nic_stats(efx); 1359 1336 } 1360 1337 spin_unlock(&efx->stats_lock); ··· 1542 1519 netif_carrier_off(efx->net_dev); 1543 1520 1544 1521 /* Clear MAC statistics */ 1545 - falcon_update_stats_xmac(efx); 1522 + efx->mac_op->update_stats(efx); 1546 1523 memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); 1547 1524 1548 1525 rc = register_netdev(net_dev); ··· 1598 1575 * before reset. */ 1599 1576 void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) 1600 1577 { 1601 - int rc; 1602 - 1603 1578 EFX_ASSERT_RESET_SERIALISED(efx); 1604 1579 1605 1580 /* The net_dev->get_stats handler is quite slow, and will fail ··· 1610 1589 mutex_lock(&efx->mac_lock); 1611 1590 mutex_lock(&efx->spi_lock); 1612 1591 1613 - rc = falcon_xmac_get_settings(efx, ecmd); 1614 - if (rc) 1615 - EFX_ERR(efx, "could not back up PHY settings\n"); 1592 + efx->phy_op->get_settings(efx, ecmd); 1616 1593 1617 1594 efx_fini_channels(efx); 1618 1595 } ··· 1635 1616 if (ok) { 1636 1617 efx_init_channels(efx); 1637 1618 1638 - if (falcon_xmac_set_settings(efx, ecmd)) 1619 + if (efx->phy_op->set_settings(efx, ecmd)) 1639 1620 EFX_ERR(efx, "could not restore PHY settings\n"); 1640 1621 } 1641 1622 ··· 1798 1779 void efx_port_dummy_op_void(struct efx_nic *efx) {} 1799 1780 void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} 1800 1781 1782 + static struct efx_mac_operations efx_dummy_mac_operations = { 1783 + .reconfigure = efx_port_dummy_op_void, 1784 + }; 1785 + 1801 1786 static struct efx_phy_operations efx_dummy_phy_operations = { 1802 1787 .init = efx_port_dummy_op_int, 1803 1788 .reconfigure = efx_port_dummy_op_void, ··· 1854 1831 spin_lock_init(&efx->netif_stop_lock); 1855 1832 spin_lock_init(&efx->stats_lock); 1856 1833 mutex_init(&efx->mac_lock); 1834 + efx->mac_op = &efx_dummy_mac_operations; 1857 1835 efx->phy_op = &efx_dummy_phy_operations; 1858 1836 efx->mii.dev = net_dev; 1859 1837 INIT_WORK(&efx->reconfigure_work, efx_reconfigure_work);
+16 -13
drivers/net/sfc/enum.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 ··· 13 13 /** 14 14 * enum efx_loopback_mode - loopback modes 15 15 * @LOOPBACK_NONE: no loopback 16 - * @LOOPBACK_XGMII: loopback within MAC at XGMII level 17 - * @LOOPBACK_XGXS: loopback within MAC at XGXS level 18 - * @LOOPBACK_XAUI: loopback within MAC at XAUI level 19 - * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level 20 - * @LOOPBACK_PCS: loopback within PHY at PCS level 21 - * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level 16 + * @LOOPBACK_GMAC: loopback within GMAC at unspecified level 17 + * @LOOPBACK_XGMII: loopback within XMAC at XGMII level 18 + * @LOOPBACK_XGXS: loopback within XMAC at XGXS level 19 + * @LOOPBACK_XAUI: loopback within XMAC at XAUI level 20 + * @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level 21 + * @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level 22 + * @LOOPBACK_PCS: loopback within 10G PHY at PCS level 23 + * @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level 22 24 * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) 23 25 */ 24 26 /* Please keep in order and up-to-date w.r.t the following two #defines */ 25 27 enum efx_loopback_mode { 26 28 LOOPBACK_NONE = 0, 27 - LOOPBACK_MAC = 1, 29 + LOOPBACK_GMAC = 1, 28 30 LOOPBACK_XGMII = 2, 29 31 LOOPBACK_XGXS = 3, 30 32 LOOPBACK_XAUI = 4, 31 - LOOPBACK_PHY = 5, 33 + LOOPBACK_GPHY = 5, 32 34 LOOPBACK_PHYXS = 6, 33 35 LOOPBACK_PCS = 7, 34 36 LOOPBACK_PMAPMD = 8, ··· 47 45 LOOPBACK_MODE_NAME(efx->loopback_mode) 48 46 49 47 /* These loopbacks occur within the controller */ 50 - #define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ 51 - (1 << LOOPBACK_XGXS) | \ 52 - (1 << LOOPBACK_XAUI)) 48 + #define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) | \ 49 + (1 << LOOPBACK_XGMII)| \ 50 + (1 << LOOPBACK_XGXS) | \ 51 + (1 << LOOPBACK_XAUI)) 53 52 54 53 #define LOOPBACK_MASK(_efx) \ 55 54 (1 << (_efx)->loopback_mode) 56 55 57 56 #define LOOPBACK_INTERNAL(_efx) \ 58 - (!!(LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx))) 57 + (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx))) 59 58 60 59 #define LOOPBACK_OUT_OF(_from, _to, _mask) \ 61 60 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
+17 -21
drivers/net/sfc/ethtool.c
··· 17 17 #include "ethtool.h" 18 18 #include "falcon.h" 19 19 #include "spi.h" 20 - #include "mac.h" 21 20 22 21 const char *efx_loopback_mode_names[] = { 23 22 [LOOPBACK_NONE] = "NONE", 24 - [LOOPBACK_MAC] = "MAC", 23 + [LOOPBACK_GMAC] = "GMAC", 25 24 [LOOPBACK_XGMII] = "XGMII", 26 25 [LOOPBACK_XGXS] = "XGXS", 27 26 [LOOPBACK_XAUI] = "XAUI", 28 - [LOOPBACK_PHY] = "PHY", 27 + [LOOPBACK_GPHY] = "GPHY", 29 28 [LOOPBACK_PHYXS] = "PHYXS", 30 29 [LOOPBACK_PCS] = "PCS", 31 30 [LOOPBACK_PMAPMD] = "PMA/PMD", ··· 199 200 struct ethtool_cmd *ecmd) 200 201 { 201 202 struct efx_nic *efx = netdev_priv(net_dev); 202 - int rc; 203 203 204 204 mutex_lock(&efx->mac_lock); 205 - rc = falcon_xmac_get_settings(efx, ecmd); 205 + efx->phy_op->get_settings(efx, ecmd); 206 206 mutex_unlock(&efx->mac_lock); 207 207 208 - return rc; 208 + /* Falcon GMAC does not support 1000Mbps HD */ 209 + ecmd->supported &= ~SUPPORTED_1000baseT_Half; 210 + 211 + return 0; 209 212 } 210 213 211 214 /* This must be called with rtnl_lock held. */ ··· 217 216 struct efx_nic *efx = netdev_priv(net_dev); 218 217 int rc; 219 218 219 + /* Falcon GMAC does not support 1000Mbps HD */ 220 + if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { 221 + EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" 222 + " setting\n"); 223 + return -EINVAL; 224 + } 225 + 220 226 mutex_lock(&efx->mac_lock); 221 - rc = falcon_xmac_set_settings(efx, ecmd); 227 + rc = efx->phy_op->set_settings(efx, ecmd); 222 228 mutex_unlock(&efx->mac_lock); 223 229 if (!rc) 224 230 efx_reconfigure_port(efx); ··· 370 362 EFX_PORT_NAME, "phy", NULL); 371 363 372 364 /* Loopback tests */ 373 - efx_fill_test(n++, strings, data, &tests->loopback_speed, 374 - EFX_PORT_NAME, "loopback.speed", NULL); 375 - efx_fill_test(n++, strings, data, &tests->loopback_full_duplex, 376 - EFX_PORT_NAME, "loopback.full_duplex", NULL); 377 365 for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { 378 366 if (!(efx->loopback_modes & (1 << mode))) 379 367 continue; ··· 675 671 { 676 672 struct efx_nic *efx = netdev_priv(net_dev); 677 673 enum efx_fc_type flow_control = efx->flow_control; 678 - int rc; 679 674 680 675 flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO); 681 676 flow_control |= pause->rx_pause ? EFX_FC_RX : 0; 682 677 flow_control |= pause->tx_pause ? EFX_FC_TX : 0; 683 678 flow_control |= pause->autoneg ? EFX_FC_AUTO : 0; 684 679 685 - /* Try to push the pause parameters */ 686 - mutex_lock(&efx->mac_lock); 687 - rc = falcon_xmac_set_pause(efx, flow_control); 688 - mutex_unlock(&efx->mac_lock); 689 - 690 - if (!rc) 691 - efx_reconfigure_port(efx); 692 - 693 - return rc; 680 + efx_reconfigure_port(efx); 681 + return 0; 694 682 } 695 683 696 684 static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
+141 -38
drivers/net/sfc/falcon.c
··· 1168 1168 falcon_generate_event(channel, &test_event); 1169 1169 } 1170 1170 1171 + void 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 1186 * Flush handling ··· 1852 1839 * 1853 1840 ************************************************************************** 1854 1841 */ 1855 - void falcon_drain_tx_fifo(struct efx_nic *efx) 1842 + 1843 + static int falcon_reset_macs(struct efx_nic *efx) 1856 1844 { 1857 - efx_oword_t temp; 1845 + efx_oword_t reg; 1858 1846 int count; 1859 1847 1860 - if ((falcon_rev(efx) < FALCON_REV_B0) || 1861 - (efx->loopback_mode != LOOPBACK_NONE)) 1862 - return; 1848 + if (falcon_rev(efx) < FALCON_REV_B0) { 1849 + /* It's not safe to use GLB_CTL_REG to reset the 1850 + * macs, so instead use the internal MAC resets 1851 + */ 1852 + if (!EFX_IS10G(efx)) { 1853 + EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1); 1854 + falcon_write(efx, &reg, GM_CFG1_REG); 1855 + udelay(1000); 1863 1856 1864 - falcon_read(efx, &temp, MAC0_CTRL_REG_KER); 1865 - /* There is no point in draining more than once */ 1866 - if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) 1867 - return; 1857 + EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0); 1858 + falcon_write(efx, &reg, GM_CFG1_REG); 1859 + udelay(1000); 1860 + return 0; 1861 + } else { 1862 + EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1); 1863 + falcon_write(efx, &reg, XM_GLB_CFG_REG); 1864 + 1865 + for (count = 0; count < 10000; count++) { 1866 + falcon_read(efx, &reg, XM_GLB_CFG_REG); 1867 + if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0) 1868 + return 0; 1869 + udelay(10); 1870 + } 1871 + 1872 + EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); 1873 + return -ETIMEDOUT; 1874 + } 1875 + } 1868 1876 1869 1877 /* MAC stats will fail whilst the TX fifo is draining. Serialise 1870 1878 * the drain sequence with the statistics fetch */ 1871 1879 spin_lock(&efx->stats_lock); 1872 1880 1873 - EFX_SET_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0, 1); 1874 - falcon_write(efx, &temp, MAC0_CTRL_REG_KER); 1881 + falcon_read(efx, &reg, MAC0_CTRL_REG_KER); 1882 + EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); 1883 + falcon_write(efx, &reg, MAC0_CTRL_REG_KER); 1875 1884 1876 - /* Reset the MAC and EM block. */ 1877 - falcon_read(efx, &temp, GLB_CTL_REG_KER); 1878 - EFX_SET_OWORD_FIELD(temp, RST_XGTX, 1); 1879 - EFX_SET_OWORD_FIELD(temp, RST_XGRX, 1); 1880 - EFX_SET_OWORD_FIELD(temp, RST_EM, 1); 1881 - falcon_write(efx, &temp, GLB_CTL_REG_KER); 1885 + falcon_read(efx, &reg, GLB_CTL_REG_KER); 1886 + EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1); 1887 + EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1); 1888 + EFX_SET_OWORD_FIELD(reg, RST_EM, 1); 1889 + falcon_write(efx, &reg, GLB_CTL_REG_KER); 1882 1890 1883 1891 count = 0; 1884 1892 while (1) { 1885 - falcon_read(efx, &temp, GLB_CTL_REG_KER); 1886 - if (!EFX_OWORD_FIELD(temp, RST_XGTX) && 1887 - !EFX_OWORD_FIELD(temp, RST_XGRX) && 1888 - !EFX_OWORD_FIELD(temp, RST_EM)) { 1893 + falcon_read(efx, &reg, GLB_CTL_REG_KER); 1894 + if (!EFX_OWORD_FIELD(reg, RST_XGTX) && 1895 + !EFX_OWORD_FIELD(reg, RST_XGRX) && 1896 + !EFX_OWORD_FIELD(reg, RST_EM)) { 1889 1897 EFX_LOG(efx, "Completed MAC reset after %d loops\n", 1890 1898 count); 1891 1899 break; ··· 1923 1889 1924 1890 /* If we've reset the EM block and the link is up, then 1925 1891 * we'll have to kick the XAUI link so the PHY can recover */ 1926 - if (efx->link_up && EFX_WORKAROUND_5147(efx)) 1892 + if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) 1927 1893 falcon_reset_xaui(efx); 1894 + 1895 + return 0; 1896 + } 1897 + 1898 + void falcon_drain_tx_fifo(struct efx_nic *efx) 1899 + { 1900 + efx_oword_t reg; 1901 + 1902 + if ((falcon_rev(efx) < FALCON_REV_B0) || 1903 + (efx->loopback_mode != LOOPBACK_NONE)) 1904 + return; 1905 + 1906 + falcon_read(efx, &reg, MAC0_CTRL_REG_KER); 1907 + /* There is no point in draining more than once */ 1908 + if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0)) 1909 + return; 1910 + 1911 + falcon_reset_macs(efx); 1928 1912 } 1929 1913 1930 1914 void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) 1931 1915 { 1932 - efx_oword_t temp; 1916 + efx_oword_t reg; 1933 1917 1934 1918 if (falcon_rev(efx) < FALCON_REV_B0) 1935 1919 return; 1936 1920 1937 1921 /* Isolate the MAC -> RX */ 1938 - falcon_read(efx, &temp, RX_CFG_REG_KER); 1939 - EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 0); 1940 - falcon_write(efx, &temp, RX_CFG_REG_KER); 1922 + falcon_read(efx, &reg, RX_CFG_REG_KER); 1923 + EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0); 1924 + falcon_write(efx, &reg, RX_CFG_REG_KER); 1941 1925 1942 1926 if (!efx->link_up) 1943 1927 falcon_drain_tx_fifo(efx); ··· 2082 2030 efx_dword_t md_stat; 2083 2031 int count; 2084 2032 2085 - for (count = 0; count < 1000; count++) { /* wait upto 10ms */ 2033 + /* wait upto 50ms - taken max from datasheet */ 2034 + for (count = 0; count < 5000; count++) { 2086 2035 falcon_readl(efx, &md_stat, MD_STAT_REG_KER); 2087 2036 if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { 2088 2037 if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || ··· 2259 2206 return -1; 2260 2207 } 2261 2208 2262 - efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; 2209 + if (efx->phy_op->macs & EFX_XMAC) 2210 + efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | 2211 + (1 << LOOPBACK_XGXS) | 2212 + (1 << LOOPBACK_XAUI)); 2213 + if (efx->phy_op->macs & EFX_GMAC) 2214 + efx->loopback_modes |= (1 << LOOPBACK_GMAC); 2215 + efx->loopback_modes |= efx->phy_op->loopbacks; 2216 + 2263 2217 return 0; 2218 + } 2219 + 2220 + int falcon_switch_mac(struct efx_nic *efx) 2221 + { 2222 + struct efx_mac_operations *old_mac_op = efx->mac_op; 2223 + efx_oword_t nic_stat; 2224 + unsigned strap_val; 2225 + 2226 + /* Internal loopbacks override the phy speed setting */ 2227 + if (efx->loopback_mode == LOOPBACK_GMAC) { 2228 + efx->link_speed = 1000; 2229 + efx->link_fd = true; 2230 + } else if (LOOPBACK_INTERNAL(efx)) { 2231 + efx->link_speed = 10000; 2232 + efx->link_fd = true; 2233 + } 2234 + 2235 + efx->mac_op = (EFX_IS10G(efx) ? 2236 + &falcon_xmac_operations : &falcon_gmac_operations); 2237 + if (old_mac_op == efx->mac_op) 2238 + return 0; 2239 + 2240 + WARN_ON(!mutex_is_locked(&efx->mac_lock)); 2241 + 2242 + /* Not all macs support a mac-level link state */ 2243 + efx->mac_up = true; 2244 + 2245 + falcon_read(efx, &nic_stat, NIC_STAT_REG); 2246 + strap_val = EFX_IS10G(efx) ? 5 : 3; 2247 + if (falcon_rev(efx) >= FALCON_REV_B0) { 2248 + EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1); 2249 + EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val); 2250 + falcon_write(efx, &nic_stat, NIC_STAT_REG); 2251 + } else { 2252 + /* Falcon A1 does not support 1G/10G speed switching 2253 + * and must not be used with a PHY that does. */ 2254 + BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); 2255 + } 2256 + 2257 + 2258 + EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); 2259 + return falcon_reset_macs(efx); 2264 2260 } 2265 2261 2266 2262 /* This call is responsible for hooking in the MAC and PHY operations */ ··· 2464 2362 EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, 2465 2363 { DP_CTRL_REG, 2466 2364 EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, 2365 + { GM_CFG2_REG, 2366 + EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) }, 2367 + { GMF_CFG0_REG, 2368 + EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) }, 2467 2369 { XM_GLB_CFG_REG, 2468 2370 EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, 2469 2371 { XM_TX_CFG_REG, ··· 2793 2687 static int falcon_probe_nic_variant(struct efx_nic *efx) 2794 2688 { 2795 2689 efx_oword_t altera_build; 2690 + efx_oword_t nic_stat; 2796 2691 2797 2692 falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); 2798 2693 if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { ··· 2801 2694 return -ENODEV; 2802 2695 } 2803 2696 2697 + falcon_read(efx, &nic_stat, NIC_STAT_REG); 2698 + 2804 2699 switch (falcon_rev(efx)) { 2805 2700 case FALCON_REV_A0: 2806 2701 case 0xff: 2807 2702 EFX_ERR(efx, "Falcon rev A0 not supported\n"); 2808 2703 return -ENODEV; 2809 2704 2810 - case FALCON_REV_A1:{ 2811 - efx_oword_t nic_stat; 2812 - 2813 - falcon_read(efx, &nic_stat, NIC_STAT_REG); 2814 - 2705 + case FALCON_REV_A1: 2815 2706 if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { 2816 2707 EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); 2817 2708 return -ENODEV; 2818 2709 } 2819 - if (!EFX_OWORD_FIELD(nic_stat, STRAP_10G)) { 2820 - EFX_ERR(efx, "1G mode not supported\n"); 2821 - return -ENODEV; 2822 - } 2823 2710 break; 2824 - } 2825 2711 2826 2712 case FALCON_REV_B0: 2827 2713 break; ··· 2823 2723 EFX_ERR(efx, "Unknown Falcon rev %d\n", falcon_rev(efx)); 2824 2724 return -ENODEV; 2825 2725 } 2726 + 2727 + /* Initial assumed speed */ 2728 + efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000; 2826 2729 2827 2730 return 0; 2828 2731 }
+3
drivers/net/sfc/falcon.h
··· 12 12 #define EFX_FALCON_H 13 13 14 14 #include "net_driver.h" 15 + #include "efx.h" 15 16 16 17 /* 17 18 * Falcon hardware control ··· 66 65 extern void falcon_remove_port(struct efx_nic *efx); 67 66 68 67 /* MAC/PHY */ 68 + extern int falcon_switch_mac(struct efx_nic *efx); 69 69 extern bool falcon_xaui_link_ok(struct efx_nic *efx); 70 70 extern int falcon_dma_stats(struct efx_nic *efx, 71 71 unsigned int done_offset); ··· 79 77 extern void falcon_enable_interrupts(struct efx_nic *efx); 80 78 extern void falcon_generate_test_event(struct efx_channel *channel, 81 79 unsigned int magic); 80 + extern void falcon_sim_phy_event(struct efx_nic *efx); 82 81 extern void falcon_generate_interrupt(struct efx_nic *efx); 83 82 extern void falcon_set_int_moderation(struct efx_channel *channel); 84 83 extern void falcon_disable_interrupts(struct efx_nic *efx);
+233
drivers/net/sfc/falcon_gmac.c
··· 1 + /**************************************************************************** 2 + * Driver for Solarflare Solarstorm network controllers and boards 3 + * Copyright 2005-2006 Fen Systems Ltd. 4 + * Copyright 2006-2008 Solarflare Communications Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License version 2 as published 8 + * by the Free Software Foundation, incorporated herein by reference. 9 + */ 10 + 11 + #include <linux/delay.h> 12 + #include "net_driver.h" 13 + #include "efx.h" 14 + #include "falcon.h" 15 + #include "mac.h" 16 + #include "falcon_hwdefs.h" 17 + #include "falcon_io.h" 18 + #include "gmii.h" 19 + 20 + /************************************************************************** 21 + * 22 + * MAC operations 23 + * 24 + *************************************************************************/ 25 + 26 + static void falcon_reconfigure_gmac(struct efx_nic *efx) 27 + { 28 + bool loopback, tx_fc, rx_fc, bytemode; 29 + int if_mode; 30 + unsigned int max_frame_len; 31 + efx_oword_t reg; 32 + 33 + /* Configuration register 1 */ 34 + tx_fc = (efx->flow_control & EFX_FC_TX) || !efx->link_fd; 35 + rx_fc = !!(efx->flow_control & EFX_FC_RX); 36 + loopback = (efx->loopback_mode == LOOPBACK_GMAC); 37 + bytemode = (efx->link_speed == 1000); 38 + 39 + EFX_POPULATE_OWORD_5(reg, 40 + GM_LOOP, loopback, 41 + GM_TX_EN, 1, 42 + GM_TX_FC_EN, tx_fc, 43 + GM_RX_EN, 1, 44 + GM_RX_FC_EN, rx_fc); 45 + falcon_write(efx, &reg, GM_CFG1_REG); 46 + udelay(10); 47 + 48 + /* Configuration register 2 */ 49 + if_mode = (bytemode) ? 2 : 1; 50 + EFX_POPULATE_OWORD_5(reg, 51 + GM_IF_MODE, if_mode, 52 + GM_PAD_CRC_EN, 1, 53 + GM_LEN_CHK, 1, 54 + GM_FD, efx->link_fd, 55 + GM_PAMBL_LEN, 0x7/*datasheet recommended */); 56 + 57 + falcon_write(efx, &reg, GM_CFG2_REG); 58 + udelay(10); 59 + 60 + /* Max frame len register */ 61 + max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); 62 + EFX_POPULATE_OWORD_1(reg, GM_MAX_FLEN, max_frame_len); 63 + falcon_write(efx, &reg, GM_MAX_FLEN_REG); 64 + udelay(10); 65 + 66 + /* FIFO configuration register 0 */ 67 + EFX_POPULATE_OWORD_5(reg, 68 + GMF_FTFENREQ, 1, 69 + GMF_STFENREQ, 1, 70 + GMF_FRFENREQ, 1, 71 + GMF_SRFENREQ, 1, 72 + GMF_WTMENREQ, 1); 73 + falcon_write(efx, &reg, GMF_CFG0_REG); 74 + udelay(10); 75 + 76 + /* FIFO configuration register 1 */ 77 + EFX_POPULATE_OWORD_2(reg, 78 + GMF_CFGFRTH, 0x12, 79 + GMF_CFGXOFFRTX, 0xffff); 80 + falcon_write(efx, &reg, GMF_CFG1_REG); 81 + udelay(10); 82 + 83 + /* FIFO configuration register 2 */ 84 + EFX_POPULATE_OWORD_2(reg, 85 + GMF_CFGHWM, 0x3f, 86 + GMF_CFGLWM, 0xa); 87 + falcon_write(efx, &reg, GMF_CFG2_REG); 88 + udelay(10); 89 + 90 + /* FIFO configuration register 3 */ 91 + EFX_POPULATE_OWORD_2(reg, 92 + GMF_CFGHWMFT, 0x1c, 93 + GMF_CFGFTTH, 0x08); 94 + falcon_write(efx, &reg, GMF_CFG3_REG); 95 + udelay(10); 96 + 97 + /* FIFO configuration register 4 */ 98 + EFX_POPULATE_OWORD_1(reg, GMF_HSTFLTRFRM_PAUSE, 1); 99 + falcon_write(efx, &reg, GMF_CFG4_REG); 100 + udelay(10); 101 + 102 + /* FIFO configuration register 5 */ 103 + falcon_read(efx, &reg, GMF_CFG5_REG); 104 + EFX_SET_OWORD_FIELD(reg, GMF_CFGBYTMODE, bytemode); 105 + EFX_SET_OWORD_FIELD(reg, GMF_CFGHDPLX, !efx->link_fd); 106 + EFX_SET_OWORD_FIELD(reg, GMF_HSTDRPLT64, !efx->link_fd); 107 + EFX_SET_OWORD_FIELD(reg, GMF_HSTFLTRFRMDC_PAUSE, 0); 108 + falcon_write(efx, &reg, GMF_CFG5_REG); 109 + udelay(10); 110 + 111 + /* MAC address */ 112 + EFX_POPULATE_OWORD_4(reg, 113 + GM_HWADDR_5, efx->net_dev->dev_addr[5], 114 + GM_HWADDR_4, efx->net_dev->dev_addr[4], 115 + GM_HWADDR_3, efx->net_dev->dev_addr[3], 116 + GM_HWADDR_2, efx->net_dev->dev_addr[2]); 117 + falcon_write(efx, &reg, GM_ADR1_REG); 118 + udelay(10); 119 + EFX_POPULATE_OWORD_2(reg, 120 + GM_HWADDR_1, efx->net_dev->dev_addr[1], 121 + GM_HWADDR_0, efx->net_dev->dev_addr[0]); 122 + falcon_write(efx, &reg, GM_ADR2_REG); 123 + udelay(10); 124 + 125 + falcon_reconfigure_mac_wrapper(efx); 126 + } 127 + 128 + static void falcon_update_stats_gmac(struct efx_nic *efx) 129 + { 130 + struct efx_mac_stats *mac_stats = &efx->mac_stats; 131 + unsigned long old_rx_pause, old_tx_pause; 132 + unsigned long new_rx_pause, new_tx_pause; 133 + int rc; 134 + 135 + rc = falcon_dma_stats(efx, GDmaDone_offset); 136 + if (rc) 137 + return; 138 + 139 + /* Pause frames are erroneously counted as errors (SFC bug 3269) */ 140 + old_rx_pause = mac_stats->rx_pause; 141 + old_tx_pause = mac_stats->tx_pause; 142 + 143 + /* Update MAC stats from DMAed values */ 144 + FALCON_STAT(efx, GRxGoodOct, rx_good_bytes); 145 + FALCON_STAT(efx, GRxBadOct, rx_bad_bytes); 146 + FALCON_STAT(efx, GRxMissPkt, rx_missed); 147 + FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier); 148 + FALCON_STAT(efx, GRxPausePkt, rx_pause); 149 + FALCON_STAT(efx, GRxBadPkt, rx_bad); 150 + FALCON_STAT(efx, GRxUcastPkt, rx_unicast); 151 + FALCON_STAT(efx, GRxMcastPkt, rx_multicast); 152 + FALCON_STAT(efx, GRxBcastPkt, rx_broadcast); 153 + FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64); 154 + FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64); 155 + FALCON_STAT(efx, GRx64Pkt, rx_64); 156 + FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127); 157 + FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255); 158 + FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511); 159 + FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023); 160 + FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx); 161 + FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo); 162 + FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo); 163 + FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx); 164 + FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo); 165 + FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo); 166 + FALCON_STAT(efx, GTxGoodBadOct, tx_bytes); 167 + FALCON_STAT(efx, GTxGoodOct, tx_good_bytes); 168 + FALCON_STAT(efx, GTxSglColPkt, tx_single_collision); 169 + FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision); 170 + FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision); 171 + FALCON_STAT(efx, GTxDefPkt, tx_deferred); 172 + FALCON_STAT(efx, GTxLateCol, tx_late_collision); 173 + FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred); 174 + FALCON_STAT(efx, GTxPausePkt, tx_pause); 175 + FALCON_STAT(efx, GTxBadPkt, tx_bad); 176 + FALCON_STAT(efx, GTxUcastPkt, tx_unicast); 177 + FALCON_STAT(efx, GTxMcastPkt, tx_multicast); 178 + FALCON_STAT(efx, GTxBcastPkt, tx_broadcast); 179 + FALCON_STAT(efx, GTxLt64Pkt, tx_lt64); 180 + FALCON_STAT(efx, GTx64Pkt, tx_64); 181 + FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127); 182 + FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255); 183 + FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511); 184 + FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023); 185 + FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx); 186 + FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo); 187 + FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo); 188 + FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp); 189 + FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error); 190 + FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error); 191 + 192 + /* Pause frames are erroneously counted as errors (SFC bug 3269) */ 193 + new_rx_pause = mac_stats->rx_pause; 194 + new_tx_pause = mac_stats->tx_pause; 195 + mac_stats->rx_bad -= (new_rx_pause - old_rx_pause); 196 + mac_stats->tx_bad -= (new_tx_pause - old_tx_pause); 197 + 198 + /* Derive stats that the MAC doesn't provide directly */ 199 + mac_stats->tx_bad_bytes = 200 + mac_stats->tx_bytes - mac_stats->tx_good_bytes; 201 + mac_stats->tx_packets = 202 + mac_stats->tx_lt64 + mac_stats->tx_64 + 203 + mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 + 204 + mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 + 205 + mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo + 206 + mac_stats->tx_gtjumbo; 207 + mac_stats->tx_collision = 208 + mac_stats->tx_single_collision + 209 + mac_stats->tx_multiple_collision + 210 + mac_stats->tx_excessive_collision + 211 + mac_stats->tx_late_collision; 212 + mac_stats->rx_bytes = 213 + mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes; 214 + mac_stats->rx_packets = 215 + mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 + 216 + mac_stats->rx_64 + mac_stats->rx_65_to_127 + 217 + mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 + 218 + mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx + 219 + mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo; 220 + mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad; 221 + mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; 222 + } 223 + 224 + static int falcon_check_gmac(struct efx_nic *efx) 225 + { 226 + return efx->phy_op->check_hw(efx); 227 + } 228 + 229 + struct efx_mac_operations falcon_gmac_operations = { 230 + .reconfigure = falcon_reconfigure_gmac, 231 + .update_stats = falcon_update_stats_gmac, 232 + .check_hw = falcon_check_gmac, 233 + };
+156
drivers/net/sfc/falcon_hwdefs.h
··· 111 111 112 112 /* NIC status register */ 113 113 #define NIC_STAT_REG 0x0200 114 + #define EE_STRAP_EN_LBN 31 115 + #define EE_STRAP_EN_WIDTH 1 116 + #define EE_STRAP_OVR_LBN 24 117 + #define EE_STRAP_OVR_WIDTH 4 114 118 #define ONCHIP_SRAM_LBN 16 115 119 #define ONCHIP_SRAM_WIDTH 1 116 120 #define SF_PRST_LBN 9 117 121 #define SF_PRST_WIDTH 1 118 122 #define EE_PRST_LBN 8 119 123 #define EE_PRST_WIDTH 1 124 + #define STRAP_PINS_LBN 0 125 + #define STRAP_PINS_WIDTH 3 120 126 /* These bit definitions are extrapolated from the list of numerical 121 127 * values for STRAP_PINS. 122 128 */ ··· 497 491 /* Multicast address hash table */ 498 492 #define MAC_MCAST_HASH_REG0_KER 0xca0 499 493 #define MAC_MCAST_HASH_REG1_KER 0xcb0 494 + 495 + /* GMAC configuration register 1 */ 496 + #define GM_CFG1_REG 0xe00 497 + #define GM_SW_RST_LBN 31 498 + #define GM_SW_RST_WIDTH 1 499 + #define GM_LOOP_LBN 8 500 + #define GM_LOOP_WIDTH 1 501 + #define GM_RX_FC_EN_LBN 5 502 + #define GM_RX_FC_EN_WIDTH 1 503 + #define GM_TX_FC_EN_LBN 4 504 + #define GM_TX_FC_EN_WIDTH 1 505 + #define GM_RX_EN_LBN 2 506 + #define GM_RX_EN_WIDTH 1 507 + #define GM_TX_EN_LBN 0 508 + #define GM_TX_EN_WIDTH 1 509 + 510 + /* GMAC configuration register 2 */ 511 + #define GM_CFG2_REG 0xe10 512 + #define GM_PAMBL_LEN_LBN 12 513 + #define GM_PAMBL_LEN_WIDTH 4 514 + #define GM_IF_MODE_LBN 8 515 + #define GM_IF_MODE_WIDTH 2 516 + #define GM_LEN_CHK_LBN 4 517 + #define GM_LEN_CHK_WIDTH 1 518 + #define GM_PAD_CRC_EN_LBN 2 519 + #define GM_PAD_CRC_EN_WIDTH 1 520 + #define GM_FD_LBN 0 521 + #define GM_FD_WIDTH 1 522 + 523 + /* GMAC maximum frame length register */ 524 + #define GM_MAX_FLEN_REG 0xe40 525 + #define GM_MAX_FLEN_LBN 0 526 + #define GM_MAX_FLEN_WIDTH 16 527 + 528 + /* GMAC station address register 1 */ 529 + #define GM_ADR1_REG 0xf00 530 + #define GM_HWADDR_5_LBN 24 531 + #define GM_HWADDR_5_WIDTH 8 532 + #define GM_HWADDR_4_LBN 16 533 + #define GM_HWADDR_4_WIDTH 8 534 + #define GM_HWADDR_3_LBN 8 535 + #define GM_HWADDR_3_WIDTH 8 536 + #define GM_HWADDR_2_LBN 0 537 + #define GM_HWADDR_2_WIDTH 8 538 + 539 + /* GMAC station address register 2 */ 540 + #define GM_ADR2_REG 0xf10 541 + #define GM_HWADDR_1_LBN 24 542 + #define GM_HWADDR_1_WIDTH 8 543 + #define GM_HWADDR_0_LBN 16 544 + #define GM_HWADDR_0_WIDTH 8 545 + 546 + /* GMAC FIFO configuration register 0 */ 547 + #define GMF_CFG0_REG 0xf20 548 + #define GMF_FTFENREQ_LBN 12 549 + #define GMF_FTFENREQ_WIDTH 1 550 + #define GMF_STFENREQ_LBN 11 551 + #define GMF_STFENREQ_WIDTH 1 552 + #define GMF_FRFENREQ_LBN 10 553 + #define GMF_FRFENREQ_WIDTH 1 554 + #define GMF_SRFENREQ_LBN 9 555 + #define GMF_SRFENREQ_WIDTH 1 556 + #define GMF_WTMENREQ_LBN 8 557 + #define GMF_WTMENREQ_WIDTH 1 558 + 559 + /* GMAC FIFO configuration register 1 */ 560 + #define GMF_CFG1_REG 0xf30 561 + #define GMF_CFGFRTH_LBN 16 562 + #define GMF_CFGFRTH_WIDTH 5 563 + #define GMF_CFGXOFFRTX_LBN 0 564 + #define GMF_CFGXOFFRTX_WIDTH 16 565 + 566 + /* GMAC FIFO configuration register 2 */ 567 + #define GMF_CFG2_REG 0xf40 568 + #define GMF_CFGHWM_LBN 16 569 + #define GMF_CFGHWM_WIDTH 6 570 + #define GMF_CFGLWM_LBN 0 571 + #define GMF_CFGLWM_WIDTH 6 572 + 573 + /* GMAC FIFO configuration register 3 */ 574 + #define GMF_CFG3_REG 0xf50 575 + #define GMF_CFGHWMFT_LBN 16 576 + #define GMF_CFGHWMFT_WIDTH 6 577 + #define GMF_CFGFTTH_LBN 0 578 + #define GMF_CFGFTTH_WIDTH 6 579 + 580 + /* GMAC FIFO configuration register 4 */ 581 + #define GMF_CFG4_REG 0xf60 582 + #define GMF_HSTFLTRFRM_PAUSE_LBN 12 583 + #define GMF_HSTFLTRFRM_PAUSE_WIDTH 12 584 + 585 + /* GMAC FIFO configuration register 5 */ 586 + #define GMF_CFG5_REG 0xf70 587 + #define GMF_CFGHDPLX_LBN 22 588 + #define GMF_CFGHDPLX_WIDTH 1 589 + #define GMF_CFGBYTMODE_LBN 19 590 + #define GMF_CFGBYTMODE_WIDTH 1 591 + #define GMF_HSTDRPLT64_LBN 18 592 + #define GMF_HSTDRPLT64_WIDTH 1 593 + #define GMF_HSTFLTRFRMDC_PAUSE_LBN 12 594 + #define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1 500 595 501 596 /* XGMAC address register low */ 502 597 #define XM_ADR_LO_REG 0x1200 ··· 1069 962 ************************************************************************** 1070 963 * 1071 964 */ 965 + 1072 966 #define GRxGoodOct_offset 0x0 967 + #define GRxGoodOct_WIDTH 48 1073 968 #define GRxBadOct_offset 0x8 969 + #define GRxBadOct_WIDTH 48 1074 970 #define GRxMissPkt_offset 0x10 971 + #define GRxMissPkt_WIDTH 32 1075 972 #define GRxFalseCRS_offset 0x14 973 + #define GRxFalseCRS_WIDTH 32 1076 974 #define GRxPausePkt_offset 0x18 975 + #define GRxPausePkt_WIDTH 32 1077 976 #define GRxBadPkt_offset 0x1C 977 + #define GRxBadPkt_WIDTH 32 1078 978 #define GRxUcastPkt_offset 0x20 979 + #define GRxUcastPkt_WIDTH 32 1079 980 #define GRxMcastPkt_offset 0x24 981 + #define GRxMcastPkt_WIDTH 32 1080 982 #define GRxBcastPkt_offset 0x28 983 + #define GRxBcastPkt_WIDTH 32 1081 984 #define GRxGoodLt64Pkt_offset 0x2C 985 + #define GRxGoodLt64Pkt_WIDTH 32 1082 986 #define GRxBadLt64Pkt_offset 0x30 987 + #define GRxBadLt64Pkt_WIDTH 32 1083 988 #define GRx64Pkt_offset 0x34 989 + #define GRx64Pkt_WIDTH 32 1084 990 #define GRx65to127Pkt_offset 0x38 991 + #define GRx65to127Pkt_WIDTH 32 1085 992 #define GRx128to255Pkt_offset 0x3C 993 + #define GRx128to255Pkt_WIDTH 32 1086 994 #define GRx256to511Pkt_offset 0x40 995 + #define GRx256to511Pkt_WIDTH 32 1087 996 #define GRx512to1023Pkt_offset 0x44 997 + #define GRx512to1023Pkt_WIDTH 32 1088 998 #define GRx1024to15xxPkt_offset 0x48 999 + #define GRx1024to15xxPkt_WIDTH 32 1089 1000 #define GRx15xxtoJumboPkt_offset 0x4C 1001 + #define GRx15xxtoJumboPkt_WIDTH 32 1090 1002 #define GRxGtJumboPkt_offset 0x50 1003 + #define GRxGtJumboPkt_WIDTH 32 1091 1004 #define GRxFcsErr64to15xxPkt_offset 0x54 1005 + #define GRxFcsErr64to15xxPkt_WIDTH 32 1092 1006 #define GRxFcsErr15xxtoJumboPkt_offset 0x58 1007 + #define GRxFcsErr15xxtoJumboPkt_WIDTH 32 1093 1008 #define GRxFcsErrGtJumboPkt_offset 0x5C 1009 + #define GRxFcsErrGtJumboPkt_WIDTH 32 1094 1010 #define GTxGoodBadOct_offset 0x80 1011 + #define GTxGoodBadOct_WIDTH 48 1095 1012 #define GTxGoodOct_offset 0x88 1013 + #define GTxGoodOct_WIDTH 48 1096 1014 #define GTxSglColPkt_offset 0x90 1015 + #define GTxSglColPkt_WIDTH 32 1097 1016 #define GTxMultColPkt_offset 0x94 1017 + #define GTxMultColPkt_WIDTH 32 1098 1018 #define GTxExColPkt_offset 0x98 1019 + #define GTxExColPkt_WIDTH 32 1099 1020 #define GTxDefPkt_offset 0x9C 1021 + #define GTxDefPkt_WIDTH 32 1100 1022 #define GTxLateCol_offset 0xA0 1023 + #define GTxLateCol_WIDTH 32 1101 1024 #define GTxExDefPkt_offset 0xA4 1025 + #define GTxExDefPkt_WIDTH 32 1102 1026 #define GTxPausePkt_offset 0xA8 1027 + #define GTxPausePkt_WIDTH 32 1103 1028 #define GTxBadPkt_offset 0xAC 1029 + #define GTxBadPkt_WIDTH 32 1104 1030 #define GTxUcastPkt_offset 0xB0 1031 + #define GTxUcastPkt_WIDTH 32 1105 1032 #define GTxMcastPkt_offset 0xB4 1033 + #define GTxMcastPkt_WIDTH 32 1106 1034 #define GTxBcastPkt_offset 0xB8 1035 + #define GTxBcastPkt_WIDTH 32 1107 1036 #define GTxLt64Pkt_offset 0xBC 1037 + #define GTxLt64Pkt_WIDTH 32 1108 1038 #define GTx64Pkt_offset 0xC0 1039 + #define GTx64Pkt_WIDTH 32 1109 1040 #define GTx65to127Pkt_offset 0xC4 1041 + #define GTx65to127Pkt_WIDTH 32 1110 1042 #define GTx128to255Pkt_offset 0xC8 1043 + #define GTx128to255Pkt_WIDTH 32 1111 1044 #define GTx256to511Pkt_offset 0xCC 1045 + #define GTx256to511Pkt_WIDTH 32 1112 1046 #define GTx512to1023Pkt_offset 0xD0 1047 + #define GTx512to1023Pkt_WIDTH 32 1113 1048 #define GTx1024to15xxPkt_offset 0xD4 1049 + #define GTx1024to15xxPkt_WIDTH 32 1114 1050 #define GTx15xxtoJumboPkt_offset 0xD8 1051 + #define GTx15xxtoJumboPkt_WIDTH 32 1115 1052 #define GTxGtJumboPkt_offset 0xDC 1053 + #define GTxGtJumboPkt_WIDTH 32 1116 1054 #define GTxNonTcpUdpPkt_offset 0xE0 1055 + #define GTxNonTcpUdpPkt_WIDTH 16 1117 1056 #define GTxMacSrcErrPkt_offset 0xE4 1057 + #define GTxMacSrcErrPkt_WIDTH 16 1118 1058 #define GTxIpSrcErrPkt_offset 0xE8 1059 + #define GTxIpSrcErrPkt_WIDTH 16 1119 1060 #define GDmaDone_offset 0xEC 1061 + #define GDmaDone_WIDTH 32 1120 1062 1121 1063 #define XgRxOctets_offset 0x0 1122 1064 #define XgRxOctets_WIDTH 48
+32 -192
drivers/net/sfc/falcon_xmac.c
··· 25 25 * MAC operations 26 26 * 27 27 *************************************************************************/ 28 - static int falcon_reset_xmac(struct efx_nic *efx) 29 - { 30 - efx_oword_t reg; 31 - int count; 32 - 33 - EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1); 34 - falcon_write(efx, &reg, XM_GLB_CFG_REG); 35 - 36 - for (count = 0; count < 10000; count++) { /* wait upto 100ms */ 37 - falcon_read(efx, &reg, XM_GLB_CFG_REG); 38 - if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0) 39 - return 0; 40 - udelay(10); 41 - } 42 - 43 - EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); 44 - return -ETIMEDOUT; 45 - } 46 28 47 29 /* Configure the XAUI driver that is an output from Falcon */ 48 30 static void falcon_setup_xaui(struct efx_nic *efx) ··· 80 98 return -ETIMEDOUT; 81 99 } 82 100 83 - static bool falcon_xgmii_status(struct efx_nic *efx) 84 - { 85 - efx_oword_t reg; 86 - 87 - if (falcon_rev(efx) < FALCON_REV_B0) 88 - return true; 89 - 90 - /* The ISR latches, so clear it and re-read */ 91 - falcon_read(efx, &reg, XM_MGT_INT_REG_B0); 92 - falcon_read(efx, &reg, XM_MGT_INT_REG_B0); 93 - 94 - if (EFX_OWORD_FIELD(reg, XM_LCLFLT) || 95 - EFX_OWORD_FIELD(reg, XM_RMTFLT)) { 96 - EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); 97 - return false; 98 - } 99 - 100 - return true; 101 - } 102 - 103 101 static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) 104 102 { 105 103 efx_oword_t reg; 106 104 107 - if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) 105 + if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) 106 + return; 107 + 108 + /* We expect xgmii faults if the wireside link is up */ 109 + if (!EFX_WORKAROUND_5147(efx) || !efx->link_up) 110 + return; 111 + 112 + /* We can only use this interrupt to signal the negative edge of 113 + * xaui_align [we have to poll the positive edge]. */ 114 + if (!efx->mac_up) 108 115 return; 109 116 110 117 /* Flush the ISR */ ··· 106 135 falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0); 107 136 } 108 137 109 - int falcon_init_xmac(struct efx_nic *efx) 110 - { 111 - int rc; 112 - 113 - /* Initialize the PHY first so the clock is around */ 114 - rc = efx->phy_op->init(efx); 115 - if (rc) 116 - goto fail1; 117 - 118 - rc = falcon_reset_xaui(efx); 119 - if (rc) 120 - goto fail2; 121 - 122 - /* Wait again. Give the PHY and MAC time to come back */ 123 - schedule_timeout_uninterruptible(HZ / 10); 124 - 125 - rc = falcon_reset_xmac(efx); 126 - if (rc) 127 - goto fail2; 128 - 129 - falcon_mask_status_intr(efx, true); 130 - return 0; 131 - 132 - fail2: 133 - efx->phy_op->fini(efx); 134 - fail1: 135 - return rc; 136 - } 137 - 138 + /* Get status of XAUI link */ 138 139 bool falcon_xaui_link_ok(struct efx_nic *efx) 139 140 { 140 141 efx_oword_t reg; ··· 130 187 EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); 131 188 falcon_write(efx, &reg, XX_CORE_STAT_REG); 132 189 133 - /* If the link is up, then check the phy side of the xaui link 134 - * (error conditions from the wire side propoagate back through 135 - * the phy to the xaui side). */ 136 - if (efx->link_up && link_ok) { 190 + /* If the link is up, then check the phy side of the xaui link */ 191 + if (efx->link_up && link_ok) 137 192 if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) 138 193 link_ok = mdio_clause45_phyxgxs_lane_sync(efx); 139 - } 140 - 141 - /* If the PHY and XAUI links are up, then check the mac's xgmii 142 - * fault state */ 143 - if (efx->link_up && link_ok) 144 - link_ok = falcon_xgmii_status(efx); 145 194 146 195 return link_ok; 147 196 } ··· 245 310 246 311 /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails 247 312 * to come back up. Bash it until it comes back up */ 248 - static bool falcon_check_xaui_link_up(struct efx_nic *efx) 313 + static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries) 249 314 { 250 - int max_tries, tries; 251 - tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; 252 - max_tries = tries; 315 + efx->mac_up = falcon_xaui_link_ok(efx); 253 316 254 317 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 255 - (efx->phy_type == PHY_TYPE_NONE) || 256 318 efx_phy_mode_disabled(efx->phy_mode)) 257 - return false; 319 + /* XAUI link is expected to be down */ 320 + return; 258 321 259 - while (tries) { 260 - if (falcon_xaui_link_ok(efx)) 261 - return true; 262 - 263 - EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", 264 - __func__, tries); 322 + while (!efx->mac_up && tries) { 323 + EFX_LOG(efx, "bashing xaui\n"); 265 324 falcon_reset_xaui(efx); 266 325 udelay(200); 267 - tries--; 268 - } 269 326 270 - EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", 271 - max_tries); 272 - return false; 327 + efx->mac_up = falcon_xaui_link_ok(efx); 328 + --tries; 329 + } 273 330 } 274 331 275 - void falcon_reconfigure_xmac(struct efx_nic *efx) 332 + static void falcon_reconfigure_xmac(struct efx_nic *efx) 276 333 { 277 - bool xaui_link_ok; 278 - 279 334 falcon_mask_status_intr(efx, false); 280 - 281 - falcon_deconfigure_mac_wrapper(efx); 282 - 283 - /* Reconfigure the PHY, disabling transmit in mac level loopback. */ 284 - if (LOOPBACK_INTERNAL(efx)) 285 - efx->phy_mode |= PHY_MODE_TX_DISABLED; 286 - else 287 - efx->phy_mode &= ~PHY_MODE_TX_DISABLED; 288 - efx->phy_op->reconfigure(efx); 289 335 290 336 falcon_reconfigure_xgxs_core(efx); 291 337 falcon_reconfigure_xmac_core(efx); 292 338 293 339 falcon_reconfigure_mac_wrapper(efx); 294 340 295 - /* Ensure XAUI link is up */ 296 - xaui_link_ok = falcon_check_xaui_link_up(efx); 297 - 298 - if (xaui_link_ok && efx->link_up) 299 - falcon_mask_status_intr(efx, true); 341 + falcon_check_xaui_link_up(efx, 5); 342 + falcon_mask_status_intr(efx, true); 300 343 } 301 344 302 - void falcon_fini_xmac(struct efx_nic *efx) 303 - { 304 - /* Isolate the MAC - PHY */ 305 - falcon_deconfigure_mac_wrapper(efx); 306 - 307 - /* Potentially power down the PHY */ 308 - efx->phy_op->fini(efx); 309 - } 310 - 311 - void falcon_update_stats_xmac(struct efx_nic *efx) 345 + static void falcon_update_stats_xmac(struct efx_nic *efx) 312 346 { 313 347 struct efx_mac_stats *mac_stats = &efx->mac_stats; 314 348 int rc; ··· 342 438 mac_stats->rx_control * 64); 343 439 } 344 440 345 - int falcon_check_xmac(struct efx_nic *efx) 441 + static int falcon_check_xmac(struct efx_nic *efx) 346 442 { 347 443 bool xaui_link_ok; 348 444 int rc; ··· 367 463 return rc; 368 464 } 369 465 370 - /* Simulate a PHY event */ 371 - void falcon_xmac_sim_phy_event(struct efx_nic *efx) 372 - { 373 - efx_qword_t phy_event; 374 - 375 - EFX_POPULATE_QWORD_2(phy_event, 376 - EV_CODE, GLOBAL_EV_DECODE, 377 - XG_PHY_INTR, 1); 378 - falcon_generate_event(&efx->channel[0], &phy_event); 379 - } 380 - 381 - int falcon_xmac_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 382 - { 383 - mdio_clause45_get_settings(efx, ecmd); 384 - ecmd->transceiver = XCVR_INTERNAL; 385 - ecmd->phy_address = efx->mii.phy_id; 386 - ecmd->autoneg = AUTONEG_DISABLE; 387 - ecmd->duplex = DUPLEX_FULL; 388 - return 0; 389 - } 390 - 391 - int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 392 - { 393 - if (ecmd->transceiver != XCVR_INTERNAL) 394 - return -EINVAL; 395 - if (ecmd->autoneg != AUTONEG_DISABLE) 396 - return -EINVAL; 397 - if (ecmd->duplex != DUPLEX_FULL) 398 - return -EINVAL; 399 - 400 - return mdio_clause45_set_settings(efx, ecmd); 401 - } 402 - 403 - 404 - int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) 405 - { 406 - bool reset; 407 - 408 - if (flow_control & EFX_FC_AUTO) { 409 - EFX_LOG(efx, "10G does not support flow control " 410 - "autonegotiation\n"); 411 - return -EINVAL; 412 - } 413 - 414 - if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX)) 415 - return -EINVAL; 416 - 417 - /* TX flow control may automatically turn itself off if the 418 - * link partner (intermittently) stops responding to pause 419 - * frames. There isn't any indication that this has happened, 420 - * so the best we do is leave it up to the user to spot this 421 - * and fix it be cycling transmit flow control on this end. */ 422 - reset = ((flow_control & EFX_FC_TX) && 423 - !(efx->flow_control & EFX_FC_TX)); 424 - if (EFX_WORKAROUND_11482(efx) && reset) { 425 - if (falcon_rev(efx) >= FALCON_REV_B0) { 426 - /* Recover by resetting the EM block */ 427 - if (efx->link_up) 428 - falcon_drain_tx_fifo(efx); 429 - } else { 430 - /* Schedule a reset to recover */ 431 - efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); 432 - } 433 - } 434 - 435 - efx->flow_control = flow_control; 436 - 437 - return 0; 438 - } 466 + struct efx_mac_operations falcon_xmac_operations = { 467 + .reconfigure = falcon_reconfigure_xmac, 468 + .update_stats = falcon_update_stats_xmac, 469 + .check_hw = falcon_check_xmac, 470 + };
+3 -13
drivers/net/sfc/mac.h
··· 1 1 /**************************************************************************** 2 2 * Driver for Solarflare Solarstorm network controllers and boards 3 3 * Copyright 2005-2006 Fen Systems Ltd. 4 - * Copyright 2006-2007 Solarflare Communications Inc. 4 + * Copyright 2006-2008 Solarflare Communications Inc. 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it 7 7 * under the terms of the GNU General Public License version 2 as published ··· 13 13 14 14 #include "net_driver.h" 15 15 16 - extern int falcon_init_xmac(struct efx_nic *efx); 17 - extern void falcon_reconfigure_xmac(struct efx_nic *efx); 18 - extern void falcon_update_stats_xmac(struct efx_nic *efx); 19 - extern void falcon_fini_xmac(struct efx_nic *efx); 20 - extern int falcon_check_xmac(struct efx_nic *efx); 21 - extern void falcon_xmac_sim_phy_event(struct efx_nic *efx); 22 - extern int falcon_xmac_get_settings(struct efx_nic *efx, 23 - struct ethtool_cmd *ecmd); 24 - extern int falcon_xmac_set_settings(struct efx_nic *efx, 25 - struct ethtool_cmd *ecmd); 26 - extern int falcon_xmac_set_pause(struct efx_nic *efx, 27 - enum efx_fc_type pause_params); 16 + extern struct efx_mac_operations falcon_gmac_operations; 17 + extern struct efx_mac_operations falcon_xmac_operations; 28 18 29 19 #endif
+31
drivers/net/sfc/net_driver.h
··· 463 463 464 464 #define PHY_ADDR_INVALID 0xff 465 465 466 + #define EFX_IS10G(efx) ((efx)->link_speed == 10000) 467 + 466 468 enum nic_state { 467 469 STATE_INIT = 0, 468 470 STATE_RUNNING = 1, ··· 505 503 EFX_FC_AUTO = 4, 506 504 }; 507 505 506 + /* Supported MAC bit-mask */ 507 + enum efx_mac_type { 508 + EFX_GMAC = 1, 509 + EFX_XMAC = 2, 510 + }; 511 + 512 + /** 513 + * struct efx_mac_operations - Efx MAC operations table 514 + * @reconfigure: Reconfigure MAC. Serialised by the mac_lock 515 + * @update_stats: Update statistics 516 + * @check_hw: Check hardware. Serialised by the mac_lock 517 + */ 518 + struct efx_mac_operations { 519 + void (*reconfigure) (struct efx_nic *efx); 520 + void (*update_stats) (struct efx_nic *efx); 521 + int (*check_hw) (struct efx_nic *efx); 522 + }; 523 + 508 524 /** 509 525 * struct efx_phy_operations - Efx PHY operations table 510 526 * @init: Initialise PHY ··· 531 511 * @clear_interrupt: Clear down interrupt 532 512 * @blink: Blink LEDs 533 513 * @check_hw: Check hardware 514 + * @get_settings: Get ethtool settings. Serialised by the mac_lock. 515 + * @set_settings: Set ethtool settings. Serialised by the mac_lock. 534 516 * @mmds: MMD presence mask 535 517 * @loopbacks: Supported loopback modes mask 536 518 */ 537 519 struct efx_phy_operations { 520 + enum efx_mac_type macs; 538 521 int (*init) (struct efx_nic *efx); 539 522 void (*fini) (struct efx_nic *efx); 540 523 void (*reconfigure) (struct efx_nic *efx); 541 524 void (*clear_interrupt) (struct efx_nic *efx); 542 525 int (*check_hw) (struct efx_nic *efx); 543 526 int (*test) (struct efx_nic *efx); 527 + void (*get_settings) (struct efx_nic *efx, 528 + struct ethtool_cmd *ecmd); 529 + int (*set_settings) (struct efx_nic *efx, 530 + struct ethtool_cmd *ecmd); 544 531 int mmds; 545 532 unsigned loopbacks; 546 533 }; ··· 713 686 * @stats_lock: Statistics update lock. Serialises statistics fetches 714 687 * @stats_enabled: Temporarily disable statistics fetches. 715 688 * Serialised by @stats_lock 689 + * @mac_op: MAC interface 716 690 * @mac_address: Permanent MAC address 717 691 * @phy_type: PHY type 718 692 * @phy_lock: PHY access lock ··· 721 693 * @phy_data: PHY private data (including PHY-specific stats) 722 694 * @mii: PHY interface 723 695 * @phy_mode: PHY operating mode. Serialised by @mac_lock. 696 + * @mac_up: MAC link state 724 697 * @link_up: Link status 725 698 * @link_fd: Link is full duplex 726 699 * @link_speed: Link speed (Mbps) ··· 792 763 spinlock_t stats_lock; 793 764 bool stats_enabled; 794 765 766 + struct efx_mac_operations *mac_op; 795 767 unsigned char mac_address[ETH_ALEN]; 796 768 797 769 enum phy_type phy_type; ··· 802 772 struct mii_if_info mii; 803 773 enum efx_phy_mode phy_mode; 804 774 775 + bool mac_up; 805 776 bool link_up; 806 777 bool link_fd; 807 778 unsigned int link_speed;
+11 -15
drivers/net/sfc/selftest.c
··· 26 26 #include "selftest.h" 27 27 #include "boards.h" 28 28 #include "workarounds.h" 29 - #include "mac.h" 30 29 #include "spi.h" 31 30 #include "falcon_io.h" 32 31 #include "mdio_10g.h" ··· 104 105 goto out; 105 106 } 106 107 107 - rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); 108 - if (rc) 109 - goto out; 108 + if (EFX_IS10G(efx)) { 109 + rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); 110 + if (rc) 111 + goto out; 112 + } 110 113 111 114 out: 112 115 mutex_unlock(&efx->mac_lock); ··· 599 598 do { 600 599 struct efx_channel *channel = &efx->channel[0]; 601 600 602 - falcon_check_xmac(efx); 601 + efx->mac_op->check_hw(efx); 603 602 schedule_timeout_uninterruptible(HZ / 10); 604 603 if (channel->work_pending) 605 604 efx_process_channel_now(channel); ··· 607 606 flush_workqueue(efx->workqueue); 608 607 rmb(); 609 608 610 - /* efx->link_up can be 1 even if the XAUI link is down, 611 - * (bug5762). Usually, it's not worth bothering with the 612 - * difference, but for selftests, we need that extra 613 - * guarantee that the link is really, really, up. 614 - */ 609 + /* We need both the phy and xaui links to be ok. 610 + * rather than relying on the falcon_xmac irq/poll 611 + * regime, just poll xaui directly */ 615 612 link_up = efx->link_up; 616 - if (!falcon_xaui_link_ok(efx)) 613 + if (link_up && EFX_IS10G(efx) && 614 + !falcon_xaui_link_ok(efx)) 617 615 link_up = false; 618 616 619 617 } while ((++count < 20) && !link_up); ··· 721 721 if (ecmd_test.autoneg == AUTONEG_ENABLE) { 722 722 ecmd_test.autoneg = AUTONEG_DISABLE; 723 723 ecmd_test.duplex = DUPLEX_FULL; 724 - ecmd_test.speed = SPEED_10000; 725 724 } 726 725 efx->loopback_mode = LOOPBACK_NONE; 727 726 ··· 730 731 efx_schedule_reset(efx, RESET_TYPE_DISABLE); 731 732 return rc; 732 733 } 733 - 734 - tests->loopback_speed = ecmd_test.speed; 735 - tests->loopback_full_duplex = ecmd_test.duplex; 736 734 737 735 rc = efx_test_phy(efx, tests); 738 736 if (rc && !rc2)
-2
drivers/net/sfc/selftest.h
··· 39 39 /* offline tests */ 40 40 int registers; 41 41 int phy; 42 - int loopback_speed; 43 - int loopback_full_duplex; 44 42 struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; 45 43 }; 46 44
+1 -1
drivers/net/sfc/sfe4001.c
··· 176 176 s32 status; 177 177 178 178 /* If XAUI link is up then do not monitor */ 179 - if (EFX_WORKAROUND_7884(efx) && falcon_xaui_link_ok(efx)) 179 + if (EFX_WORKAROUND_7884(efx) && efx->mac_up) 180 180 return 0; 181 181 182 182 /* Check the powered status of the PHY. Lack of power implies that
+6 -4
drivers/net/sfc/tenxpress.c
··· 1 1 /**************************************************************************** 2 - * Driver for Solarflare 802.3an compliant PHY 3 - * Copyright 2007 Solarflare Communications Inc. 2 + * Driver for Solarflare Solarstorm network controllers and boards 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 ··· 15 15 #include "phy.h" 16 16 #include "falcon_hwdefs.h" 17 17 #include "boards.h" 18 - #include "mac.h" 19 18 20 19 /* We expect these MMDs to be in the package */ 21 20 /* AN not here as mdio_check_mmds() requires STAT2 support */ ··· 380 381 link_ok = tenxpress_link_ok(efx, true); 381 382 382 383 if (link_ok != efx->link_up) 383 - falcon_xmac_sim_phy_event(efx); 384 + falcon_sim_phy_event(efx); 384 385 385 386 if (phy_data->phy_mode != PHY_MODE_NORMAL) 386 387 return 0; ··· 452 453 } 453 454 454 455 struct efx_phy_operations falcon_tenxpress_phy_ops = { 456 + .macs = EFX_XMAC, 455 457 .init = tenxpress_phy_init, 456 458 .reconfigure = tenxpress_phy_reconfigure, 457 459 .check_hw = tenxpress_phy_check_hw, 458 460 .fini = tenxpress_phy_fini, 459 461 .clear_interrupt = tenxpress_phy_clear_interrupt, 460 462 .test = tenxpress_phy_test, 463 + .get_settings = mdio_clause45_get_settings, 464 + .set_settings = mdio_clause45_set_settings, 461 465 .mmds = TENXPRESS_REQUIRED_DEVS, 462 466 .loopbacks = TENXPRESS_LOOPBACKS, 463 467 };
+5 -2
drivers/net/sfc/xfp_phy.c
··· 17 17 #include "mdio_10g.h" 18 18 #include "xenpack.h" 19 19 #include "phy.h" 20 - #include "mac.h" 20 + #include "falcon.h" 21 21 22 22 #define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ 23 23 MDIO_MMDREG_DEVS_PMAPMD | \ ··· 125 125 int link_up = xfp_link_ok(efx); 126 126 /* Simulate a PHY event if link state has changed */ 127 127 if (link_up != efx->link_up) 128 - falcon_xmac_sim_phy_event(efx); 128 + falcon_sim_phy_event(efx); 129 129 130 130 rc = efx->board_info.monitor(efx); 131 131 if (rc) { ··· 169 169 } 170 170 171 171 struct efx_phy_operations falcon_xfp_phy_ops = { 172 + .macs = EFX_XMAC, 172 173 .init = xfp_phy_init, 173 174 .reconfigure = xfp_phy_reconfigure, 174 175 .check_hw = xfp_phy_check_hw, 175 176 .fini = xfp_phy_fini, 176 177 .clear_interrupt = xfp_phy_clear_interrupt, 178 + .get_settings = mdio_clause45_get_settings, 179 + .set_settings = mdio_clause45_set_settings, 177 180 .mmds = XFP_REQUIRED_DEVS, 178 181 .loopbacks = XFP_LOOPBACKS, 179 182 };