[openwrt/openwrt] realtek: 6.6: refactor mac config and link up for RTL83xx
LEDE Commits
lede-commits at lists.infradead.org
Sat Sep 14 12:30:38 PDT 2024
svanheule pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/cd958d945be06a1b810d55912f32d6e922d952ea
commit cd958d945be06a1b810d55912f32d6e922d952ea
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Tue Aug 27 08:01:57 2024 -0400
realtek: 6.6: refactor mac config and link up for RTL83xx
Since kernel commit c5714f68a76bcad3d ("net: phylink: explicitly invalidate
link_state members in mac_config") it should be clear that link data can
only be used in mac_link_up(). Refactor that for the RTL83xx targets.
Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
---
.../files-6.6/drivers/net/dsa/rtl83xx/dsa.c | 161 +++++++++------------
.../files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h | 15 +-
2 files changed, 81 insertions(+), 95 deletions(-)
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
index e32933ee91..7ec3f4af1b 100644
--- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/dsa.c
@@ -671,104 +671,31 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
unsigned int mode,
const struct phylink_link_state *state)
{
+ struct dsa_port *dp = dsa_to_port(ds, port);
struct rtl838x_switch_priv *priv = ds->priv;
- u32 reg;
- int speed_bit = priv->family_id == RTL8380_FAMILY_ID ? 4 : 3;
+ u32 mcr;
pr_debug("%s port %d, mode %x\n", __func__, port, mode);
- if (port == priv->cpu_port) {
- /* Set Speed, duplex, flow control
- * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
- * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN
- * | MEDIA_SEL
- */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- sw_w32(0x6192F, priv->r->mac_force_mode_ctrl(priv->cpu_port));
- /* allow CRC errors on CPU-port */
- sw_w32_mask(0, 0x8, RTL838X_MAC_PORT_CTRL(priv->cpu_port));
- } else {
- sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl(priv->cpu_port));
- }
+ /* currently only needed for RTL8380 */
+ if (priv->family_id != RTL8380_FAMILY_ID)
return;
- }
-
- reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
- /* Auto-Negotiation does not work for MAC in RTL8390 */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
- pr_debug("PHY autonegotiates\n");
- reg |= RTL838X_NWAY_EN;
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
- rtl83xx_config_interface(port, state->interface);
- return;
- }
- }
- if (mode != MLO_AN_FIXED)
- pr_debug("Fixed state.\n");
-
- /* Clear id_mode_dis bit, and the existing port mode, let
- * RGMII_MODE_EN bet set by mac_link_{up,down} */
- if (priv->family_id == RTL8380_FAMILY_ID) {
- reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN);
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
- if (state->pause & MLO_PAUSE_TX)
- reg |= RTL838X_TX_PAUSE_EN;
- reg |= RTL838X_RX_PAUSE_EN;
- }
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- reg &= ~(RTL839X_RX_PAUSE_EN | RTL839X_TX_PAUSE_EN);
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
- if (state->pause & MLO_PAUSE_TX)
- reg |= RTL839X_TX_PAUSE_EN;
- reg |= RTL839X_RX_PAUSE_EN;
- }
- }
-
-
- reg &= ~(3 << speed_bit);
- switch (state->speed) {
- case SPEED_1000:
- reg |= 2 << speed_bit;
- break;
- case SPEED_100:
- reg |= 1 << speed_bit;
- break;
- default:
- break; /* Ignore, including 10MBit which has a speed value of 0 */
+ if (dsa_port_is_cpu(dp)) {
+ /* allow CRC errors on CPU-port */
+ sw_w32_mask(0, 0x8, priv->r->mac_port_ctrl(port));
+ return;
}
- if (priv->family_id == RTL8380_FAMILY_ID) {
- reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
- if (state->link)
- reg |= RTL838X_FORCE_LINK_EN;
- if (state->duplex == RTL838X_DUPLEX_MODE)
- reg |= RTL838X_DUPLEX_MODE;
- } else if (priv->family_id == RTL8390_FAMILY_ID) {
- reg &= ~(RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
- if (state->link)
- reg |= RTL839X_FORCE_LINK_EN;
- if (state->duplex == RTL839X_DUPLEX_MODE)
- reg |= RTL839X_DUPLEX_MODE;
- }
-
- /* LAG members must use DUPLEX and we need to enable the link */
- if (priv->lagmembers & BIT_ULL(port)) {
- switch(priv->family_id) {
- case RTL8380_FAMILY_ID:
- reg |= (RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN);
- break;
- case RTL8390_FAMILY_ID:
- reg |= (RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN);
- break;
- }
+ mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+ if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
+ pr_debug("port %d PHY autonegotiates\n", port);
+ rtl83xx_config_interface(port, state->interface);
+ mcr |= RTL838X_NWAY_EN;
+ } else {
+ mcr &= ~RTL838X_NWAY_EN;
}
-
- /* Disable AN */
- if (priv->family_id == RTL8380_FAMILY_ID)
- reg &= ~RTL838X_NWAY_EN;
- sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+ sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
}
static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port,
@@ -916,12 +843,14 @@ static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
phy_interface_t interface)
{
struct rtl838x_switch_priv *priv = ds->priv;
+ int mask = 0;
/* Stop TX/RX to port */
sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
/* No longer force link */
- sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl(port));
+ mask = RTL83XX_FORCE_EN | RTL83XX_FORCE_LINK_EN;
+ sw_w32_mask(mask, 0, priv->r->mac_force_mode_ctrl(port));
}
static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
@@ -949,10 +878,60 @@ static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
+ struct dsa_port *dp = dsa_to_port(ds, port);
struct rtl838x_switch_priv *priv = ds->priv;
+ u32 mcr, spdsel;
+
+ if (speed == SPEED_1000)
+ spdsel = RTL_SPEED_1000;
+ else if (speed == SPEED_100)
+ spdsel = RTL_SPEED_100;
+ else
+ spdsel = RTL_SPEED_10;
+
+ mcr = sw_r32(priv->r->mac_force_mode_ctrl(port));
+
+ if (priv->family_id == RTL8380_FAMILY_ID) {
+ mcr &= ~RTL838X_RX_PAUSE_EN;
+ mcr &= ~RTL838X_TX_PAUSE_EN;
+ mcr &= ~RTL838X_DUPLEX_MODE;
+ mcr &= ~RTL838X_SPEED_MASK;
+ mcr |= RTL83XX_FORCE_LINK_EN;
+ mcr |= spdsel << RTL838X_SPEED_SHIFT;
+
+ if (tx_pause)
+ mcr |= RTL838X_TX_PAUSE_EN;
+ if (rx_pause)
+ mcr |= RTL838X_RX_PAUSE_EN;
+ if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+ mcr |= RTL838X_DUPLEX_MODE;
+ if (dsa_port_is_cpu(dp))
+ mcr |= RTL83XX_FORCE_EN;
+
+ } else if (priv->family_id == RTL8390_FAMILY_ID) {
+ mcr &= ~RTL839X_RX_PAUSE_EN;
+ mcr &= ~RTL839X_TX_PAUSE_EN;
+ mcr &= ~RTL839X_DUPLEX_MODE;
+ mcr &= ~RTL839X_SPEED_MASK;
+ mcr |= RTL83XX_FORCE_LINK_EN;
+ mcr |= spdsel << RTL839X_SPEED_SHIFT;
+
+ if (tx_pause)
+ mcr |= RTL839X_TX_PAUSE_EN;
+ if (rx_pause)
+ mcr |= RTL839X_RX_PAUSE_EN;
+ if (duplex == DUPLEX_FULL || priv->lagmembers & BIT_ULL(port))
+ mcr |= RTL839X_DUPLEX_MODE;
+ if (dsa_port_is_cpu(dp))
+ mcr |= RTL83XX_FORCE_EN;
+ }
+
+ pr_debug("%s port %d, mode %x, speed %d, duplex %d, txpause %d, rxpause %d: set mcr=%08x\n",
+ __func__, port, mode, speed, duplex, tx_pause, rx_pause, mcr);
+ sw_w32(mcr, priv->r->mac_force_mode_ctrl(port));
+
/* Restart TX/RX to port */
sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
- /* TODO: Set speed/duplex/pauses */
}
static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
diff --git a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
index 176fd07fe4..13a0bb5ffa 100644
--- a/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-6.6/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -144,17 +144,24 @@
#define RTL931X_MAC_LINK_MEDIA_STS (0x0EC8)
/* MAC link state bits */
-#define RTL838X_FORCE_EN (1 << 0)
-#define RTL838X_FORCE_LINK_EN (1 << 1)
+#define RTL_SPEED_10 0
+#define RTL_SPEED_100 1
+#define RTL_SPEED_1000 2
+
+#define RTL83XX_FORCE_EN (1 << 0)
+#define RTL83XX_FORCE_LINK_EN (1 << 1)
+
#define RTL838X_NWAY_EN (1 << 2)
#define RTL838X_DUPLEX_MODE (1 << 3)
+#define RTL838X_SPEED_SHIFT (4)
+#define RTL838X_SPEED_MASK (3 << RTL838X_SPEED_SHIFT)
#define RTL838X_TX_PAUSE_EN (1 << 6)
#define RTL838X_RX_PAUSE_EN (1 << 7)
#define RTL838X_MAC_FORCE_FC_EN (1 << 8)
-#define RTL839X_FORCE_EN (1 << 0)
-#define RTL839X_FORCE_LINK_EN (1 << 1)
#define RTL839X_DUPLEX_MODE (1 << 2)
+#define RTL839X_SPEED_SHIFT (3)
+#define RTL839X_SPEED_MASK (3 << RTL839X_SPEED_SHIFT)
#define RTL839X_TX_PAUSE_EN (1 << 5)
#define RTL839X_RX_PAUSE_EN (1 << 6)
#define RTL839X_MAC_FORCE_FC_EN (1 << 7)
More information about the lede-commits
mailing list