aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-04-29 04:05:08 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-29 20:32:30 -0400
commit68e7f45e118f98b77cfa007aa2d97b5dac69fe6b (patch)
treed2e05579a0fc1f5a28bce8ff09ac6863d1907186 /drivers/net/sfc/falcon.c
parent1b1c2e95103ce391c2ea39a9460968fcb73deb30 (diff)
sfc: Use generic MDIO functions and definitions
Make use of the newly-added generic MDIO clause 45 support and remove redundant definitions. Add an 'efx_' prefix to the remaining driver-specific MDIO functions and remove arguments which are redundant with efx->mdio.prtad. 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.c137
1 files changed, 37 insertions, 100 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 466a8abb0053..c049364aec46 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
2063 ************************************************************************** 2063 **************************************************************************
2064 */ 2064 */
2065 2065
2066/* Use the top bit of the MII PHY id to indicate the PHY type
2067 * (1G/10G), with the remaining bits as the actual PHY id.
2068 *
2069 * This allows us to avoid leaking information from the mii_if_info
2070 * structure into other data structures.
2071 */
2072#define FALCON_PHY_ID_ID_WIDTH EFX_WIDTH(MD_PRT_DEV_ADR)
2073#define FALCON_PHY_ID_ID_MASK ((1 << FALCON_PHY_ID_ID_WIDTH) - 1)
2074#define FALCON_PHY_ID_WIDTH (FALCON_PHY_ID_ID_WIDTH + 1)
2075#define FALCON_PHY_ID_MASK ((1 << FALCON_PHY_ID_WIDTH) - 1)
2076#define FALCON_PHY_ID_10G (1 << (FALCON_PHY_ID_WIDTH - 1))
2077
2078
2079/* Packing the clause 45 port and device fields into a single value */
2080#define MD_PRT_ADR_COMP_LBN (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN)
2081#define MD_PRT_ADR_COMP_WIDTH MD_PRT_ADR_WIDTH
2082#define MD_DEV_ADR_COMP_LBN 0
2083#define MD_DEV_ADR_COMP_WIDTH MD_DEV_ADR_WIDTH
2084
2085
2086/* Wait for GMII access to complete */ 2066/* Wait for GMII access to complete */
2087static int falcon_gmii_wait(struct efx_nic *efx) 2067static int falcon_gmii_wait(struct efx_nic *efx)
2088{ 2068{
@@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx)
2108 return -ETIMEDOUT; 2088 return -ETIMEDOUT;
2109} 2089}
2110 2090
2111/* Writes a GMII register of a PHY connected to Falcon using MDIO. */ 2091/* Write an MDIO register of a PHY connected to Falcon. */
2112static void falcon_mdio_write(struct net_device *net_dev, int phy_id, 2092static int falcon_mdio_write(struct net_device *net_dev,
2113 int addr, int value) 2093 int prtad, int devad, u16 addr, u16 value)
2114{ 2094{
2115 struct efx_nic *efx = netdev_priv(net_dev); 2095 struct efx_nic *efx = netdev_priv(net_dev);
2116 unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
2117 efx_oword_t reg; 2096 efx_oword_t reg;
2097 int rc;
2118 2098
2119 /* The 'generic' prt/dev packing in mdio_10g.h is conveniently 2099 EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
2120 * chosen so that the only current user, Falcon, can take the 2100 prtad, devad, addr, value);
2121 * packed value and use them directly.
2122 * Fail to build if this assumption is broken.
2123 */
2124 BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G);
2125 BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH);
2126 BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN);
2127 BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN);
2128
2129 if (phy_id2 == PHY_ADDR_INVALID)
2130 return;
2131
2132 /* See falcon_mdio_read for an explanation. */
2133 if (!(phy_id & FALCON_PHY_ID_10G)) {
2134 int mmd = ffs(efx->phy_op->mmds) - 1;
2135 EFX_TRACE(efx, "Fixing erroneous clause22 write\n");
2136 phy_id2 = mdio_clause45_pack(phy_id2, mmd)
2137 & FALCON_PHY_ID_ID_MASK;
2138 }
2139
2140 EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id,
2141 addr, value);
2142 2101
2143 spin_lock_bh(&efx->phy_lock); 2102 spin_lock_bh(&efx->phy_lock);
2144 2103
2145 /* Check MII not currently being accessed */ 2104 /* Check MDIO not currently being accessed */
2146 if (falcon_gmii_wait(efx) != 0) 2105 rc = falcon_gmii_wait(efx);
2106 if (rc)
2147 goto out; 2107 goto out;
2148 2108
2149 /* Write the address/ID register */ 2109 /* Write the address/ID register */
2150 EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); 2110 EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
2151 falcon_write(efx, &reg, MD_PHY_ADR_REG_KER); 2111 falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
2152 2112
2153 EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2); 2113 EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
2154 falcon_write(efx, &reg, MD_ID_REG_KER); 2114 falcon_write(efx, &reg, MD_ID_REG_KER);
2155 2115
2156 /* Write data */ 2116 /* Write data */
@@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
2163 falcon_write(efx, &reg, MD_CS_REG_KER); 2123 falcon_write(efx, &reg, MD_CS_REG_KER);
2164 2124
2165 /* Wait for data to be written */ 2125 /* Wait for data to be written */
2166 if (falcon_gmii_wait(efx) != 0) { 2126 rc = falcon_gmii_wait(efx);
2127 if (rc) {
2167 /* Abort the write operation */ 2128 /* Abort the write operation */
2168 EFX_POPULATE_OWORD_2(reg, 2129 EFX_POPULATE_OWORD_2(reg,
2169 MD_WRC, 0, 2130 MD_WRC, 0,
@@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
2174 2135
2175 out: 2136 out:
2176 spin_unlock_bh(&efx->phy_lock); 2137 spin_unlock_bh(&efx->phy_lock);
2138 return rc;
2177} 2139}
2178 2140
2179/* Reads a GMII register from a PHY connected to Falcon. If no value 2141/* Read an MDIO register of a PHY connected to Falcon. */
2180 * could be read, -1 will be returned. */ 2142static int falcon_mdio_read(struct net_device *net_dev,
2181static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) 2143 int prtad, int devad, u16 addr)
2182{ 2144{
2183 struct efx_nic *efx = netdev_priv(net_dev); 2145 struct efx_nic *efx = netdev_priv(net_dev);
2184 unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
2185 efx_oword_t reg; 2146 efx_oword_t reg;
2186 int value = -1; 2147 int rc;
2187
2188 if (phy_addr == PHY_ADDR_INVALID)
2189 return -1;
2190
2191 /* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G)
2192 * but the generic Linux code does not make any distinction or have
2193 * any state for this.
2194 * We spot the case where someone tried to talk 22 to a 45 PHY and
2195 * redirect the request to the lowest numbered MMD as a clause45
2196 * request. This is enough to allow simple queries like id and link
2197 * state to succeed. TODO: We may need to do more in future.
2198 */
2199 if (!(phy_id & FALCON_PHY_ID_10G)) {
2200 int mmd = ffs(efx->phy_op->mmds) - 1;
2201 EFX_TRACE(efx, "Fixing erroneous clause22 read\n");
2202 phy_addr = mdio_clause45_pack(phy_addr, mmd)
2203 & FALCON_PHY_ID_ID_MASK;
2204 }
2205 2148
2206 spin_lock_bh(&efx->phy_lock); 2149 spin_lock_bh(&efx->phy_lock);
2207 2150
2208 /* Check MII not currently being accessed */ 2151 /* Check MDIO not currently being accessed */
2209 if (falcon_gmii_wait(efx) != 0) 2152 rc = falcon_gmii_wait(efx);
2153 if (rc)
2210 goto out; 2154 goto out;
2211 2155
2212 EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); 2156 EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
2213 falcon_write(efx, &reg, MD_PHY_ADR_REG_KER); 2157 falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
2214 2158
2215 EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr); 2159 EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
2216 falcon_write(efx, &reg, MD_ID_REG_KER); 2160 falcon_write(efx, &reg, MD_ID_REG_KER);
2217 2161
2218 /* Request data to be read */ 2162 /* Request data to be read */
@@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
2220 falcon_write(efx, &reg, MD_CS_REG_KER); 2164 falcon_write(efx, &reg, MD_CS_REG_KER);
2221 2165
2222 /* Wait for data to become available */ 2166 /* Wait for data to become available */
2223 value = falcon_gmii_wait(efx); 2167 rc = falcon_gmii_wait(efx);
2224 if (value == 0) { 2168 if (rc == 0) {
2225 falcon_read(efx, &reg, MD_RXD_REG_KER); 2169 falcon_read(efx, &reg, MD_RXD_REG_KER);
2226 value = EFX_OWORD_FIELD(reg, MD_RXD); 2170 rc = EFX_OWORD_FIELD(reg, MD_RXD);
2227 EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n", 2171 EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
2228 phy_id, addr, value); 2172 prtad, devad, addr, rc);
2229 } else { 2173 } else {
2230 /* Abort the read operation */ 2174 /* Abort the read operation */
2231 EFX_POPULATE_OWORD_2(reg, 2175 EFX_POPULATE_OWORD_2(reg,
@@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
2233 MD_GC, 1); 2177 MD_GC, 1);
2234 falcon_write(efx, &reg, MD_CS_REG_KER); 2178 falcon_write(efx, &reg, MD_CS_REG_KER);
2235 2179
2236 EFX_LOG(efx, "read from GMII 0x%x register %02x, got " 2180 EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
2237 "error %d\n", phy_id, addr, value); 2181 prtad, devad, addr, rc);
2238 } 2182 }
2239 2183
2240 out: 2184 out:
2241 spin_unlock_bh(&efx->phy_lock); 2185 spin_unlock_bh(&efx->phy_lock);
2242 2186 return rc;
2243 return value;
2244}
2245
2246static void falcon_init_mdio(struct mii_if_info *gmii)
2247{
2248 gmii->mdio_read = falcon_mdio_read;
2249 gmii->mdio_write = falcon_mdio_write;
2250 gmii->phy_id_mask = FALCON_PHY_ID_MASK;
2251 gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1);
2252} 2187}
2253 2188
2254static int falcon_probe_phy(struct efx_nic *efx) 2189static int falcon_probe_phy(struct efx_nic *efx)
@@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx)
2342 if (rc) 2277 if (rc)
2343 return rc; 2278 return rc;
2344 2279
2345 /* Set up GMII structure for PHY */ 2280 /* Set up MDIO structure for PHY */
2346 efx->mii.supports_gmii = true; 2281 efx->mdio.mmds = efx->phy_op->mmds;
2347 falcon_init_mdio(&efx->mii); 2282 efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
2283 efx->mdio.mdio_read = falcon_mdio_read;
2284 efx->mdio.mdio_write = falcon_mdio_write;
2348 2285
2349 /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ 2286 /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
2350 if (falcon_rev(efx) >= FALCON_REV_B0) 2287 if (falcon_rev(efx) >= FALCON_REV_B0)
@@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
2761 if (rc == -EINVAL) { 2698 if (rc == -EINVAL) {
2762 EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n"); 2699 EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
2763 efx->phy_type = PHY_TYPE_NONE; 2700 efx->phy_type = PHY_TYPE_NONE;
2764 efx->mii.phy_id = PHY_ADDR_INVALID; 2701 efx->mdio.prtad = MDIO_PRTAD_NONE;
2765 board_rev = 0; 2702 board_rev = 0;
2766 rc = 0; 2703 rc = 0;
2767 } else if (rc) { 2704 } else if (rc) {
@@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
2771 struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3; 2708 struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
2772 2709
2773 efx->phy_type = v2->port0_phy_type; 2710 efx->phy_type = v2->port0_phy_type;
2774 efx->mii.phy_id = v2->port0_phy_addr; 2711 efx->mdio.prtad = v2->port0_phy_addr;
2775 board_rev = le16_to_cpu(v2->board_revision); 2712 board_rev = le16_to_cpu(v2->board_revision);
2776 2713
2777 if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { 2714 if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
@@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
2793 /* Read the MAC addresses */ 2730 /* Read the MAC addresses */
2794 memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN); 2731 memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
2795 2732
2796 EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id); 2733 EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
2797 2734
2798 efx_set_board_info(efx, board_rev); 2735 efx_set_board_info(efx, board_rev);
2799 2736