aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 00:50:46 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:58:17 -0500
commit04cc8cacb01c09fba2297faf1477cd570ba43f0b (patch)
treef17dbd584b072d14f1500c6f6d659be993ae35c7
parent177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97 (diff)
sfc: Implement auto-negotiation
Add infrastructure for auto-negotiation of speed, duplex and flow control. When using 10Xpress, auto-negotiate flow control. While we're at it, clean up the code to warn when partner is not 10GBASE-T capable. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sfc/ethtool.c57
-rw-r--r--drivers/net/sfc/falcon.c6
-rw-r--r--drivers/net/sfc/falcon_gmac.c4
-rw-r--r--drivers/net/sfc/falcon_xmac.c2
-rw-r--r--drivers/net/sfc/mdio_10g.c348
-rw-r--r--drivers/net/sfc/mdio_10g.h32
-rw-r--r--drivers/net/sfc/net_driver.h38
-rw-r--r--drivers/net/sfc/tenxpress.c138
-rw-r--r--drivers/net/sfc/xfp_phy.c1
9 files changed, 472 insertions, 154 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 1b33f89df4d5..0e81af6d8348 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -12,11 +12,13 @@
12#include <linux/ethtool.h> 12#include <linux/ethtool.h>
13#include <linux/rtnetlink.h> 13#include <linux/rtnetlink.h>
14#include "net_driver.h" 14#include "net_driver.h"
15#include "workarounds.h"
15#include "selftest.h" 16#include "selftest.h"
16#include "efx.h" 17#include "efx.h"
17#include "ethtool.h" 18#include "ethtool.h"
18#include "falcon.h" 19#include "falcon.h"
19#include "spi.h" 20#include "spi.h"
21#include "mdio_10g.h"
20 22
21const char *efx_loopback_mode_names[] = { 23const char *efx_loopback_mode_names[] = {
22 [LOOPBACK_NONE] = "NONE", 24 [LOOPBACK_NONE] = "NONE",
@@ -674,14 +676,51 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
674 struct ethtool_pauseparam *pause) 676 struct ethtool_pauseparam *pause)
675{ 677{
676 struct efx_nic *efx = netdev_priv(net_dev); 678 struct efx_nic *efx = netdev_priv(net_dev);
677 enum efx_fc_type flow_control = efx->flow_control; 679 enum efx_fc_type wanted_fc;
680 bool reset;
678 681
679 flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO); 682 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
680 flow_control |= pause->rx_pause ? EFX_FC_RX : 0; 683 (pause->tx_pause ? EFX_FC_TX : 0) |
681 flow_control |= pause->tx_pause ? EFX_FC_TX : 0; 684 (pause->autoneg ? EFX_FC_AUTO : 0));
682 flow_control |= pause->autoneg ? EFX_FC_AUTO : 0; 685
686 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
687 EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n");
688 return -EINVAL;
689 }
690
691 if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) &&
692 (wanted_fc & EFX_FC_AUTO)) {
693 EFX_LOG(efx, "PHY does not support flow control "
694 "autonegotiation\n");
695 return -EINVAL;
696 }
697
698 /* TX flow control may automatically turn itself off if the
699 * link partner (intermittently) stops responding to pause
700 * frames. There isn't any indication that this has happened,
701 * so the best we do is leave it up to the user to spot this
702 * and fix it be cycling transmit flow control on this end. */
703 reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX);
704 if (EFX_WORKAROUND_11482(efx) && reset) {
705 if (falcon_rev(efx) >= FALCON_REV_B0) {
706 /* Recover by resetting the EM block */
707 if (efx->link_up)
708 falcon_drain_tx_fifo(efx);
709 } else {
710 /* Schedule a reset to recover */
711 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
712 }
713 }
714
715 /* Try to push the pause parameters */
716 mutex_lock(&efx->mac_lock);
717
718 efx->wanted_fc = wanted_fc;
719 mdio_clause45_set_pause(efx);
720 __efx_reconfigure_port(efx);
721
722 mutex_unlock(&efx->mac_lock);
683 723
684 efx_reconfigure_port(efx);
685 return 0; 724 return 0;
686} 725}
687 726
@@ -690,9 +729,9 @@ static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
690{ 729{
691 struct efx_nic *efx = netdev_priv(net_dev); 730 struct efx_nic *efx = netdev_priv(net_dev);
692 731
693 pause->rx_pause = !!(efx->flow_control & EFX_FC_RX); 732 pause->rx_pause = !!(efx->wanted_fc & EFX_FC_RX);
694 pause->tx_pause = !!(efx->flow_control & EFX_FC_TX); 733 pause->tx_pause = !!(efx->wanted_fc & EFX_FC_TX);
695 pause->autoneg = !!(efx->flow_control & EFX_FC_AUTO); 734 pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO);
696} 735}
697 736
698 737
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index f09eded40fba..fde4e7912c39 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1998,7 +1998,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
1998 /* Transmission of pause frames when RX crosses the threshold is 1998 /* Transmission of pause frames when RX crosses the threshold is
1999 * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. 1999 * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL.
2000 * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ 2000 * Action on receipt of pause frames is controller by XM_DIS_FCNTL */
2001 tx_fc = !!(efx->flow_control & EFX_FC_TX); 2001 tx_fc = !!(efx->link_fc & EFX_FC_TX);
2002 falcon_read(efx, &reg, RX_CFG_REG_KER); 2002 falcon_read(efx, &reg, RX_CFG_REG_KER);
2003 EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); 2003 EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc);
2004 2004
@@ -2328,9 +2328,9 @@ int falcon_probe_port(struct efx_nic *efx)
2328 2328
2329 /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ 2329 /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
2330 if (falcon_rev(efx) >= FALCON_REV_B0) 2330 if (falcon_rev(efx) >= FALCON_REV_B0)
2331 efx->flow_control = EFX_FC_RX | EFX_FC_TX; 2331 efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
2332 else 2332 else
2333 efx->flow_control = EFX_FC_RX; 2333 efx->wanted_fc = EFX_FC_RX;
2334 2334
2335 /* Allocate buffer for stats */ 2335 /* Allocate buffer for stats */
2336 rc = falcon_alloc_buffer(efx, &efx->stats_buffer, 2336 rc = falcon_alloc_buffer(efx, &efx->stats_buffer,
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
index 247f8025ef00..b6e6eb963905 100644
--- a/drivers/net/sfc/falcon_gmac.c
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -31,8 +31,8 @@ static void falcon_reconfigure_gmac(struct efx_nic *efx)
31 efx_oword_t reg; 31 efx_oword_t reg;
32 32
33 /* Configuration register 1 */ 33 /* Configuration register 1 */
34 tx_fc = (efx->flow_control & EFX_FC_TX) || !efx->link_fd; 34 tx_fc = (efx->link_fc & EFX_FC_TX) || !efx->link_fd;
35 rx_fc = !!(efx->flow_control & EFX_FC_RX); 35 rx_fc = !!(efx->link_fc & EFX_FC_RX);
36 loopback = (efx->loopback_mode == LOOPBACK_GMAC); 36 loopback = (efx->loopback_mode == LOOPBACK_GMAC);
37 bytemode = (efx->link_speed == 1000); 37 bytemode = (efx->link_speed == 1000);
38 38
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 2206eada3463..0ce8f015386c 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -142,7 +142,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
142{ 142{
143 unsigned int max_frame_len; 143 unsigned int max_frame_len;
144 efx_oword_t reg; 144 efx_oword_t reg;
145 bool rx_fc = !!(efx->flow_control & EFX_FC_RX); 145 bool rx_fc = !!(efx->link_fc & EFX_FC_RX);
146 146
147 /* Configure MAC - cut-thru mode is hard wired on */ 147 /* Configure MAC - cut-thru mode is hard wired on */
148 EFX_POPULATE_DWORD_3(reg, 148 EFX_POPULATE_DWORD_3(reg,
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 8d91131aa5ab..037601e0b9d7 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -47,13 +47,16 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
47 if (LOOPBACK_INTERNAL(efx)) 47 if (LOOPBACK_INTERNAL(efx))
48 return 0; 48 return 0;
49 49
50 /* Read MMD STATUS2 to check it is responding. */ 50 if (mmd != MDIO_MMD_AN) {
51 status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2); 51 /* Read MMD STATUS2 to check it is responding. */
52 if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & 52 status = mdio_clause45_read(efx, phy_id, mmd,
53 ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) != 53 MDIO_MMDREG_STAT2);
54 MDIO_MMDREG_STAT2_PRESENT_VAL) { 54 if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
55 EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd); 55 ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
56 return -EIO; 56 MDIO_MMDREG_STAT2_PRESENT_VAL) {
57 EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
58 return -EIO;
59 }
57 } 60 }
58 61
59 /* Read MMD STATUS 1 to check for fault. */ 62 /* Read MMD STATUS 1 to check for fault. */
@@ -179,12 +182,15 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
179 else if (efx->loopback_mode == LOOPBACK_PHYXS) 182 else if (efx->loopback_mode == LOOPBACK_PHYXS)
180 mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | 183 mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
181 MDIO_MMDREG_DEVS_PCS | 184 MDIO_MMDREG_DEVS_PCS |
182 MDIO_MMDREG_DEVS_PMAPMD); 185 MDIO_MMDREG_DEVS_PMAPMD |
186 MDIO_MMDREG_DEVS_AN);
183 else if (efx->loopback_mode == LOOPBACK_PCS) 187 else if (efx->loopback_mode == LOOPBACK_PCS)
184 mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | 188 mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
185 MDIO_MMDREG_DEVS_PMAPMD); 189 MDIO_MMDREG_DEVS_PMAPMD |
190 MDIO_MMDREG_DEVS_AN);
186 else if (efx->loopback_mode == LOOPBACK_PMAPMD) 191 else if (efx->loopback_mode == LOOPBACK_PMAPMD)
187 mmd_mask &= ~MDIO_MMDREG_DEVS_PMAPMD; 192 mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
193 MDIO_MMDREG_DEVS_AN);
188 194
189 while (mmd_mask) { 195 while (mmd_mask) {
190 if (mmd_mask & 1) { 196 if (mmd_mask & 1) {
@@ -244,6 +250,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
244 int low_power, unsigned int mmd_mask) 250 int low_power, unsigned int mmd_mask)
245{ 251{
246 int mmd = 0; 252 int mmd = 0;
253 mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
247 while (mmd_mask) { 254 while (mmd_mask) {
248 if (mmd_mask & 1) 255 if (mmd_mask & 1)
249 mdio_clause45_set_mmd_lpower(efx, low_power, mmd); 256 mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
@@ -252,103 +259,302 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
252 } 259 }
253} 260}
254 261
262static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
263{
264 int phy_id = efx->mii.phy_id;
265 u32 result = 0;
266 int reg;
267
268 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
269 if (reg & ADVERTISE_10HALF)
270 result |= ADVERTISED_10baseT_Half;
271 if (reg & ADVERTISE_10FULL)
272 result |= ADVERTISED_10baseT_Full;
273 if (reg & ADVERTISE_100HALF)
274 result |= ADVERTISED_100baseT_Half;
275 if (reg & ADVERTISE_100FULL)
276 result |= ADVERTISED_100baseT_Full;
277 if (reg & LPA_RESV)
278 result |= xnp;
279
280 return result;
281}
282
255/** 283/**
256 * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO. 284 * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
257 * @efx: Efx NIC 285 * @efx: Efx NIC
258 * @ecmd: Buffer for settings 286 * @ecmd: Buffer for settings
259 * 287 *
260 * On return the 'port', 'speed', 'supported' and 'advertising' fields of 288 * On return the 'port', 'speed', 'supported' and 'advertising' fields of
261 * ecmd have been filled out based on the PMA type. 289 * ecmd have been filled out.
262 */ 290 */
263void mdio_clause45_get_settings(struct efx_nic *efx, 291void mdio_clause45_get_settings(struct efx_nic *efx,
264 struct ethtool_cmd *ecmd) 292 struct ethtool_cmd *ecmd)
265{ 293{
266 int pma_type; 294 mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
295}
267 296
268 /* If no PMA is present we are presumably talking something XAUI-ish 297/**
269 * like CX4. Which we report as FIBRE (see below) */ 298 * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
270 if ((efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)) == 0) { 299 * @efx: Efx NIC
271 ecmd->speed = SPEED_10000; 300 * @ecmd: Buffer for settings
272 ecmd->port = PORT_FIBRE; 301 * @xnp: Advertised Extended Next Page state
273 ecmd->supported = SUPPORTED_FIBRE; 302 * @xnp_lpa: Link Partner's advertised XNP state
274 ecmd->advertising = ADVERTISED_FIBRE; 303 *
275 return; 304 * On return the 'port', 'speed', 'supported' and 'advertising' fields of
276 } 305 * ecmd have been filled out.
306 */
307void mdio_clause45_get_settings_ext(struct efx_nic *efx,
308 struct ethtool_cmd *ecmd,
309 u32 xnp, u32 xnp_lpa)
310{
311 int phy_id = efx->mii.phy_id;
312 int reg;
277 313
278 pma_type = mdio_clause45_read(efx, efx->mii.phy_id, 314 ecmd->transceiver = XCVR_INTERNAL;
279 MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL2); 315 ecmd->phy_address = phy_id;
280 pma_type &= MDIO_PMAPMD_CTRL2_TYPE_MASK;
281 316
282 switch (pma_type) { 317 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
283 /* We represent CX4 as fibre in the absence of anything 318 MDIO_MMDREG_CTRL2);
284 better. */ 319 switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
285 case MDIO_PMAPMD_CTRL2_10G_CX4:
286 ecmd->speed = SPEED_10000;
287 ecmd->port = PORT_FIBRE;
288 ecmd->supported = SUPPORTED_FIBRE;
289 ecmd->advertising = ADVERTISED_FIBRE;
290 break;
291 /* 10G Base-T */
292 case MDIO_PMAPMD_CTRL2_10G_BT: 320 case MDIO_PMAPMD_CTRL2_10G_BT:
293 ecmd->speed = SPEED_10000;
294 ecmd->port = PORT_TP;
295 ecmd->supported = SUPPORTED_TP | SUPPORTED_10000baseT_Full;
296 ecmd->advertising = (ADVERTISED_FIBRE
297 | ADVERTISED_10000baseT_Full);
298 break;
299 case MDIO_PMAPMD_CTRL2_1G_BT: 321 case MDIO_PMAPMD_CTRL2_1G_BT:
300 ecmd->speed = SPEED_1000;
301 ecmd->port = PORT_TP;
302 ecmd->supported = SUPPORTED_TP | SUPPORTED_1000baseT_Full;
303 ecmd->advertising = (ADVERTISED_FIBRE
304 | ADVERTISED_1000baseT_Full);
305 break;
306 case MDIO_PMAPMD_CTRL2_100_BT: 322 case MDIO_PMAPMD_CTRL2_100_BT:
307 ecmd->speed = SPEED_100;
308 ecmd->port = PORT_TP;
309 ecmd->supported = SUPPORTED_TP | SUPPORTED_100baseT_Full;
310 ecmd->advertising = (ADVERTISED_FIBRE
311 | ADVERTISED_100baseT_Full);
312 break;
313 case MDIO_PMAPMD_CTRL2_10_BT: 323 case MDIO_PMAPMD_CTRL2_10_BT:
314 ecmd->speed = SPEED_10;
315 ecmd->port = PORT_TP; 324 ecmd->port = PORT_TP;
316 ecmd->supported = SUPPORTED_TP | SUPPORTED_10baseT_Full; 325 ecmd->supported = SUPPORTED_TP;
317 ecmd->advertising = ADVERTISED_FIBRE | ADVERTISED_10baseT_Full; 326 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
327 MDIO_MMDREG_SPEED);
328 if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
329 ecmd->supported |= SUPPORTED_10000baseT_Full;
330 if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
331 ecmd->supported |= (SUPPORTED_1000baseT_Full |
332 SUPPORTED_1000baseT_Half);
333 if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
334 ecmd->supported |= (SUPPORTED_100baseT_Full |
335 SUPPORTED_100baseT_Half);
336 if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
337 ecmd->supported |= (SUPPORTED_10baseT_Full |
338 SUPPORTED_10baseT_Half);
339 ecmd->advertising = ADVERTISED_TP;
318 break; 340 break;
319 /* All the other defined modes are flavours of 341
320 * 10G optical */ 342 /* We represent CX4 as fibre in the absence of anything better */
343 case MDIO_PMAPMD_CTRL2_10G_CX4:
344 /* All the other defined modes are flavours of optical */
321 default: 345 default:
322 ecmd->speed = SPEED_10000;
323 ecmd->port = PORT_FIBRE; 346 ecmd->port = PORT_FIBRE;
324 ecmd->supported = SUPPORTED_FIBRE; 347 ecmd->supported = SUPPORTED_FIBRE;
325 ecmd->advertising = ADVERTISED_FIBRE; 348 ecmd->advertising = ADVERTISED_FIBRE;
326 break; 349 break;
327 } 350 }
351
352 if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
353 ecmd->supported |= SUPPORTED_Autoneg;
354 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
355 MDIO_MMDREG_CTRL1);
356 if (reg & BMCR_ANENABLE) {
357 ecmd->autoneg = AUTONEG_ENABLE;
358 ecmd->advertising |=
359 ADVERTISED_Autoneg |
360 mdio_clause45_get_an(efx,
361 MDIO_AN_ADVERTISE, xnp);
362 } else
363 ecmd->autoneg = AUTONEG_DISABLE;
364 } else
365 ecmd->autoneg = AUTONEG_DISABLE;
366
367 /* If AN is enabled and complete, report best common mode */
368 if (ecmd->autoneg &&
369 (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_MMDREG_STAT1) &
370 (1 << MDIO_AN_STATUS_AN_DONE_LBN))) {
371 u32 common, lpa;
372 lpa = mdio_clause45_get_an(efx, MDIO_AN_LPA, xnp_lpa);
373 common = ecmd->advertising & lpa;
374 if (common & ADVERTISED_10000baseT_Full) {
375 ecmd->speed = SPEED_10000;
376 ecmd->duplex = DUPLEX_FULL;
377 } else if (common & (ADVERTISED_1000baseT_Full |
378 ADVERTISED_1000baseT_Half)) {
379 ecmd->speed = SPEED_1000;
380 ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
381 } else if (common & (ADVERTISED_100baseT_Full |
382 ADVERTISED_100baseT_Half)) {
383 ecmd->speed = SPEED_100;
384 ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
385 } else {
386 ecmd->speed = SPEED_10;
387 ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
388 }
389 } else {
390 /* Report forced settings */
391 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
392 MDIO_MMDREG_CTRL1);
393 ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
394 ((reg & BMCR_SPEED100) ? 100 : 10));
395 ecmd->duplex = (reg & BMCR_FULLDPLX ||
396 ecmd->speed == SPEED_10000);
397 }
328} 398}
329 399
330/** 400/**
331 * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO. 401 * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
332 * @efx: Efx NIC 402 * @efx: Efx NIC
333 * @ecmd: New settings 403 * @ecmd: New settings
334 *
335 * Currently this just enforces that we are _not_ changing the
336 * 'port', 'speed', 'supported' or 'advertising' settings as these
337 * cannot be changed on any currently supported PHY.
338 */ 404 */
339int mdio_clause45_set_settings(struct efx_nic *efx, 405int mdio_clause45_set_settings(struct efx_nic *efx,
340 struct ethtool_cmd *ecmd) 406 struct ethtool_cmd *ecmd)
341{ 407{
342 struct ethtool_cmd tmpcmd; 408 int phy_id = efx->mii.phy_id;
343 mdio_clause45_get_settings(efx, &tmpcmd); 409 struct ethtool_cmd prev;
344 /* None of the current PHYs support more than one mode 410 u32 required;
345 * of operation (and only 10GBT ever will), so keep things 411 int ctrl1_bits, reg;
346 * simple for now */ 412
347 if ((ecmd->speed == tmpcmd.speed) && (ecmd->port == tmpcmd.port) && 413 efx->phy_op->get_settings(efx, &prev);
348 (ecmd->supported == tmpcmd.supported) && 414
349 (ecmd->advertising == tmpcmd.advertising)) 415 if (ecmd->advertising == prev.advertising &&
416 ecmd->speed == prev.speed &&
417 ecmd->duplex == prev.duplex &&
418 ecmd->port == prev.port &&
419 ecmd->autoneg == prev.autoneg)
350 return 0; 420 return 0;
351 return -EOPNOTSUPP; 421
422 /* We can only change these settings for -T PHYs */
423 if (prev.port != PORT_TP || ecmd->port != PORT_TP)
424 return -EINVAL;
425
426 /* Check that PHY supports these settings and work out the
427 * basic control bits */
428 if (ecmd->duplex) {
429 switch (ecmd->speed) {
430 case SPEED_10:
431 ctrl1_bits = BMCR_FULLDPLX;
432 required = SUPPORTED_10baseT_Full;
433 break;
434 case SPEED_100:
435 ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
436 required = SUPPORTED_100baseT_Full;
437 break;
438 case SPEED_1000:
439 ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
440 required = SUPPORTED_1000baseT_Full;
441 break;
442 case SPEED_10000:
443 ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
444 BMCR_FULLDPLX);
445 required = SUPPORTED_10000baseT_Full;
446 break;
447 default:
448 return -EINVAL;
449 }
450 } else {
451 switch (ecmd->speed) {
452 case SPEED_10:
453 ctrl1_bits = 0;
454 required = SUPPORTED_10baseT_Half;
455 break;
456 case SPEED_100:
457 ctrl1_bits = BMCR_SPEED100;
458 required = SUPPORTED_100baseT_Half;
459 break;
460 case SPEED_1000:
461 ctrl1_bits = BMCR_SPEED1000;
462 required = SUPPORTED_1000baseT_Half;
463 break;
464 default:
465 return -EINVAL;
466 }
467 }
468 if (ecmd->autoneg)
469 required |= SUPPORTED_Autoneg;
470 required |= ecmd->advertising;
471 if (required & ~prev.supported)
472 return -EINVAL;
473
474 /* Set the basic control bits */
475 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
476 MDIO_MMDREG_CTRL1);
477 reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
478 reg |= ctrl1_bits;
479 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
480 reg);
481
482 /* Set the AN registers */
483 if (ecmd->autoneg != prev.autoneg ||
484 ecmd->advertising != prev.advertising) {
485 bool xnp = false;
486
487 if (efx->phy_op->set_xnp_advertise)
488 xnp = efx->phy_op->set_xnp_advertise(efx,
489 ecmd->advertising);
490
491 if (ecmd->autoneg) {
492 reg = 0;
493 if (ecmd->advertising & ADVERTISED_10baseT_Half)
494 reg |= ADVERTISE_10HALF;
495 if (ecmd->advertising & ADVERTISED_10baseT_Full)
496 reg |= ADVERTISE_10FULL;
497 if (ecmd->advertising & ADVERTISED_100baseT_Half)
498 reg |= ADVERTISE_100HALF;
499 if (ecmd->advertising & ADVERTISED_100baseT_Full)
500 reg |= ADVERTISE_100FULL;
501 if (xnp)
502 reg |= ADVERTISE_RESV;
503 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
504 MDIO_AN_ADVERTISE, reg);
505 }
506
507 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
508 MDIO_MMDREG_CTRL1);
509 if (ecmd->autoneg)
510 reg |= BMCR_ANENABLE | BMCR_ANRESTART;
511 else
512 reg &= ~BMCR_ANENABLE;
513 if (xnp)
514 reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
515 else
516 reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
517 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
518 MDIO_MMDREG_CTRL1, reg);
519 }
520
521 return 0;
522}
523
524void mdio_clause45_set_pause(struct efx_nic *efx)
525{
526 int phy_id = efx->mii.phy_id;
527 int reg;
528
529 if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
530 /* Set pause capability advertising */
531 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
532 MDIO_AN_ADVERTISE);
533 reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
534 reg |= efx_fc_advertise(efx->wanted_fc);
535 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
536 MDIO_AN_ADVERTISE, reg);
537
538 /* Restart auto-negotiation */
539 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
540 MDIO_MMDREG_CTRL1);
541 if (reg & BMCR_ANENABLE) {
542 reg |= BMCR_ANRESTART;
543 mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
544 MDIO_MMDREG_CTRL1, reg);
545 }
546 }
547}
548
549enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
550{
551 int phy_id = efx->mii.phy_id;
552 int lpa;
553
554 if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
555 return efx->wanted_fc;
556 lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
557 return efx_fc_resolve(efx->wanted_fc, lpa);
352} 558}
353 559
354void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev, 560void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 4830e0c1da0b..80c63dde8864 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -81,6 +81,17 @@
81#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) 81#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
82#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) 82#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)
83#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) 83#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
84#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN)
85
86/* Bits in MMDREG_SPEED */
87#define MDIO_MMDREG_SPEED_10G_LBN 0
88#define MDIO_MMDREG_SPEED_10G_WIDTH 1
89#define MDIO_MMDREG_SPEED_1000M_LBN 4
90#define MDIO_MMDREG_SPEED_1000M_WIDTH 1
91#define MDIO_MMDREG_SPEED_100M_LBN 5
92#define MDIO_MMDREG_SPEED_100M_WIDTH 1
93#define MDIO_MMDREG_SPEED_10M_LBN 6
94#define MDIO_MMDREG_SPEED_10M_WIDTH 1
84 95
85/* Bits in MMDREG_STAT2 */ 96/* Bits in MMDREG_STAT2 */
86#define MDIO_MMDREG_STAT2_PRESENT_VAL (2) 97#define MDIO_MMDREG_STAT2_PRESENT_VAL (2)
@@ -119,12 +130,20 @@
119#define MDIO_PHYXS_LANE_ALIGNED_LBN (12) 130#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
120 131
121/* AN registers */ 132/* AN registers */
133#define MDIO_AN_CTRL_XNP_LBN 13
122#define MDIO_AN_STATUS (1) 134#define MDIO_AN_STATUS (1)
123#define MDIO_AN_STATUS_XNP_LBN (7) 135#define MDIO_AN_STATUS_XNP_LBN (7)
124#define MDIO_AN_STATUS_PAGE_LBN (6) 136#define MDIO_AN_STATUS_PAGE_LBN (6)
125#define MDIO_AN_STATUS_AN_DONE_LBN (5) 137#define MDIO_AN_STATUS_AN_DONE_LBN (5)
126#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0) 138#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0)
127 139
140#define MDIO_AN_ADVERTISE 16
141#define MDIO_AN_ADVERTISE_XNP_LBN 12
142#define MDIO_AN_LPA 19
143#define MDIO_AN_XNP 22
144#define MDIO_AN_LPA_XNP 25
145
146#define MDIO_AN_10GBT_ADVERTISE 32
128#define MDIO_AN_10GBT_STATUS (33) 147#define MDIO_AN_10GBT_STATUS (33)
129#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ 148#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
130#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ 149#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
@@ -251,10 +270,23 @@ extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
251extern void mdio_clause45_get_settings(struct efx_nic *efx, 270extern void mdio_clause45_get_settings(struct efx_nic *efx,
252 struct ethtool_cmd *ecmd); 271 struct ethtool_cmd *ecmd);
253 272
273/* Read (some of) the PHY settings over MDIO */
274extern void
275mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd,
276 u32 xnp, u32 xnp_lpa);
277
254/* Set (some of) the PHY settings over MDIO */ 278/* Set (some of) the PHY settings over MDIO */
255extern int mdio_clause45_set_settings(struct efx_nic *efx, 279extern int mdio_clause45_set_settings(struct efx_nic *efx,
256 struct ethtool_cmd *ecmd); 280 struct ethtool_cmd *ecmd);
257 281
282/* Set pause parameters to be advertised through AN (if available) */
283extern void mdio_clause45_set_pause(struct efx_nic *efx);
284
285/* Get pause parameters from AN if available (otherwise return
286 * requested pause parameters)
287 */
288enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx);
289
258/* Wait for specified MMDs to exit reset within a timeout */ 290/* Wait for specified MMDs to exit reset within a timeout */
259extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, 291extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
260 unsigned int mmd_mask); 292 unsigned int mmd_mask);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 883086e39455..fb8d72527a34 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -511,6 +511,35 @@ enum efx_mac_type {
511 EFX_XMAC = 2, 511 EFX_XMAC = 2,
512}; 512};
513 513
514static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc)
515{
516 unsigned int adv = 0;
517 if (wanted_fc & EFX_FC_RX)
518 adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
519 if (wanted_fc & EFX_FC_TX)
520 adv ^= ADVERTISE_PAUSE_ASYM;
521 return adv;
522}
523
524static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
525 unsigned int lpa)
526{
527 unsigned int adv = efx_fc_advertise(wanted_fc);
528
529 if (!(wanted_fc & EFX_FC_AUTO))
530 return wanted_fc;
531
532 if (adv & lpa & ADVERTISE_PAUSE_CAP)
533 return EFX_FC_RX | EFX_FC_TX;
534 if (adv & lpa & ADVERTISE_PAUSE_ASYM) {
535 if (adv & ADVERTISE_PAUSE_CAP)
536 return EFX_FC_RX;
537 if (lpa & ADVERTISE_PAUSE_CAP)
538 return EFX_FC_TX;
539 }
540 return 0;
541}
542
514/** 543/**
515 * struct efx_mac_operations - Efx MAC operations table 544 * struct efx_mac_operations - Efx MAC operations table
516 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock 545 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
@@ -533,6 +562,8 @@ struct efx_mac_operations {
533 * @check_hw: Check hardware 562 * @check_hw: Check hardware
534 * @get_settings: Get ethtool settings. Serialised by the mac_lock. 563 * @get_settings: Get ethtool settings. Serialised by the mac_lock.
535 * @set_settings: Set ethtool settings. Serialised by the mac_lock. 564 * @set_settings: Set ethtool settings. Serialised by the mac_lock.
565 * @set_xnp_advertise: Set abilities advertised in Extended Next Page
566 * (only needed where AN bit is set in mmds)
536 * @mmds: MMD presence mask 567 * @mmds: MMD presence mask
537 * @loopbacks: Supported loopback modes mask 568 * @loopbacks: Supported loopback modes mask
538 */ 569 */
@@ -548,6 +579,7 @@ struct efx_phy_operations {
548 struct ethtool_cmd *ecmd); 579 struct ethtool_cmd *ecmd);
549 int (*set_settings) (struct efx_nic *efx, 580 int (*set_settings) (struct efx_nic *efx,
550 struct ethtool_cmd *ecmd); 581 struct ethtool_cmd *ecmd);
582 bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
551 int mmds; 583 int mmds;
552 unsigned loopbacks; 584 unsigned loopbacks;
553}; 585};
@@ -724,11 +756,12 @@ union efx_multicast_hash {
724 * @mac_up: MAC link state 756 * @mac_up: MAC link state
725 * @link_up: Link status 757 * @link_up: Link status
726 * @link_fd: Link is full duplex 758 * @link_fd: Link is full duplex
759 * @link_fc: Actualy flow control flags
727 * @link_speed: Link speed (Mbps) 760 * @link_speed: Link speed (Mbps)
728 * @n_link_state_changes: Number of times the link has changed state 761 * @n_link_state_changes: Number of times the link has changed state
729 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. 762 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
730 * @multicast_hash: Multicast hash table 763 * @multicast_hash: Multicast hash table
731 * @flow_control: Flow control flags - separate RX/TX so can't use link_options 764 * @wanted_fc: Wanted flow control flags
732 * @reconfigure_work: work item for dealing with PHY events 765 * @reconfigure_work: work item for dealing with PHY events
733 * @loopback_mode: Loopback status 766 * @loopback_mode: Loopback status
734 * @loopback_modes: Supported loopback mode bitmask 767 * @loopback_modes: Supported loopback mode bitmask
@@ -805,12 +838,13 @@ struct efx_nic {
805 bool mac_up; 838 bool mac_up;
806 bool link_up; 839 bool link_up;
807 bool link_fd; 840 bool link_fd;
841 enum efx_fc_type link_fc;
808 unsigned int link_speed; 842 unsigned int link_speed;
809 unsigned int n_link_state_changes; 843 unsigned int n_link_state_changes;
810 844
811 bool promiscuous; 845 bool promiscuous;
812 union efx_multicast_hash multicast_hash; 846 union efx_multicast_hash multicast_hash;
813 enum efx_fc_type flow_control; 847 enum efx_fc_type wanted_fc;
814 struct work_struct reconfigure_work; 848 struct work_struct reconfigure_work;
815 849
816 atomic_t rx_reset; 850 atomic_t rx_reset;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index d60353bb40b6..634ff9198823 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -17,10 +17,10 @@
17#include "boards.h" 17#include "boards.h"
18 18
19/* We expect these MMDs to be in the package */ 19/* We expect these MMDs to be in the package */
20/* AN not here as mdio_check_mmds() requires STAT2 support */
21#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ 20#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \
22 MDIO_MMDREG_DEVS_PCS | \ 21 MDIO_MMDREG_DEVS_PCS | \
23 MDIO_MMDREG_DEVS_PHYXS) 22 MDIO_MMDREG_DEVS_PHYXS | \
23 MDIO_MMDREG_DEVS_AN)
24 24
25#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 25#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
26 (1 << LOOPBACK_PCS) | \ 26 (1 << LOOPBACK_PCS) | \
@@ -57,6 +57,7 @@
57#define PMA_PMD_LED_ON (1) 57#define PMA_PMD_LED_ON (1)
58#define PMA_PMD_LED_OFF (2) 58#define PMA_PMD_LED_OFF (2)
59#define PMA_PMD_LED_FLASH (3) 59#define PMA_PMD_LED_FLASH (3)
60#define PMA_PMD_LED_MASK 3
60/* All LEDs under hardware control */ 61/* All LEDs under hardware control */
61#define PMA_PMD_LED_FULL_AUTO (0) 62#define PMA_PMD_LED_FULL_AUTO (0)
62/* Green and Amber under hardware control, Red off */ 63/* Green and Amber under hardware control, Red off */
@@ -242,78 +243,60 @@ unlock:
242 return rc; 243 return rc;
243} 244}
244 245
245static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp) 246static void tenxpress_check_bad_lp(struct efx_nic *efx, bool link_ok)
246{ 247{
247 struct tenxpress_phy_data *pd = efx->phy_data; 248 struct tenxpress_phy_data *pd = efx->phy_data;
249 int phy_id = efx->mii.phy_id;
250 bool bad_lp;
248 int reg; 251 int reg;
249 252
253 if (link_ok) {
254 bad_lp = false;
255 } else {
256 /* Check that AN has started but not completed. */
257 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
258 MDIO_AN_STATUS);
259 if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN)))
260 return; /* LP status is unknown */
261 bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN));
262 if (bad_lp)
263 pd->bad_lp_tries++;
264 }
265
250 /* Nothing to do if all is well and was previously so. */ 266 /* Nothing to do if all is well and was previously so. */
251 if (!(bad_lp || pd->bad_lp_tries)) 267 if (!pd->bad_lp_tries)
252 return; 268 return;
253 269
254 reg = mdio_clause45_read(efx, efx->mii.phy_id, 270 /* Use the RX (red) LED as an error indicator once we've seen AN
255 MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG); 271 * failure several times in a row, and also log a message. */
256 272 if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
257 if (bad_lp) 273 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
258 pd->bad_lp_tries++; 274 PMA_PMD_LED_OVERR_REG);
259 else 275 reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
260 pd->bad_lp_tries = 0; 276 if (!bad_lp) {
261 277 reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
262 if (pd->bad_lp_tries == MAX_BAD_LP_TRIES) { 278 } else {
263 pd->bad_lp_tries = 0; /* Restart count */ 279 reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN;
264 reg &= ~(PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN); 280 EFX_ERR(efx, "appears to be plugged into a port"
265 reg |= (PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN); 281 " that is not 10GBASE-T capable. The PHY"
266 EFX_ERR(efx, "This NIC appears to be plugged into" 282 " supports 10GBASE-T ONLY, so no link can"
267 " a port that is not 10GBASE-T capable.\n" 283 " be established\n");
268 " This PHY is 10GBASE-T ONLY, so no link can" 284 }
269 " be established.\n"); 285 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
270 } else { 286 PMA_PMD_LED_OVERR_REG, reg);
271 reg |= (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN); 287 pd->bad_lp_tries = bad_lp;
272 } 288 }
273 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
274 PMA_PMD_LED_OVERR_REG, reg);
275} 289}
276 290
277/* Check link status and return a boolean OK value. If the link is NOT 291static bool tenxpress_link_ok(struct efx_nic *efx)
278 * OK we have a quick rummage round to see if we appear to be plugged
279 * into a non-10GBT port and if so warn the user that they won't get
280 * link any time soon as we are 10GBT only, unless caller specified
281 * not to do this check (it isn't useful in loopback) */
282static bool tenxpress_link_ok(struct efx_nic *efx, bool check_lp)
283{ 292{
284 bool ok = mdio_clause45_links_ok(efx, TENXPRESS_REQUIRED_DEVS); 293 if (efx->loopback_mode == LOOPBACK_NONE)
285 294 return mdio_clause45_links_ok(efx, MDIO_MMDREG_DEVS_AN);
286 if (ok) { 295 else
287 tenxpress_set_bad_lp(efx, false); 296 return mdio_clause45_links_ok(efx,
288 } else if (check_lp) { 297 MDIO_MMDREG_DEVS_PMAPMD |
289 /* Are we plugged into the wrong sort of link? */ 298 MDIO_MMDREG_DEVS_PCS |
290 bool bad_lp = false; 299 MDIO_MMDREG_DEVS_PHYXS);
291 int phy_id = efx->mii.phy_id;
292 int an_stat = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
293 MDIO_AN_STATUS);
294 int xphy_stat = mdio_clause45_read(efx, phy_id,
295 MDIO_MMD_PMAPMD,
296 PMA_PMD_XSTATUS_REG);
297 /* Are we plugged into anything that sends FLPs? If
298 * not we can't distinguish between not being plugged
299 * in and being plugged into a non-AN antique. The FLP
300 * bit has the advantage of not clearing when autoneg
301 * restarts. */
302 if (!(xphy_stat & (1 << PMA_PMD_XSTAT_FLP_LBN))) {
303 tenxpress_set_bad_lp(efx, false);
304 return ok;
305 }
306
307 /* If it can do 10GBT it must be XNP capable */
308 bad_lp = !(an_stat & (1 << MDIO_AN_STATUS_XNP_LBN));
309 if (!bad_lp && (an_stat & (1 << MDIO_AN_STATUS_PAGE_LBN))) {
310 bad_lp = !(mdio_clause45_read(efx, phy_id,
311 MDIO_MMD_AN, MDIO_AN_10GBT_STATUS) &
312 (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN));
313 }
314 tenxpress_set_bad_lp(efx, bad_lp);
315 }
316 return ok;
317} 300}
318 301
319static void tenxpress_phyxs_loopback(struct efx_nic *efx) 302static void tenxpress_phyxs_loopback(struct efx_nic *efx)
@@ -359,9 +342,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
359 342
360 phy_data->loopback_mode = efx->loopback_mode; 343 phy_data->loopback_mode = efx->loopback_mode;
361 phy_data->phy_mode = efx->phy_mode; 344 phy_data->phy_mode = efx->phy_mode;
362 efx->link_up = tenxpress_link_ok(efx, false); 345 efx->link_up = tenxpress_link_ok(efx);
363 efx->link_speed = 10000; 346 efx->link_speed = 10000;
364 efx->link_fd = true; 347 efx->link_fd = true;
348 efx->link_fc = mdio_clause45_get_pause(efx);
365} 349}
366 350
367static void tenxpress_phy_clear_interrupt(struct efx_nic *efx) 351static void tenxpress_phy_clear_interrupt(struct efx_nic *efx)
@@ -377,7 +361,8 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
377 bool link_ok; 361 bool link_ok;
378 int rc = 0; 362 int rc = 0;
379 363
380 link_ok = tenxpress_link_ok(efx, true); 364 link_ok = tenxpress_link_ok(efx);
365 tenxpress_check_bad_lp(efx, link_ok);
381 366
382 if (link_ok != efx->link_up) 367 if (link_ok != efx->link_up)
383 falcon_sim_phy_event(efx); 368 falcon_sim_phy_event(efx);
@@ -451,6 +436,27 @@ static int tenxpress_phy_test(struct efx_nic *efx)
451 return tenxpress_special_reset(efx); 436 return tenxpress_special_reset(efx);
452} 437}
453 438
439static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
440{
441 int phy = efx->mii.phy_id;
442 u32 lpa = 0;
443 int reg;
444
445 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
446 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
447 lpa |= ADVERTISED_10000baseT_Full;
448 return lpa;
449}
450
451static void
452tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
453{
454 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
455 tenxpress_get_xnp_lpa(efx));
456 ecmd->supported |= SUPPORTED_10000baseT_Full;
457 ecmd->advertising |= ADVERTISED_10000baseT_Full;
458}
459
454struct efx_phy_operations falcon_tenxpress_phy_ops = { 460struct efx_phy_operations falcon_tenxpress_phy_ops = {
455 .macs = EFX_XMAC, 461 .macs = EFX_XMAC,
456 .init = tenxpress_phy_init, 462 .init = tenxpress_phy_init,
@@ -459,7 +465,7 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
459 .fini = tenxpress_phy_fini, 465 .fini = tenxpress_phy_fini,
460 .clear_interrupt = tenxpress_phy_clear_interrupt, 466 .clear_interrupt = tenxpress_phy_clear_interrupt,
461 .test = tenxpress_phy_test, 467 .test = tenxpress_phy_test,
462 .get_settings = mdio_clause45_get_settings, 468 .get_settings = tenxpress_get_settings,
463 .set_settings = mdio_clause45_set_settings, 469 .set_settings = mdio_clause45_set_settings,
464 .mmds = TENXPRESS_REQUIRED_DEVS, 470 .mmds = TENXPRESS_REQUIRED_DEVS,
465 .loopbacks = TENXPRESS_LOOPBACKS, 471 .loopbacks = TENXPRESS_LOOPBACKS,
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index d4e203ddcf1c..fbe8e25a1ed5 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -155,6 +155,7 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
155 efx->link_up = xfp_link_ok(efx); 155 efx->link_up = xfp_link_ok(efx);
156 efx->link_speed = 10000; 156 efx->link_speed = 10000;
157 efx->link_fd = true; 157 efx->link_fd = true;
158 efx->link_fc = efx->wanted_fc;
158} 159}
159 160
160 161