diff mbox series

[net-next,5/7] net: txgbe: support switching mode to 1000BASE-X and SGMII

Message ID 20230724102341.10401-6-jiawenwu@trustnetic.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series support more link mode for TXGBE | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1342 this patch: 1342
netdev/cc_maintainers warning 6 maintainers not CCed: kuba@kernel.org maciej.fijalkowski@intel.com piotr.raczynski@intel.com davem@davemloft.net pabeni@redhat.com edumazet@google.com
netdev/build_clang success Errors and warnings before: 1365 this patch: 1365
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1365 this patch: 1365
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 110 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jiawen Wu July 24, 2023, 10:23 a.m. UTC
Disable data path before PCS VR reset while switching PCS mode, to prevent
the blocking of data path. Enable AN interrupt for CL37 auto-negotiation.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/ethernet/wangxun/libwx/wx_type.h  |  2 ++
 drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c | 28 +++++++++++++++++++
 drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h |  2 ++
 .../net/ethernet/wangxun/txgbe/txgbe_phy.c    | 22 +++++++++++++--
 4 files changed, 52 insertions(+), 2 deletions(-)

Comments

Russell King (Oracle) July 24, 2023, 10:40 a.m. UTC | #1
On Mon, Jul 24, 2023 at 06:23:39PM +0800, Jiawen Wu wrote:
> @@ -185,6 +186,8 @@ static void txgbe_mac_link_up(struct phylink_config *config,
>  	struct wx *wx = netdev_priv(to_net_dev(config->dev));
>  	u32 txcfg, wdg;
>  
> +	txgbe_enable_sec_tx_path(wx);
> +
>  	txcfg = rd32(wx, WX_MAC_TX_CFG);
>  	txcfg &= ~WX_MAC_TX_CFG_SPEED_MASK;
>  
> @@ -210,8 +213,20 @@ static void txgbe_mac_link_up(struct phylink_config *config,
>  	wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
>  }
>  
> +static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode,
> +			     phy_interface_t interface)
> +{
> +	struct wx *wx = netdev_priv(to_net_dev(config->dev));
> +
> +	wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
> +	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
> +
> +	return txgbe_disable_sec_tx_path(wx);

Is there a reason why the sec_tx_path is enabled/disabled asymmetrically?

I would expect the transmit path to be disabled in mac_link_down() and
re-enabled in mac_link_up().

Alternatively, if it just needs to be disabled for reconfiguration,
I would expect it to be disabled in mac_prepare() and re-enabled in
mac_finish().

The disable in mac_prepare() and enable in mac_link_up() just looks
rather strange, because it isn't symmetrical.

Thanks.
Jiawen Wu July 25, 2023, 2:29 a.m. UTC | #2
On Monday, July 24, 2023 6:40 PM, Russell King (Oracle) wrote:
> On Mon, Jul 24, 2023 at 06:23:39PM +0800, Jiawen Wu wrote:
> > @@ -185,6 +186,8 @@ static void txgbe_mac_link_up(struct phylink_config *config,
> >  	struct wx *wx = netdev_priv(to_net_dev(config->dev));
> >  	u32 txcfg, wdg;
> >
> > +	txgbe_enable_sec_tx_path(wx);
> > +
> >  	txcfg = rd32(wx, WX_MAC_TX_CFG);
> >  	txcfg &= ~WX_MAC_TX_CFG_SPEED_MASK;
> >
> > @@ -210,8 +213,20 @@ static void txgbe_mac_link_up(struct phylink_config *config,
> >  	wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
> >  }
> >
> > +static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode,
> > +			     phy_interface_t interface)
> > +{
> > +	struct wx *wx = netdev_priv(to_net_dev(config->dev));
> > +
> > +	wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
> > +	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
> > +
> > +	return txgbe_disable_sec_tx_path(wx);
> 
> Is there a reason why the sec_tx_path is enabled/disabled asymmetrically?
> 
> I would expect the transmit path to be disabled in mac_link_down() and
> re-enabled in mac_link_up().
> 
> Alternatively, if it just needs to be disabled for reconfiguration,
> I would expect it to be disabled in mac_prepare() and re-enabled in
> mac_finish().
> 
> The disable in mac_prepare() and enable in mac_link_up() just looks
> rather strange, because it isn't symmetrical.

It needs to be disabled for PCS switch mode, I will move the re-enable to
mac_finish().
diff mbox series

Patch

diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
index 1de88a33a698..50b92cfb46a0 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -205,6 +205,8 @@ 
 #define WX_TSC_CTL                   0x1D000
 #define WX_TSC_CTL_TX_DIS            BIT(1)
 #define WX_TSC_CTL_TSEC_DIS          BIT(0)
+#define WX_TSC_ST                    0x1D004
+#define WX_TSC_ST_SECTX_RDY          BIT(0)
 #define WX_TSC_BUF_AE                0x1D00C
 #define WX_TSC_BUF_AE_THR            GENMASK(9, 0)
 
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
index 6e130d1f7a7b..90168aab11ae 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c
@@ -13,6 +13,34 @@ 
 #include "txgbe_type.h"
 #include "txgbe_hw.h"
 
+/**
+ *  txgbe_disable_sec_tx_path - Stops the transmit data path
+ *  @wx: pointer to hardware structure
+ *
+ *  Stops the transmit data path and waits for the HW to internally empty
+ *  the tx security block
+ **/
+int txgbe_disable_sec_tx_path(struct wx *wx)
+{
+	int val;
+
+	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, WX_TSC_CTL_TX_DIS);
+	return read_poll_timeout(rd32, val, val & WX_TSC_ST_SECTX_RDY,
+				 1000, 20000, false, wx, WX_TSC_ST);
+}
+
+/**
+ *  txgbe_enable_sec_tx_path - Enables the transmit data path
+ *  @wx: pointer to hardware structure
+ *
+ *  Enables the transmit data path.
+ **/
+void txgbe_enable_sec_tx_path(struct wx *wx)
+{
+	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, 0);
+	WX_WRITE_FLUSH(wx);
+}
+
 /**
  *  txgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
  *  @wx: pointer to hardware structure
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h
index e82f65dff8a6..abc729eb187a 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.h
@@ -4,6 +4,8 @@ 
 #ifndef _TXGBE_HW_H_
 #define _TXGBE_HW_H_
 
+int txgbe_disable_sec_tx_path(struct wx *wx);
+void txgbe_enable_sec_tx_path(struct wx *wx);
 int txgbe_read_pba_string(struct wx *wx, u8 *pba_num, u32 pba_num_size);
 int txgbe_validate_eeprom_checksum(struct wx *wx, u16 *checksum_val);
 int txgbe_reset_hw(struct wx *wx);
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
index 8779645a54be..30a5ed2ed316 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -18,6 +18,7 @@ 
 #include "../libwx/wx_hw.h"
 #include "txgbe_type.h"
 #include "txgbe_phy.h"
+#include "txgbe_hw.h"
 
 static int txgbe_swnodes_register(struct txgbe *txgbe)
 {
@@ -133,7 +134,7 @@  static int txgbe_mdio_pcs_init(struct txgbe *txgbe)
 	if (!mii_bus)
 		return -ENOMEM;
 
-	mii_bus->name = "txgbe_pcs_mdio_bus";
+	mii_bus->name = DW_MII_BUS_TXGBE;
 	mii_bus->read_c45 = &txgbe_pcs_read;
 	mii_bus->write_c45 = &txgbe_pcs_write;
 	mii_bus->parent = &pdev->dev;
@@ -185,6 +186,8 @@  static void txgbe_mac_link_up(struct phylink_config *config,
 	struct wx *wx = netdev_priv(to_net_dev(config->dev));
 	u32 txcfg, wdg;
 
+	txgbe_enable_sec_tx_path(wx);
+
 	txcfg = rd32(wx, WX_MAC_TX_CFG);
 	txcfg &= ~WX_MAC_TX_CFG_SPEED_MASK;
 
@@ -210,8 +213,20 @@  static void txgbe_mac_link_up(struct phylink_config *config,
 	wr32(wx, WX_MAC_WDG_TIMEOUT, wdg);
 }
 
+static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode,
+			     phy_interface_t interface)
+{
+	struct wx *wx = netdev_priv(to_net_dev(config->dev));
+
+	wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0);
+	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0);
+
+	return txgbe_disable_sec_tx_path(wx);
+}
+
 static const struct phylink_mac_ops txgbe_mac_ops = {
 	.mac_select_pcs = txgbe_phylink_mac_select,
+	.mac_prepare = txgbe_mac_prepare,
 	.mac_config = txgbe_mac_config,
 	.mac_link_down = txgbe_mac_link_down,
 	.mac_link_up = txgbe_mac_link_up,
@@ -234,6 +249,8 @@  static int txgbe_phylink_init(struct txgbe *txgbe)
 	config->mac_capabilities = MAC_10000FD | MAC_1000FD | MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
 	phy_mode = PHY_INTERFACE_MODE_10GBASER;
 	__set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_1000BASEX, config->supported_interfaces);
+	__set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces);
 	fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_PHYLINK]);
 	phylink = phylink_create(config, fwnode, phy_mode, &txgbe_mac_ops);
 	if (IS_ERR(phylink))
@@ -431,7 +448,8 @@  static void txgbe_irq_handler(struct irq_desc *desc)
 
 	chained_irq_exit(chip, desc);
 
-	if (eicr & (TXGBE_PX_MISC_ETH_LK | TXGBE_PX_MISC_ETH_LKDN)) {
+	if (eicr & (TXGBE_PX_MISC_ETH_LK | TXGBE_PX_MISC_ETH_LKDN |
+		    TXGBE_PX_MISC_ETH_AN)) {
 		u32 reg = rd32(wx, TXGBE_CFG_PORT_ST);
 
 		phylink_mac_change(txgbe->phylink, !!(reg & TXGBE_CFG_PORT_ST_LINK_UP));