mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-09-09 00:06:08 +08:00
Import pending series introducing support for standalone PCS drivers. This has previously already been used by the airoha target, and is also the base for the closer-to-upstream patches for MediaTek MT7988 10G SerDes support. In order to not having to diverge from upstream also backport series for standardized handling for PHY and PCS SerDes pair polarity. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
580 lines
19 KiB
Diff
580 lines
19 KiB
Diff
From 0be12d497dbe2ea783e805f0375869cb573cd52a Mon Sep 17 00:00:00 2001
|
|
From: Daniel Golle <daniel@makrotopia.org>
|
|
Date: Tue, 12 Dec 2023 03:51:14 +0000
|
|
Subject: [PATCH 4/4] net: ethernet: mtk_eth_soc: add paths and SerDes modes
|
|
for MT7988
|
|
|
|
MT7988 comes with two SerDes interfaces to connect external PHYs or
|
|
transceivers in USXGMII, 10GBase-R, 5GBase-R, 2500Base-X, 1000Base-X and
|
|
Cisco SGMII interface modes.
|
|
|
|
Implement support for configuring for the new paths to SerDes interfaces.
|
|
|
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
---
|
|
drivers/net/ethernet/mediatek/mtk_eth_path.c | 81 ++++++++-
|
|
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 165 +++++++++++++++----
|
|
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 49 +++++-
|
|
3 files changed, 252 insertions(+), 43 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
|
@@ -35,8 +35,16 @@ static const char *mtk_eth_path_name(u64
|
|
return "gmac2_2p5gphy";
|
|
case MTK_ETH_PATH_GMAC2_GEPHY:
|
|
return "gmac2_gephy";
|
|
+ case MTK_ETH_PATH_GMAC3_SGMII:
|
|
+ return "gmac3_sgmii";
|
|
case MTK_ETH_PATH_GDM1_ESW:
|
|
return "gdm1_esw";
|
|
+ case MTK_ETH_PATH_GMAC1_USXGMII:
|
|
+ return "gmac1_usxgmii";
|
|
+ case MTK_ETH_PATH_GMAC2_USXGMII:
|
|
+ return "gmac2_usxgmii";
|
|
+ case MTK_ETH_PATH_GMAC3_USXGMII:
|
|
+ return "gmac3_usxgmii";
|
|
default:
|
|
return "unknown path";
|
|
}
|
|
@@ -190,7 +198,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
|
|
return 0;
|
|
}
|
|
|
|
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
|
|
+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
|
|
+{
|
|
+ unsigned int val = 0;
|
|
+ bool updated = true;
|
|
+ int mac_id = 0;
|
|
+
|
|
+ /* Disable SYSCFG1 SGMII */
|
|
+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
|
|
+
|
|
+ switch (path) {
|
|
+ case MTK_ETH_PATH_GMAC1_USXGMII:
|
|
+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
|
|
+ mac_id = MTK_GMAC1_ID;
|
|
+ break;
|
|
+ case MTK_ETH_PATH_GMAC2_USXGMII:
|
|
+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
|
|
+ mac_id = MTK_GMAC2_ID;
|
|
+ break;
|
|
+ case MTK_ETH_PATH_GMAC3_USXGMII:
|
|
+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
|
|
+ mac_id = MTK_GMAC3_ID;
|
|
+ break;
|
|
+ default:
|
|
+ updated = false;
|
|
+ };
|
|
+
|
|
+ if (updated) {
|
|
+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
|
|
+ SYSCFG0_SGMII_MASK, val);
|
|
+
|
|
+ if (mac_id == MTK_GMAC2_ID)
|
|
+ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
|
|
+ MUX_G2_USXGMII_SEL);
|
|
+ }
|
|
+
|
|
+ dev_dbg(eth->dev, "path %s in %s updated = %d\n",
|
|
+ mtk_eth_path_name(path), __func__, updated);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
|
|
{
|
|
unsigned int val = 0;
|
|
bool updated = true;
|
|
@@ -207,6 +256,9 @@ static int set_mux_gmac12_to_gephy_sgmii
|
|
case MTK_ETH_PATH_GMAC2_SGMII:
|
|
val |= SYSCFG0_SGMII_GMAC2_V2;
|
|
break;
|
|
+ case MTK_ETH_PATH_GMAC3_SGMII:
|
|
+ val |= SYSCFG0_SGMII_GMAC3_V2;
|
|
+ break;
|
|
default:
|
|
updated = false;
|
|
}
|
|
@@ -245,7 +297,15 @@ static const struct mtk_eth_muxc mtk_eth
|
|
}, {
|
|
.name = "mux_gmac12_to_gephy_sgmii",
|
|
.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
|
|
- .set_path = set_mux_gmac12_to_gephy_sgmii,
|
|
+ .set_path = set_mux_gmac123_to_gephy_sgmii,
|
|
+ }, {
|
|
+ .name = "mux_gmac123_to_gephy_sgmii",
|
|
+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
|
|
+ .set_path = set_mux_gmac123_to_gephy_sgmii,
|
|
+ }, {
|
|
+ .name = "mux_gmac123_to_usxgmii",
|
|
+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
|
|
+ .set_path = set_mux_gmac123_to_usxgmii,
|
|
},
|
|
};
|
|
|
|
@@ -278,12 +338,25 @@ out:
|
|
return err;
|
|
}
|
|
|
|
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
|
+{
|
|
+ u64 path;
|
|
+
|
|
+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII :
|
|
+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII :
|
|
+ MTK_ETH_PATH_GMAC3_USXGMII;
|
|
+
|
|
+ /* Setup proper MUXes along the path */
|
|
+ return mtk_eth_mux_setup(eth, path);
|
|
+}
|
|
+
|
|
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
|
{
|
|
u64 path;
|
|
|
|
- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
|
|
- MTK_ETH_PATH_GMAC2_SGMII;
|
|
+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
|
|
+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
|
|
+ MTK_ETH_PATH_GMAC3_SGMII;
|
|
|
|
/* Setup proper MUXes along the path */
|
|
return mtk_eth_mux_setup(eth, path);
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
@@ -24,6 +24,8 @@
|
|
#include <linux/pinctrl/devinfo.h>
|
|
#include <linux/phylink.h>
|
|
#include <linux/pcs/pcs-mtk-lynxi.h>
|
|
+#include <linux/pcs/pcs.h>
|
|
+#include <linux/phy/phy.h>
|
|
#include <linux/jhash.h>
|
|
#include <linux/bitfield.h>
|
|
#include <net/dsa.h>
|
|
@@ -523,23 +525,28 @@ static void mtk_setup_bridge_switch(stru
|
|
MTK_GSW_CFG);
|
|
}
|
|
|
|
-static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
|
|
- phy_interface_t interface)
|
|
+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
|
|
{
|
|
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
|
- phylink_config);
|
|
- struct mtk_eth *eth = mac->hw;
|
|
- unsigned int sid;
|
|
+ u32 mac_fsm, gdm_fsm;
|
|
|
|
- if (interface == PHY_INTERFACE_MODE_SGMII ||
|
|
- phy_interface_mode_is_8023z(interface)) {
|
|
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
|
- 0 : mac->id;
|
|
+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
|
|
|
|
- return eth->sgmii_pcs[sid];
|
|
- }
|
|
+ switch (mac->id) {
|
|
+ case MTK_GMAC2_ID:
|
|
+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
|
|
+ break;
|
|
+ case MTK_GMAC3_ID:
|
|
+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
|
|
+ break;
|
|
+ default:
|
|
+ return true;
|
|
+ };
|
|
|
|
- return NULL;
|
|
+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
|
|
+ (gdm_fsm & 0xFFFF0000) == 0x00000000)
|
|
+ return true;
|
|
+
|
|
+ return false;
|
|
}
|
|
|
|
static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode,
|
|
@@ -602,6 +609,15 @@ static void mtk_mac_config(struct phylin
|
|
goto init_err;
|
|
}
|
|
break;
|
|
+ case PHY_INTERFACE_MODE_USXGMII:
|
|
+ case PHY_INTERFACE_MODE_10GBASER:
|
|
+ case PHY_INTERFACE_MODE_5GBASER:
|
|
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
|
|
+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
|
|
+ if (err)
|
|
+ goto init_err;
|
|
+ }
|
|
+ break;
|
|
case PHY_INTERFACE_MODE_INTERNAL:
|
|
if (mac->id == MTK_GMAC2_ID &&
|
|
MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
|
|
@@ -655,8 +671,6 @@ static void mtk_mac_config(struct phylin
|
|
val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
|
|
val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
|
|
regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
|
|
-
|
|
- mac->interface = state->interface;
|
|
}
|
|
|
|
/* SGMII */
|
|
@@ -673,9 +687,12 @@ static void mtk_mac_config(struct phylin
|
|
|
|
/* Save the syscfg0 value for mac_finish */
|
|
mac->syscfg0 = val;
|
|
- } else if (phylink_autoneg_inband(mode)) {
|
|
+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
|
|
+ state->interface != PHY_INTERFACE_MODE_10GBASER &&
|
|
+ state->interface != PHY_INTERFACE_MODE_5GBASER &&
|
|
+ phylink_autoneg_inband(mode)) {
|
|
dev_err(eth->dev,
|
|
- "In-band mode not supported in non SGMII mode!\n");
|
|
+ "In-band mode not supported in non-SerDes modes!\n");
|
|
return;
|
|
}
|
|
|
|
@@ -686,8 +703,22 @@ static void mtk_mac_config(struct phylin
|
|
|
|
if (mac->id == MTK_GMAC1_ID)
|
|
mtk_setup_bridge_switch(eth);
|
|
+ } else if (mtk_is_netsys_v3_or_greater(eth)) {
|
|
+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
|
|
+
|
|
+ /* FIXME: In current hardware design, we have to reset FE
|
|
+ * when swtiching XGDM to GDM. Therefore, here trigger an SER
|
|
+ * to let GDM go back to the initial state.
|
|
+ */
|
|
+ if ((mtk_interface_mode_is_xgmii(eth, mac->interface) ||
|
|
+ mac->interface == PHY_INTERFACE_MODE_NA) &&
|
|
+ !mtk_check_gmac23_idle(mac) &&
|
|
+ !test_bit(MTK_RESETTING, ð->state))
|
|
+ schedule_work(ð->pending_work);
|
|
}
|
|
|
|
+ mac->interface = state->interface;
|
|
+
|
|
return;
|
|
|
|
err_phy:
|
|
@@ -738,6 +769,9 @@ static void mtk_mac_link_down(struct phy
|
|
mtk_m32(mac->hw,
|
|
MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0,
|
|
MTK_MAC_MCR(mac->id));
|
|
+ if (mtk_is_netsys_v3_or_greater(mac->hw))
|
|
+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0,
|
|
+ MTK_XGMAC_STS(mac->id));
|
|
} else if (mac->id != MTK_GMAC1_ID) {
|
|
/* XGMAC except for built-in switch */
|
|
mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE,
|
|
@@ -956,7 +990,6 @@ static int mtk_mac_enable_tx_lpi(struct
|
|
|
|
static const struct phylink_mac_ops mtk_phylink_ops = {
|
|
.mac_prepare = mtk_mac_prepare,
|
|
- .mac_select_pcs = mtk_mac_select_pcs,
|
|
.mac_config = mtk_mac_config,
|
|
.mac_finish = mtk_mac_finish,
|
|
.mac_link_down = mtk_mac_link_down,
|
|
@@ -4971,7 +5004,8 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
phy_interface_t phy_mode;
|
|
struct phylink *phylink;
|
|
struct mtk_mac *mac;
|
|
- int id, err;
|
|
+ int id, err, count;
|
|
+ unsigned int sid;
|
|
int txqs = 1;
|
|
u32 val;
|
|
|
|
@@ -5042,6 +5076,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD |
|
|
MAC_2500FD;
|
|
mac->phylink_config.lpi_timer_default = 1000;
|
|
+ mac->phylink_config.num_available_pcs = 0;
|
|
|
|
/* MT7623 gmac0 is now missing its speed-specific PLL configuration
|
|
* in its .mac_config method (since state->speed is not valid there.
|
|
@@ -5072,13 +5107,62 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
|
|
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
|
|
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
|
- mac->phylink_config.supported_interfaces);
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
|
- mac->phylink_config.supported_interfaces);
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
|
- mac->phylink_config.supported_interfaces);
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
+
|
|
+ if (mtk_is_netsys_v3_or_greater(mac->hw)) {
|
|
+ __set_bit(PHY_INTERFACE_MODE_5GBASER,
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
+ __set_bit(PHY_INTERFACE_MODE_10GBASER,
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
+ __set_bit(PHY_INTERFACE_MODE_USXGMII,
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
+
|
|
+ err = fwnode_phylink_pcs_parse(of_fwnode_handle(np), NULL, &count);
|
|
+ if (err == -ENODEV) {
|
|
+ err = 0;
|
|
+ goto no_pcs;
|
|
+ }
|
|
+
|
|
+ if (count > 2)
|
|
+ err = -ENOMEM;
|
|
+
|
|
+ if (err)
|
|
+ goto free_netdev;
|
|
+
|
|
+ err = fwnode_phylink_pcs_parse(of_fwnode_handle(np), mac->available_pcs, &count);
|
|
+ if (err)
|
|
+ goto free_netdev;
|
|
+
|
|
+ mac->phylink_config.available_pcs = mac->available_pcs;
|
|
+ mac->phylink_config.num_available_pcs = count;
|
|
+ } else {
|
|
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) {
|
|
+ /* single LynxI PCS used by either GMAC */
|
|
+ if (!test_bit(phy_mode, eth->sgmii_pcs[0]->supported_interfaces))
|
|
+ goto no_pcs;
|
|
+ if (eth->shared_sgmii_used) {
|
|
+ err = -EBUSY;
|
|
+ goto free_netdev;
|
|
+ }
|
|
+ sid = 0;
|
|
+ eth->shared_sgmii_used = true;
|
|
+ } else {
|
|
+ sid = id;
|
|
+ }
|
|
+ mac->phylink_config.available_pcs = ð->sgmii_pcs[sid];
|
|
+ mac->phylink_config.num_available_pcs = 1;
|
|
+ }
|
|
+
|
|
+ phy_interface_or(mac->phylink_config.supported_interfaces,
|
|
+ mac->phylink_config.supported_interfaces,
|
|
+ mac->phylink_config.pcs_interfaces);
|
|
}
|
|
|
|
+no_pcs:
|
|
if (mtk_is_netsys_v3_or_greater(mac->hw) &&
|
|
MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW) &&
|
|
id == MTK_GMAC1_ID) {
|
|
@@ -5088,18 +5172,16 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
phy_interface_zero(mac->phylink_config.supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
|
mac->phylink_config.supported_interfaces);
|
|
+ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
|
|
+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
|
|
+ __set_bit(PHY_INTERFACE_MODE_5GBASER,
|
|
+ mac->phylink_config.supported_interfaces);
|
|
+ __set_bit(PHY_INTERFACE_MODE_10GBASER,
|
|
+ mac->phylink_config.supported_interfaces);
|
|
+ __set_bit(PHY_INTERFACE_MODE_USXGMII,
|
|
+ mac->phylink_config.supported_interfaces);
|
|
}
|
|
|
|
- phylink = phylink_create(&mac->phylink_config,
|
|
- of_fwnode_handle(mac->of_node),
|
|
- phy_mode, &mtk_phylink_ops);
|
|
- if (IS_ERR(phylink)) {
|
|
- err = PTR_ERR(phylink);
|
|
- goto free_netdev;
|
|
- }
|
|
-
|
|
- mac->phylink = phylink;
|
|
-
|
|
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
|
|
id == MTK_GMAC2_ID)
|
|
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
|
@@ -5122,6 +5204,16 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
eth->netdev[id]->irq = eth->irq[MTK_FE_IRQ_SHARED];
|
|
eth->netdev[id]->dev.of_node = np;
|
|
|
|
+ phylink = phylink_create(&mac->phylink_config,
|
|
+ of_fwnode_handle(mac->of_node),
|
|
+ phy_mode, &mtk_phylink_ops);
|
|
+ if (IS_ERR(phylink)) {
|
|
+ err = PTR_ERR(phylink);
|
|
+ goto free_netdev;
|
|
+ }
|
|
+
|
|
+ mac->phylink = phylink;
|
|
+
|
|
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
|
eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
|
|
else
|
|
@@ -5315,7 +5407,8 @@ static int mtk_probe(struct platform_dev
|
|
regmap_write(cci, 0, 3);
|
|
}
|
|
|
|
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
|
|
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) &&
|
|
+ !mtk_is_netsys_v3_or_greater(eth)) {
|
|
err = mtk_sgmii_init(eth);
|
|
|
|
if (err)
|
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
@@ -570,6 +570,7 @@
|
|
#define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
|
|
#define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
|
|
#define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
|
|
+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
|
|
|
|
|
|
/* ethernet subsystem clock register */
|
|
@@ -611,6 +612,7 @@
|
|
#define TOP_MISC_NETSYS_PCS_MUX 0x0
|
|
#define NETSYS_PCS_MUX_MASK GENMASK(1, 0)
|
|
#define MUX_G2_USXGMII_SEL BIT(1)
|
|
+#define MUX_HSGMII1_G1_SEL BIT(0)
|
|
|
|
#define USB_PHY_SWITCH_REG 0x218
|
|
#define QPHY_SEL_MASK GENMASK(1, 0)
|
|
@@ -636,6 +638,8 @@
|
|
#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
|
|
#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
|
|
|
|
+/* Debug Purpose Register */
|
|
+#define MTK_PSE_FQFC_CFG 0x100
|
|
#define MTK_FE_CDM1_FSM 0x220
|
|
#define MTK_FE_CDM2_FSM 0x224
|
|
#define MTK_FE_CDM3_FSM 0x238
|
|
@@ -644,6 +648,11 @@
|
|
#define MTK_FE_CDM6_FSM 0x328
|
|
#define MTK_FE_GDM1_FSM 0x228
|
|
#define MTK_FE_GDM2_FSM 0x22C
|
|
+#define MTK_FE_GDM3_FSM 0x23C
|
|
+#define MTK_FE_PSE_FREE 0x240
|
|
+#define MTK_FE_DROP_FQ 0x244
|
|
+#define MTK_FE_DROP_FC 0x248
|
|
+#define MTK_FE_DROP_PPE 0x24C
|
|
|
|
#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100))
|
|
|
|
@@ -972,6 +981,7 @@ enum mkt_eth_capabilities {
|
|
MTK_RGMII_BIT = 0,
|
|
MTK_TRGMII_BIT,
|
|
MTK_SGMII_BIT,
|
|
+ MTK_USXGMII_BIT,
|
|
MTK_2P5GPHY_BIT,
|
|
MTK_ESW_BIT,
|
|
MTK_GEPHY_BIT,
|
|
@@ -996,6 +1006,8 @@ enum mkt_eth_capabilities {
|
|
MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
|
|
MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
|
|
MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
|
|
+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
|
|
+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
|
|
|
|
/* PATH BITS */
|
|
MTK_ETH_PATH_GMAC1_RGMII_BIT,
|
|
@@ -1005,13 +1017,18 @@ enum mkt_eth_capabilities {
|
|
MTK_ETH_PATH_GMAC2_SGMII_BIT,
|
|
MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
|
|
MTK_ETH_PATH_GMAC2_GEPHY_BIT,
|
|
+ MTK_ETH_PATH_GMAC3_SGMII_BIT,
|
|
MTK_ETH_PATH_GDM1_ESW_BIT,
|
|
+ MTK_ETH_PATH_GMAC1_USXGMII_BIT,
|
|
+ MTK_ETH_PATH_GMAC2_USXGMII_BIT,
|
|
+ MTK_ETH_PATH_GMAC3_USXGMII_BIT,
|
|
};
|
|
|
|
/* Supported hardware group on SoCs */
|
|
#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
|
|
#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
|
|
#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
|
|
+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
|
|
#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT)
|
|
#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
|
|
#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
|
|
@@ -1041,6 +1058,10 @@ enum mkt_eth_capabilities {
|
|
BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
|
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
|
|
BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
|
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \
|
|
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
|
|
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
|
|
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
|
|
|
|
/* Supported path present on SoCs */
|
|
#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
|
@@ -1050,7 +1071,11 @@ enum mkt_eth_capabilities {
|
|
#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
|
#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
|
|
#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
|
+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
|
|
#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
|
|
+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
|
|
+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
|
|
+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
|
|
|
|
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
|
|
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
|
|
@@ -1059,7 +1084,11 @@ enum mkt_eth_capabilities {
|
|
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
|
|
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
|
|
#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
|
|
+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
|
|
#define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
|
|
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
|
|
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
|
|
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
|
|
|
|
/* MUXes present on SoCs */
|
|
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
|
|
@@ -1086,6 +1115,12 @@ enum mkt_eth_capabilities {
|
|
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
|
|
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
|
|
|
|
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \
|
|
+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
|
|
+
|
|
+#define MTK_MUX_GMAC123_TO_USXGMII \
|
|
+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
|
|
+
|
|
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
|
|
|
|
#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
|
@@ -1117,9 +1152,12 @@ enum mkt_eth_capabilities {
|
|
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
|
MTK_RSTCTRL_PPE1 | MTK_SRAM)
|
|
|
|
-#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC2_2P5GPHY | \
|
|
- MTK_MUX_GMAC2_TO_2P5GPHY | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
|
|
- MTK_RSTCTRL_PPE2 | MTK_SRAM)
|
|
+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
|
|
+ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
|
|
+ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
|
|
+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
|
|
+ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
|
|
+ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
|
|
|
|
struct mtk_tx_dma_desc_info {
|
|
dma_addr_t addr;
|
|
@@ -1300,6 +1338,7 @@ struct mtk_eth {
|
|
struct regmap *ethsys;
|
|
struct regmap *infra;
|
|
struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
|
|
+ bool shared_sgmii_used;
|
|
struct regmap *pctl;
|
|
bool hwlro;
|
|
refcount_t dma_refcnt;
|
|
@@ -1366,6 +1405,8 @@ struct mtk_mac {
|
|
struct device_node *of_node;
|
|
struct phylink *phylink;
|
|
struct phylink_config phylink_config;
|
|
+ struct phylink_pcs *current_pcs;
|
|
+ struct phylink_pcs *available_pcs[2];
|
|
struct mtk_eth *hw;
|
|
struct mtk_hw_stats *hw_stats;
|
|
__be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
|
|
@@ -1517,6 +1558,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
|
|
int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
|
|
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
|
|
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
|
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
|
|
|
int mtk_eth_offload_init(struct mtk_eth *eth, u8 id);
|
|
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
|