mirror of
https://git.openwrt.org/openwrt/openwrt.git/
synced 2025-10-06 02:52:47 +02:00
airoha: en7581: Add support for external PHY
This add a pending version of the Airoha PCS driver to add support for External PHY. The Airoha PCS driver will receive some minor modification once we the PCS subsystem will be defined upstream. Add all the required node for GDM2 and GDM4 and enable the PCS config. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
@@ -283,7 +283,7 @@ CONFIG_PCIE_PME=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCS_MTK_LYNXI=y
|
||||
CONFIG_PCS_AIROHA_AN7581=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_PER_VMA_LOCK=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
|
@@ -438,6 +438,48 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pon_pcs: pcs@1fa08000 {
|
||||
compatible = "airoha,an7581-pcs-pon";
|
||||
reg = <0x0 0x1fa08000 0x0 0x1000>,
|
||||
<0x0 0x1fa80000 0x0 0x60>,
|
||||
<0x0 0x1fa80a00 0x0 0x164>,
|
||||
<0x0 0x1fa84000 0x0 0x450>,
|
||||
<0x0 0x1fa85900 0x0 0x338>,
|
||||
<0x0 0x1fa86000 0x0 0x300>,
|
||||
<0x0 0x1fa8a000 0x0 0x1000>,
|
||||
<0x0 0x1fa8b000 0x0 0x1000>;
|
||||
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
|
||||
"multi_sgmii", "usxgmii",
|
||||
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
|
||||
|
||||
resets = <&scuclk EN7581_XPON_MAC_RST>,
|
||||
<&scuclk EN7581_XPON_PHY_RST>;
|
||||
reset-names = "mac", "phy";
|
||||
|
||||
airoha,scu = <&scuclk>;
|
||||
};
|
||||
|
||||
eth_pcs: pcs@1fa09000 {
|
||||
compatible = "airoha,an7581-pcs-eth";
|
||||
reg = <0x0 0x1fa09000 0x0 0x1000>,
|
||||
<0x0 0x1fa70000 0x0 0x60>,
|
||||
<0x0 0x1fa70a00 0x0 0x164>,
|
||||
<0x0 0x1fa74000 0x0 0x450>,
|
||||
<0x0 0x1fa75900 0x0 0x338>,
|
||||
<0x0 0x1fa76000 0x0 0x300>,
|
||||
<0x0 0x1fa7a000 0x0 0x1000>,
|
||||
<0x0 0x1fa7b000 0x0 0x1000>;
|
||||
reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
|
||||
"multi_sgmii", "usxgmii",
|
||||
"hsgmii_rate_adp", "xfi_ana", "xfi_pma";
|
||||
|
||||
resets = <&scuclk EN7581_XSI_MAC_RST>,
|
||||
<&scuclk EN7581_XSI_PHY_RST>;
|
||||
reset-names = "mac", "phy";
|
||||
|
||||
airoha,scu = <&scuclk>;
|
||||
};
|
||||
|
||||
chip_scu: syscon@1fa20000 {
|
||||
compatible = "airoha,en7581-chip-scu", "syscon";
|
||||
reg = <0x0 0x1fa20000 0x0 0x388>;
|
||||
@@ -753,6 +795,22 @@
|
||||
pause;
|
||||
};
|
||||
};
|
||||
|
||||
gdm2: ethernet@2 {
|
||||
compatible = "airoha,eth-mac";
|
||||
reg = <2>;
|
||||
pcs = <&pon_pcs>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gdm4: ethernet@4 {
|
||||
compatible = "airoha,eth-mac";
|
||||
reg = <4>;
|
||||
pcs = <ð_pcs>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
switch: switch@1fb58000 {
|
||||
|
@@ -0,0 +1,26 @@
|
||||
From 5cb5f11469dfcbd7568fbca8b79c0f20a21cfbf5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 10:09:15 +0100
|
||||
Subject: [PATCH 2/9] net: airoha: deassert XSI line on hw init
|
||||
|
||||
In preparation for phylink support, deassert XSI line as we will naw
|
||||
make actual use of them for external PHY/SFP cage support.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1401,6 +1401,10 @@ static int airoha_hw_init(struct platfor
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->xsi_rsts), eth->xsi_rsts);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
msleep(20);
|
||||
err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts);
|
||||
if (err)
|
@@ -0,0 +1,31 @@
|
||||
From ad29054f9b0e96e30a5d0bb6967d1204b8ea8bd1 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 10:12:02 +0100
|
||||
Subject: [PATCH 3/9] net: airoha: add reference for SPORT GDM4 in
|
||||
qdma_get_gdm_port
|
||||
|
||||
Add SPORT reference in get gdm port as the on receive the SPORT 0x18 is
|
||||
assigned for the GDM4 port.
|
||||
|
||||
While at it also add comments to better identify GDM1 ports.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -605,8 +605,11 @@ static int airoha_qdma_get_gdm_port(stru
|
||||
|
||||
sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
|
||||
switch (sport) {
|
||||
+ case 0x18:
|
||||
+ port = 3; /* GDM4 */
|
||||
+ break;
|
||||
case 0x10 ... 0x14:
|
||||
- port = 0;
|
||||
+ port = 0; /* GDM1 */
|
||||
break;
|
||||
case 0x2 ... 0x4:
|
||||
port = sport - 1;
|
@@ -0,0 +1,52 @@
|
||||
From 6fbb7d72520393a3d447399799d436f17c03ff24 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 10:29:52 +0100
|
||||
Subject: [PATCH 5/9] net: airoha: drop redundant GDM3/4 define
|
||||
|
||||
The GDM FWD register are all the same hence it's redundant to have
|
||||
specific define for GDM3 and GDM4. Drop the redundant define and use the
|
||||
generic macro.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 8 +-------
|
||||
2 files changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -507,8 +507,8 @@ static int airoha_fe_init(struct airoha_
|
||||
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
|
||||
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
|
||||
|
||||
- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK);
|
||||
- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN);
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -128,6 +128,7 @@
|
||||
GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3))
|
||||
|
||||
#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n)
|
||||
+#define GDM_PAD_EN BIT(28)
|
||||
#define GDM_DROP_CRC_ERR BIT(23)
|
||||
#define GDM_IP4_CKSUM BIT(22)
|
||||
#define GDM_TCP_CKSUM BIT(21)
|
||||
@@ -349,13 +350,6 @@
|
||||
#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25)
|
||||
#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17)
|
||||
|
||||
-#define REG_GDM3_FWD_CFG GDM3_BASE
|
||||
-#define GDM3_PAD_EN_MASK BIT(28)
|
||||
-
|
||||
-#define REG_GDM4_FWD_CFG GDM4_BASE
|
||||
-#define GDM4_PAD_EN_MASK BIT(28)
|
||||
-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8)
|
||||
-
|
||||
#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c)
|
||||
#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16)
|
||||
#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12)
|
@@ -0,0 +1,40 @@
|
||||
From a3cd6eb3259282a68b608fc923121460c0d3d2f7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 10:35:41 +0100
|
||||
Subject: [PATCH 6/9] net: airoha: add initial fixup for GDM3/4 port support
|
||||
|
||||
GDM3 and GDM4 require different configuration for max long frame
|
||||
definition, needs the QDMA to strip CRC on RX and require the SPORT to
|
||||
be enabled to correctly be identified.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 12 ++++++++++--
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 1 +
|
||||
2 files changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -507,8 +507,10 @@ static int airoha_fe_init(struct airoha_
|
||||
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
|
||||
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
|
||||
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN);
|
||||
- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3),
|
||||
+ GDM_PAD_EN | GDM_STRIP_CRC);
|
||||
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4),
|
||||
+ GDM_PAD_EN | GDM_STRIP_CRC);
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
@@ -1643,7 +1645,8 @@ static int airoha_dev_open(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (netdev_uses_dsa(dev))
|
||||
+ /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */
|
||||
+ if (netdev_uses_dsa(dev) || port->id > 2)
|
||||
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
else
|
@@ -0,0 +1,44 @@
|
||||
From fecb65813ddf52abf310bc2227a0ac869dc897d1 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Wed, 29 Jan 2025 14:47:41 +0100
|
||||
Subject: [PATCH 1/3] airoha: ethernet: drop xsi-mac reset
|
||||
|
||||
In preparation for support for Ethernet and PON PCS, drop the xsi-mac
|
||||
reset from airoha_eth. This reset is related to the Ethernet PCS and
|
||||
should be handled in the dedicated driver.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++-----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
|
||||
2 files changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2948,11 +2948,10 @@ static int airoha_probe(struct platform_
|
||||
return err;
|
||||
}
|
||||
|
||||
- eth->xsi_rsts[0].id = "xsi-mac";
|
||||
- eth->xsi_rsts[1].id = "hsi0-mac";
|
||||
- eth->xsi_rsts[2].id = "hsi1-mac";
|
||||
- eth->xsi_rsts[3].id = "hsi-mac";
|
||||
- eth->xsi_rsts[4].id = "xfp-mac";
|
||||
+ eth->xsi_rsts[0].id = "hsi0-mac";
|
||||
+ eth->xsi_rsts[1].id = "hsi1-mac";
|
||||
+ eth->xsi_rsts[2].id = "hsi-mac";
|
||||
+ eth->xsi_rsts[3].id = "xfp-mac";
|
||||
err = devm_reset_control_bulk_get_exclusive(eth->dev,
|
||||
ARRAY_SIZE(eth->xsi_rsts),
|
||||
eth->xsi_rsts);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -21,7 +21,7 @@
|
||||
#define AIROHA_MAX_NUM_IRQ_BANKS 4
|
||||
#define AIROHA_MAX_DSA_PORTS 7
|
||||
#define AIROHA_MAX_NUM_RSTS 3
|
||||
-#define AIROHA_MAX_NUM_XSI_RSTS 5
|
||||
+#define AIROHA_MAX_NUM_XSI_RSTS 4
|
||||
#define AIROHA_MAX_MTU 9216
|
||||
#define AIROHA_MAX_PACKET_SIZE 2048
|
||||
#define AIROHA_NUM_QOS_CHANNELS 4
|
@@ -0,0 +1,64 @@
|
||||
From d5fb4ad1beec53ca5d3b44d9b88598ed4ab0b34d Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 9 May 2025 16:36:22 +0200
|
||||
Subject: [PATCH 1/6] net: phylink: add .pcs_link_down PCS OP
|
||||
|
||||
Permit for PCS driver to define specific operation to torn down the link
|
||||
between the MAC and the PCS.
|
||||
|
||||
This might be needed for some PCS that reset counter or require special
|
||||
reset to correctly work if the link needs to be restored later.
|
||||
|
||||
On phylink_link_down() call, the additional phylink_pcs_link_down() will
|
||||
be called before .mac_link_down to torn down the link.
|
||||
|
||||
PCS driver will need to define .pcs_link_down to make use of this.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 8 ++++++++
|
||||
include/linux/phylink.h | 2 ++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -1041,6 +1041,12 @@ static void phylink_pcs_link_up(struct p
|
||||
pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
|
||||
}
|
||||
|
||||
+static void phylink_pcs_link_down(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ if (pcs && pcs->ops->pcs_link_down)
|
||||
+ pcs->ops->pcs_link_down(pcs);
|
||||
+}
|
||||
+
|
||||
static void phylink_pcs_poll_stop(struct phylink *pl)
|
||||
{
|
||||
if (pl->cfg_link_an_mode == MLO_AN_INBAND)
|
||||
@@ -1454,6 +1460,8 @@ static void phylink_link_down(struct phy
|
||||
|
||||
if (ndev)
|
||||
netif_carrier_off(ndev);
|
||||
+ phylink_pcs_link_down(pl->pcs);
|
||||
+
|
||||
pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
|
||||
pl->cur_interface);
|
||||
phylink_info(pl, "Link is Down\n");
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -430,6 +430,7 @@ struct phylink_pcs {
|
||||
* (where necessary).
|
||||
* @pcs_pre_init: configure PCS components necessary for MAC hardware
|
||||
* initialization e.g. RX clock for stmmac.
|
||||
+ * @pcs_link_down: torn down link between MAC and PCS.
|
||||
*/
|
||||
struct phylink_pcs_ops {
|
||||
int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
|
||||
@@ -450,6 +451,7 @@ struct phylink_pcs_ops {
|
||||
void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
int (*pcs_pre_init)(struct phylink_pcs *pcs);
|
||||
+ void (*pcs_link_down)(struct phylink_pcs *pcs);
|
||||
};
|
||||
|
||||
#if 0 /* For kernel-doc purposes only. */
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
||||
From bdcad9ab6b0f071e8492d88064a58323d7155aa7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 13:23:13 +0100
|
||||
Subject: [PATCH] net: airoha: add phylink support for GDM2/4
|
||||
|
||||
Add phylink support for GDM2/4 port that require configuration of the
|
||||
PCS to make the external PHY or attached SFP cage work.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 133 ++++++++++++++++++++++
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 4 +
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 12 ++
|
||||
3 files changed, 149 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/tcp.h>
|
||||
+#include <linux/pcs/pcs-airoha.h>
|
||||
#include <linux/u64_stats_sync.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/page_pool/helpers.h>
|
||||
@@ -71,6 +72,11 @@ static void airoha_qdma_irq_disable(stru
|
||||
airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
|
||||
}
|
||||
|
||||
+static bool airhoa_is_phy_external(struct airoha_gdm_port *port)
|
||||
+{
|
||||
+ return port->id != 1;
|
||||
+}
|
||||
+
|
||||
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||
{
|
||||
struct airoha_eth *eth = port->qdma->eth;
|
||||
@@ -1640,6 +1646,17 @@ static int airoha_dev_open(struct net_de
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
|
||||
+ if (err) {
|
||||
+ netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
|
||||
+ err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ phylink_start(port->phylink);
|
||||
+ }
|
||||
+
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
if (err)
|
||||
@@ -1693,6 +1710,11 @@ static int airoha_dev_stop(struct net_de
|
||||
}
|
||||
}
|
||||
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ phylink_stop(port->phylink);
|
||||
+ phylink_disconnect_phy(port->phylink);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2781,6 +2803,20 @@ static const struct ethtool_ops airoha_e
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
};
|
||||
|
||||
+static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port,
|
||||
+ phylink_config);
|
||||
+
|
||||
+ return port->pcs;
|
||||
+}
|
||||
+
|
||||
+static void airoha_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
+ const struct phylink_link_state *state)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
|
||||
{
|
||||
int i;
|
||||
@@ -2825,6 +2861,99 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
return false;
|
||||
}
|
||||
|
||||
+static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
|
||||
+ unsigned int mode, phy_interface_t interface,
|
||||
+ int speed, int duplex, bool tx_pause, bool rx_pause)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port,
|
||||
+ phylink_config);
|
||||
+ struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_eth *eth = qdma->eth;
|
||||
+ u32 frag_size_tx, frag_size_rx;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_10000:
|
||||
+ case SPEED_5000:
|
||||
+ frag_size_tx = 8;
|
||||
+ frag_size_rx = 8;
|
||||
+ break;
|
||||
+ case SPEED_2500:
|
||||
+ frag_size_tx = 2;
|
||||
+ frag_size_rx = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ frag_size_tx = 1;
|
||||
+ frag_size_rx = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Configure TX/RX frag based on speed */
|
||||
+ if (port->id == 4) {
|
||||
+ airoha_fe_rmw(eth, REG_GDMA4_TMBI_FRAG, GDMA4_SGMII0_TX_FRAG_SIZE,
|
||||
+ FIELD_PREP(GDMA4_SGMII0_TX_FRAG_SIZE, frag_size_tx));
|
||||
+
|
||||
+ airoha_fe_rmw(eth, REG_GDMA4_RMBI_FRAG, GDMA4_SGMII0_RX_FRAG_SIZE,
|
||||
+ FIELD_PREP(GDMA4_SGMII0_RX_FRAG_SIZE, frag_size_rx));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_mac_ops airoha_phylink_ops = {
|
||||
+ .mac_select_pcs = airoha_phylink_mac_select_pcs,
|
||||
+ .mac_config = airoha_mac_config,
|
||||
+ .mac_link_up = airoha_mac_link_up,
|
||||
+ .mac_link_down = airoha_mac_link_down,
|
||||
+};
|
||||
+
|
||||
+static int airoha_setup_phylink(struct net_device *dev)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
+ struct device_node *np = dev->dev.of_node;
|
||||
+ phy_interface_t phy_mode;
|
||||
+ struct phylink *phylink;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_get_phy_mode(np, &phy_mode);
|
||||
+ if (err) {
|
||||
+ dev_err(&dev->dev, "incorrect phy-mode\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ port->phylink_config.dev = &dev->dev;
|
||||
+ port->phylink_config.type = PHYLINK_NETDEV;
|
||||
+ port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
|
||||
+ MAC_5000FD | MAC_10000FD;
|
||||
+
|
||||
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
+ port->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
+ port->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
+ port->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_USXGMII,
|
||||
+ port->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_10GBASER,
|
||||
+ port->phylink_config.supported_interfaces);
|
||||
+
|
||||
+ port->pcs = airoha_pcs_create(&dev->dev);
|
||||
+ if (IS_ERR(port->pcs))
|
||||
+ return PTR_ERR(port->pcs);
|
||||
+
|
||||
+ phylink = phylink_create(&port->phylink_config,
|
||||
+ of_fwnode_handle(np),
|
||||
+ phy_mode, &airoha_phylink_ops);
|
||||
+ if (IS_ERR(phylink))
|
||||
+ return PTR_ERR(phylink);
|
||||
+
|
||||
+ port->phylink = phylink;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
struct device_node *np, int index)
|
||||
{
|
||||
@@ -2903,6 +3032,12 @@ static int airoha_alloc_gdm_port(struct
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ err = airoha_setup_phylink(dev);
|
||||
+ if (err)
|
||||
+ goto free_metadata_dst;
|
||||
+ }
|
||||
+
|
||||
err = register_netdev(dev);
|
||||
if (err)
|
||||
goto free_metadata_dst;
|
||||
@@ -3006,6 +3141,10 @@ error_hw_cleanup:
|
||||
if (port && port->dev->reg_state == NETREG_REGISTERED) {
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ phylink_destroy(port->phylink);
|
||||
+ airoha_pcs_destroy(port->pcs);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
@@ -3033,6 +3172,10 @@ static void airoha_remove(struct platfor
|
||||
airoha_dev_stop(port->dev);
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
+ if (airhoa_is_phy_external(port)) {
|
||||
+ phylink_destroy(port->phylink);
|
||||
+ airoha_pcs_destroy(port->pcs);
|
||||
+ }
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -528,6 +528,10 @@ struct airoha_gdm_port {
|
||||
struct net_device *dev;
|
||||
int id;
|
||||
|
||||
+ struct phylink *phylink;
|
||||
+ struct phylink_config phylink_config;
|
||||
+ struct phylink_pcs *pcs;
|
||||
+
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -361,6 +361,18 @@
|
||||
#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5)
|
||||
#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0)
|
||||
|
||||
+#define REG_GDMA4_TMBI_FRAG 0x2028
|
||||
+#define GDMA4_SGMII1_TX_WEIGHT GENMASK(31, 26)
|
||||
+#define GDMA4_SGMII1_TX_FRAG_SIZE GENMASK(25, 16)
|
||||
+#define GDMA4_SGMII0_TX_WEIGHT GENMASK(15, 10)
|
||||
+#define GDMA4_SGMII0_TX_FRAG_SIZE GENMASK(9, 0)
|
||||
+
|
||||
+#define REG_GDMA4_RMBI_FRAG 0x202c
|
||||
+#define GDMA4_SGMII1_RX_WEIGHT GENMASK(31, 26)
|
||||
+#define GDMA4_SGMII1_RX_FRAG_SIZE GENMASK(25, 16)
|
||||
+#define GDMA4_SGMII0_RX_WEIGHT GENMASK(15, 10)
|
||||
+#define GDMA4_SGMII0_RX_FRAG_SIZE GENMASK(9, 0)
|
||||
+
|
||||
#define REG_MC_VLAN_EN 0x2100
|
||||
#define MC_VLAN_EN_MASK BIT(0)
|
||||
|
Reference in New Issue
Block a user