SP devices using NCSI require the MAC transmitter and optical Tx to
remain enabled when the host interface is down.
Skip disabling MAC Tx in mac_link_down() for NCSI devices. Keep the
data-path shutdown in mac_prepare() for PCS reconfiguration, and
re-enable MAC Tx in mac_finish() without waiting for host link-up.
txgbe_down() still performs a LAN reset through txgbe_reset_hw() after
the MAC is left enabled. This does not clear MAC Tx on NCSI devices,
because the NCSI firmware protects the MAC configuration from the LAN
reset, so no further re-enable is needed on the down path.
Keep TX_DISABLE deasserted while an NCSI host interface is down.
Retain normal SFP GPIO handling while the interface is up, including
transmit fault recovery.
TX_DISABLE is driven by the SFP core, which asserts it at probe and
whenever the upstream is stopped by phylink_stop(). Neither the SFP
core nor phylink provides a way to keep the transmitter enabled while
the interface is down.
Therefore, handle this in the GPIO controller: requests to assert
TX_DISABLE are ignored while WX_STATE_DOWN is set on an NCSI device.
WX_STATE_DOWN is set before phylink_stop() in txgbe_down() and cleared
before phylink_start() in txgbe_up_complete(), so requests made while
the interface is up, including TX fault recovery, still reach the
hardware.
While the interface is down, the SFP core considers TX_DISABLE
asserted although the line is driven low. This does not affect the
SFP state machine, which stays in SFP_S_DOWN until the upstream is
started again and then deasserts TX_DISABLE itself.
Fixes: 08f08f9390e4 ("net: txgbe: Support phylink MAC layer")
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
index dc9f243146580..589ad5d2f17b3 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -182,7 +182,8 @@ static void txgbe_mac_link_down(struct phylink_config *config,
{
struct wx *wx = phylink_to_wx(config);
- wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
+ if (!wx->ncsi_enabled)
+ wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
wx->speed = SPEED_UNKNOWN;
if (test_bit(WX_STATE_PTP_RUNNING, wx->state))@@ -253,6 +254,10 @@ static int txgbe_mac_finish(struct phylink_config *config, unsigned int mode,
txgbe_enable_sec_tx_path(wx);
wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
+ /* NCSI requires MAC Tx to be enabled even if the host link stays down. */
+ if (wx->ncsi_enabled)
+ wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, WX_MAC_TX_CFG_TE);
+
return 0;
}
@@ -368,6 +373,11 @@ static int txgbe_gpio_direction_out(struct gpio_chip *chip, unsigned int offset,
unsigned long flags;
u32 set;
+ /* Keep the NCSI transmitter enabled while the host interface is down. */
+ if (wx->ncsi_enabled && BIT(offset) == TXGBE_GPIOBIT_1 &&
+ test_bit(WX_STATE_DOWN, wx->state))
+ val = 0;
+
set = val ? BIT(offset) : 0;
raw_spin_lock_irqsave(&wx->gpio_lock, flags);
--
2.51.0