mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-24 06:17:51 +04:00
realtek: dsa: support RTL931x MAC force mode
RTL931x controls forced link, speed, duplex, and flow control with separate enable bits. Describe the register layout and provide a MAC link-state source selector so the common RTL93xx callbacks can manage its force-mode transitions. This supports fixed links, CPU ports, and dynamic SFP PHYs while leaving statically described PHY links and direct PCS links hardware-controlled. Dynamic SGMII and out-of-band PHYs remain forced, while dynamic USXGMII PHYs return to PCS-controlled state after the force pulse. Assisted-by: ChatGPT (OpenAI GPT-5.6 Sol) Link: https://github.com/openwrt/openwrt/pull/25118 Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
This commit is contained in:
3 files changed
+49
-12
No files matched your search
@@ -329,8 +329,7 @@ static void rtldsa_93xx_phylink_mac_config(struct phylink_config *config,
|
||||
return;
|
||||
|
||||
cfg = &priv->r->mac_force_mode;
|
||||
force_dynamic_phy = priv->family_id == RTL9300_FAMILY_ID &&
|
||||
!priv->ports[port].phy &&
|
||||
force_dynamic_phy = !priv->ports[port].phy &&
|
||||
(mode == MLO_AN_PHY || state->interface == PHY_INTERFACE_MODE_SGMII);
|
||||
|
||||
/* Select PCS before dropping force mode to avoid a transient link down. */
|
||||
@@ -340,8 +339,7 @@ static void rtldsa_93xx_phylink_mac_config(struct phylink_config *config,
|
||||
RTLDSA_MAC_LINK_STATE_SOURCE_PCS,
|
||||
state->interface);
|
||||
|
||||
if (priv->family_id == RTL9300_FAMILY_ID &&
|
||||
(mode == MLO_AN_FIXED || force_dynamic_phy)) {
|
||||
if (mode == MLO_AN_FIXED || force_dynamic_phy) {
|
||||
/* Keep links that require force mode forced down. */
|
||||
regmap_write(priv->map, priv->r->mac_force_mode_ctrl(port),
|
||||
cfg->force_en_mask | cfg->fc_force_en_mask);
|
||||
@@ -385,8 +383,7 @@ static void rtldsa_93xx_phylink_mac_link_down(struct phylink_config *config,
|
||||
int port = dp->index;
|
||||
|
||||
cfg = &priv->r->mac_force_mode;
|
||||
force_dynamic_phy = priv->family_id == RTL9300_FAMILY_ID &&
|
||||
!priv->ports[port].phy &&
|
||||
force_dynamic_phy = !priv->ports[port].phy &&
|
||||
(mode == MLO_AN_PHY || interface == PHY_INTERFACE_MODE_SGMII);
|
||||
|
||||
/* Stop TX/RX to port */
|
||||
@@ -398,8 +395,7 @@ static void rtldsa_93xx_phylink_mac_link_down(struct phylink_config *config,
|
||||
RTLDSA_MAC_LINK_STATE_SOURCE_PCS,
|
||||
interface);
|
||||
|
||||
if (priv->family_id == RTL9300_FAMILY_ID &&
|
||||
(dsa_port_is_cpu(dp) || mode == MLO_AN_FIXED || force_dynamic_phy)) {
|
||||
if (dsa_port_is_cpu(dp) || mode == MLO_AN_FIXED || force_dynamic_phy) {
|
||||
/* Preserve force mode while forcing the link down. */
|
||||
regmap_update_bits(priv->map, priv->r->mac_force_mode_ctrl(port),
|
||||
cfg->link_up_mask, 0);
|
||||
@@ -473,9 +469,6 @@ static void rtldsa_93xx_phylink_mac_link_up(struct phylink_config *config,
|
||||
bool dynamic_phy, force_dynamic_phy, keep_forced;
|
||||
u32 mcr, spdsel;
|
||||
|
||||
if (priv->family_id != RTL9300_FAMILY_ID)
|
||||
goto restart;
|
||||
|
||||
/*
|
||||
* The RTL93xx polling machinery does more than issue MDIO
|
||||
* transactions. It collects resolved link state and distributes it
|
||||
|
||||
@@ -34,7 +34,15 @@
|
||||
#define RTL930X_MEDIA_SEL BIT(16)
|
||||
|
||||
#define RTL931X_FORCE_LINK_EN BIT(0)
|
||||
#define RTL931X_FORCE_DUPLEX_EN BIT(2)
|
||||
#define RTL931X_FORCE_SPEED_EN BIT(3)
|
||||
#define RTL931X_MAC_FORCE_FC_EN BIT(4)
|
||||
#define RTL931X_FORCE_LINK BIT(9)
|
||||
#define RTL931X_DUPLEX_MODE BIT(11)
|
||||
#define RTL931X_SPEED_SHIFT (12)
|
||||
#define RTL931X_SPEED_MASK (15 << RTL931X_SPEED_SHIFT)
|
||||
#define RTL931X_TX_PAUSE_EN BIT(16)
|
||||
#define RTL931X_RX_PAUSE_EN BIT(17)
|
||||
|
||||
enum rtldsa_mac_link_state_source {
|
||||
RTLDSA_MAC_LINK_STATE_SOURCE_PCS,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <asm/mach-rtl-otto/mach-rtl-otto.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "lag.h"
|
||||
#include "l2.h"
|
||||
@@ -82,6 +83,11 @@
|
||||
#define RTL931X_LED_CLK_SEL_200NS 2
|
||||
#define RTL931X_LED_CLK_SEL_100NS 3
|
||||
|
||||
#define RTL931X_SMI_PHY_ABLTY_GET_SEL(port) (0x0cac + ((port) / 16) * 4)
|
||||
#define RTL931X_SMI_PHY_ABLTY_MDIO 0x0
|
||||
#define RTL931X_SMI_PHY_ABLTY_SDS 0x2
|
||||
#define RTL931X_SMI_PHY_ABLTY_MASK(port) (GENMASK(1, 0) << (((port) % 16) * 2))
|
||||
|
||||
static inline int rtl931x_mac_force_mode_ctrl(int p)
|
||||
{
|
||||
return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2);
|
||||
@@ -382,6 +388,28 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv)
|
||||
dev_dbg(dev, "%08x: %08x\n", 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4));
|
||||
}
|
||||
|
||||
static int
|
||||
rtldsa_931x_mac_link_state_source_set(struct rtl838x_switch_priv *priv,
|
||||
int port,
|
||||
enum rtldsa_mac_link_state_source source,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
u32 mask, src_val;
|
||||
|
||||
if (port >= RTL931X_CPU_PORT)
|
||||
return 0;
|
||||
|
||||
mask = RTL931X_SMI_PHY_ABLTY_MASK(port);
|
||||
if (source == RTLDSA_MAC_LINK_STATE_SOURCE_PCS)
|
||||
src_val = RTL931X_SMI_PHY_ABLTY_SDS;
|
||||
else
|
||||
src_val = RTL931X_SMI_PHY_ABLTY_MDIO;
|
||||
|
||||
return regmap_update_bits(priv->map,
|
||||
RTL931X_SMI_PHY_ABLTY_GET_SEL(port),
|
||||
mask, field_prep(mask, src_val));
|
||||
}
|
||||
|
||||
const struct rtldsa_config rtldsa_931x_cfg = {
|
||||
.switch_ops = &rtldsa_93xx_switch_ops,
|
||||
.phylink_mac_ops = &rtldsa_93xx_phylink_mac_ops,
|
||||
@@ -432,10 +460,18 @@ const struct rtldsa_config rtldsa_931x_cfg = {
|
||||
.stp_get = rtldsa_931x_stp_get,
|
||||
.stp_set = rtl931x_stp_set,
|
||||
.mac_force_mode = {
|
||||
.force_en_mask = RTL931X_FORCE_LINK_EN,
|
||||
.force_en_mask = RTL931X_FORCE_LINK_EN |
|
||||
RTL931X_FORCE_DUPLEX_EN |
|
||||
RTL931X_FORCE_SPEED_EN,
|
||||
.fc_force_en_mask = RTL931X_MAC_FORCE_FC_EN,
|
||||
.link_up_mask = RTL931X_FORCE_LINK,
|
||||
.duplex_mask = RTL931X_DUPLEX_MODE,
|
||||
.speed_mask = RTL931X_SPEED_MASK,
|
||||
.tx_pause_mask = RTL931X_TX_PAUSE_EN,
|
||||
.rx_pause_mask = RTL931X_RX_PAUSE_EN,
|
||||
},
|
||||
.mac_force_mode_ctrl = rtl931x_mac_force_mode_ctrl,
|
||||
.mac_link_state_source_set = rtldsa_931x_mac_link_state_source_set,
|
||||
.mac_link_sts = RTL931X_MAC_LINK_STS,
|
||||
.mac_port_ctrl = rtl931x_mac_port_ctrl,
|
||||
.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 |
|
||||
|
||||
Reference in new issue
Block a user