This series brings a variety of fixes and enhancements for mtk_eth_soc,
adds support for the MT7981 SoC and facilitates sharing the SGMII PCS
code between mtk_eth_soc and mt7530.
Also prepare support for MT7988 which has been done while net-next was
closed.
Note that this series depends on commit 697c3892d825
("regmap: apply reg_base and reg_downshift for single register ops") to
not break mt7530 pcs register access.
For SGMII and 1000Base-X mode to work well it also depends on commit
193250ace270 ("net: ethernet: mtk_eth_soc: fix RX data corruption issue")
which has already been merged via the net tree.
The whole series has been tested on MT7622+MT7531 (BPi-R64),
MT7623+MT7530 (BPi-R2), MT7981+GPY211 (GL.iNet GL-MT3000) and
MT7986+MT7531 (BPi-R3). On the BananaPi R3 a variete of SFP modules
have been tested, all of them (some SGMII with PHY, others 2500Base-X
or 1000Base-X without PHY) are working well now.
Changes since v11:
* remove patch "net: ethernet: mtk_eth_soc: fix RX data corruption issue"
as it has already been merged via net tree
* add commits fixing 1000Base-X and 2500Base-X modes after phylink_pcs
conversion
* completely remove mtk_sgmii.c as only about 20 lines were left in that
file
* Add commits from Lorenzo for MT7988 as requested by him
Changes since v10:
* improve mediatek,mt7981-eth dt-bindings
* use regmap_set_bits instead of regmap_update_bits where possible
* completely remove mtk_sgmii.c
* no need to keep struct mtk_sgmii either as it had only a single
element
Changes since v9:
* fix path in mediatek,sgmiisys dt-binding
Changes since v8:
* move mediatek,sgmiisys dt-bindings to correct net/pcs folder
* rebase on top of net-next/main so series applies cleanly again
Changes since v7:
* move mediatek,sgmiisys.yaml to more appropriate folder
* don't include <linux/phylink.h> twice in PCS driver, sort includes
Changes since v6:
* label MAC MCR bit 12 in 08/12, MediaTek replied explaining its function
Changes since v5:
* drop dev pointer also from struct mtk_sgmii, pass it as function
parameter instead
* address comments left for dt-bindings
* minor improvements to commit messages
Changes since v4:
* remove unused dev pointer in struct pcs_mtk_lynxi
* squash link timer check into correct follow-up patch
Changes since v3:
* remove unused #define's
* use BMCR_* instead of #define'ing our own constants
* return before changing registers in case of invalid link timer
Changes since v2:
* improve dt-bindings, convert sgmisys bindings to dt-schema yaml
* fix typo
Changes since v1:
* apply reverse xmas tree everywhere
* improve commit descriptions
* add dt binding documentation
* various small changes addressing all comments received for v1
Daniel Golle (13):
net: ethernet: mtk_eth_soc: add support for MT7981 SoC
dt-bindings: net: mediatek,net: add mt7981-eth binding
dt-bindings: arm: mediatek: sgmiisys: Convert to DT schema
dt-bindings: arm: mediatek: sgmiisys: add MT7981 SoC
net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
net: ethernet: mtk_eth_soc: reset PCS state
net: ethernet: mtk_eth_soc: only write values if needed
net: ethernet: mtk_eth_soc: fix 1000Base-X and 2500Base-X modes
net: ethernet: mediatek: Fix SerDes link status if not in SGMII mode
net: ethernet: mtk_eth_soc: ppe: add support for flow accounting
net: pcs: add driver for MediaTek SGMII PCS
net: ethernet: mtk_eth_soc: switch to external PCS driver
net: dsa: mt7530: use external PCS driver
Lorenzo Bianconi (6):
net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability bit
net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
net: ethernet: mtk_eth_soc: rely on num_devs and remove MTK_MAC_COUNT
net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability bit
net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data struct to u64
net: ethernet: mtk_eth_soc: add support for MT7988 SoC
.../arm/mediatek/mediatek,sgmiisys.txt | 27 --
.../devicetree/bindings/net/mediatek,net.yaml | 53 ++-
.../bindings/net/pcs/mediatek,sgmiisys.yaml | 55 +++
MAINTAINERS | 7 +
drivers/net/dsa/Kconfig | 1 +
drivers/net/dsa/mt7530.c | 277 +++--------
drivers/net/dsa/mt7530.h | 47 +-
drivers/net/ethernet/mediatek/Kconfig | 2 +
drivers/net/ethernet/mediatek/Makefile | 2 +-
drivers/net/ethernet/mediatek/mtk_eth_path.c | 36 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 448 +++++++++++++++---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 301 ++++++++----
drivers/net/ethernet/mediatek/mtk_ppe.c | 114 ++++-
drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +-
.../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +-
.../net/ethernet/mediatek/mtk_ppe_offload.c | 8 +
drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +
drivers/net/ethernet/mediatek/mtk_sgmii.c | 203 --------
drivers/net/pcs/Kconfig | 7 +
drivers/net/pcs/Makefile | 1 +
drivers/net/pcs/pcs-mtk-lynxi.c | 308 ++++++++++++
include/linux/pcs/pcs-mtk-lynxi.h | 13 +
22 files changed, 1266 insertions(+), 692 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
base-commit: 36e5e391a25af28dc1f4586f95d577b38ff4ed72
--
2.39.2
Daniel Golle (13):
net: ethernet: mtk_eth_soc: add support for MT7981 SoC
dt-bindings: net: mediatek,net: add mt7981-eth binding
dt-bindings: arm: mediatek: sgmiisys: Convert to DT schema
dt-bindings: arm: mediatek: sgmiisys: add MT7981 SoC
net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
net: ethernet: mtk_eth_soc: reset PCS state
net: ethernet: mtk_eth_soc: only write values if needed
net: ethernet: mtk_eth_soc: fix 1000Base-X and 2500Base-X modes
net: ethernet: mtk_eth_soc: Fix link status for none-SGMII modes
net: ethernet: mtk_eth_soc: ppe: add support for flow accounting
net: pcs: add driver for MediaTek SGMII PCS
net: ethernet: mtk_eth_soc: switch to external PCS driver
net: dsa: mt7530: use external PCS driver
Lorenzo Bianconi (5):
net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability bit
net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
net: ethernet: mtk_eth_soc: rely on num_devs and remove MTK_MAC_COUNT
net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability bit
net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data struct to u64
.../arm/mediatek/mediatek,sgmiisys.txt | 27 --
.../devicetree/bindings/net/mediatek,net.yaml | 53 ++-
.../bindings/net/pcs/mediatek,sgmiisys.yaml | 55 +++
MAINTAINERS | 7 +
drivers/net/dsa/Kconfig | 1 +
drivers/net/dsa/mt7530.c | 277 ++++-----------
drivers/net/dsa/mt7530.h | 47 +--
drivers/net/ethernet/mediatek/Kconfig | 2 +
drivers/net/ethernet/mediatek/Makefile | 2 +-
drivers/net/ethernet/mediatek/mtk_eth_path.c | 36 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 314 ++++++++++++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 207 ++++++------
drivers/net/ethernet/mediatek/mtk_ppe.c | 114 ++++++-
drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +-
.../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +-
.../net/ethernet/mediatek/mtk_ppe_offload.c | 8 +
drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +
drivers/net/ethernet/mediatek/mtk_sgmii.c | 203 -----------
drivers/net/pcs/Kconfig | 7 +
drivers/net/pcs/Makefile | 1 +
drivers/net/pcs/pcs-mtk-lynxi.c | 308 +++++++++++++++++
include/linux/pcs/pcs-mtk-lynxi.h | 13 +
22 files changed, 1051 insertions(+), 679 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
base-commit: 36e5e391a25af28dc1f4586f95d577b38ff4ed72
--
2.39.2
The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like
MT7986.
In addition MT7981 is equipped with a built-in 1000Base-T PHY which can
be used with GMAC1.
As many MT7981 boards make use of inverting SGMII signal polarity, add
new device-tree attribute 'mediatek,pn_swap' to support them.
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 31 ++++++++++++++++++++
drivers/net/ethernet/mediatek/mtk_sgmii.c | 10 +++++++
4 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 72648535a14d..317e447f4991 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
{
- unsigned int val = 0;
+ unsigned int val = 0, mask = 0, reg = 0;
bool updated = true;
switch (path) {
case MTK_ETH_PATH_GMAC2_SGMII:
- val = CO_QPHY_SEL;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
+ reg = USB_PHY_SWITCH_REG;
+ val = SGMII_QPHY_SEL;
+ mask = QPHY_SEL_MASK;
+ } else {
+ reg = INFRA_MISC2;
+ val = CO_QPHY_SEL;
+ mask = val;
+ }
break;
default:
updated = false;
@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
}
if (updated)
- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
+ regmap_update_bits(eth->infra, reg, mask, val);
dev_dbg(eth->dev, "path %s in %s updated = %d\n",
mtk_eth_path_name(path), __func__, updated);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 14be6ea51b88..cfb15a84b894 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4860,6 +4860,26 @@ static const struct mtk_soc_data mt7629_data = {
},
};
+static const struct mtk_soc_data mt7981_data = {
+ .reg_map = &mt7986_reg_map,
+ .ana_rgc3 = 0x128,
+ .caps = MT7981_CAPS,
+ .hw_features = MTK_HW_FEATURES,
+ .required_clks = MT7981_CLKS_BITMAP,
+ .required_pctl = false,
+ .offload_version = 2,
+ .hash_offset = 4,
+ .foe_entry_size = sizeof(struct mtk_foe_entry),
+ .txrx = {
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+ .dma_len_offset = 8,
+ },
+};
+
static const struct mtk_soc_data mt7986_data = {
.reg_map = &mt7986_reg_map,
.ana_rgc3 = 0x128,
@@ -4902,6 +4922,7 @@ const struct of_device_id of_mtk_match[] = {
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
{ .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
{},
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index afc9d52e79bf..7230dcb29315 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -551,11 +551,22 @@
#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
#define SGMII_PHYA_PWD BIT(4)
+/* Register to QPHY wrapper control */
+#define SGMSYS_QPHY_WRAP_CTRL 0xec
+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
+
/* Infrasys subsystem config registers */
#define INFRA_MISC2 0x70c
#define CO_QPHY_SEL BIT(0)
#define GEPHY_MAC_SEL BIT(1)
+/* Top misc registers */
+#define USB_PHY_SWITCH_REG 0x218
+#define QPHY_SEL_MASK GENMASK(1, 0)
+#define SGMII_QPHY_SEL 0x2
+
/* MT7628/88 specific stuff */
#define MT7628_PDMA_OFFSET 0x0800
#define MT7628_SDM_OFFSET 0x0c00
@@ -736,6 +747,17 @@ enum mtk_clks_map {
BIT(MTK_CLK_SGMII2_CDR_FB) | \
BIT(MTK_CLK_SGMII_CK) | \
BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+ BIT(MTK_CLK_WOCPU0) | \
+ BIT(MTK_CLK_SGMII_TX_250M) | \
+ BIT(MTK_CLK_SGMII_RX_250M) | \
+ BIT(MTK_CLK_SGMII_CDR_REF) | \
+ BIT(MTK_CLK_SGMII_CDR_FB) | \
+ BIT(MTK_CLK_SGMII2_TX_250M) | \
+ BIT(MTK_CLK_SGMII2_RX_250M) | \
+ BIT(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT(MTK_CLK_SGMII2_CDR_FB) | \
+ BIT(MTK_CLK_SGMII_CK))
#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
BIT(MTK_CLK_SGMII_TX_250M) | \
@@ -849,6 +871,7 @@ enum mkt_eth_capabilities {
MTK_NETSYS_V2_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
+ MTK_U3_COPHY_V2_BIT,
/* MUX BITS*/
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -883,6 +906,7 @@ enum mkt_eth_capabilities {
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -955,6 +979,11 @@ enum mkt_eth_capabilities {
MTK_MUX_U3_GMAC2_TO_QPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
+#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
+
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
@@ -1068,12 +1097,14 @@ struct mtk_soc_data {
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
* @interface: Currently configured interface mode
* @pcs: Phylink PCS structure
+ * @flags: Flags indicating hardware properties
*/
struct mtk_pcs {
struct regmap *regmap;
u32 ana_rgc3;
phy_interface_t interface;
struct phylink_pcs pcs;
+ u32 flags;
};
/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index bb00de1003ac..d7ffaaeaf9ab 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -88,6 +88,11 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
+ SGMII_PN_SWAP_MASK,
+ SGMII_PN_SWAP_TX_RX);
+
if (interface == PHY_INTERFACE_MODE_2500BASEX)
rgc3 = RG_PHY_SPEED_3_125G;
else
@@ -182,6 +187,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
ss->pcs[i].ana_rgc3 = ana_rgc3;
ss->pcs[i].regmap = syscon_node_to_regmap(np);
+
+ ss->pcs[i].flags = 0;
+ if (of_property_read_bool(np, "mediatek,pnswap"))
+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
+
of_node_put(np);
if (IS_ERR(ss->pcs[i].regmap))
return PTR_ERR(ss->pcs[i].regmap);
--
2.39.2
Introduce DT bindings for the MT7981 SoC to mediatek,net.yaml.
Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
.../devicetree/bindings/net/mediatek,net.yaml | 53 +++++++++++++++++--
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
index 7ef696204c5a..b7f6474dc5ab 100644
--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
@@ -21,6 +21,7 @@ properties:
- mediatek,mt7623-eth
- mediatek,mt7622-eth
- mediatek,mt7629-eth
+ - mediatek,mt7981-eth
- mediatek,mt7986-eth
- ralink,rt5350-eth
@@ -78,6 +79,11 @@ properties:
description:
List of phandles to wireless ethernet dispatch nodes.
+ mediatek,wed-pcie:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Phandle to the mediatek wed-pcie controller.
+
dma-coherent: true
mdio-bus:
@@ -123,6 +129,8 @@ allOf:
mediatek,wed: false
+ mediatek,wed-pcie: false
+
- if:
properties:
compatible:
@@ -160,6 +168,8 @@ allOf:
description:
Phandle to the mediatek pcie-mirror controller.
+ mediatek,wed-pcie: false
+
- if:
properties:
compatible:
@@ -206,6 +216,44 @@ allOf:
mediatek,wed: false
+ mediatek,wed-pcie: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: mediatek,mt7981-eth
+ then:
+ properties:
+ interrupts:
+ minItems: 4
+
+ clocks:
+ minItems: 15
+ maxItems: 15
+
+ clock-names:
+ items:
+ - const: fe
+ - const: gp2
+ - const: gp1
+ - const: wocpu0
+ - const: sgmii_ck
+ - const: sgmii_tx250m
+ - const: sgmii_rx250m
+ - const: sgmii_cdr_ref
+ - const: sgmii_cdr_fb
+ - const: sgmii2_tx250m
+ - const: sgmii2_rx250m
+ - const: sgmii2_cdr_ref
+ - const: sgmii2_cdr_fb
+ - const: netsys0
+ - const: netsys1
+
+ mediatek,sgmiisys:
+ minItems: 2
+ maxItems: 2
+
- if:
properties:
compatible:
@@ -242,11 +290,6 @@ allOf:
minItems: 2
maxItems: 2
- mediatek,wed-pcie:
- $ref: /schemas/types.yaml#/definitions/phandle
- description:
- Phandle to the mediatek wed-pcie controller.
-
patternProperties:
"^mac@[0-1]$":
type: object
--
2.39.2
Convert mediatek,sgmiiisys bindings to DT schema format.
Add maintainer Matthias Brugger, no maintainers were listed in the
original documentation.
As this node is also referenced by the Ethernet controller and used
as SGMII PCS add this fact to the description.
Move the file to Documentation/devicetree/bindings/pcs/ which seems more
appropriate given that the great majority of registers are related to
SGMII PCS functionality and only one register represents clock bits.
Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
.../arm/mediatek/mediatek,sgmiisys.txt | 27 ----------
.../bindings/net/pcs/mediatek,sgmiisys.yaml | 49 +++++++++++++++++++
2 files changed, 49 insertions(+), 27 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
deleted file mode 100644
index d2c24c277514..000000000000
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-MediaTek SGMIISYS controller
-============================
-
-The MediaTek SGMIISYS controller provides various clocks to the system.
-
-Required Properties:
-
-- compatible: Should be:
- - "mediatek,mt7622-sgmiisys", "syscon"
- - "mediatek,mt7629-sgmiisys", "syscon"
- - "mediatek,mt7981-sgmiisys_0", "syscon"
- - "mediatek,mt7981-sgmiisys_1", "syscon"
- - "mediatek,mt7986-sgmiisys_0", "syscon"
- - "mediatek,mt7986-sgmiisys_1", "syscon"
-- #clock-cells: Must be 1
-
-The SGMIISYS controller uses the common clk binding from
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-
-Example:
-
-sgmiisys: sgmiisys@1b128000 {
- compatible = "mediatek,mt7622-sgmiisys", "syscon";
- reg = <0 0x1b128000 0 0x1000>;
- #clock-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
new file mode 100644
index 000000000000..7ce597011a32
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/mediatek,sgmiisys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SGMIISYS Controller
+
+maintainers:
+ - Matthias Brugger <[email protected]>
+
+description:
+ The MediaTek SGMIISYS controller provides a SGMII PCS and some clocks
+ to the ethernet subsystem to which it is attached.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt7622-sgmiisys
+ - mediatek,mt7629-sgmiisys
+ - mediatek,mt7986-sgmiisys_0
+ - mediatek,mt7986-sgmiisys_1
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ sgmiisys: syscon@1b128000 {
+ compatible = "mediatek,mt7622-sgmiisys", "syscon";
+ reg = <0 0x1b128000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+ };
--
2.39.2
Add mediatek,pnswap boolean property needed on many boards using the
MediaTek MT7981 SoC.
Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
.../devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
index 7ce597011a32..66a95191bd77 100644
--- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
@@ -19,6 +19,8 @@ properties:
- enum:
- mediatek,mt7622-sgmiisys
- mediatek,mt7629-sgmiisys
+ - mediatek,mt7981-sgmiisys_0
+ - mediatek,mt7981-sgmiisys_1
- mediatek,mt7986-sgmiisys_0
- mediatek,mt7986-sgmiisys_1
- const: syscon
@@ -29,6 +31,10 @@ properties:
'#clock-cells':
const: 1
+ mediatek,pnswap:
+ description: Invert polarity of the SGMII data lanes
+ type: boolean
+
required:
- compatible
- reg
--
2.39.2
Set MDIO bus clock frequency and allow setting a custom maximum
frequency from device tree.
Reviewed-by: Andrew Lunn <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
Tested-by: Bj?rn Mork <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++
2 files changed, 28 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index cfb15a84b894..030d87c42bd4 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -789,8 +789,10 @@ static const struct phylink_mac_ops mtk_phylink_ops = {
static int mtk_mdio_init(struct mtk_eth *eth)
{
+ unsigned int max_clk = 2500000, divider;
struct device_node *mii_np;
int ret;
+ u32 val;
mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
if (!mii_np) {
@@ -818,6 +820,25 @@ static int mtk_mdio_init(struct mtk_eth *eth)
eth->mii_bus->parent = eth->dev;
snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
+
+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) {
+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
+ dev_err(eth->dev, "MDIO clock frequency out of range");
+ ret = -EINVAL;
+ goto err_put_node;
+ }
+ max_clk = val;
+ }
+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
+
+ /* Configure MDC Divider */
+ val = mtk_r32(eth, MTK_PPSC);
+ val &= ~PPSC_MDC_CFG;
+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
+ mtk_w32(eth, val, MTK_PPSC);
+
+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
+
ret = of_mdiobus_register(eth->mii_bus, mii_np);
err_put_node:
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 7230dcb29315..7014c02ba2d4 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -363,6 +363,13 @@
#define RX_DMA_VTAG_V2 BIT(0)
#define RX_DMA_L4_VALID_V2 BIT(2)
+/* PHY Polling and SMI Master Control registers */
+#define MTK_PPSC 0x10000
+#define PPSC_MDC_CFG GENMASK(29, 24)
+#define PPSC_MDC_TURBO BIT(20)
+#define MDC_MAX_FREQ 25000000
+#define MDC_MAX_DIVIDER 63
+
/* PHY Indirect Access Control registers */
#define MTK_PHY_IAC 0x10004
#define PHY_IAC_ACCESS BIT(31)
--
2.39.2
Reset the internal PCS state machine when changing interface mode.
This prevents confusing the state machine when changing interface
modes, e.g. from SGMII to 2500Base-X or vice-versa.
Reviewed-by: Russell King (Oracle) <[email protected]>
Tested-by: Bj?rn Mork <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 7014c02ba2d4..142def8629c8 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -548,6 +548,10 @@
#define SGMII_SEND_AN_ERROR_EN BIT(11)
#define SGMII_IF_MODE_MASK GENMASK(5, 1)
+/* Register to reset SGMII design */
+#define SGMII_RESERVED_0 0x34
+#define SGMII_SW_RESET BIT(0)
+
/* Register to set SGMII speed, ANA RG_ Control Signals III*/
#define SGMSYS_ANA_RG_CS3 0x2028
#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index d7ffaaeaf9ab..d7e7352041a4 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
+ /* Reset SGMII PCS state */
+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
+ SGMII_SW_RESET, SGMII_SW_RESET);
+
if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
SGMII_PN_SWAP_MASK,
--
2.39.2
Only restart auto-negotiation and write link timer if actually
necessary. This prevents loosing the link in case of minor
changes.
Reviewed-by: Russell King (Oracle) <[email protected]>
Tested-by: Bj?rn Mork <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index d7e7352041a4..61bd9986466a 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
const unsigned long *advertising,
bool permit_pause_to_mac)
{
+ bool mode_changed = false, changed, use_an;
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
unsigned int rgc3, sgm_mode, bmcr;
int advertise, link_timer;
- bool changed, use_an;
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
advertising);
if (advertise < 0)
return advertise;
- link_timer = phylink_get_link_timer_ns(interface);
- if (link_timer < 0)
- return link_timer;
-
/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
* we assume that fixes it's speed at bitrate = line rate (in
* other words, 1000Mbps or 2500Mbps).
@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
}
if (use_an) {
- /* FIXME: Do we need to set AN_RESTART here? */
- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
+ bmcr = SGMII_AN_ENABLE;
} else {
bmcr = 0;
}
if (mpcs->interface != interface) {
+ link_timer = phylink_get_link_timer_ns(interface);
+ if (link_timer < 0)
+ return link_timer;
+
/* PHYA power down */
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
@@ -106,16 +105,17 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
RG_PHY_SPEED_3_125G, rgc3);
+ /* Setup the link timer */
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
+
mpcs->interface = interface;
+ mode_changed = true;
}
/* Update the advertisement, noting whether it has changed */
regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
SGMII_ADVERTISE, advertise, &changed);
- /* Setup the link timer and QPHY power up inside SGMIISYS */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
/* Update the sgmsys mode register */
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
@@ -123,7 +123,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
/* Update the BMCR */
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
+ SGMII_AN_ENABLE, bmcr);
/* Release PHYA power down state
* Only removing bit SGMII_PHYA_PWD isn't enough.
@@ -137,7 +137,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
usleep_range(50, 100);
regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
- return changed;
+ return changed || mode_changed;
}
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
--
2.39.2
After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
would work only after `ethtool -s eth1 autoneg off`.
As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
to control auto-negotiation on the external interface it doesn't make
much sense to use it to control on-board SGMII auto-negotiation between
MAC and PHY.
Set correct values to really only enable SGMII auto-negotiation when
actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
enable remote-fault detection only if in-band-status is enabled.
This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
board and also makes it possible to use interface-mode-switching PHYs
operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
2500M mode on other boards.
Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 61bd9986466a..58d8cb3aa7f4 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -38,9 +38,9 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
const unsigned long *advertising,
bool permit_pause_to_mac)
{
- bool mode_changed = false, changed, use_an;
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3, sgm_mode, bmcr;
+ unsigned int rgc3, sgm_mode = 0, bmcr = 0;
+ bool mode_changed = false, changed;
int advertise, link_timer;
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
@@ -55,27 +55,13 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
if (interface == PHY_INTERFACE_MODE_SGMII) {
sgm_mode = SGMII_IF_MODE_SGMII;
if (phylink_autoneg_inband(mode)) {
+ bmcr = SGMII_AN_ENABLE;
sgm_mode |= SGMII_REMOTE_FAULT_DIS |
SGMII_SPEED_DUPLEX_AN;
- use_an = true;
- } else {
- use_an = false;
}
- } else if (phylink_autoneg_inband(mode)) {
- /* 1000base-X or 2500base-X autoneg */
- sgm_mode = SGMII_REMOTE_FAULT_DIS;
- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
- advertising);
- } else {
+ } else if (!phylink_autoneg_inband(mode)) {
/* 1000base-X or 2500base-X without autoneg */
- sgm_mode = 0;
- use_an = false;
- }
-
- if (use_an) {
- bmcr = SGMII_AN_ENABLE;
- } else {
- bmcr = 0;
+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
}
if (mpcs->interface != interface) {
--
2.39.2
Link partner advertised link modes are not reported by the SerDes
hardware if not operating in SGMII mode. Hence we cannot use
phylink_mii_c22_pcs_decode_state() in this case.
Implement reporting link and an_complete only and use speed according to
the interface mode.
Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_sgmii.c | 26 ++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 58d8cb3aa7f4..98d80007d3bd 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -23,14 +23,30 @@ static void mtk_pcs_get_state(struct phylink_pcs *pcs,
struct phylink_link_state *state)
{
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int bm, adv;
+ unsigned int bm, bmsr, adv;
- /* Read the BMSR and LPA */
+ /* Read the BMSR */
regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+ bmsr = FIELD_GET(SGMII_BMSR, bm);
- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
- FIELD_GET(SGMII_LPA, adv));
+ /* link partner advertised link modes are not reported by the
+ * hardware when not operating in SGMII mode. Hence we cannot
+ * use phylink_mii_c22_pcs_decode_state() in this case.
+ */
+ if (state->interface != PHY_INTERFACE_MODE_SGMII) {
+ state->link = !!(bmsr & BMSR_LSTATUS);
+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
+ state->speed = (state->interface ==
+ PHY_INTERFACE_MODE_2500BASEX) ?
+ SPEED_2500 : SPEED_1000;
+ state->duplex = DUPLEX_FULL;
+
+ return;
+ }
+
+ /* Read LPA and use standard decode function for SGMII mode */
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
}
static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
--
2.39.2
The PPE units found in MT7622 and newer support packet and byte
accounting of hw-offloaded flows. Add support for reading those counters
as found in MediaTek's SDK[1].
[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
Tested-by: Bj?rn Mork <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
drivers/net/ethernet/mediatek/mtk_ppe.c | 114 +++++++++++++++++-
drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +++-
.../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +-
.../net/ethernet/mediatek/mtk_ppe_offload.c | 8 ++
drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++
7 files changed, 172 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 030d87c42bd4..e63e59fc3b19 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4711,8 +4711,8 @@ static int mtk_probe(struct platform_device *pdev)
for (i = 0; i < num_ppe; i++) {
u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
- eth->soc->offload_version, i);
+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
+
if (!eth->ppe[i]) {
err = -ENOMEM;
goto err_deinit_ppe;
@@ -4834,6 +4834,7 @@ static const struct mtk_soc_data mt7622_data = {
.required_pctl = false,
.offload_version = 2,
.hash_offset = 2,
+ .has_accounting = true,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4871,6 +4872,7 @@ static const struct mtk_soc_data mt7629_data = {
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
+ .has_accounting = true,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4891,6 +4893,7 @@ static const struct mtk_soc_data mt7981_data = {
.offload_version = 2,
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
+ .has_accounting = true,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4911,6 +4914,7 @@ static const struct mtk_soc_data mt7986_data = {
.offload_version = 2,
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
+ .has_accounting = true,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 142def8629c8..1c7a51fccc0f 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1069,6 +1069,8 @@ struct mtk_reg_map {
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
* @foe_entry_size Foe table entry size.
+ * @has_accounting Bool indicating support for accounting of
+ * offloaded flows.
* @txd_size Tx DMA descriptor size.
* @rxd_size Rx DMA descriptor size.
* @rx_irq_done_mask Rx irq done register mask.
@@ -1086,6 +1088,7 @@ struct mtk_soc_data {
u8 hash_offset;
u16 foe_entry_size;
netdev_features_t hw_features;
+ bool has_accounting;
struct {
u32 txd_size;
u32 rxd_size;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
index 6883eb34cd8b..c099e8736716 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
return ret;
}
+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
+{
+ int ret;
+ u32 val;
+
+ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
+ !(val & MTK_PPE_MIB_SER_CR_ST),
+ 20, MTK_PPE_WAIT_TIMEOUT_US);
+
+ if (ret)
+ dev_err(ppe->dev, "MIB table busy");
+
+ return ret;
+}
+
+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
+{
+ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
+ u32 val, cnt_r0, cnt_r1, cnt_r2;
+ int ret;
+
+ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
+ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
+
+ ret = mtk_ppe_mib_wait_busy(ppe);
+ if (ret)
+ return ret;
+
+ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
+ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
+ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
+
+ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
+
+ return 0;
+}
+
static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
{
ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
@@ -458,6 +500,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
hwe->ib1 &= ~MTK_FOE_IB1_STATE;
hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
dma_wmb();
+ if (ppe->accounting) {
+ struct mtk_foe_accounting *acct;
+
+ acct = ppe->acct_table + entry->hash * sizeof(*acct);
+ acct->packets = 0;
+ acct->bytes = 0;
+ }
}
entry->hash = 0xffff;
@@ -565,6 +614,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
wmb();
hwe->ib1 = entry->ib1;
+ if (ppe->accounting)
+ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
+
dma_wmb();
mtk_ppe_cache_clear(ppe);
@@ -756,11 +808,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
return mtk_ppe_wait_busy(ppe);
}
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index)
+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
+ struct mtk_foe_accounting *diff)
+{
+ struct mtk_foe_accounting *acct;
+ int size = sizeof(struct mtk_foe_accounting);
+ u64 bytes, packets;
+
+ if (!ppe->accounting)
+ return NULL;
+
+ if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
+ return NULL;
+
+ acct = ppe->acct_table + index * size;
+
+ acct->bytes += bytes;
+ acct->packets += packets;
+
+ if (diff) {
+ diff->bytes = bytes;
+ diff->packets = packets;
+ }
+
+ return acct;
+}
+
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
{
+ bool accounting = eth->soc->has_accounting;
const struct mtk_soc_data *soc = eth->soc;
+ struct mtk_foe_accounting *acct;
struct device *dev = eth->dev;
+ struct mtk_mib_entry *mib;
struct mtk_ppe *ppe;
u32 foe_flow_size;
void *foe;
@@ -777,7 +857,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
ppe->base = base;
ppe->eth = eth;
ppe->dev = dev;
- ppe->version = version;
+ ppe->version = eth->soc->offload_version;
+ ppe->accounting = accounting;
foe = dmam_alloc_coherent(ppe->dev,
MTK_PPE_ENTRIES * soc->foe_entry_size,
@@ -793,6 +874,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
if (!ppe->foe_flow)
goto err_free_l2_flows;
+ if (accounting) {
+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
+ &ppe->mib_phys, GFP_KERNEL);
+ if (!mib)
+ return NULL;
+
+ ppe->mib_table = mib;
+
+ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
+ GFP_KERNEL);
+
+ if (!acct)
+ return NULL;
+
+ ppe->acct_table = acct;
+ }
+
mtk_ppe_debugfs_init(ppe, index);
return ppe;
@@ -922,6 +1020,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
}
+
+ if (ppe->accounting && ppe->mib_phys) {
+ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
+ MTK_PPE_MIB_CFG_EN);
+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
+ MTK_PPE_MIB_CFG_RD_CLR);
+ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
+ MTK_PPE_MIB_CFG_RD_CLR);
+ }
}
int mtk_ppe_stop(struct mtk_ppe *ppe)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
index 5e8bc48252b1..e1aab2e8e262 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -57,6 +57,7 @@ enum {
#define MTK_FOE_IB2_MULTICAST BIT(8)
#define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12)
+#define MTK_FOE_IB2_MIB_CNT BIT(15)
#define MTK_FOE_IB2_WDMA_DEVIDX BIT(16)
#define MTK_FOE_IB2_WDMA_WINFO BIT(17)
@@ -285,16 +286,34 @@ struct mtk_flow_entry {
unsigned long cookie;
};
+struct mtk_mib_entry {
+ u32 byt_cnt_l;
+ u16 byt_cnt_h;
+ u32 pkt_cnt_l;
+ u8 pkt_cnt_h;
+ u8 _rsv0;
+ u32 _rsv1;
+} __packed;
+
+struct mtk_foe_accounting {
+ u64 bytes;
+ u64 packets;
+};
+
struct mtk_ppe {
struct mtk_eth *eth;
struct device *dev;
void __iomem *base;
int version;
char dirname[5];
+ bool accounting;
void *foe_table;
dma_addr_t foe_phys;
+ struct mtk_mib_entry *mib_table;
+ dma_addr_t mib_phys;
+
u16 foe_check_time[MTK_PPE_ENTRIES];
struct hlist_head *foe_flow;
@@ -303,8 +322,8 @@ struct mtk_ppe {
void *acct_table;
};
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index);
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+
void mtk_ppe_deinit(struct mtk_eth *eth);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);
@@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
+ struct mtk_foe_accounting *diff);
#endif
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
index 391b071bcff3..53cf87e9acbb 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
struct mtk_foe_mac_info *l2;
struct mtk_flow_addr_info ai = {};
+ struct mtk_foe_accounting *acct;
unsigned char h_source[ETH_ALEN];
unsigned char h_dest[ETH_ALEN];
int type, state;
@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
if (bind && state != MTK_FOE_STATE_BIND)
continue;
+ acct = mtk_foe_entry_get_mib(ppe, i, NULL);
+
type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
seq_printf(m, "%05x %s %7s", i,
mtk_foe_entry_state_str(state),
@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
*((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
seq_printf(m, " eth=%pM->%pM etype=%04x"
- " vlan=%d,%d ib1=%08x ib2=%08x\n",
+ " vlan=%d,%d ib1=%08x ib2=%08x"
+ " packets=%llu bytes=%llu\n",
h_source, h_dest, ntohs(l2->etype),
- l2->vlan1, l2->vlan2, entry->ib1, ib2);
+ l2->vlan1, l2->vlan2, entry->ib1, ib2,
+ acct ? acct->packets : 0, acct ? acct->bytes : 0);
}
return 0;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
index 81afd5ee3fbf..f02ccffb1e79 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -497,6 +497,7 @@ static int
mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
{
struct mtk_flow_entry *entry;
+ struct mtk_foe_accounting diff;
u32 idle;
entry = rhashtable_lookup(ð->flow_table, &f->cookie,
@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
f->stats.lastused = jiffies - idle * HZ;
+ if (entry->hash != 0xFFFF &&
+ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
+ &diff)) {
+ f->stats.pkts += diff.packets;
+ f->stats.bytes += diff.bytes;
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
index 0fdb983b0a88..a2e61b3eb006 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
@@ -149,6 +149,20 @@ enum {
#define MTK_PPE_MIB_TB_BASE 0x338
+#define MTK_PPE_MIB_SER_CR 0x33C
+#define MTK_PPE_MIB_SER_CR_ST BIT(16)
+#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0)
+
+#define MTK_PPE_MIB_SER_R0 0x340
+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0)
+
+#define MTK_PPE_MIB_SER_R1 0x344
+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16)
+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0)
+
+#define MTK_PPE_MIB_SER_R2 0x348
+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
+
#define MTK_PPE_MIB_CACHE_CTL 0x350
#define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
#define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
--
2.39.2
The SGMII core found in several MediaTek SoCs is identical to what can
also be found in MediaTek's MT7531 Ethernet switch IC.
As this has not always been clear, both drivers developed different
implementations to deal with the PCS.
Recently Alexander Couzens pointed out this fact which lead to the
development of this shared driver.
Add a dedicated driver, mostly by copying the code now found in the
Ethernet driver. The now redundant code will be removed by a follow-up
commit.
Suggested-by: Alexander Couzens <[email protected]>
Suggested-by: Russell King (Oracle) <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
MAINTAINERS | 7 +
drivers/net/pcs/Kconfig | 7 +
drivers/net/pcs/Makefile | 1 +
drivers/net/pcs/pcs-mtk-lynxi.c | 308 ++++++++++++++++++++++++++++++
include/linux/pcs/pcs-mtk-lynxi.h | 13 ++
5 files changed, 336 insertions(+)
create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
diff --git a/MAINTAINERS b/MAINTAINERS
index edd3d562beee..7485315a9c65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13047,6 +13047,14 @@ L: [email protected]
S: Maintained
F: drivers/net/ethernet/mediatek/
+MEDIATEK ETHERNET PCS DRIVER
+M: Alexander Couzens <[email protected]>
+M: Daniel Golle <[email protected]>
+L: [email protected]
+S: Maintained
+F: drivers/net/pcs/pcs-mtk-lynxi.c
+F: include/linux/pcs/pcs-mtk-lynxi.h
+
MEDIATEK I2C CONTROLLER DRIVER
M: Qii Wang <[email protected]>
L: [email protected]
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 6e7e6c346a3e..7c34fb7cbf7b 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -18,6 +18,13 @@ config PCS_LYNX
This module provides helpers to phylink for managing the Lynx PCS
which is part of the Layerscape and QorIQ Ethernet SERDES.
+config PCS_MTK_LYNXI
+ tristate
+ select REGMAP
+ help
+ This module provides helpers to phylink for managing the LynxI PCS
+ which is part of MediaTek's SoC and Ethernet switch ICs.
+
config PCS_RZN1_MIIC
tristate "Renesas RZ/N1 MII converter"
depends on OF && (ARCH_RZN1 || COMPILE_TEST)
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index 4c780d8f2e98..9b9afd6b1c22 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -5,5 +5,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-nxp.o
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o
obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o
diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
new file mode 100644
index 000000000000..ecee351bd646
--- /dev/null
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018-2019 MediaTek Inc.
+/* A library for MediaTek SGMII circuit
+ *
+ * Author: Sean Wang <[email protected]>
+ * Author: Alexander Couzens <[email protected]>
+ * Author: Daniel Golle <[email protected]>
+ *
+ */
+
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/phylink.h>
+#include <linux/regmap.h>
+
+/* SGMII subsystem config registers */
+/* BMCR (low 16) BMSR (high 16) */
+#define SGMSYS_PCS_CONTROL_1 0x0
+#define SGMII_BMCR GENMASK(15, 0)
+#define SGMII_BMSR GENMASK(31, 16)
+
+#define SGMSYS_PCS_DEVICE_ID 0x4
+#define SGMII_LYNXI_DEV_ID 0x4d544950
+
+#define SGMSYS_PCS_ADVERTISE 0x8
+#define SGMII_ADVERTISE GENMASK(15, 0)
+#define SGMII_LPA GENMASK(31, 16)
+
+#define SGMSYS_PCS_SCRATCH 0x14
+#define SGMII_DEV_VERSION GENMASK(31, 16)
+
+/* Register to programmable link timer, the unit in 2 * 8ns */
+#define SGMSYS_PCS_LINK_TIMER 0x18
+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \
+ (ns / 2 / 8))
+
+/* Register to control remote fault */
+#define SGMSYS_SGMII_MODE 0x20
+#define SGMII_IF_MODE_SGMII BIT(0)
+#define SGMII_SPEED_DUPLEX_AN BIT(1)
+#define SGMII_SPEED_MASK GENMASK(3, 2)
+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
+#define SGMII_DUPLEX_HALF BIT(4)
+#define SGMII_REMOTE_FAULT_DIS BIT(8)
+
+/* Register to reset SGMII design */
+#define SGMSYS_RESERVED_0 0x34
+#define SGMII_SW_RESET BIT(0)
+
+/* Register to set SGMII speed, ANA RG_ Control Signals III */
+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2)
+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
+
+/* Register to power up QPHY */
+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
+#define SGMII_PHYA_PWD BIT(4)
+
+/* Register to QPHY wrapper control */
+#define SGMSYS_QPHY_WRAP_CTRL 0xec
+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
+
+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated
+ * data
+ * @regmap: The register map pointing at the range used to setup
+ * SGMII modes
+ * @dev: Pointer to device owning the PCS
+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap
+ * @interface: Currently configured interface mode
+ * @pcs: Phylink PCS structure
+ * @flags: Flags indicating hardware properties
+ */
+struct mtk_pcs_lynxi {
+ struct regmap *regmap;
+ u32 ana_rgc3;
+ phy_interface_t interface;
+ struct phylink_pcs pcs;
+ u32 flags;
+};
+
+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
+{
+ return container_of(pcs, struct mtk_pcs_lynxi, pcs);
+}
+
+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
+ struct phylink_link_state *state)
+{
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+ unsigned int bm, bmsr, adv;
+
+ /* Read the BMSR */
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
+ bmsr = FIELD_GET(SGMII_BMSR, bm);
+
+ /* link partner advertised link modes are not reported by the
+ * hardware when not operating in SGMII mode. Hence we cannot
+ * use phylink_mii_c22_pcs_decode_state() in this case.
+ */
+ if (state->interface != PHY_INTERFACE_MODE_SGMII) {
+ state->link = !!(bmsr & BMSR_LSTATUS);
+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
+ state->speed = (state->interface ==
+ PHY_INTERFACE_MODE_2500BASEX) ?
+ SPEED_2500 : SPEED_1000;
+ state->duplex = DUPLEX_FULL;
+
+ return;
+ }
+
+ /* Read LPA and use standard decode function for SGMII mode */
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+ phylink_mii_c22_pcs_decode_state(state, bmsr,
+ FIELD_GET(SGMII_LPA, adv));
+}
+
+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
+ phy_interface_t interface,
+ const unsigned long *advertising,
+ bool permit_pause_to_mac)
+{
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+ unsigned int rgc3, sgm_mode = 0, bmcr = 0;
+ bool mode_changed = false, changed;
+ int advertise, link_timer;
+
+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+ advertising);
+ if (advertise < 0)
+ return advertise;
+
+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
+ * we assume that fixes it's speed at bitrate = line rate (in
+ * other words, 1000Mbps or 2500Mbps).
+ */
+ if (interface == PHY_INTERFACE_MODE_SGMII) {
+ sgm_mode = SGMII_IF_MODE_SGMII;
+ if (phylink_autoneg_inband(mode)) {
+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
+ SGMII_SPEED_DUPLEX_AN;
+ bmcr = BMCR_ANENABLE;
+ }
+ } else if (!phylink_autoneg_inband(mode)) {
+ /* 1000base-X or 2500base-X without autoneg */
+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
+ }
+
+ if (mpcs->interface != interface) {
+ link_timer = phylink_get_link_timer_ns(interface);
+ if (link_timer < 0)
+ return link_timer;
+
+ /* PHYA power down */
+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
+ SGMII_PHYA_PWD);
+
+ /* Reset SGMII PCS state */
+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
+ SGMII_SW_RESET);
+
+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
+ SGMII_PN_SWAP_MASK,
+ SGMII_PN_SWAP_TX_RX);
+
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+ rgc3 = SGMII_PHY_SPEED_3_125G;
+ else
+ rgc3 = SGMII_PHY_SPEED_1_25G;
+
+ /* Configure the underlying interface speed */
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
+ SGMII_PHY_SPEED_MASK, rgc3);
+
+ /* Setup the link timer */
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+ SGMII_LINK_TIMER_VAL(link_timer));
+
+ mpcs->interface = interface;
+ mode_changed = true;
+ }
+
+ /* Update the advertisement, noting whether it has changed */
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
+ SGMII_ADVERTISE, advertise, &changed);
+
+ /* Update the sgmsys mode register */
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
+ SGMII_IF_MODE_SGMII, sgm_mode);
+
+ /* Update the BMCR */
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+ BMCR_ANENABLE, bmcr);
+
+ /* Release PHYA power down state
+ * Only removing bit SGMII_PHYA_PWD isn't enough.
+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
+ * prevents SGMII from working. The SGMII still shows link but no traffic
+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
+ * taken from a good working state of the SGMII interface.
+ * Unknown how much the QPHY needs but it is racy without a sleep.
+ * Tested on mt7622 & mt7986.
+ */
+ usleep_range(50, 100);
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
+
+ return changed || mode_changed;
+}
+
+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
+{
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+
+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
+}
+
+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
+ phy_interface_t interface, int speed,
+ int duplex)
+{
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+ unsigned int sgm_mode;
+
+ if (!phylink_autoneg_inband(mode)) {
+ /* Force the speed and duplex setting */
+ if (speed == SPEED_10)
+ sgm_mode = SGMII_SPEED_10;
+ else if (speed == SPEED_100)
+ sgm_mode = SGMII_SPEED_100;
+ else
+ sgm_mode = SGMII_SPEED_1000;
+
+ if (duplex != DUPLEX_FULL)
+ sgm_mode |= SGMII_DUPLEX_HALF;
+
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
+ sgm_mode);
+ }
+}
+
+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
+ .pcs_get_state = mtk_pcs_lynxi_get_state,
+ .pcs_config = mtk_pcs_lynxi_config,
+ .pcs_an_restart = mtk_pcs_lynxi_restart_an,
+ .pcs_link_up = mtk_pcs_lynxi_link_up,
+};
+
+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
+ struct regmap *regmap, u32 ana_rgc3,
+ u32 flags)
+{
+ struct mtk_pcs_lynxi *mpcs;
+ u32 id, ver;
+ int ret;
+
+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
+ if (ret < 0)
+ return NULL;
+
+ if (id != SGMII_LYNXI_DEV_ID) {
+ dev_err(dev, "unknown PCS device id %08x\n", id);
+ return NULL;
+ }
+
+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
+ if (ret < 0)
+ return NULL;
+
+ ver = FIELD_GET(SGMII_DEV_VERSION, ver);
+ if (ver != 0x1) {
+ dev_err(dev, "unknown PCS device version %04x\n", ver);
+ return NULL;
+ }
+
+ dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id,
+ ver);
+
+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
+ if (!mpcs)
+ return NULL;
+
+ mpcs->ana_rgc3 = ana_rgc3;
+ mpcs->regmap = regmap;
+ mpcs->flags = flags;
+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
+ mpcs->pcs.poll = true;
+ mpcs->interface = PHY_INTERFACE_MODE_NA;
+
+ return &mpcs->pcs;
+}
+EXPORT_SYMBOL(mtk_pcs_lynxi_create);
+
+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
+{
+ if (!pcs)
+ return;
+
+ kfree(pcs_to_mtk_pcs_lynxi(pcs));
+}
+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/pcs/pcs-mtk-lynxi.h b/include/linux/pcs/pcs-mtk-lynxi.h
new file mode 100644
index 000000000000..be3b4ab32f4a
--- /dev/null
+++ b/include/linux/pcs/pcs-mtk-lynxi.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_MTK_LYNXI_H
+#define __LINUX_PCS_MTK_LYNXI_H
+
+#include <linux/phylink.h>
+#include <linux/regmap.h>
+
+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
+ struct regmap *regmap,
+ u32 ana_rgc3, u32 flags);
+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
+#endif
--
2.39.2
Now that we got a PCS driver, use it and remove the now redundant
PCS code and it's header macros from the Ethernet driver.
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/Kconfig | 2 +
drivers/net/ethernet/mediatek/Makefile | 2 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +--------
drivers/net/ethernet/mediatek/mtk_sgmii.c | 219 --------------------
5 files changed, 56 insertions(+), 321 deletions(-)
delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
index 97374fb3ee79..da0db417ab69 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC
select DIMLIB
select PAGE_POOL
select PAGE_POOL_STATS
+ select PCS_MTK_LYNXI
+ select REGMAP_MMIO
help
This driver supports the gigabit ethernet MACs in the
MediaTek SoC family.
diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
index 8e0c61c33ff8..03e008fbc859 100644
--- a/drivers/net/ethernet/mediatek/Makefile
+++ b/drivers/net/ethernet/mediatek/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
+mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
ifdef CONFIG_DEBUG_FS
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e63e59fc3b19..817951718681 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/pinctrl/devinfo.h>
#include <linux/phylink.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
#include <linux/jhash.h>
#include <linux/bitfield.h>
#include <net/dsa.h>
@@ -444,7 +445,7 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
0 : mac->id;
- return mtk_sgmii_select_pcs(eth->sgmii, sid);
+ return eth->sgmii_pcs[sid];
}
return NULL;
@@ -4077,8 +4078,17 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
return 0;
}
+static void mtk_sgmii_destroy(struct mtk_eth *eth)
+{
+ int i;
+
+ for (i = 0; i < MTK_MAX_DEVS; i++)
+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
+}
+
static int mtk_cleanup(struct mtk_eth *eth)
{
+ mtk_sgmii_destroy(eth);
mtk_unreg_dev(eth);
mtk_free_dev(eth);
cancel_work_sync(ð->pending_work);
@@ -4514,6 +4524,36 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
rtnl_unlock();
}
+static int mtk_sgmii_init(struct mtk_eth *eth)
+{
+ struct device_node *np;
+ struct regmap *regmap;
+ u32 flags;
+ int i;
+
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
+ if (!np)
+ break;
+
+ regmap = syscon_node_to_regmap(np);
+ flags = 0;
+ if (of_property_read_bool(np, "mediatek,pnswap"))
+ flags |= MTK_SGMII_FLAG_PN_SWAP;
+
+ of_node_put(np);
+
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap,
+ eth->soc->ana_rgc3,
+ flags);
+ }
+
+ return 0;
+}
+
static int mtk_probe(struct platform_device *pdev)
{
struct resource *res = NULL;
@@ -4577,13 +4617,7 @@ static int mtk_probe(struct platform_device *pdev)
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
- GFP_KERNEL);
- if (!eth->sgmii)
- return -ENOMEM;
-
- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
- eth->soc->ana_rgc3);
+ err = mtk_sgmii_init(eth);
if (err)
return err;
@@ -4594,14 +4628,17 @@ static int mtk_probe(struct platform_device *pdev)
"mediatek,pctl");
if (IS_ERR(eth->pctl)) {
dev_err(&pdev->dev, "no pctl regmap found\n");
- return PTR_ERR(eth->pctl);
+ err = PTR_ERR(eth->pctl);
+ goto err_destroy_sgmii;
}
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
+ if (!res) {
+ err = -EINVAL;
+ goto err_destroy_sgmii;
+ }
}
if (eth->soc->offload_version) {
@@ -4760,6 +4797,8 @@ static int mtk_probe(struct platform_device *pdev)
mtk_hw_deinit(eth);
err_wed_exit:
mtk_wed_exit();
+err_destroy_sgmii:
+ mtk_sgmii_destroy(eth);
return err;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 1c7a51fccc0f..3dfa880da41a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -509,65 +509,6 @@
#define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
#define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-/* SGMII subsystem config registers */
-/* BMCR (low 16) BMSR (high 16) */
-#define SGMSYS_PCS_CONTROL_1 0x0
-#define SGMII_BMCR GENMASK(15, 0)
-#define SGMII_BMSR GENMASK(31, 16)
-#define SGMII_AN_RESTART BIT(9)
-#define SGMII_ISOLATE BIT(10)
-#define SGMII_AN_ENABLE BIT(12)
-#define SGMII_LINK_STATYS BIT(18)
-#define SGMII_AN_ABILITY BIT(19)
-#define SGMII_AN_COMPLETE BIT(21)
-#define SGMII_PCS_FAULT BIT(23)
-#define SGMII_AN_EXPANSION_CLR BIT(30)
-
-#define SGMSYS_PCS_ADVERTISE 0x8
-#define SGMII_ADVERTISE GENMASK(15, 0)
-#define SGMII_LPA GENMASK(31, 16)
-
-/* Register to programmable link timer, the unit in 2 * 8ns */
-#define SGMSYS_PCS_LINK_TIMER 0x18
-#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
-
-/* Register to control remote fault */
-#define SGMSYS_SGMII_MODE 0x20
-#define SGMII_IF_MODE_SGMII BIT(0)
-#define SGMII_SPEED_DUPLEX_AN BIT(1)
-#define SGMII_SPEED_MASK GENMASK(3, 2)
-#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
-#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
-#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
-#define SGMII_DUPLEX_HALF BIT(4)
-#define SGMII_IF_MODE_BIT5 BIT(5)
-#define SGMII_REMOTE_FAULT_DIS BIT(8)
-#define SGMII_CODE_SYNC_SET_VAL BIT(9)
-#define SGMII_CODE_SYNC_SET_EN BIT(10)
-#define SGMII_SEND_AN_ERROR_EN BIT(11)
-#define SGMII_IF_MODE_MASK GENMASK(5, 1)
-
-/* Register to reset SGMII design */
-#define SGMII_RESERVED_0 0x34
-#define SGMII_SW_RESET BIT(0)
-
-/* Register to set SGMII speed, ANA RG_ Control Signals III*/
-#define SGMSYS_ANA_RG_CS3 0x2028
-#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
-#define RG_PHY_SPEED_1_25G 0x0
-#define RG_PHY_SPEED_3_125G BIT(2)
-
-/* Register to power up QPHY */
-#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
-#define SGMII_PHYA_PWD BIT(4)
-
-/* Register to QPHY wrapper control */
-#define SGMSYS_QPHY_WRAP_CTRL 0xec
-#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
-#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
-
/* Infrasys subsystem config registers */
#define INFRA_MISC2 0x70c
#define CO_QPHY_SEL BIT(0)
@@ -1104,31 +1045,6 @@ struct mtk_soc_data {
/* currently no SoC has more than 2 macs */
#define MTK_MAX_DEVS 2
-/* struct mtk_pcs - This structure holds each sgmii regmap and associated
- * data
- * @regmap: The register map pointing at the range used to setup
- * SGMII modes
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
- * @interface: Currently configured interface mode
- * @pcs: Phylink PCS structure
- * @flags: Flags indicating hardware properties
- */
-struct mtk_pcs {
- struct regmap *regmap;
- u32 ana_rgc3;
- phy_interface_t interface;
- struct phylink_pcs pcs;
- u32 flags;
-};
-
-/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
- * characteristics
- * @pcs Array of individual PCS structures
- */
-struct mtk_sgmii {
- struct mtk_pcs pcs[MTK_MAX_DEVS];
-};
-
/* struct mtk_eth - This is the main datasructure for holding the state
* of the driver
* @dev: The device pointer
@@ -1148,6 +1064,7 @@ struct mtk_sgmii {
* MII modes
* @infra: The register map pointing at the range used to setup
* SGMII and GePHY path
+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
* @pctl: The register map pointing at the range used to setup
* GMAC port drive/slew values
* @dma_refcnt: track how many netdevs are using the DMA engine
@@ -1188,8 +1105,8 @@ struct mtk_eth {
u32 msg_enable;
unsigned long sysclk;
struct regmap *ethsys;
- struct regmap *infra;
- struct mtk_sgmii *sgmii;
+ struct regmap *infra;
+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
struct regmap *pctl;
bool hwlro;
refcount_t dma_refcnt;
@@ -1351,10 +1268,6 @@ void mtk_stats_update_mac(struct mtk_mac *mac);
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
- u32 ana_rgc3);
-
int mtk_gmac_sgmii_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);
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c b/drivers/net/ethernet/mediatek/mtk_sgmii.c
deleted file mode 100644
index 98d80007d3bd..000000000000
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ /dev/null
@@ -1,219 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2018-2019 MediaTek Inc.
-
-/* A library for MediaTek SGMII circuit
- *
- * Author: Sean Wang <[email protected]>
- *
- */
-
-#include <linux/mfd/syscon.h>
-#include <linux/of.h>
-#include <linux/phylink.h>
-#include <linux/regmap.h>
-
-#include "mtk_eth_soc.h"
-
-static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
-{
- return container_of(pcs, struct mtk_pcs, pcs);
-}
-
-static void mtk_pcs_get_state(struct phylink_pcs *pcs,
- struct phylink_link_state *state)
-{
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int bm, bmsr, adv;
-
- /* Read the BMSR */
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
- bmsr = FIELD_GET(SGMII_BMSR, bm);
-
- /* link partner advertised link modes are not reported by the
- * hardware when not operating in SGMII mode. Hence we cannot
- * use phylink_mii_c22_pcs_decode_state() in this case.
- */
- if (state->interface != PHY_INTERFACE_MODE_SGMII) {
- state->link = !!(bmsr & BMSR_LSTATUS);
- state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
- state->speed = (state->interface ==
- PHY_INTERFACE_MODE_2500BASEX) ?
- SPEED_2500 : SPEED_1000;
- state->duplex = DUPLEX_FULL;
-
- return;
- }
-
- /* Read LPA and use standard decode function for SGMII mode */
- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
- phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
-}
-
-static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface,
- const unsigned long *advertising,
- bool permit_pause_to_mac)
-{
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int rgc3, sgm_mode = 0, bmcr = 0;
- bool mode_changed = false, changed;
- int advertise, link_timer;
-
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
- advertising);
- if (advertise < 0)
- return advertise;
-
- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
- * we assume that fixes it's speed at bitrate = line rate (in
- * other words, 1000Mbps or 2500Mbps).
- */
- if (interface == PHY_INTERFACE_MODE_SGMII) {
- sgm_mode = SGMII_IF_MODE_SGMII;
- if (phylink_autoneg_inband(mode)) {
- bmcr = SGMII_AN_ENABLE;
- sgm_mode |= SGMII_REMOTE_FAULT_DIS |
- SGMII_SPEED_DUPLEX_AN;
- }
- } else if (!phylink_autoneg_inband(mode)) {
- /* 1000base-X or 2500base-X without autoneg */
- sgm_mode = SGMII_REMOTE_FAULT_DIS;
- }
-
- if (mpcs->interface != interface) {
- link_timer = phylink_get_link_timer_ns(interface);
- if (link_timer < 0)
- return link_timer;
-
- /* PHYA power down */
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
- /* Reset SGMII PCS state */
- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
- SGMII_SW_RESET, SGMII_SW_RESET);
-
- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
- SGMII_PN_SWAP_MASK,
- SGMII_PN_SWAP_TX_RX);
-
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- rgc3 = RG_PHY_SPEED_3_125G;
- else
- rgc3 = 0;
-
- /* Configure the underlying interface speed */
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
- RG_PHY_SPEED_3_125G, rgc3);
-
- /* Setup the link timer */
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
- mpcs->interface = interface;
- mode_changed = true;
- }
-
- /* Update the advertisement, noting whether it has changed */
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
- SGMII_ADVERTISE, advertise, &changed);
-
- /* Update the sgmsys mode register */
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
- SGMII_IF_MODE_SGMII, sgm_mode);
-
- /* Update the BMCR */
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_ENABLE, bmcr);
-
- /* Release PHYA power down state
- * Only removing bit SGMII_PHYA_PWD isn't enough.
- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
- * prevents SGMII from working. The SGMII still shows link but no traffic
- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
- * taken from a good working state of the SGMII interface.
- * Unknown how much the QPHY needs but it is racy without a sleep.
- * Tested on mt7622 & mt7986.
- */
- usleep_range(50, 100);
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
- return changed || mode_changed;
-}
-
-static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
-{
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
- SGMII_AN_RESTART, SGMII_AN_RESTART);
-}
-
-static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface, int speed, int duplex)
-{
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
- unsigned int sgm_mode;
-
- if (!phylink_autoneg_inband(mode)) {
- /* Force the speed and duplex setting */
- if (speed == SPEED_10)
- sgm_mode = SGMII_SPEED_10;
- else if (speed == SPEED_100)
- sgm_mode = SGMII_SPEED_100;
- else
- sgm_mode = SGMII_SPEED_1000;
-
- if (duplex != DUPLEX_FULL)
- sgm_mode |= SGMII_DUPLEX_HALF;
-
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
- sgm_mode);
- }
-}
-
-static const struct phylink_pcs_ops mtk_pcs_ops = {
- .pcs_get_state = mtk_pcs_get_state,
- .pcs_config = mtk_pcs_config,
- .pcs_an_restart = mtk_pcs_restart_an,
- .pcs_link_up = mtk_pcs_link_up,
-};
-
-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
-{
- struct device_node *np;
- int i;
-
- for (i = 0; i < MTK_MAX_DEVS; i++) {
- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
- if (!np)
- break;
-
- ss->pcs[i].ana_rgc3 = ana_rgc3;
- ss->pcs[i].regmap = syscon_node_to_regmap(np);
-
- ss->pcs[i].flags = 0;
- if (of_property_read_bool(np, "mediatek,pnswap"))
- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
-
- of_node_put(np);
- if (IS_ERR(ss->pcs[i].regmap))
- return PTR_ERR(ss->pcs[i].regmap);
-
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
- ss->pcs[i].pcs.poll = true;
- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
- }
-
- return 0;
-}
-
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
-{
- if (!ss->pcs[id].regmap)
- return NULL;
-
- return &ss->pcs[id].pcs;
-}
--
2.39.2
Implement regmap access wrappers, for now only to be used by the
pcs-mtk driver.
Make use of external PCS driver and drop the reduntant implementation
in mt7530.c.
As a nice side effect the SGMII registers can now also more easily be
inspected for debugging via /sys/kernel/debug/regmap.
Reviewed-by: Russell King (Oracle) <[email protected]>
Tested-by: Bj?rn Mork <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/dsa/Kconfig | 1 +
drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
drivers/net/dsa/mt7530.h | 47 +------
3 files changed, 71 insertions(+), 254 deletions(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index f6f3b43dfb06..6b45fa8b6907 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -38,6 +38,7 @@ config NET_DSA_MT7530
tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
select NET_DSA_TAG_MTK
select MEDIATEK_GE_PHY
+ select PCS_MTK_LYNXI
help
This enables support for the MediaTek MT7530 and MT7531 Ethernet
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 3a15015bc409..582ba30374c8 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -14,6 +14,7 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -2567,128 +2568,11 @@ static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port,
return 0;
}
-static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
- phy_interface_t interface, int speed, int duplex)
-{
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
- int port = pcs_to_mt753x_pcs(pcs)->port;
- unsigned int val;
-
- /* For adjusting speed and duplex of SGMII force mode. */
- if (interface != PHY_INTERFACE_MODE_SGMII ||
- phylink_autoneg_inband(mode))
- return;
-
- /* SGMII force mode setting */
- val = mt7530_read(priv, MT7531_SGMII_MODE(port));
- val &= ~MT7531_SGMII_IF_MODE_MASK;
-
- switch (speed) {
- case SPEED_10:
- val |= MT7531_SGMII_FORCE_SPEED_10;
- break;
- case SPEED_100:
- val |= MT7531_SGMII_FORCE_SPEED_100;
- break;
- case SPEED_1000:
- val |= MT7531_SGMII_FORCE_SPEED_1000;
- break;
- }
-
- /* MT7531 SGMII 1G force mode can only work in full duplex mode,
- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
- *
- * The speed check is unnecessary as the MAC capabilities apply
- * this restriction. --rmk
- */
- if ((speed == SPEED_10 || speed == SPEED_100) &&
- duplex != DUPLEX_FULL)
- val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
-
- mt7530_write(priv, MT7531_SGMII_MODE(port), val);
-}
-
static bool mt753x_is_mac_port(u32 port)
{
return (port == 5 || port == 6);
}
-static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
- phy_interface_t interface)
-{
- u32 val;
-
- if (!mt753x_is_mac_port(port))
- return -EINVAL;
-
- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
- MT7531_SGMII_PHYA_PWD);
-
- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
- val &= ~MT7531_RG_TPHY_SPEED_MASK;
- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
- * encoding.
- */
- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
-
- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
-
- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
- */
- mt7530_rmw(priv, MT7531_SGMII_MODE(port),
- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
- MT7531_SGMII_FORCE_SPEED_1000);
-
- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
-
- return 0;
-}
-
-static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
- phy_interface_t interface)
-{
- if (!mt753x_is_mac_port(port))
- return -EINVAL;
-
- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
- MT7531_SGMII_PHYA_PWD);
-
- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
-
- mt7530_set(priv, MT7531_SGMII_MODE(port),
- MT7531_SGMII_REMOTE_FAULT_DIS |
- MT7531_SGMII_SPEED_DUPLEX_AN);
-
- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
- MT7531_SGMII_TX_CONFIG_MASK, 1);
-
- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
-
- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
-
- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
-
- return 0;
-}
-
-static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
-{
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
- int port = pcs_to_mt753x_pcs(pcs)->port;
- u32 val;
-
- /* Only restart AN when AN is enabled */
- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
- if (val & MT7531_SGMII_AN_ENABLE) {
- val |= MT7531_SGMII_AN_RESTART;
- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
- }
-}
-
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
@@ -2711,11 +2595,11 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phydev = dp->slave->phydev;
return mt7531_rgmii_setup(priv, port, interface, phydev);
case PHY_INTERFACE_MODE_SGMII:
- return mt7531_sgmii_setup_mode_an(priv, port, interface);
case PHY_INTERFACE_MODE_NA:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
- return mt7531_sgmii_setup_mode_force(priv, port, interface);
+ /* handled in SGMII PCS driver */
+ return 0;
default:
return -EINVAL;
}
@@ -2740,11 +2624,11 @@ mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
switch (interface) {
case PHY_INTERFACE_MODE_TRGMII:
+ return &priv->pcs[port].pcs;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
- return &priv->pcs[port].pcs;
-
+ return priv->ports[port].sgmii_pcs;
default:
return NULL;
}
@@ -2982,86 +2866,6 @@ static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
state->pause |= MLO_PAUSE_TX;
}
-static int
-mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
- struct phylink_link_state *state)
-{
- u32 status, val;
- u16 config_reg;
-
- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
- state->link = !!(status & MT7531_SGMII_LINK_STATUS);
- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
- if (state->interface == PHY_INTERFACE_MODE_SGMII &&
- (status & MT7531_SGMII_AN_ENABLE)) {
- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
- config_reg = val >> 16;
-
- switch (config_reg & LPA_SGMII_SPD_MASK) {
- case LPA_SGMII_1000:
- state->speed = SPEED_1000;
- break;
- case LPA_SGMII_100:
- state->speed = SPEED_100;
- break;
- case LPA_SGMII_10:
- state->speed = SPEED_10;
- break;
- default:
- dev_err(priv->dev, "invalid sgmii PHY speed\n");
- state->link = false;
- return -EINVAL;
- }
-
- if (config_reg & LPA_SGMII_FULL_DUPLEX)
- state->duplex = DUPLEX_FULL;
- else
- state->duplex = DUPLEX_HALF;
- }
-
- return 0;
-}
-
-static void
-mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
- struct phylink_link_state *state)
-{
- unsigned int val;
-
- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
- state->link = !!(val & MT7531_SGMII_LINK_STATUS);
- if (!state->link)
- return;
-
- state->an_complete = state->link;
-
- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
- state->speed = SPEED_2500;
- else
- state->speed = SPEED_1000;
-
- state->duplex = DUPLEX_FULL;
- state->pause = MLO_PAUSE_NONE;
-}
-
-static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
- struct phylink_link_state *state)
-{
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
- int port = pcs_to_mt753x_pcs(pcs)->port;
-
- if (state->interface == PHY_INTERFACE_MODE_SGMII) {
- mt7531_sgmii_pcs_get_state_an(priv, port, state);
- return;
- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
- mt7531_sgmii_pcs_get_state_inband(priv, port, state);
- return;
- }
-
- state->link = false;
-}
-
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface,
const unsigned long *advertising,
@@ -3081,18 +2885,57 @@ static const struct phylink_pcs_ops mt7530_pcs_ops = {
.pcs_an_restart = mt7530_pcs_an_restart,
};
-static const struct phylink_pcs_ops mt7531_pcs_ops = {
- .pcs_validate = mt753x_pcs_validate,
- .pcs_get_state = mt7531_pcs_get_state,
- .pcs_config = mt753x_pcs_config,
- .pcs_an_restart = mt7531_pcs_an_restart,
- .pcs_link_up = mt7531_pcs_link_up,
+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct mt7530_priv *priv = context;
+
+ *val = mt7530_read(priv, reg);
+ return 0;
+};
+
+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct mt7530_priv *priv = context;
+
+ mt7530_write(priv, reg, val);
+ return 0;
+};
+
+static int mt7530_regmap_update_bits(void *context, unsigned int reg,
+ unsigned int mask, unsigned int val)
+{
+ struct mt7530_priv *priv = context;
+
+ mt7530_rmw(priv, reg, mask, val);
+ return 0;
+};
+
+static const struct regmap_bus mt7531_regmap_bus = {
+ .reg_write = mt7530_regmap_write,
+ .reg_read = mt7530_regmap_read,
+ .reg_update_bits = mt7530_regmap_update_bits,
+};
+
+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
+ { \
+ .name = _name, \
+ .reg_bits = 16, \
+ .val_bits = 32, \
+ .reg_stride = 4, \
+ .reg_base = _reg_base, \
+ .max_register = 0x17c, \
+ }
+
+static const struct regmap_config mt7531_pcs_config[] = {
+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
};
static int
mt753x_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
+ struct regmap *regmap;
int i, ret;
/* Initialise the PCS devices */
@@ -3100,8 +2943,6 @@ mt753x_setup(struct dsa_switch *ds)
priv->pcs[i].pcs.ops = priv->info->pcs_ops;
priv->pcs[i].priv = priv;
priv->pcs[i].port = i;
- if (mt753x_is_mac_port(i))
- priv->pcs[i].pcs.poll = 1;
}
ret = priv->info->sw_setup(ds);
@@ -3116,6 +2957,16 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
+ if (priv->id == ID_MT7531)
+ for (i = 0; i < 2; i++) {
+ regmap = devm_regmap_init(ds->dev,
+ &mt7531_regmap_bus, priv,
+ &mt7531_pcs_config[i]);
+ priv->ports[5 + i].sgmii_pcs =
+ mtk_pcs_lynxi_create(ds->dev, regmap,
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
+ }
+
return ret;
}
@@ -3211,7 +3062,7 @@ static const struct mt753x_info mt753x_table[] = {
},
[ID_MT7531] = {
.id = ID_MT7531,
- .pcs_ops = &mt7531_pcs_ops,
+ .pcs_ops = &mt7530_pcs_ops,
.sw_setup = mt7531_setup,
.phy_read_c22 = mt7531_ind_c22_phy_read,
.phy_write_c22 = mt7531_ind_c22_phy_write,
@@ -3321,7 +3172,7 @@ static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
- int ret = 0;
+ int ret = 0, i;
if (!priv)
return;
@@ -3340,6 +3191,10 @@ mt7530_remove(struct mdio_device *mdiodev)
mt7530_free_irq(priv);
dsa_unregister_switch(priv->ds);
+
+ for (i = 0; i < 2; ++i)
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
+
mutex_destroy(&priv->reg_mutex);
}
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 6b2fc6290ea8..c5d29f3fc1d8 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -364,47 +364,8 @@ enum mt7530_vlan_port_acc_frm {
CCR_TX_OCT_CNT_BAD)
/* MT7531 SGMII register group */
-#define MT7531_SGMII_REG_BASE 0x5000
-#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
- ((p) - 5) * 0x1000 + (r))
-
-/* Register forSGMII PCS_CONTROL_1 */
-#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
-#define MT7531_SGMII_LINK_STATUS BIT(18)
-#define MT7531_SGMII_AN_ENABLE BIT(12)
-#define MT7531_SGMII_AN_RESTART BIT(9)
-#define MT7531_SGMII_AN_COMPLETE BIT(21)
-
-/* Register for SGMII PCS_SPPED_ABILITY */
-#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
-#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
-#define MT7531_SGMII_TX_CONFIG BIT(0)
-
-/* Register for SGMII_MODE */
-#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
-#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
-#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
-#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
-#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
-#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
-#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
-#define MT7531_SGMII_FORCE_SPEED_10 0
-#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
-
-enum mt7531_sgmii_force_duplex {
- MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
-};
-
-/* Fields of QPHY_PWR_STATE_CTRL */
-#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
-#define MT7531_SGMII_PHYA_PWD BIT(4)
-
-/* Values of SGMII SPEED */
-#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
-#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
-#define MT7531_RG_TPHY_SPEED_1_25G 0x0
-#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000)
+#define MT7531_PHYA_CTRL_SIGNAL3 0x128
/* Register for system reset */
#define MT7530_SYS_CTRL 0x7000
@@ -703,13 +664,13 @@ struct mt7530_fdb {
* @pm: The matrix used to show all connections with the port.
* @pvid: The VLAN specified is to be considered a PVID at ingress. Any
* untagged frames will be assigned to the related VLAN.
- * @vlan_filtering: The flags indicating whether the port that can recognize
- * VLAN-tagged frames.
+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports
*/
struct mt7530_port {
bool enable;
u32 pm;
u16 pvid;
+ struct phylink_pcs *sgmii_pcs;
};
/* Port 5 interface select definitions */
--
2.39.2
From: Lorenzo Bianconi <[email protected]>
Introduce MTK_NETSYS_V1 bit in the device capabilities for
MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
2 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 817951718681..e34065e17446 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -683,7 +683,7 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
if (IS_ENABLED(CONFIG_SOC_MT7621)) {
@@ -1062,7 +1062,7 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd,
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
}
@@ -1120,7 +1120,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -1311,7 +1311,7 @@ static void mtk_tx_set_dma_desc(struct net_device *dev, void *txd,
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
mtk_tx_set_dma_desc_v2(dev, txd, info);
else
mtk_tx_set_dma_desc_v1(dev, txd, info);
@@ -1962,7 +1962,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
break;
/* find out which mac the packet come from. values start at 1 */
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
@@ -2058,7 +2058,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb->dev = netdev;
bytes += skb->len;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
if (hash != MTK_RXD5_FOE_ENTRY)
@@ -2084,7 +2084,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
mtk_ppe_check_skb(eth->ppe[0], skb, hash);
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
if (trxd.rxd3 & RX_DMA_VTAG_V2) {
vlan_proto = RX_DMA_VPID(trxd.rxd4);
vlan_tci = RX_DMA_VID(trxd.rxd4);
@@ -2409,7 +2409,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
txd->txd2 = next_ptr;
txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -2462,7 +2462,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
ofs += MTK_QTX_OFFSET;
@@ -2598,7 +2598,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
rxd->rxd3 = 0;
rxd->rxd4 = 0;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
rxd->rxd5 = 0;
rxd->rxd6 = 0;
rxd->rxd7 = 0;
@@ -3164,7 +3164,7 @@ static int mtk_start_dma(struct mtk_eth *eth)
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
@@ -3567,7 +3567,7 @@ static void mtk_hw_reset(struct mtk_eth *eth)
{
u32 val;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
val = RSTCTRL_PPE0_V2;
} else {
@@ -3579,7 +3579,7 @@ static void mtk_hw_reset(struct mtk_eth *eth)
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
0x3ffffff);
}
@@ -3775,7 +3775,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
else
mtk_hw_reset(eth);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
/* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
@@ -3812,7 +3812,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
*/
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
}
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 3dfa880da41a..cb3cdf0b38d5 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -820,6 +820,7 @@ enum mkt_eth_capabilities {
MTK_SHARED_INT_BIT,
MTK_TRGMII_MT7621_CLK_BIT,
MTK_QDMA_BIT,
+ MTK_NETSYS_V1_BIT,
MTK_NETSYS_V2_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
@@ -855,6 +856,7 @@ enum mkt_eth_capabilities {
#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
#define MTK_QDMA BIT(MTK_QDMA_BIT)
+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
@@ -911,25 +913,30 @@ enum mkt_eth_capabilities {
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
-#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
- MTK_GMAC2_RGMII | MTK_SHARED_INT | \
- MTK_TRGMII_MT7621_CLK | MTK_QDMA)
-
-#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
- MTK_MUX_GDM1_TO_GMAC1_ESW | \
- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
-
-#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
- MTK_QDMA)
-
-#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628)
-
-#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \
+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \
+ MTK_NETSYS_V1)
+
+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \
+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \
+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \
+ MTK_QDMA | MTK_NETSYS_V1)
+
+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+ MTK_GMAC2_RGMII | MTK_QDMA | \
+ MTK_NETSYS_V1)
+
+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \
+ MTK_NETSYS_V1)
+
+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \
+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
+ MTK_MUX_GDM1_TO_GMAC1_ESW | \
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII)
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
--
2.39.2
From: Lorenzo Bianconi <[email protected]>
This is a preliminary patch to add MT7988 SoC support since it runs 3
macs instead of 2.
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index e34065e17446..c858f21f603c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4082,7 +4082,10 @@ static void mtk_sgmii_destroy(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAX_DEVS; i++)
+ if (!eth->sgmii_pcs)
+ return;
+
+ for (i = 0; i < eth->soc->num_devs; i++)
mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
}
@@ -4531,7 +4534,12 @@ static int mtk_sgmii_init(struct mtk_eth *eth)
u32 flags;
int i;
- for (i = 0; i < MTK_MAX_DEVS; i++) {
+ eth->sgmii_pcs = devm_kzalloc(eth->dev,
+ sizeof(*eth->sgmii_pcs) *
+ eth->soc->num_devs,
+ GFP_KERNEL);
+
+ for (i = 0; i < eth->soc->num_devs; i++) {
np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
if (!np)
break;
@@ -4576,6 +4584,18 @@ static int mtk_probe(struct platform_device *pdev)
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
eth->ip_align = NET_IP_ALIGN;
+ eth->netdev = devm_kzalloc(eth->dev,
+ sizeof(*eth->netdev) * eth->soc->num_devs,
+ GFP_KERNEL);
+ if (!eth->netdev)
+ return -ENOMEM;
+
+ eth->mac = devm_kzalloc(eth->dev,
+ sizeof(*eth->mac) * eth->soc->num_devs,
+ GFP_KERNEL);
+ if (!eth->mac)
+ return -ENOMEM;
+
spin_lock_init(ð->page_lock);
spin_lock_init(ð->tx_irq_lock);
spin_lock_init(ð->rx_irq_lock);
@@ -4761,7 +4781,7 @@ static int mtk_probe(struct platform_device *pdev)
goto err_deinit_ppe;
}
- for (i = 0; i < MTK_MAX_DEVS; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
@@ -4835,6 +4855,7 @@ static const struct mtk_soc_data mt2701_data = {
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4853,6 +4874,7 @@ static const struct mtk_soc_data mt7621_data = {
.required_pctl = false,
.offload_version = 1,
.hash_offset = 2,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4874,6 +4896,7 @@ static const struct mtk_soc_data mt7622_data = {
.offload_version = 2,
.hash_offset = 2,
.has_accounting = true,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4893,6 +4916,7 @@ static const struct mtk_soc_data mt7623_data = {
.required_pctl = true,
.offload_version = 1,
.hash_offset = 2,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4912,6 +4936,7 @@ static const struct mtk_soc_data mt7629_data = {
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_accounting = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4933,6 +4958,7 @@ static const struct mtk_soc_data mt7981_data = {
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4952,6 +4978,7 @@ static const struct mtk_soc_data mt7986_data = {
.required_pctl = false,
.offload_version = 2,
.hash_offset = 4,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
.txrx = {
@@ -4970,6 +4997,7 @@ static const struct mtk_soc_data rt5350_data = {
.hw_features = MTK_HW_FEATURES_MT7628,
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index cb3cdf0b38d5..f0c38c856cd0 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1016,6 +1016,7 @@ struct mtk_reg_map {
* @required_pctl A bool value to show whether the SoC requires
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
+ * @num_devs SoC number of macs.
* @foe_entry_size Foe table entry size.
* @has_accounting Bool indicating support for accounting of
* offloaded flows.
@@ -1034,6 +1035,7 @@ struct mtk_soc_data {
bool required_pctl;
u8 offload_version;
u8 hash_offset;
+ u8 num_devs;
u16 foe_entry_size;
netdev_features_t hw_features;
bool has_accounting;
@@ -1049,9 +1051,6 @@ struct mtk_soc_data {
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-/* currently no SoC has more than 2 macs */
-#define MTK_MAX_DEVS 2
-
/* struct mtk_eth - This is the main datasructure for holding the state
* of the driver
* @dev: The device pointer
@@ -1106,14 +1105,14 @@ struct mtk_eth {
spinlock_t tx_irq_lock;
spinlock_t rx_irq_lock;
struct net_device dummy_dev;
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
+ struct net_device **netdev;
+ struct mtk_mac **mac;
int irq[3];
u32 msg_enable;
unsigned long sysclk;
struct regmap *ethsys;
struct regmap *infra;
- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
+ struct phylink_pcs **sgmii_pcs;
struct regmap *pctl;
bool hwlro;
refcount_t dma_refcnt;
--
2.39.2
From: Lorenzo Bianconi <[email protected]>
Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c858f21f603c..1f802330ff13 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -988,7 +988,7 @@ static void mtk_stats_update(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->mac[i] || !eth->mac[i]->hw_stats)
continue;
if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) {
@@ -1493,7 +1493,7 @@ static int mtk_queue_stopped(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
if (netif_queue_stopped(eth->netdev[i]))
@@ -1507,7 +1507,7 @@ static void mtk_wake_queue(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
netif_tx_wake_all_queues(eth->netdev[i]);
@@ -1968,7 +1968,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
!eth->netdev[mac]))
goto release_desc;
@@ -2948,7 +2948,7 @@ static int mtk_set_features(struct net_device *dev, netdev_features_t features)
MTK_CDMP_EG_CTRL);
/* sync features with other MAC */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i] || eth->netdev[i] == dev)
continue;
eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
@@ -3038,7 +3038,7 @@ static void mtk_dma_free(struct mtk_eth *eth)
const struct mtk_soc_data *soc = eth->soc;
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++)
+ for (i = 0; i < soc->num_devs; i++)
if (eth->netdev[i])
netdev_reset_queue(eth->netdev[i]);
if (eth->scratch_ring) {
@@ -3192,7 +3192,7 @@ static void mtk_gdm_config(struct mtk_eth *eth, u32 config)
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
return;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
/* default setup the forward port to send frame to PDMA */
@@ -3796,7 +3796,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
* up with the more appropriate value when mtk_mac_config call is being
* invoked.
*/
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
struct net_device *dev = eth->netdev[i];
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
@@ -4002,7 +4002,7 @@ static void mtk_pending_work(struct work_struct *work)
mtk_prepare_for_reset(eth);
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
continue;
@@ -4018,7 +4018,7 @@ static void mtk_pending_work(struct work_struct *work)
mtk_hw_init(eth, true);
/* restart DMA and enable IRQs */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!test_bit(i, &restart))
continue;
@@ -4046,7 +4046,7 @@ static int mtk_free_dev(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
free_netdev(eth->netdev[i]);
@@ -4065,7 +4065,7 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
struct mtk_mac *mac;
if (!eth->netdev[i])
continue;
@@ -4370,7 +4370,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
}
id = be32_to_cpup(_id);
- if (id >= MTK_MAC_COUNT) {
+ if (id >= eth->soc->num_devs) {
dev_err(eth->dev, "%d is not a valid mac id\n", id);
return -EINVAL;
}
@@ -4506,7 +4506,7 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
rtnl_lock();
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
dev = eth->netdev[i];
if (!dev || !(dev->flags & IFF_UP))
@@ -4830,7 +4830,7 @@ static int mtk_remove(struct platform_device *pdev)
int i;
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
mtk_stop(eth->netdev[i]);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f0c38c856cd0..8c5f72603604 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -33,7 +33,6 @@
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
#define MTK_QDMA_RING_SIZE 2048
#define MTK_DMA_SIZE 512
-#define MTK_MAC_COUNT 2
#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
#define MTK_DMA_DUMMY_DESC 0xffffffff
--
2.39.2
From: Lorenzo Bianconi <[email protected]>
Introduce MTK_NETSYS_V3 bit in the device capabilities.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++-
2 files changed, 134 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 1f802330ff13..aee7c9a53f88 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -968,17 +968,32 @@ void mtk_stats_update_mac(struct mtk_mac *mac)
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
hw_stats->rx_flow_control_packets +=
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
- hw_stats->tx_skip +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
- hw_stats->tx_collisions +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
- hw_stats->tx_bytes +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
- if (stats)
- hw_stats->tx_bytes += (stats << 32);
- hw_stats->tx_packets +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ hw_stats->tx_skip +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
+ hw_stats->tx_collisions +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
+ hw_stats->tx_bytes +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
+ if (stats)
+ hw_stats->tx_bytes += (stats << 32);
+ hw_stats->tx_packets +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
+ } else {
+ hw_stats->tx_skip +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
+ hw_stats->tx_collisions +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
+ hw_stats->tx_bytes +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
+ if (stats)
+ hw_stats->tx_bytes += (stats << 32);
+ hw_stats->tx_packets +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+ }
}
u64_stats_update_end(&hw_stats->syncp);
@@ -1282,7 +1297,10 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
data |= TX_DMA_LS0;
WRITE_ONCE(desc->txd3, data);
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+ if (mac->id == MTK_GMAC3_ID)
+ data = PSE_GDM3_PORT;
+ else
+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
WRITE_ONCE(desc->txd4, data);
@@ -1293,6 +1311,9 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd,
/* tx checksum offload */
if (info->csum)
data |= TX_DMA_CHKSUM_V2;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
+ netdev_uses_dsa(dev))
+ data |= TX_DMA_SPTAG_V3;
}
WRITE_ONCE(desc->txd5, data);
@@ -1358,8 +1379,13 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
mtk_tx_set_dma_desc(dev, itxd, &txd_info);
itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+ if (mac->id == MTK_GMAC1_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
+
setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
k++);
@@ -1407,8 +1433,13 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
memset(tx_buf, 0, sizeof(*tx_buf));
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+
+ if (mac->id == MTK_GMAC1_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
txd_info.size, k++);
@@ -1962,11 +1993,24 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
break;
/* find out which mac the packet come from. values start at 1 */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
+
+ switch (val) {
+ case PSE_GDM1_PORT:
+ case PSE_GDM2_PORT:
+ mac = val - 1;
+ break;
+ case PSE_GDM3_PORT:
+ mac = MTK_GMAC3_ID;
+ break;
+ default:
+ break;
+ }
+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+ }
if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
!eth->netdev[mac]))
@@ -2212,7 +2256,9 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
tx_buf = mtk_desc_to_tx_buf(ring, desc,
eth->soc->txrx.txd_size);
if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- mac = 1;
+ mac = MTK_GMAC2_ID;
+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
+ mac = MTK_GMAC3_ID;
if (!tx_buf->data)
break;
@@ -3835,7 +3881,26 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ /* PSE should not drop port1, port8 and port9 packets */
+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
+
+ /* GDM and CDM Threshold */
+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
+
+ /* Disable GDM1 RX CRC stripping */
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
+ val &= ~MTK_GDMA_STRP_CRC;
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
+
+ /* PSE GDM3 MIB counter has incorrect hw default values,
+ * so the driver ought to read clear the values beforehand
+ * in case ethtool retrieve wrong mib values.
+ */
+ for (i = 0; i < 0x80; i += 0x4)
+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
/* PSE should not drop port8 and port9 packets from WDMA Tx */
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
@@ -4407,7 +4472,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
}
spin_lock_init(&mac->hw_stats->stats_lock);
u64_stats_init(&mac->hw_stats->syncp);
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ mac->hw_stats->reg_offset = id * 0x80;
+ else
+ mac->hw_stats->reg_offset = id * 0x40;
/* phylink create */
err = of_get_phy_mode(np, &phy_mode);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 8c5f72603604..e4f6cca8a3a8 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -123,6 +123,7 @@
#define MTK_GDMA_ICS_EN BIT(22)
#define MTK_GDMA_TCS_EN BIT(21)
#define MTK_GDMA_UCS_EN BIT(20)
+#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
#define MTK_GDMA_DROP_ALL 0x7777
@@ -288,8 +289,6 @@
/* QDMA Interrupt grouping registers */
#define MTK_RLS_DONE_INT BIT(0)
-#define MTK_STAT_OFFSET 0x40
-
/* QDMA TX NUM */
#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
#define MTK_QDMA_GMAC2_QID 8
@@ -302,6 +301,8 @@
#define TX_DMA_CHKSUM_V2 (0x7 << 28)
#define TX_DMA_TSO_V2 BIT(31)
+#define TX_DMA_SPTAG_V3 BIT(27)
+
/* QDMA V2 descriptor txd4 */
#define TX_DMA_FPORT_SHIFT_V2 8
#define TX_DMA_FPORT_MASK_V2 0xf
@@ -640,6 +641,7 @@ enum mtk_tx_flags {
*/
MTK_TX_FLAGS_FPORT0 = 0x04,
MTK_TX_FLAGS_FPORT1 = 0x08,
+ MTK_TX_FLAGS_FPORT2 = 0x10,
};
/* This enum allows us to identify how the clock is defined on the array of the
@@ -725,6 +727,42 @@ enum mtk_dev_state {
MTK_RESETTING
};
+/* PSE Port Definition */
+enum mtk_pse_port {
+ PSE_ADMA_PORT = 0,
+ PSE_GDM1_PORT,
+ PSE_GDM2_PORT,
+ PSE_PPE0_PORT,
+ PSE_PPE1_PORT,
+ PSE_QDMA_TX_PORT,
+ PSE_QDMA_RX_PORT,
+ PSE_DROP_PORT,
+ PSE_WDMA0_PORT,
+ PSE_WDMA1_PORT,
+ PSE_TDMA_PORT,
+ PSE_NONE_PORT,
+ PSE_PPE2_PORT,
+ PSE_WDMA2_PORT,
+ PSE_EIP197_PORT,
+ PSE_GDM3_PORT,
+ PSE_PORT_MAX
+};
+
+/* GMAC Identifier */
+enum mtk_gmac_id {
+ MTK_GMAC1_ID = 0,
+ MTK_GMAC2_ID,
+ MTK_GMAC3_ID,
+ MTK_GMAC_ID_MAX
+};
+
+/* GDM Type */
+enum mtk_gdm_type {
+ MTK_GDM_TYPE = 0,
+ MTK_XGDM_TYPE,
+ MTK_GDM_TYPE_MAX
+};
+
enum mtk_tx_buf_type {
MTK_TYPE_SKB,
MTK_TYPE_XDP_TX,
@@ -821,6 +859,7 @@ enum mkt_eth_capabilities {
MTK_QDMA_BIT,
MTK_NETSYS_V1_BIT,
MTK_NETSYS_V2_BIT,
+ MTK_NETSYS_V3_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
MTK_U3_COPHY_V2_BIT,
@@ -857,6 +896,7 @@ enum mkt_eth_capabilities {
#define MTK_QDMA BIT(MTK_QDMA_BIT)
#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
--
2.39.2
From: Lorenzo Bianconi <[email protected]>
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Daniel Golle <[email protected]>
---
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++++++++----------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 317e447f4991..34ac492e047c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -15,10 +15,10 @@
struct mtk_eth_muxc {
const char *name;
int cap_bit;
- int (*set_path)(struct mtk_eth *eth, int path);
+ int (*set_path)(struct mtk_eth *eth, u64 path);
};
-static const char *mtk_eth_path_name(int path)
+static const char *mtk_eth_path_name(u64 path)
{
switch (path) {
case MTK_ETH_PATH_GMAC1_RGMII:
@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int path)
}
}
-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
{
bool updated = true;
u32 val, mask, set;
@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
return 0;
}
-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
return 0;
}
-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0, mask = 0, reg = 0;
bool updated = true;
@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
return 0;
}
-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
return 0;
}
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
},
};
-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
{
int i, err = 0;
@@ -249,7 +249,7 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
{
- int path;
+ u64 path;
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
MTK_ETH_PATH_GMAC2_SGMII;
@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
{
- int path = 0;
+ u64 path = 0;
if (mac_id == 1)
path = MTK_ETH_PATH_GMAC2_GEPHY;
@@ -274,7 +274,7 @@ 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 path;
+ u64 path;
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
MTK_ETH_PATH_GMAC2_RGMII;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index e4f6cca8a3a8..e5bfc2d891ad 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1069,7 +1069,7 @@ struct mtk_reg_map {
struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
- u32 caps;
+ u64 caps;
u32 required_clks;
bool required_pctl;
u8 offload_version;
--
2.39.2
> Gesendet: Dienstag, 07. März 2023 um 16:54 Uhr
> Von: "Daniel Golle" <[email protected]>
> Link partner advertised link modes are not reported by the SerDes
> hardware if not operating in SGMII mode. Hence we cannot use
> phylink_mii_c22_pcs_decode_state() in this case.
> Implement reporting link and an_complete only and use speed according to
> the interface mode.
Hi,
have tested Parts 1-12 this on bananapi-r3 (mt7986) with 1G Fiber SFP (no 2g5 available yet) on gmac1 and lan4 (mt7531 p5)
Tested-by: Frank Wunderlich <[email protected]>
Thx Daniel for working on SFP support :)
regards Frank
> Gesendet: Dienstag, 07. März 2023 um 16:54 Uhr
> Von: "Daniel Golle" <[email protected]>
> The SGMII core found in several MediaTek SoCs is identical to what can
> also be found in MediaTek's MT7531 Ethernet switch IC.
> As this has not always been clear, both drivers developed different
> implementations to deal with the PCS.
> Recently Alexander Couzens pointed out this fact which lead to the
> development of this shared driver.
>
> Add a dedicated driver, mostly by copying the code now found in the
> Ethernet driver. The now redundant code will be removed by a follow-up
> commit.
Hi,
have tested Parts 1-12 this on bananapi-r3 (mt7986) with 1G Fiber SFP (no 2g5 available yet) on gmac1 and lan4 (mt7531 p5)
Tested-by: Frank Wunderlich <[email protected]>
Thx Daniel for working on SFP support :)
regards Frank
> Gesendet: Dienstag, 07. März 2023 um 16:53 Uhr
> Von: "Daniel Golle" <[email protected]>
> Only restart auto-negotiation and write link timer if actually
> necessary. This prevents loosing the link in case of minor
> changes.
Hi,
have tested Parts 1-12 this on bananapi-r3 (mt7986) with 1G Fiber SFP (no 2g5 available yet) on gmac1 and lan4 (mt7531 p5)
Tested-by: Frank Wunderlich <[email protected]>
Thx Daniel for working on SFP support :)
regards Frank
> Gesendet: Dienstag, 07. März 2023 um 16:53 Uhr
> Von: "Daniel Golle" <[email protected]>
>
> Reset the internal PCS state machine when changing interface mode.
> This prevents confusing the state machine when changing interface
> modes, e.g. from SGMII to 2500Base-X or vice-versa.
>
> Reviewed-by: Russell King (Oracle) <[email protected]>
> Tested-by: Bjørn Mork <[email protected]>
> Signed-off-by: Daniel Golle <[email protected]>
Hi,
have tested Parts 1-12 this on bananapi-r3 (mt7986) with 1G Fiber SFP (no 2g5 available yet) on gmac1 and lan4 (mt7531 p5)
Tested-by: Frank Wunderlich <[email protected]>
Thx Daniel for working on SFP support :)
regards Frank
> Gesendet: Dienstag, 07. März 2023 um 16:53 Uhr
> Von: "Daniel Golle" <[email protected]>
>
> After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> would work only after `ethtool -s eth1 autoneg off`.
> As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> to control auto-negotiation on the external interface it doesn't make
> much sense to use it to control on-board SGMII auto-negotiation between
> MAC and PHY.
> Set correct values to really only enable SGMII auto-negotiation when
> actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> enable remote-fault detection only if in-band-status is enabled.
> This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> board and also makes it possible to use interface-mode-switching PHYs
> operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> 2500M mode on other boards.
Hi,
have tested Parts 1-12 this on bananapi-r3 (mt7986) with 1G Fiber SFP (no 2g5 available yet) on gmac1 and lan4 (mt7531 p5)
Tested-by: Frank Wunderlich <[email protected]>
Thx Daniel for working on SFP support :)
regards Frank
On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> would work only after `ethtool -s eth1 autoneg off`.
> As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> to control auto-negotiation on the external interface it doesn't make
> much sense to use it to control on-board SGMII auto-negotiation between
> MAC and PHY.
> Set correct values to really only enable SGMII auto-negotiation when
> actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> enable remote-fault detection only if in-band-status is enabled.
> This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> board and also makes it possible to use interface-mode-switching PHYs
> operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> 2500M mode on other boards.
>
> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> Signed-off-by: Daniel Golle <[email protected]>
NAK.
There are PHYs out there which operate in SGMII mode but do not
exchange the SGMII 16-bit configuration word. The code implemented
here by me was explicitly to allow such a configuration to work,
which is defined as:
SGMII *without* mode == inband
An example of this is the Broadcom 84881 PHY which can be found on
SFP modules.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Tue, Mar 07, 2023 at 03:54:11PM +0000, Daniel Golle wrote:
> Link partner advertised link modes are not reported by the SerDes
> hardware if not operating in SGMII mode. Hence we cannot use
> phylink_mii_c22_pcs_decode_state() in this case.
> Implement reporting link and an_complete only and use speed according to
> the interface mode.
>
> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> Signed-off-by: Daniel Golle <[email protected]>
This has been proven to work by Frank Wunderlich last October, so by
making this change, you will be regressing his setup.
What are you testing against? Have you proven independently that the
link partner is indeed sending a valid advertisement for the LPA
register to be filled in?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Am 8. März 2023 12:38:31 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
>On Tue, Mar 07, 2023 at 03:54:11PM +0000, Daniel Golle wrote:
>> Link partner advertised link modes are not reported by the SerDes
>> hardware if not operating in SGMII mode. Hence we cannot use
>> phylink_mii_c22_pcs_decode_state() in this case.
>> Implement reporting link and an_complete only and use speed according to
>> the interface mode.
>>
>> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
>> Signed-off-by: Daniel Golle <[email protected]>
>
>This has been proven to work by Frank Wunderlich last October, so by
>making this change, you will be regressing his setup.
Hi
My tests were done with 1 kind of 1g fibre sfp as i only have these atm...have ordered some 2g5 rj54 ones,but don't have them yet. I'm not sure if they are working with/without sgmii (1000base-X) and if they have builtin phy.
Daniel have a lot more of different SFPs and some (especially 2g5) were not working after our pcs change.
>What are you testing against? Have you proven independently that the
>link partner is indeed sending a valid advertisement for the LPA
>register to be filled in?
>
regards Frank
On Wed, Mar 08, 2023 at 12:44:57PM +0100, Frank Wunderlich wrote:
> Am 8. M?rz 2023 12:38:31 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> >On Tue, Mar 07, 2023 at 03:54:11PM +0000, Daniel Golle wrote:
> >> Link partner advertised link modes are not reported by the SerDes
> >> hardware if not operating in SGMII mode. Hence we cannot use
> >> phylink_mii_c22_pcs_decode_state() in this case.
> >> Implement reporting link and an_complete only and use speed according to
> >> the interface mode.
> >>
> >> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> >> Signed-off-by: Daniel Golle <[email protected]>
> >
> >This has been proven to work by Frank Wunderlich last October, so by
> >making this change, you will be regressing his setup.
>
> Hi
>
> My tests were done with 1 kind of 1g fibre sfp as i only have these atm...have ordered some 2g5 rj54 ones,but don't have them yet. I'm not sure if they are working with/without sgmii (1000base-X) and if they have builtin phy.
>
> Daniel have a lot more of different SFPs and some (especially 2g5) were not working after our pcs change.
Exactly. 1 GBit/s SFPs with built-in PHY and using SGMII are working
fine before and after conversion to phylink_pcs. 1000Base-X and
2500Base-X PHYs and SFPs were broken after this.
The patch about (and the other one you already NACK'ed) fixes those
codepaths which were simply not used in Frank's setup.
>
> >What are you testing against? Have you proven independently that the
> >link partner is indeed sending a valid advertisement for the LPA
> >register to be filled in?
> >
I have a ballpark of different SFPs and MediaTek boards with different
PHYs here and tried all of them.
I have no way to tell if the SFPs and PHYs which stopped working after
the phylink_pcs conversion are sending valid advertisement. The only
other boards with SFP slots I got here are RealTek-based switches, and
all I can say is that on an RTL8380 based 1G switch both, the SFP
modules containing a PHY and operating in SGMII mode as well as the
ones without a PHY exposed via i2c-mdio and operating in 1000Base-X
mode are working fine with that switch, with both, stock firmware and
OpenWrt running on it.
However, even should they not send valid advertisement, they are very
common parts and they were working before and not after the change to
phylink_pcs, for the reasons mentioned in the description of this
patch.
On Wed, Mar 08, 2023 at 11:35:40AM +0000, Russell King (Oracle) wrote:
> On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> > After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> > would work only after `ethtool -s eth1 autoneg off`.
> > As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> > to control auto-negotiation on the external interface it doesn't make
> > much sense to use it to control on-board SGMII auto-negotiation between
> > MAC and PHY.
> > Set correct values to really only enable SGMII auto-negotiation when
> > actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> > enable remote-fault detection only if in-band-status is enabled.
> > This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> > board and also makes it possible to use interface-mode-switching PHYs
> > operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> > 2500M mode on other boards.
> >
> > Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > Signed-off-by: Daniel Golle <[email protected]>
>
> NAK.
>
> There are PHYs out there which operate in SGMII mode but do not
> exchange the SGMII 16-bit configuration word. The code implemented
> here by me was explicitly to allow such a configuration to work,
> which is defined as:
>
> SGMII *without* mode == inband
>
> An example of this is the Broadcom 84881 PHY which can be found on
> SFP modules.
I also have multiple such 1000Base-T SFP modules here (finisar, AJYA),
and this change doesn't touch the codepaths relevant for those. They
are operating in SGMII mode, they have always been working fine.
What I'm trying to fix here is 1000Base-X and 2500Base-X mode which
has been broken by introducing ETHTOOL_LINK_MODE_Autoneg_BIT as the
deciding factor for in-band AN here.
Can you explain why ETHTOOL_LINK_MODE_Autoneg_BIT was used there in
first place? Is my understanding of this bit controlling autoneg on the
*external* interface rather than on the *system-side* interface wrong?
On Wed, Mar 08, 2023 at 12:44:57PM +0100, Frank Wunderlich wrote:
> Am 8. M?rz 2023 12:38:31 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> >On Tue, Mar 07, 2023 at 03:54:11PM +0000, Daniel Golle wrote:
> >> Link partner advertised link modes are not reported by the SerDes
> >> hardware if not operating in SGMII mode. Hence we cannot use
> >> phylink_mii_c22_pcs_decode_state() in this case.
> >> Implement reporting link and an_complete only and use speed according to
> >> the interface mode.
> >>
> >> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> >> Signed-off-by: Daniel Golle <[email protected]>
> >
> >This has been proven to work by Frank Wunderlich last October, so by
> >making this change, you will be regressing his setup.
>
> Hi
>
> My tests were done with 1 kind of 1g fibre sfp as i only have these atm...have ordered some 2g5 rj54 ones,but don't have them yet. I'm not sure if they are working with/without sgmii (1000base-X) and if they have builtin phy.
Fiber SFPs do not have a built in PHY. They merely convert the serdes
electrical waveform into light and back again, possibly with some
retiming of the received waveform, and a bit of monitoring. They're
pretty simple devices.
They certainly do not change the protocol in any way.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 12:11:48PM +0000, Daniel Golle wrote:
> On Wed, Mar 08, 2023 at 11:35:40AM +0000, Russell King (Oracle) wrote:
> > On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> > > After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> > > would work only after `ethtool -s eth1 autoneg off`.
> > > As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> > > to control auto-negotiation on the external interface it doesn't make
> > > much sense to use it to control on-board SGMII auto-negotiation between
> > > MAC and PHY.
> > > Set correct values to really only enable SGMII auto-negotiation when
> > > actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> > > enable remote-fault detection only if in-band-status is enabled.
> > > This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> > > board and also makes it possible to use interface-mode-switching PHYs
> > > operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> > > 2500M mode on other boards.
> > >
> > > Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > > Signed-off-by: Daniel Golle <[email protected]>
> >
> > NAK.
> >
> > There are PHYs out there which operate in SGMII mode but do not
> > exchange the SGMII 16-bit configuration word. The code implemented
> > here by me was explicitly to allow such a configuration to work,
> > which is defined as:
> >
> > SGMII *without* mode == inband
> >
> > An example of this is the Broadcom 84881 PHY which can be found on
> > SFP modules.
>
> I also have multiple such 1000Base-T SFP modules here (finisar, AJYA),
> and this change doesn't touch the codepaths relevant for those. They
> are operating in SGMII mode, they have always been working fine.
>
> What I'm trying to fix here is 1000Base-X and 2500Base-X mode which
> has been broken by introducing ETHTOOL_LINK_MODE_Autoneg_BIT as the
> deciding factor for in-band AN here.
... which is correct.
> Can you explain why ETHTOOL_LINK_MODE_Autoneg_BIT was used there in
> first place? Is my understanding of this bit controlling autoneg on the
> *external* interface rather than on the *system-side* interface wrong?
Think about what 1000BASE-X is for. It's not really for internal links,
it's intended by IEEE 802.3 to be the 1G *media* side protocol for
1000BASE-SX, 1000BASE-LX, 1000BASE-CX etc links.
Therefore, when being used in that case, one may wish to disable
autoneg over the fibre link. Hence, turning off autoneg via ethtool
*should* turn off autoneg over the fibre link. So, using
ETHTOOL_LINK_MODE_Autoneg_BIT to gate 802.3z autonegotiation the
correct thing to do.
If we have a PHY using 1000BASE-X, then it is at odds with the
primary purpose of this protocol, especially with it comes to AN.
This is why phylink used to refuse to accept PHYs when using 802.3z
mode, but Marek wanted this to work, so relaxed the checks
preventing such a setup working.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 12:41:43PM +0000, Russell King (Oracle) wrote:
> On Wed, Mar 08, 2023 at 12:11:48PM +0000, Daniel Golle wrote:
> > On Wed, Mar 08, 2023 at 11:35:40AM +0000, Russell King (Oracle) wrote:
> > > On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> > > > After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> > > > would work only after `ethtool -s eth1 autoneg off`.
> > > > As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> > > > to control auto-negotiation on the external interface it doesn't make
> > > > much sense to use it to control on-board SGMII auto-negotiation between
> > > > MAC and PHY.
> > > > Set correct values to really only enable SGMII auto-negotiation when
> > > > actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> > > > enable remote-fault detection only if in-band-status is enabled.
> > > > This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> > > > board and also makes it possible to use interface-mode-switching PHYs
> > > > operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> > > > 2500M mode on other boards.
> > > >
> > > > Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > > > Signed-off-by: Daniel Golle <[email protected]>
> > >
> > > NAK.
> > >
> > > There are PHYs out there which operate in SGMII mode but do not
> > > exchange the SGMII 16-bit configuration word. The code implemented
> > > here by me was explicitly to allow such a configuration to work,
> > > which is defined as:
> > >
> > > SGMII *without* mode == inband
> > >
> > > An example of this is the Broadcom 84881 PHY which can be found on
> > > SFP modules.
> >
> > I also have multiple such 1000Base-T SFP modules here (finisar, AJYA),
> > and this change doesn't touch the codepaths relevant for those. They
> > are operating in SGMII mode, they have always been working fine.
> >
> > What I'm trying to fix here is 1000Base-X and 2500Base-X mode which
> > has been broken by introducing ETHTOOL_LINK_MODE_Autoneg_BIT as the
> > deciding factor for in-band AN here.
>
> ... which is correct.
>
> > Can you explain why ETHTOOL_LINK_MODE_Autoneg_BIT was used there in
> > first place? Is my understanding of this bit controlling autoneg on the
> > *external* interface rather than on the *system-side* interface wrong?
>
> Think about what 1000BASE-X is for. It's not really for internal links,
> it's intended by IEEE 802.3 to be the 1G *media* side protocol for
> 1000BASE-SX, 1000BASE-LX, 1000BASE-CX etc links.
>
> Therefore, when being used in that case, one may wish to disable
> autoneg over the fibre link. Hence, turning off autoneg via ethtool
> *should* turn off autoneg over the fibre link. So, using
> ETHTOOL_LINK_MODE_Autoneg_BIT to gate 802.3z autonegotiation the
> correct thing to do.
>
> If we have a PHY using 1000BASE-X, then it is at odds with the
> primary purpose of this protocol, especially with it comes to AN.
> This is why phylink used to refuse to accept PHYs when using 802.3z
> mode, but Marek wanted this to work, so relaxed the checks
> preventing such a setup working.
Sadly 2500Base-X is very commonly used to connect 2500Base-T-capable
PHYs or SFP modules. I also got an ATS branded 1000M/100M/10M copper
SFP module which uses 1000Base-X as system-side interface, independently
of the speed of the link partner on the TP interface.
All of them do not work with inband-AN enabled and a link only comes
up after `ethtool -s eth1 autoneg off` in the current implementation,
while previously they were working just fine.
I understand that there isn't really a good solution for 1000Base-X as
thanks to you I now understand that SerDes autoneg just transparently
ends up being autoneg on a fiber link.
2500Base-X, however, is hardly used for fiber links, but rather mostly
for 2500Base-T PHYs and SFP module as well as xPON SFPs. Maybe we could
at least have in-band AN disabled by default for those to get them
working without requiring the user to carry out ethtool settings?
On Wed, Mar 08, 2023 at 12:53:13PM +0000, Daniel Golle wrote:
> On Wed, Mar 08, 2023 at 12:41:43PM +0000, Russell King (Oracle) wrote:
> > On Wed, Mar 08, 2023 at 12:11:48PM +0000, Daniel Golle wrote:
> > > On Wed, Mar 08, 2023 at 11:35:40AM +0000, Russell King (Oracle) wrote:
> > > > On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> > > > > After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> > > > > would work only after `ethtool -s eth1 autoneg off`.
> > > > > As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> > > > > to control auto-negotiation on the external interface it doesn't make
> > > > > much sense to use it to control on-board SGMII auto-negotiation between
> > > > > MAC and PHY.
> > > > > Set correct values to really only enable SGMII auto-negotiation when
> > > > > actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> > > > > enable remote-fault detection only if in-band-status is enabled.
> > > > > This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> > > > > board and also makes it possible to use interface-mode-switching PHYs
> > > > > operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> > > > > 2500M mode on other boards.
> > > > >
> > > > > Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > > > > Signed-off-by: Daniel Golle <[email protected]>
> > > >
> > > > NAK.
> > > >
> > > > There are PHYs out there which operate in SGMII mode but do not
> > > > exchange the SGMII 16-bit configuration word. The code implemented
> > > > here by me was explicitly to allow such a configuration to work,
> > > > which is defined as:
> > > >
> > > > SGMII *without* mode == inband
> > > >
> > > > An example of this is the Broadcom 84881 PHY which can be found on
> > > > SFP modules.
> > >
> > > I also have multiple such 1000Base-T SFP modules here (finisar, AJYA),
> > > and this change doesn't touch the codepaths relevant for those. They
> > > are operating in SGMII mode, they have always been working fine.
> > >
> > > What I'm trying to fix here is 1000Base-X and 2500Base-X mode which
> > > has been broken by introducing ETHTOOL_LINK_MODE_Autoneg_BIT as the
> > > deciding factor for in-band AN here.
> >
> > ... which is correct.
> >
> > > Can you explain why ETHTOOL_LINK_MODE_Autoneg_BIT was used there in
> > > first place? Is my understanding of this bit controlling autoneg on the
> > > *external* interface rather than on the *system-side* interface wrong?
> >
> > Think about what 1000BASE-X is for. It's not really for internal links,
> > it's intended by IEEE 802.3 to be the 1G *media* side protocol for
> > 1000BASE-SX, 1000BASE-LX, 1000BASE-CX etc links.
> >
> > Therefore, when being used in that case, one may wish to disable
> > autoneg over the fibre link. Hence, turning off autoneg via ethtool
> > *should* turn off autoneg over the fibre link. So, using
> > ETHTOOL_LINK_MODE_Autoneg_BIT to gate 802.3z autonegotiation the
> > correct thing to do.
> >
> > If we have a PHY using 1000BASE-X, then it is at odds with the
> > primary purpose of this protocol, especially with it comes to AN.
> > This is why phylink used to refuse to accept PHYs when using 802.3z
> > mode, but Marek wanted this to work, so relaxed the checks
> > preventing such a setup working.
>
> Sadly 2500Base-X is very commonly used to connect 2500Base-T-capable
> PHYs or SFP modules. I also got an ATS branded 1000M/100M/10M copper
> SFP module which uses 1000Base-X as system-side interface, independently
> of the speed of the link partner on the TP interface.
> All of them do not work with inband-AN enabled and a link only comes
> up after `ethtool -s eth1 autoneg off` in the current implementation,
> while previously they were working just fine.
>
> I understand that there isn't really a good solution for 1000Base-X as
> thanks to you I now understand that SerDes autoneg just transparently
> ends up being autoneg on a fiber link.
>
> 2500Base-X, however, is hardly used for fiber links, but rather mostly
> for 2500Base-T PHYs and SFP module as well as xPON SFPs. Maybe we could
> at least have in-band AN disabled by default for those to get them
> working without requiring the user to carry out ethtool settings?
We could _possibly_ make 2500base-X ignore the autoneg bit, but in
order to do that I would want to make other changes, because this
is getting absolutely stupid to have these decisions being made in
each and every PCS - and have each PCS author implementing different
decision making in their PCS driver.
The problem that gives is it makes phylink maintenance in hard,
because it becomes impossible to predict what the effect of any
change is.
It also means that plugging the same SFP module into different
hardware will give different results (maybe it works, maybe it
doesn't.)
So, what I would want to do is to move the decision about whether
the PCS should enable in-band into the phylink core code instead
of these random decisions being made in each PCS.
At that point, we can then make the decision about whether the
ethtool autoneg bit should affect whether the PCS uses inband
depending on whether the PCS is effectively the media facing
entity, or whether there is a PHY attached - and if there is a PHY
attached, ask the PHY whether it will be using in-band or not.
This also would give a way to ensure that all PCS adopt the same
behaviour.
Does that sound a reasonable approach?
Strangely, I already have some patches along those lines in my
net-queue branch. See:
net: phylink: add helpers for decoding mode
net: use phylink_mode_*() helpers
net: phylink: split PCS in-band from inband mode
It's nowhere near finished though, it was just an idea back in
2021 when the problem of getting rid of differing PCS behaviours
was on my mind.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 01:12:10PM +0000, Russell King (Oracle) wrote:
> So, what I would want to do is to move the decision about whether
> the PCS should enable in-band into the phylink core code instead
> of these random decisions being made in each PCS.
>
> At that point, we can then make the decision about whether the
> ethtool autoneg bit should affect whether the PCS uses inband
> depending on whether the PCS is effectively the media facing
> entity, or whether there is a PHY attached - and if there is a PHY
> attached, ask the PHY whether it will be using in-band or not.
>
> This also would give a way to ensure that all PCS adopt the same
> behaviour.
>
> Does that sound a reasonable approach?
>
> Strangely, I already have some patches along those lines in my
> net-queue branch. See:
>
> net: phylink: add helpers for decoding mode
> net: use phylink_mode_*() helpers
> net: phylink: split PCS in-band from inband mode
>
> It's nowhere near finished though, it was just an idea back in
> 2021 when the problem of getting rid of differing PCS behaviours
> was on my mind.
Having looked at those patches
(http://git.armlinux.org.uk/cgit/linux-arm.git/commit/?h=net-queue&id=a632167d226cf95d92cd887b2f1678e1539833b1)
and seen the way in which they are incomplete, could you sketch here how
do you see an actual pcs_validate() implementation making use of the new
"mode" argument?
I'd expect there to be some logic which changes the "mode", if the PCS
validation with the existing one fails... or?
On Wed, Mar 08, 2023 at 03:46:42PM +0200, Vladimir Oltean wrote:
> On Wed, Mar 08, 2023 at 01:12:10PM +0000, Russell King (Oracle) wrote:
> > So, what I would want to do is to move the decision about whether
> > the PCS should enable in-band into the phylink core code instead
> > of these random decisions being made in each PCS.
> >
> > At that point, we can then make the decision about whether the
> > ethtool autoneg bit should affect whether the PCS uses inband
> > depending on whether the PCS is effectively the media facing
> > entity, or whether there is a PHY attached - and if there is a PHY
> > attached, ask the PHY whether it will be using in-band or not.
> >
> > This also would give a way to ensure that all PCS adopt the same
> > behaviour.
> >
> > Does that sound a reasonable approach?
> >
> > Strangely, I already have some patches along those lines in my
> > net-queue branch. See:
> >
> > net: phylink: add helpers for decoding mode
> > net: use phylink_mode_*() helpers
> > net: phylink: split PCS in-band from inband mode
> >
> > It's nowhere near finished though, it was just an idea back in
> > 2021 when the problem of getting rid of differing PCS behaviours
> > was on my mind.
>
> Having looked at those patches
> (http://git.armlinux.org.uk/cgit/linux-arm.git/commit/?h=net-queue&id=a632167d226cf95d92cd887b2f1678e1539833b1)
> and seen the way in which they are incomplete, could you sketch here how
> do you see an actual pcs_validate() implementation making use of the new
> "mode" argument?
>
> I'd expect there to be some logic which changes the "mode", if the PCS
> validation with the existing one fails... or?
You may notice that I explicitly didn't include the patches adding the
mode argument to the validation path, precisely because that's an
unanswered question.
I haven't done much work in this area because I gave up with trying to
convert mv88e6xxx to phylink_pcs because it just became impossible
due to the history of the driver - and that destroyed my motivation
for further work, because that would mean I'd just accumulate more
and more patches. You may have noticed that I'm hardly doing any
development work on phylink over the last few months, instead
concentrating on problem non-DSA network drivers.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 01:12:10PM +0000, Russell King (Oracle) wrote:
> On Wed, Mar 08, 2023 at 12:53:13PM +0000, Daniel Golle wrote:
> > On Wed, Mar 08, 2023 at 12:41:43PM +0000, Russell King (Oracle) wrote:
> > > On Wed, Mar 08, 2023 at 12:11:48PM +0000, Daniel Golle wrote:
> > > > On Wed, Mar 08, 2023 at 11:35:40AM +0000, Russell King (Oracle) wrote:
> > > > > On Tue, Mar 07, 2023 at 03:53:58PM +0000, Daniel Golle wrote:
> > > > > > After conversion to phylink_pcs the 1000Base-X and 2500Base-X modes
> > > > > > would work only after `ethtool -s eth1 autoneg off`.
> > > > > > As ethtool autoneg and the ETHTOOL_LINK_MODE_Autoneg_BIT is supposed
> > > > > > to control auto-negotiation on the external interface it doesn't make
> > > > > > much sense to use it to control on-board SGMII auto-negotiation between
> > > > > > MAC and PHY.
> > > > > > Set correct values to really only enable SGMII auto-negotiation when
> > > > > > actually operating in SGMII mode. For 1000Base-X and 2500Base-X mode,
> > > > > > enable remote-fault detection only if in-band-status is enabled.
> > > > > > This fixes using 1000Base-X and 2500Base-X SFPs on the BananaPi R3
> > > > > > board and also makes it possible to use interface-mode-switching PHYs
> > > > > > operating in either SGMII mode for 10M/100M/1000M or in 2500Base-X for
> > > > > > 2500M mode on other boards.
> > > > > >
> > > > > > Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > > > > > Signed-off-by: Daniel Golle <[email protected]>
> > > > >
> > > > > NAK.
> > > > >
> > > > > There are PHYs out there which operate in SGMII mode but do not
> > > > > exchange the SGMII 16-bit configuration word. The code implemented
> > > > > here by me was explicitly to allow such a configuration to work,
> > > > > which is defined as:
> > > > >
> > > > > SGMII *without* mode == inband
> > > > >
> > > > > An example of this is the Broadcom 84881 PHY which can be found on
> > > > > SFP modules.
> > > >
> > > > I also have multiple such 1000Base-T SFP modules here (finisar, AJYA),
> > > > and this change doesn't touch the codepaths relevant for those. They
> > > > are operating in SGMII mode, they have always been working fine.
> > > >
> > > > What I'm trying to fix here is 1000Base-X and 2500Base-X mode which
> > > > has been broken by introducing ETHTOOL_LINK_MODE_Autoneg_BIT as the
> > > > deciding factor for in-band AN here.
> > >
> > > ... which is correct.
> > >
> > > > Can you explain why ETHTOOL_LINK_MODE_Autoneg_BIT was used there in
> > > > first place? Is my understanding of this bit controlling autoneg on the
> > > > *external* interface rather than on the *system-side* interface wrong?
> > >
> > > Think about what 1000BASE-X is for. It's not really for internal links,
> > > it's intended by IEEE 802.3 to be the 1G *media* side protocol for
> > > 1000BASE-SX, 1000BASE-LX, 1000BASE-CX etc links.
> > >
> > > Therefore, when being used in that case, one may wish to disable
> > > autoneg over the fibre link. Hence, turning off autoneg via ethtool
> > > *should* turn off autoneg over the fibre link. So, using
> > > ETHTOOL_LINK_MODE_Autoneg_BIT to gate 802.3z autonegotiation the
> > > correct thing to do.
> > >
> > > If we have a PHY using 1000BASE-X, then it is at odds with the
> > > primary purpose of this protocol, especially with it comes to AN.
> > > This is why phylink used to refuse to accept PHYs when using 802.3z
> > > mode, but Marek wanted this to work, so relaxed the checks
> > > preventing such a setup working.
> >
> > Sadly 2500Base-X is very commonly used to connect 2500Base-T-capable
> > PHYs or SFP modules. I also got an ATS branded 1000M/100M/10M copper
> > SFP module which uses 1000Base-X as system-side interface, independently
> > of the speed of the link partner on the TP interface.
> > All of them do not work with inband-AN enabled and a link only comes
> > up after `ethtool -s eth1 autoneg off` in the current implementation,
> > while previously they were working just fine.
> >
> > I understand that there isn't really a good solution for 1000Base-X as
> > thanks to you I now understand that SerDes autoneg just transparently
> > ends up being autoneg on a fiber link.
> >
> > 2500Base-X, however, is hardly used for fiber links, but rather mostly
> > for 2500Base-T PHYs and SFP module as well as xPON SFPs. Maybe we could
> > at least have in-band AN disabled by default for those to get them
> > working without requiring the user to carry out ethtool settings?
>
> We could _possibly_ make 2500base-X ignore the autoneg bit, but in
> order to do that I would want to make other changes, because this
> is getting absolutely stupid to have these decisions being made in
> each and every PCS - and have each PCS author implementing different
> decision making in their PCS driver.
>
> The problem that gives is it makes phylink maintenance in hard,
> because it becomes impossible to predict what the effect of any
> change is.
>
> It also means that plugging the same SFP module into different
> hardware will give different results (maybe it works, maybe it
> doesn't.)
>
> So, what I would want to do is to move the decision about whether
> the PCS should enable in-band into the phylink core code instead
> of these random decisions being made in each PCS.
>
> At that point, we can then make the decision about whether the
> ethtool autoneg bit should affect whether the PCS uses inband
> depending on whether the PCS is effectively the media facing
> entity, or whether there is a PHY attached - and if there is a PHY
> attached, ask the PHY whether it will be using in-band or not.
>
> This also would give a way to ensure that all PCS adopt the same
> behaviour.
>
> Does that sound a reasonable approach?
In general it sound reasonable. We may need more SFP qurik bits to
indicate presence of a PHY on SFP modules which do not expose that
PHY via i2c-mdio or otherwise let the host know about it's presence.
For my TP-LINK TL-SM410U 2500Base-T SFP this unfortunately seems to
be the case, and I assume it's actually like that for most
2500Base-T as well as xPON SFPs... (xPON SFPs are usually managed
via high-level protocols, even Web-UI is common there. They don't
tell you much about them via I2C, I suppose to get them to work in
as many SFP host devices as possible without any software changes).
FYI:
TP-LINK TL-SM410U 2500Base-T module:
sfp EE: 00000000: 03 04 07 00 00 00 00 00 00 40 00 01 1f 00 00 00 .........@......
sfp EE: 00000010: 00 00 00 00 54 50 2d 4c 49 4e 4b 20 20 20 20 20 ....TP-LINK
sfp EE: 00000020: 20 20 20 20 00 30 b5 c2 54 4c 2d 53 4d 34 31 30 .0..TL-SM410
sfp EE: 00000030: 55 20 20 20 20 20 20 20 32 2e 30 20 00 00 00 1b U 2.0 ....
sfp EE: 00000040: 00 08 01 00 80 ff ff ff 40 3d f0 0d c0 ff ff ff ........@=......
sfp EE: 00000050: c8 39 7a 08 c0 ff ff ff 50 3d f0 0d c0 ff ff ff .9z.....P=......
sfp sfp2: module TP-LINK TL-SM410U rev 2.0 sn 12260M4001782 dc 220622
And this is the ATS SFP-GE-T 10/100/1000M copper module doing
rate-adaptation to 1000Base-X:
sfp sfp1: EEPROM extended structure checksum failure: 0xb0 != 0xaf
sfp EE: 00000000: 03 04 07 00 00 00 02 12 00 01 01 01 0c 00 03 00 ................
sfp EE: 00000010: 00 00 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 ....OEM
sfp EE: 00000020: 20 20 20 20 00 00 90 65 53 46 50 2d 47 45 2d 54 ...eSFP-GE-T
sfp EE: 00000030: 20 20 20 20 00 00 00 00 43 20 20 20 00 00 00 f0 ....C ....
sfp EE: 00000040: 00 12 00 00 32 31 30 37 31 30 41 30 30 31 32 37 ....210710A00127
sfp EE: 00000050: 33 39 00 00 32 31 30 37 31 30 20 20 60 00 01 af 39..210710 `...
sfp sfp1: module OEM SFP-GE-T rev C sn dc
That one already needs quirks to even work at all as TX-FAULT is not
reported properly by the module, see
https://github.com/dangowrt/linux/commit/2c694bd494583f08858fabca97cfdc79de8ba089
>
> Strangely, I already have some patches along those lines in my
> net-queue branch. See:
>
> net: phylink: add helpers for decoding mode
> net: use phylink_mode_*() helpers
> net: phylink: split PCS in-band from inband mode
>
> It's nowhere near finished though, it was just an idea back in
> 2021 when the problem of getting rid of differing PCS behaviours
> was on my mind.
I'll take a look and let you know.
For this series, I will post v13 without the two patches fixing
????Base-X modes tomorrow, waiting for other comments on the current
post of the series up to then.
On Wed, Mar 08, 2023 at 02:32:40PM +0000, Daniel Golle wrote:
> In general it sound reasonable. We may need more SFP qurik bits to
> indicate presence of a PHY on SFP modules which do not expose that
> PHY via i2c-mdio or otherwise let the host know about it's presence.
That's a whole load of fun - some modules where the PHY is inaccessible
will be using 1000base-X, others will be using SGMII. So yes, its
likely that we may need quirks for these. We don't have quirks yet
because you're the first to suggest there's a problem.
> For my TP-LINK TL-SM410U 2500Base-T SFP this unfortunately seems to
> be the case, and I assume it's actually like that for most
> 2500Base-T as well as xPON SFPs... (xPON SFPs are usually managed
> via high-level protocols, even Web-UI is common there. They don't
> tell you much about them via I2C, I suppose to get them to work in
> as many SFP host devices as possible without any software changes).
xPON SFPs are a whole different ball game. For some, they auto-detect
while booting and try 2500base-X or 1000base-X to see which will sync
and if not they try the other. Other xPON SFPs run their host interface
at a speed determined by the configuration set by the remote end. Other
xPON SFPs may do something entirely different.
In many cases, their EEPROM is a full of errors - such as advertising
that they're 1.2 or 1.3 Gbd while operating in 2500base-X mode.
They do weird stuff with their status pins as well, for example, some
use the RX_LOS pin as a uart - which is a problem if it's e.g. tied
from the cage to a switch that uses the pin to gate the link-up
indication without any software control of that!
With xPON SFPs, it's just a total minefield, which lots of SFF MSA
violations all over the place. They're essentially a law to themselves
(this is exactly why we have the quirks infrastructure.)
> FYI:
> TP-LINK TL-SM410U 2500Base-T module:
>
> sfp EE: 00000000: 03 04 07 00 00 00 00 00 00 40 00 01 1f 00 00 00 .........@......
> sfp EE: 00000010: 00 00 00 00 54 50 2d 4c 49 4e 4b 20 20 20 20 20 ....TP-LINK
> sfp EE: 00000020: 20 20 20 20 00 30 b5 c2 54 4c 2d 53 4d 34 31 30 .0..TL-SM410
> sfp EE: 00000030: 55 20 20 20 20 20 20 20 32 2e 30 20 00 00 00 1b U 2.0 ....
> sfp EE: 00000040: 00 08 01 00 80 ff ff ff 40 3d f0 0d c0 ff ff ff ........@=......
> sfp EE: 00000050: c8 39 7a 08 c0 ff ff ff 50 3d f0 0d c0 ff ff ff .9z.....P=......
> sfp sfp2: module TP-LINK TL-SM410U rev 2.0 sn 12260M4001782 dc 220622
I'm guessing this is a module with a checksum problem...
> And this is the ATS SFP-GE-T 10/100/1000M copper module doing
> rate-adaptation to 1000Base-X:
>
> sfp sfp1: EEPROM extended structure checksum failure: 0xb0 != 0xaf
Given how close that is, it looks like they used the wrong algorithm.
> sfp EE: 00000000: 03 04 07 00 00 00 02 12 00 01 01 01 0c 00 03 00 ................
> sfp EE: 00000010: 00 00 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 ....OEM
> sfp EE: 00000020: 20 20 20 20 00 00 90 65 53 46 50 2d 47 45 2d 54 ...eSFP-GE-T
> sfp EE: 00000030: 20 20 20 20 00 00 00 00 43 20 20 20 00 00 00 f0 ....C ....
> sfp EE: 00000040: 00 12 00 00 32 31 30 37 31 30 41 30 30 31 32 37 ....210710A00127
> sfp EE: 00000050: 33 39 00 00 32 31 30 37 31 30 20 20 60 00 01 af 39..210710 `...
> sfp sfp1: module OEM SFP-GE-T rev C sn dc
Welcome to the wonderful world of horribly broken SFPs.
Do we know what form of rate adaption this module needs on the
transmit path? Does it require the host to pace itself to the media
speed (which I suspect will be unreadable if the PHY isn't accessible)
or will it send pause frames?
It would be nice to add these to my database - please send me the
output of ethtool -m $iface raw on > foo.bin for each module.
> That one already needs quirks to even work at all as TX-FAULT is not
> reported properly by the module, see
>
> https://github.com/dangowrt/linux/commit/2c694bd494583f08858fabca97cfdc79de8ba089
I'm guessing that's not on a kernel version that has:
73472c830eae net: sfp: add support for HALNy GPON SFP
5029be761161 net: sfp: move Huawei MA5671A fixup
275416754e9a net: sfp: move Alcatel Lucent 3FE46541AA fixup
23571c7b9643 net: sfp: move quirk handling into sfp.c
8475c4b70b04 net: sfp: re-implement soft state polling setup
which reworks how we deal with the soft/hard state signals.
I think the problem space is growing, and I fear that if we try to
address all these issues in one go, we're going to end up with way
too much to deal with in one go (which means poor reviews etc.)
Can we try to concentrate on fixing one problem at a time, rather
than throwing a whole load of problems into the mix?
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 03:01:07PM +0000, Russell King (Oracle) wrote:
> On Wed, Mar 08, 2023 at 02:32:40PM +0000, Daniel Golle wrote:
> > In general it sound reasonable. We may need more SFP qurik bits to
> > indicate presence of a PHY on SFP modules which do not expose that
> > PHY via i2c-mdio or otherwise let the host know about it's presence.
>
> That's a whole load of fun - some modules where the PHY is inaccessible
> will be using 1000base-X, others will be using SGMII. So yes, its
> likely that we may need quirks for these. We don't have quirks yet
> because you're the first to suggest there's a problem.
>
> > For my TP-LINK TL-SM410U 2500Base-T SFP this unfortunately seems to
> > be the case, and I assume it's actually like that for most
> > 2500Base-T as well as xPON SFPs... (xPON SFPs are usually managed
> > via high-level protocols, even Web-UI is common there. They don't
> > tell you much about them via I2C, I suppose to get them to work in
> > as many SFP host devices as possible without any software changes).
>
> xPON SFPs are a whole different ball game. For some, they auto-detect
> while booting and try 2500base-X or 1000base-X to see which will sync
> and if not they try the other. Other xPON SFPs run their host interface
> at a speed determined by the configuration set by the remote end. Other
> xPON SFPs may do something entirely different.
>
> In many cases, their EEPROM is a full of errors - such as advertising
> that they're 1.2 or 1.3 Gbd while operating in 2500base-X mode.
>
> They do weird stuff with their status pins as well, for example, some
> use the RX_LOS pin as a uart - which is a problem if it's e.g. tied
> from the cage to a switch that uses the pin to gate the link-up
> indication without any software control of that!
>
> With xPON SFPs, it's just a total minefield, which lots of SFF MSA
> violations all over the place. They're essentially a law to themselves
> (this is exactly why we have the quirks infrastructure.)
>
> > FYI:
> > TP-LINK TL-SM410U 2500Base-T module:
> >
> > sfp EE: 00000000: 03 04 07 00 00 00 00 00 00 40 00 01 1f 00 00 00 .........@......
> > sfp EE: 00000010: 00 00 00 00 54 50 2d 4c 49 4e 4b 20 20 20 20 20 ....TP-LINK
> > sfp EE: 00000020: 20 20 20 20 00 30 b5 c2 54 4c 2d 53 4d 34 31 30 .0..TL-SM410
> > sfp EE: 00000030: 55 20 20 20 20 20 20 20 32 2e 30 20 00 00 00 1b U 2.0 ....
> > sfp EE: 00000040: 00 08 01 00 80 ff ff ff 40 3d f0 0d c0 ff ff ff ........@=......
> > sfp EE: 00000050: c8 39 7a 08 c0 ff ff ff 50 3d f0 0d c0 ff ff ff .9z.....P=......
> > sfp sfp2: module TP-LINK TL-SM410U rev 2.0 sn 12260M4001782 dc 220622
>
> I'm guessing this is a module with a checksum problem...
No, the checksum of the TL-SM410U is correct. I have patched the kernel
to always dump the EEPROM, so I can share it with you.
>
> > And this is the ATS SFP-GE-T 10/100/1000M copper module doing
> > rate-adaptation to 1000Base-X:
> >
> > sfp sfp1: EEPROM extended structure checksum failure: 0xb0 != 0xaf
>
> Given how close that is, it looks like they used the wrong algorithm.
>
> > sfp EE: 00000000: 03 04 07 00 00 00 02 12 00 01 01 01 0c 00 03 00 ................
> > sfp EE: 00000010: 00 00 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 ....OEM
> > sfp EE: 00000020: 20 20 20 20 00 00 90 65 53 46 50 2d 47 45 2d 54 ...eSFP-GE-T
> > sfp EE: 00000030: 20 20 20 20 00 00 00 00 43 20 20 20 00 00 00 f0 ....C ....
> > sfp EE: 00000040: 00 12 00 00 32 31 30 37 31 30 41 30 30 31 32 37 ....210710A00127
> > sfp EE: 00000050: 33 39 00 00 32 31 30 37 31 30 20 20 60 00 01 af 39..210710 `...
> > sfp sfp1: module OEM SFP-GE-T rev C sn dc
>
> Welcome to the wonderful world of horribly broken SFPs.
>
> Do we know what form of rate adaption this module needs on the
> transmit path? Does it require the host to pace itself to the media
> speed (which I suspect will be unreadable if the PHY isn't accessible)
> or will it send pause frames?
>
> It would be nice to add these to my database - please send me the
> output of ethtool -m $iface raw on > foo.bin for each module.
>
> > That one already needs quirks to even work at all as TX-FAULT is not
> > reported properly by the module, see
> >
> > https://github.com/dangowrt/linux/commit/2c694bd494583f08858fabca97cfdc79de8ba089
>
> I'm guessing that's not on a kernel version that has:
>
> 73472c830eae net: sfp: add support for HALNy GPON SFP
> 5029be761161 net: sfp: move Huawei MA5671A fixup
> 275416754e9a net: sfp: move Alcatel Lucent 3FE46541AA fixup
> 23571c7b9643 net: sfp: move quirk handling into sfp.c
> 8475c4b70b04 net: sfp: re-implement soft state polling setup
>
> which reworks how we deal with the soft/hard state signals.
>
> I think the problem space is growing, and I fear that if we try to
> address all these issues in one go, we're going to end up with way
> too much to deal with in one go (which means poor reviews etc.)
>
> Can we try to concentrate on fixing one problem at a time, rather
> than throwing a whole load of problems into the mix?
Ok. I'll just repost tomorrow without the ????Base-X AN realted patches.
>
> Thanks.
>
> --
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 03:08:55PM +0000, Daniel Golle wrote:
> On Wed, Mar 08, 2023 at 03:01:07PM +0000, Russell King (Oracle) wrote:
> > > FYI:
> > > TP-LINK TL-SM410U 2500Base-T module:
> > >
> > > sfp EE: 00000000: 03 04 07 00 00 00 00 00 00 40 00 01 1f 00 00 00 .........@......
> > > sfp EE: 00000010: 00 00 00 00 54 50 2d 4c 49 4e 4b 20 20 20 20 20 ....TP-LINK
> > > sfp EE: 00000020: 20 20 20 20 00 30 b5 c2 54 4c 2d 53 4d 34 31 30 .0..TL-SM410
> > > sfp EE: 00000030: 55 20 20 20 20 20 20 20 32 2e 30 20 00 00 00 1b U 2.0 ....
> > > sfp EE: 00000040: 00 08 01 00 80 ff ff ff 40 3d f0 0d c0 ff ff ff ........@=......
> > > sfp EE: 00000050: c8 39 7a 08 c0 ff ff ff 50 3d f0 0d c0 ff ff ff .9z.....P=......
> > > sfp sfp2: module TP-LINK TL-SM410U rev 2.0 sn 12260M4001782 dc 220622
> >
> > I'm guessing this is a module with a checksum problem...
>
> No, the checksum of the TL-SM410U is correct. I have patched the kernel
> to always dump the EEPROM, so I can share it with you.
Bear in mind that I haven't spent time with the spec to manually decode
the above, when I have tools to do that for me when given the EEPROM in
the correct form, which is:
> > It would be nice to add these to my database - please send me the
> > output of ethtool -m $iface raw on > foo.bin for each module.
so if you can do that for me, then I can see whether it's likely that
the patches that are already in mainline will do anything to solve
the workaround you've had to add for the hw signals.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Wed, Mar 08, 2023 at 12:05:19PM +0000, Daniel Golle wrote:
> On Wed, Mar 08, 2023 at 12:44:57PM +0100, Frank Wunderlich wrote:
> > Am 8. M?rz 2023 12:38:31 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> > >On Tue, Mar 07, 2023 at 03:54:11PM +0000, Daniel Golle wrote:
> > >> Link partner advertised link modes are not reported by the SerDes
> > >> hardware if not operating in SGMII mode. Hence we cannot use
> > >> phylink_mii_c22_pcs_decode_state() in this case.
> > >> Implement reporting link and an_complete only and use speed according to
> > >> the interface mode.
> > >>
> > >> Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs")
> > >> Signed-off-by: Daniel Golle <[email protected]>
> > >
> > >This has been proven to work by Frank Wunderlich last October, so by
> > >making this change, you will be regressing his setup.
> >
> > Hi
> >
> > My tests were done with 1 kind of 1g fibre sfp as i only have these atm...have ordered some 2g5 rj54 ones,but don't have them yet. I'm not sure if they are working with/without sgmii (1000base-X) and if they have builtin phy.
> >
> > Daniel have a lot more of different SFPs and some (especially 2g5) were not working after our pcs change.
>
> Exactly. 1 GBit/s SFPs with built-in PHY and using SGMII are working
> fine before and after conversion to phylink_pcs. 1000Base-X and
> 2500Base-X PHYs and SFPs were broken after this.
>
> The patch about (and the other one you already NACK'ed) fixes those
> codepaths which were simply not used in Frank's setup.
You're replying to "Frank" but I think the "you" you are using there
is addressed to me.
I beg to differ with your assessment over whether the code paths were
used or not. Here's the proof from Frank's testing:
https://lore.kernel.org/all/trinity-4470b00b-771b-466e-9f3a-a3df72758208-1666435920485@3c-app-gmx-bs49/
The values at offset 8 (0x40e041a0) _are_ 1000base-X AN values, not
SGMII. There are many messages in that thread showing valid 1000base-X
AN values in register 8 (that being the local advertisement in the
lower 16 bits, and the partner's advertisement in the upper 16 bits.
The link partner in this case sent 0x40e0, which is:
#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
#define LPA_LPACK 0x4000 /* Link partner acked us */
and our advertisement was 0x41a0:
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
(bit 14 is managed by the PCS.)
> I have a ballpark of different SFPs and MediaTek boards with different
> PHYs here and tried all of them.
>
> I have no way to tell if the SFPs and PHYs which stopped working after
> the phylink_pcs conversion are sending valid advertisement. The only
> other boards with SFP slots I got here are RealTek-based switches, and
> all I can say is that on an RTL8380 based 1G switch both, the SFP
> modules containing a PHY and operating in SGMII mode as well as the
> ones without a PHY exposed via i2c-mdio and operating in 1000Base-X
> mode are working fine with that switch, with both, stock firmware and
> OpenWrt running on it.
>
> However, even should they not send valid advertisement, they are very
> common parts and they were working before and not after the change to
> phylink_pcs, for the reasons mentioned in the description of this
> patch.
Let me re-iterate in a different way to make this crystal clear: the
fibre SFP is completely transparent with respect to the PCS-to-PCS
link.
The clause 37 autonegotiation is between the PCS at one end and the PCS
at the other end. The fibre SFP is not involved in it. All that fibre
SFPs do is convert the serdes waveform into a varying optical intensity
and back again to a serdes waveform. They do not attempt to interpret
the waveform, but they may shape it via retimer circuitry and adjust
the gain to provide a compliant electrical signal.
So, if the PCS at the far end of the link is sending a zero
advertisement or not sending an advertisement at all, then the LPA
register will contain a zero irrespective of the fibre SFP module
being used.
Another case where it may give a zero value but with a copper SFP
is if the copper SFP is using 1000base-X or SGMII but without
sending an advertisement. As I've already stated, BCM84881 is
known to do this, which is used on some copper SFP modules. It
may be that some copper SFP modules have the PHY setup to use
1000base-X but without any clause 37 advertisement - that would
not surprise me in the least.
I would suggest that if you replaced your mediatek board in your
setup with something else, e.g. an Armada 388 based Clearfog board
which is known to work correctly, used the same fibre SFPs, you'll
find that negotiation would not complete and the link wouldn't
come up. Then if you use the same fibre SFPs that I do at both
ends, you'll find the same problem (because the fibre SFPs make
no difference as far as the in-band AN is concerned.)
I hope this helps.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Hi
> Gesendet: Mittwoch, 08. März 2023 um 16:24 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
> > > It would be nice to add these to my database - please send me the
> > > output of ethtool -m $iface raw on > foo.bin for each module.
>
> so if you can do that for me, then I can see whether it's likely that
> the patches that are already in mainline will do anything to solve
> the workaround you've had to add for the hw signals.
i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
i dumped the eeprom like you mention for your database:
$ hexdump -C 2g5_sfp.bin
00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
how can we add a quirk to support this?
some more information:
root@bpi-r3:~# ethtool eth1
Settings for eth1:
Supported ports: [ FIBRE ]
Supported link modes: 2500baseX/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 2500baseX/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 2500Mb/s
Duplex: Full
Auto-negotiation: on
Port: FIBRE
PHYAD: 0
Transceiver: internal
Current message level: 0x000000ff (255)
drv probe link timer ifdown ifup rx_err tx_err
Link detected: yes
root@bpi-r3:~# ethtool -m eth1
Identifier : 0x03 (SFP)
Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID)
Connector : 0x07 (LC)
Transceiver codes : 0x00 0x01 0x00 0x00 0x00 0x00 0x02 0x00 0x00
Transceiver type : SONET: OC-48, short reach
Encoding : 0x05 (SONET Scrambled)
BR, Nominal : 2500MBd
Rate identifier : 0x00 (unspecified)
Length (SMF,km) : 0km
Length (SMF) : 0m
Length (50um) : 300m
Length (62.5um) : 200m
Length (Copper) : 0m
Length (OM3) : 0m
Laser wavelength : 850nm
Vendor name : OEM
Vendor OUI : 00:00:00
Vendor PN : SFP-2.5G-T
Vendor rev : 1.0
Option values : 0x00 0x1a
Option : RX_LOS implemented
Option : TX_FAULT implemented
Option : TX_DISABLE implemented
BR margin, max : 0%
BR margin, min : 0%
Vendor SN : SK2301110008
Date code : 230110
Optical diagnostics support : Yes
Laser bias current : 6.000 mA
Laser output power : 0.5000 mW / -3.01 dBm
Receiver signal average optical power : 0.4000 mW / -3.98 dBm
Module temperature : 28.21 degrees C / 82.78 degrees F
Module voltage : 3.3067 V
Alarm/warning flags implemented : Yes
Laser bias current high alarm : Off
Laser bias current low alarm : Off
Laser bias current high warning : Off
Laser bias current low warning : Off
Laser output power high alarm : Off
Laser output power low alarm : Off
Laser output power high warning : Off
Laser output power low warning : Off
Module temperature high alarm : Off
Module temperature low alarm : Off
Module temperature high warning : Off
Module temperature low warning : Off
Module voltage high alarm : Off
Module voltage low alarm : Off
Module voltage high warning : Off
Module voltage low warning : Off
Laser rx power high alarm : Off
Laser rx power low alarm : Off
Laser rx power high warning : Off
Laser rx power low warning : Off
Laser bias current high alarm threshold : 15.000 mA
Laser bias current low alarm threshold : 1.000 mA
Laser bias current high warning threshold : 13.000 mA
Laser bias current low warning threshold : 2.000 mA
Laser output power high alarm threshold : 1.9952 mW / 3.00 dBm
Laser output power low alarm threshold : 0.1584 mW / -8.00 dBm
Laser output power high warning threshold : 1.5848 mW / 2.00 dBm
Laser output power low warning threshold : 0.1778 mW / -7.50 dBm
Module temperature high alarm threshold : 95.00 degrees C / 203.00 degrees F
Module temperature low alarm threshold : -50.00 degrees C / -58.00 degrees F
Module temperature high warning threshold : 90.00 degrees C / 194.00 degrees F
Module temperature low warning threshold : -45.00 degrees C / -49.00 degrees F
Module voltage high alarm threshold : 3.6000 V
Module voltage low alarm threshold : 3.0000 V
Module voltage high warning threshold : 3.5000 V
Module voltage low warning threshold : 3.1000 V
Laser rx power high alarm threshold : 1.1220 mW / 0.50 dBm
Laser rx power low alarm threshold : 0.0199 mW / -17.01 dBm
Laser rx power high warning threshold : 1.0000 mW / 0.00 dBm
Laser rx power low warning threshold : 0.0223 mW / -16.52 dBm
i guess this sfp have a phy as it can operate in 100/1000/2500 mode like described on the module.
but only tested in 2500base-T mode only.
regards Frank
> Gesendet: Samstag, 11. März 2023 um 13:05 Uhr
> Von: "Frank Wunderlich" <[email protected]>
> > Gesendet: Mittwoch, 08. März 2023 um 16:24 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
> > > > It would be nice to add these to my database - please send me the
> > > > output of ethtool -m $iface raw on > foo.bin for each module.
> >
> > so if you can do that for me, then I can see whether it's likely that
> > the patches that are already in mainline will do anything to solve
> > the workaround you've had to add for the hw signals.
>
> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
>
> i dumped the eeprom like you mention for your database:
>
> $ hexdump -C 2g5_sfp.bin
> 00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
> 00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
> 00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
> 00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
> 00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
> 00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
> 00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
> 00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
> 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> *
> 00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
> 00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
> 00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
> 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
> 00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
> 00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
> 00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
> 00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
> 00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
> 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
> 000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
> 000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
> 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
>
> how can we add a quirk to support this?
tried to add the quirk like this onto v13
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -403,6 +403,8 @@ static const struct sfp_quirk sfp_quirks[] = {
SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
+
+ SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_2500basex),
};
but still no link...
how can i verify the quirk was applied? see only this in dmesg:
[ 2.192274] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
also tried to force speed (module should support 100/1000/2500), but it seems i can set speed option only on
gmac (eth1) and not on the sfp (phy).
i guess between mac and sfp speed is always 2500base-X and after the phy (if there is any) the link speed is
maybe different.
regards Frank
On Sat, Mar 11, 2023 at 02:26:13PM +0100, Frank Wunderlich wrote:
> > Gesendet: Samstag, 11. M?rz 2023 um 13:05 Uhr
> > Von: "Frank Wunderlich" <[email protected]>
> > > Gesendet: Mittwoch, 08. M?rz 2023 um 16:24 Uhr
> > > Von: "Russell King (Oracle)" <[email protected]>
> > > > > It would be nice to add these to my database - please send me the
> > > > > output of ethtool -m $iface raw on > foo.bin for each module.
> > >
> > > so if you can do that for me, then I can see whether it's likely that
> > > the patches that are already in mainline will do anything to solve
> > > the workaround you've had to add for the hw signals.
> >
> > i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> >
> > i dumped the eeprom like you mention for your database:
> >
> > $ hexdump -C 2g5_sfp.bin
> > 00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
> > 00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
> > 00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
> > 00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
> > 00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
> > 00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
> > 00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
> > 00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
> > 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > *
> > 00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
> > 00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
> > 00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
> > 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > 00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
> > 00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
> > 00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
> > 00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
> > 00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
> > 00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
> > 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
> > 000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
> > 000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
> > 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > 000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
> >
> > how can we add a quirk to support this?
>
> tried to add the quirk like this onto v13
>
> --- a/drivers/net/phy/sfp.c
> +++ b/drivers/net/phy/sfp.c
> @@ -403,6 +403,8 @@ static const struct sfp_quirk sfp_quirks[] = {
> SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
> SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
> SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
> +
> + SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_2500basex),
> };
>
> but still no link...
>
> how can i verify the quirk was applied? see only this in dmesg:
>
> [ 2.192274] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
>
> also tried to force speed (module should support 100/1000/2500), but it seems i can set speed option only on
> gmac (eth1) and not on the sfp (phy).
>
> i guess between mac and sfp speed is always 2500base-X and after the phy (if there is any) the link speed is
> maybe different.
As discussed in the previous iteration of the series where I suggested to
add work-arounds disabling in-band AN for 1000Base-X and 2500Base-X having
those will also affect fiber transceivers which transparently pass-through
the electrical SerDes signal into light. Russell explained it very well
and I now agree that a good solution would be to add a new SFP quirk
indicating that a SFP module got a "hidden" PHY which doesn't like in-band
autonegotiation.
tl;dr What you are seeing is the expected behavior.
Try 'ethtool -s eth1 autoneg off', and the link should come up.
Cheers
Daniel
>
> regards Frank
>
On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
> Hi
>
> > Gesendet: Mittwoch, 08. M?rz 2023 um 16:24 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
> > > > It would be nice to add these to my database - please send me the
> > > > output of ethtool -m $iface raw on > foo.bin for each module.
> >
> > so if you can do that for me, then I can see whether it's likely that
> > the patches that are already in mainline will do anything to solve
> > the workaround you've had to add for the hw signals.
>
> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
>
> i dumped the eeprom like you mention for your database:
>
> $ hexdump -C 2g5_sfp.bin
> 00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
> 00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
> 00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
> 00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
> 00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
> 00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
> 00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
> 00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
> 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> *
> 00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
> 00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
> 00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
> 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
> 00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
> 00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
> 00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
> 00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
> 00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
> 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
> 000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
> 000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
> 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> 000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
>
> how can we add a quirk to support this?
Why does it need a quirk?
>
> some more information:
>
> root@bpi-r3:~# ethtool eth1
> Settings for eth1:
> Supported ports: [ FIBRE ]
> Supported link modes: 2500baseX/Full
> Supported pause frame use: Symmetric Receive-only
> Supports auto-negotiation: Yes
> Supported FEC modes: Not reported
> Advertised link modes: 2500baseX/Full
> Advertised pause frame use: Symmetric Receive-only
> Advertised auto-negotiation: Yes
> Advertised FEC modes: Not reported
> Speed: 2500Mb/s
> Duplex: Full
> Auto-negotiation: on
> Port: FIBRE
> PHYAD: 0
> Transceiver: internal
> Current message level: 0x000000ff (255)
> drv probe link timer ifdown ifup rx_err tx_err
> Link detected: yes
> root@bpi-r3:~# ethtool -m eth1
> Identifier : 0x03 (SFP)
> Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID)
> Connector : 0x07 (LC)
> Transceiver codes : 0x00 0x01 0x00 0x00 0x00 0x00 0x02 0x00 0x00
> Transceiver type : SONET: OC-48, short reach
> Encoding : 0x05 (SONET Scrambled)
> BR, Nominal : 2500MBd
> Rate identifier : 0x00 (unspecified)
> Length (SMF,km) : 0km
> Length (SMF) : 0m
> Length (50um) : 300m
> Length (62.5um) : 200m
> Length (Copper) : 0m
> Length (OM3) : 0m
> Laser wavelength : 850nm
> Vendor name : OEM
> Vendor OUI : 00:00:00
> Vendor PN : SFP-2.5G-T
> Vendor rev : 1.0
> Option values : 0x00 0x1a
> Option : RX_LOS implemented
> Option : TX_FAULT implemented
> Option : TX_DISABLE implemented
> BR margin, max : 0%
> BR margin, min : 0%
> Vendor SN : SK2301110008
> Date code : 230110
> Optical diagnostics support : Yes
> Laser bias current : 6.000 mA
> Laser output power : 0.5000 mW / -3.01 dBm
> Receiver signal average optical power : 0.4000 mW / -3.98 dBm
> Module temperature : 28.21 degrees C / 82.78 degrees F
> Module voltage : 3.3067 V
> Alarm/warning flags implemented : Yes
> Laser bias current high alarm : Off
> Laser bias current low alarm : Off
> Laser bias current high warning : Off
> Laser bias current low warning : Off
> Laser output power high alarm : Off
> Laser output power low alarm : Off
> Laser output power high warning : Off
> Laser output power low warning : Off
> Module temperature high alarm : Off
> Module temperature low alarm : Off
> Module temperature high warning : Off
> Module temperature low warning : Off
> Module voltage high alarm : Off
> Module voltage low alarm : Off
> Module voltage high warning : Off
> Module voltage low warning : Off
> Laser rx power high alarm : Off
> Laser rx power low alarm : Off
> Laser rx power high warning : Off
> Laser rx power low warning : Off
> Laser bias current high alarm threshold : 15.000 mA
> Laser bias current low alarm threshold : 1.000 mA
> Laser bias current high warning threshold : 13.000 mA
> Laser bias current low warning threshold : 2.000 mA
> Laser output power high alarm threshold : 1.9952 mW / 3.00 dBm
> Laser output power low alarm threshold : 0.1584 mW / -8.00 dBm
> Laser output power high warning threshold : 1.5848 mW / 2.00 dBm
> Laser output power low warning threshold : 0.1778 mW / -7.50 dBm
> Module temperature high alarm threshold : 95.00 degrees C / 203.00 degrees F
> Module temperature low alarm threshold : -50.00 degrees C / -58.00 degrees F
> Module temperature high warning threshold : 90.00 degrees C / 194.00 degrees F
> Module temperature low warning threshold : -45.00 degrees C / -49.00 degrees F
> Module voltage high alarm threshold : 3.6000 V
> Module voltage low alarm threshold : 3.0000 V
> Module voltage high warning threshold : 3.5000 V
> Module voltage low warning threshold : 3.1000 V
> Laser rx power high alarm threshold : 1.1220 mW / 0.50 dBm
> Laser rx power low alarm threshold : 0.0199 mW / -17.01 dBm
> Laser rx power high warning threshold : 1.0000 mW / 0.00 dBm
> Laser rx power low warning threshold : 0.0223 mW / -16.52 dBm
>
> i guess this sfp have a phy as it can operate in 100/1000/2500 mode like described on the module.
It would help to know the kernel messages.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Sat, Mar 11, 2023 at 02:51:27PM +0000, Daniel Golle wrote:
> On Sat, Mar 11, 2023 at 02:26:13PM +0100, Frank Wunderlich wrote:
> > > Gesendet: Samstag, 11. M?rz 2023 um 13:05 Uhr
> > > Von: "Frank Wunderlich" <[email protected]>
> > > > Gesendet: Mittwoch, 08. M?rz 2023 um 16:24 Uhr
> > > > Von: "Russell King (Oracle)" <[email protected]>
> > > > > > It would be nice to add these to my database - please send me the
> > > > > > output of ethtool -m $iface raw on > foo.bin for each module.
> > > >
> > > > so if you can do that for me, then I can see whether it's likely that
> > > > the patches that are already in mainline will do anything to solve
> > > > the workaround you've had to add for the hw signals.
> > >
> > > i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> > >
> > > i dumped the eeprom like you mention for your database:
> > >
> > > $ hexdump -C 2g5_sfp.bin
> > > 00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
> > > 00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
> > > 00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
> > > 00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
> > > 00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
> > > 00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
> > > 00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
> > > 00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
> > > 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > *
> > > 00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
> > > 00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
> > > 00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
> > > 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > 00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
> > > 00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
> > > 00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
> > > 00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
> > > 00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
> > > 00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
> > > 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
> > > 000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
> > > 000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
> > > 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > 000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
> > >
> > > how can we add a quirk to support this?
> >
> > tried to add the quirk like this onto v13
> >
> > --- a/drivers/net/phy/sfp.c
> > +++ b/drivers/net/phy/sfp.c
> > @@ -403,6 +403,8 @@ static const struct sfp_quirk sfp_quirks[] = {
> > SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
> > SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
> > SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
> > +
> > + SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_2500basex),
> > };
> >
> > but still no link...
> >
> > how can i verify the quirk was applied? see only this in dmesg:
> >
> > [ 2.192274] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> >
> > also tried to force speed (module should support 100/1000/2500), but it seems i can set speed option only on
> > gmac (eth1) and not on the sfp (phy).
> >
> > i guess between mac and sfp speed is always 2500base-X and after the phy (if there is any) the link speed is
> > maybe different.
>
> As discussed in the previous iteration of the series where I suggested to
> add work-arounds disabling in-band AN for 1000Base-X and 2500Base-X having
> those will also affect fiber transceivers which transparently pass-through
> the electrical SerDes signal into light. Russell explained it very well
> and I now agree that a good solution would be to add a new SFP quirk
> indicating that a SFP module got a "hidden" PHY which doesn't like in-band
> autonegotiation.
I do not believe that fibre SFPs have hidden PHYs that disrupt the
autonegotiation. What makes you think that they do? Do you have
autonegotiation working with some fibre SFP modules but not other
fibre modules?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Am 11. März 2023 21:00:20 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
>On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
>> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
>> how can we add a quirk to support this?
>
>Why does it need a quirk?
To disable the inband-mode for this 2.5g copper
sfp. But have not found a way to set a flag which i
can grab in phylink.
The interface imho can only hold 1 value
(speedmode which is correctly set to 2500baseX)
and the mode holds ethtool options which seem
not accessable from phylink.c
>>
>> some more information:
>>
>> root@bpi-r3:~# ethtool eth1
>> Settings for eth1:
>> Supported ports: [ FIBRE ]
>> Supported link modes: 2500baseX/Full
>> Supported pause frame use: Symmetric Receive-only
>> Supports auto-negotiation: Yes
>> Supported FEC modes: Not reported
>> Advertised link modes: 2500baseX/Full
>> Advertised pause frame use: Symmetric Receive-only
>> Advertised auto-negotiation: Yes
>> Advertised FEC modes: Not reported
>> Speed: 2500Mb/s
>> Duplex: Full
>> Auto-negotiation: on
>> Port: FIBRE
>> PHYAD: 0
>> Transceiver: internal
>> Current message level: 0x000000ff (255)
>> drv probe link timer ifdown ifup rx_err tx_err
>> Link detected: yes
>> root@bpi-r3:~# ethtool -m eth1
>> Identifier : 0x03 (SFP)
>> Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID)
>> Connector : 0x07 (LC)
>> Transceiver codes : 0x00 0x01 0x00 0x00 0x00 0x00 0x02 0x00 0x00
>> Transceiver type : SONET: OC-48, short reach
>> Encoding : 0x05 (SONET Scrambled)
>> BR, Nominal : 2500MBd
>> Vendor name : OEM
>> Vendor OUI : 00:00:00
>> Vendor PN : SFP-2.5G-T
>> Vendor rev : 1.0
>> Option values : 0x00 0x1a
...
>>
>> i guess this sfp have a phy as it can operate in 100/1000/2500 mode like described on the module.
>
>It would help to know the kernel messages.
I had only the sfp message with vendor/partno and the interface up from mac (2500baseX/Full)
But no link up.
Which message(s) do you want to see?
regards Frank
On Sat, Mar 11, 2023 at 09:21:47PM +0100, Frank Wunderlich wrote:
> Am 11. M?rz 2023 21:00:20 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> >On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
>
> >> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
>
> >> how can we add a quirk to support this?
> >
> >Why does it need a quirk?
>
> To disable the inband-mode for this 2.5g copper
> sfp. But have not found a way to set a flag which i
> can grab in phylink.
We could make sfp_parse_support() set Autoneg, Pause, and Asym_Pause
in "modes" at the top of that function, and then use the SFP modes
quirk to clear the Autoneg bit for this SFP. Would that work for you?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Sat, Mar 11, 2023 at 08:02:47PM +0000, Russell King (Oracle) wrote:
> On Sat, Mar 11, 2023 at 02:51:27PM +0000, Daniel Golle wrote:
> > On Sat, Mar 11, 2023 at 02:26:13PM +0100, Frank Wunderlich wrote:
> > > > Gesendet: Samstag, 11. M?rz 2023 um 13:05 Uhr
> > > > Von: "Frank Wunderlich" <[email protected]>
> > > > > Gesendet: Mittwoch, 08. M?rz 2023 um 16:24 Uhr
> > > > > Von: "Russell King (Oracle)" <[email protected]>
> > > > > > > It would be nice to add these to my database - please send me the
> > > > > > > output of ethtool -m $iface raw on > foo.bin for each module.
> > > > >
> > > > > so if you can do that for me, then I can see whether it's likely that
> > > > > the patches that are already in mainline will do anything to solve
> > > > > the workaround you've had to add for the hw signals.
> > > >
> > > > i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> > > >
> > > > i dumped the eeprom like you mention for your database:
> > > >
> > > > $ hexdump -C 2g5_sfp.bin
> > > > 00000000 03 04 07 00 01 00 00 00 00 02 00 05 19 00 00 00 |................|
> > > > 00000010 1e 14 00 00 4f 45 4d 20 20 20 20 20 20 20 20 20 |....OEM |
> > > > 00000020 20 20 20 20 00 00 00 00 53 46 50 2d 32 2e 35 47 | ....SFP-2.5G|
> > > > 00000030 2d 54 20 20 20 20 20 20 31 2e 30 20 03 52 00 19 |-T 1.0 .R..|
> > > > 00000040 00 1a 00 00 53 4b 32 33 30 31 31 31 30 30 30 38 |....SK2301110008|
> > > > 00000050 20 20 20 20 32 33 30 31 31 30 20 20 68 f0 01 e8 | 230110 h...|
> > > > 00000060 00 00 11 37 4f 7a dc ff 3d c0 6e 74 9b 7c 06 ca |...7Oz..=.nt.|..|
> > > > 00000070 e1 d0 f9 00 00 00 00 00 00 00 00 00 08 f0 fc 64 |...............d|
> > > > 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > > *
> > > > 00000100 5f 00 ce 00 5a 00 d3 00 8c a0 75 30 88 b8 79 18 |_...Z.....u0..y.|
> > > > 00000110 1d 4c 01 f4 19 64 03 e8 4d f0 06 30 3d e8 06 f2 |.L...d..M..0=...|
> > > > 00000120 2b d4 00 c7 27 10 00 df 00 00 00 00 00 00 00 00 |+...'...........|
> > > > 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > > 00000140 00 00 00 00 3f 80 00 00 00 00 00 00 01 00 00 00 |....?...........|
> > > > 00000150 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 f1 |................|
> > > > 00000160 29 1a 82 41 0b b8 13 88 0f a0 ff ff ff ff 80 ff |)..A............|
> > > > 00000170 00 00 ff ff 00 00 ff ff 04 ff ff ff ff ff ff 00 |................|
> > > > 00000180 43 4e 53 38 54 55 54 41 41 43 33 30 2d 31 34 31 |CNS8TUTAAC30-141|
> > > > 00000190 30 2d 30 34 56 30 34 20 49 fb 46 00 00 00 00 29 |0-04V04 I.F....)|
> > > > 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > > 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 aa aa |................|
> > > > 000001c0 47 4c 43 2d 54 20 20 20 20 20 20 20 20 20 20 20 |GLC-T |
> > > > 000001d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 97 | .|
> > > > 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
> > > > 000001f0 00 00 00 00 00 00 00 00 00 40 00 40 00 00 00 00 |.........@.@....|
> > > >
> > > > how can we add a quirk to support this?
> > >
> > > tried to add the quirk like this onto v13
> > >
> > > --- a/drivers/net/phy/sfp.c
> > > +++ b/drivers/net/phy/sfp.c
> > > @@ -403,6 +403,8 @@ static const struct sfp_quirk sfp_quirks[] = {
> > > SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
> > > SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
> > > SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
> > > +
> > > + SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_2500basex),
> > > };
> > >
> > > but still no link...
> > >
> > > how can i verify the quirk was applied? see only this in dmesg:
> > >
> > > [ 2.192274] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> > >
> > > also tried to force speed (module should support 100/1000/2500), but it seems i can set speed option only on
> > > gmac (eth1) and not on the sfp (phy).
> > >
> > > i guess between mac and sfp speed is always 2500base-X and after the phy (if there is any) the link speed is
> > > maybe different.
> >
> > As discussed in the previous iteration of the series where I suggested to
> > add work-arounds disabling in-band AN for 1000Base-X and 2500Base-X having
> > those will also affect fiber transceivers which transparently pass-through
> > the electrical SerDes signal into light. Russell explained it very well
> > and I now agree that a good solution would be to add a new SFP quirk
> > indicating that a SFP module got a "hidden" PHY which doesn't like in-band
> > autonegotiation.
>
> I do not believe that fibre SFPs have hidden PHYs that disrupt the
> autonegotiation. What makes you think that they do?
This is not a fiber SFP, but rather a 2500Base-T RJ-45 module.
Hence it quite certainly has some kind of PHY.
> Do you have
> autonegotiation working with some fibre SFP modules but not other
> fibre modules?
I've tried only with one 1000Base-SX module and can confirm (like
Frank already did in your previous discussion some weeks ago) that
with that autonegotiation is working fine. Only those RJ-45 which
do not expose the PHY via i2c-mdio are problematic apparently, as
Linux/phylink *assumes* that they do in-band AN, but at least some
of them don't.
> Gesendet: Samstag, 11. März 2023 um 21:30 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
> On Sat, Mar 11, 2023 at 09:21:47PM +0100, Frank Wunderlich wrote:
> > Am 11. März 2023 21:00:20 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> > >On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
> >
> > >> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> >
> > >> how can we add a quirk to support this?
> > >
> > >Why does it need a quirk?
> >
> > To disable the inband-mode for this 2.5g copper
> > sfp. But have not found a way to set a flag which i
> > can grab in phylink.
>
> We could make sfp_parse_support() set Autoneg, Pause, and Asym_Pause
> in "modes" at the top of that function, and then use the SFP modes
> quirk to clear the Autoneg bit for this SFP. Would that work for you?
i already tried this (without moving the autoneg/pause to sfp_parse_support):
static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
{
linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
}
quirk was executed, but no change (no link on 2g5 sfp).
i guess you mean moving code handling the dt-property for inband-mode in phylink_parse_mode (phylink.c) to the sfp-function (drivers/net/phy/sfp-bus.c)
as a first test i tried to disable autoneg for the inband-setting
@@ -840,11 +842,18 @@ static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
linkmode_zero(pl->supported);
phylink_set(pl->supported, MII);
- phylink_set(pl->supported, Autoneg);
+ //phylink_set(pl->supported, Autoneg);
phylink_set(pl->supported, Asym_Pause);
phylink_set(pl->supported, Pause);
pl->link_config.an_enabled = true;
- pl->cfg_link_an_mode = MLO_AN_INBAND;
+ //pl->cfg_link_an_mode = MLO_AN_INBAND;
+
+ //how to access sfp->inband_disable?
+ printk(KERN_ALERT "DEBUG: Passed %s:%d %d==%d (inband)??",__FUNCTION__,__LINE__, pl->cfg_link_an_mode, MLO_AN_INBAND);
+ //pl->cfg_link_an_mode = MLO_AN_PHY;
+ pl->link_config.an_enabled = false;
+ //phylink_clear(pl->supported, Autoneg);
+ printk(KERN_ALERT "DEBUG: Passed %s:%d %d==%d (inband)?? (forced phy-mode)",__FUNCTION__,__LINE__, pl->cfg_link_an_mode, MLO_AN_INBAND);
switch (pl->link_config.interface) {
case PHY_INTERFACE_MODE_SGMII:
@@ -947,7 +956,7 @@ static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
}
/* Check if MAC/PCS also supports Autoneg. */
- pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
+ //pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg);
}
return 0;
but it seems this is not enough (or i miss something) and i get error when i try to set mac up
root@bpi-r3:~# ip link set eth1 up
[ 30.044144] mtk_soc_eth 15100000.ethernet eth1: mtk_open: could not attach PHY: -19
RTNETLINK answers: No such device
regards Frank
and i can confirm that disabling autoneg on userspace brings up link on the 2.5g rj45 sfp
root@bpi-r3:~# ip link set eth1 up
[ 73.433869] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
root@bpi-r3:~# ip link show eth1
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
link/ether 92:2f:d3:16:6f:94 brd ff:ff:ff:ff:ff:ff
root@bpi-r3:~# ethtool -s eth1 autoneg off
root@bpi-r3:~# [ 147.190136] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 2.5Gbps/Full - flow control off
[ 147.198600] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
root@bpi-r3:~#
wonder which flags this changes compared to the original state...these i have to set in code when the sfp is recognized.
setting these flags in the phylink_parse_mode (or skipping set AN-flags) seem to break it completely
regards Frank
Just to make it clear...the issue with the copper-sfps is no regression of this series it exists before.
i only had none of them to test for until this weekend....my 1g fibre-sfp were working fine with the inband-flag.
this patch tries to fix it in mtk driver, this was rejected (as far as i understand it should be handled in phylink core instead of pcs driver).
and no more in the v13, so we try to fix it another way.
whatever i do in phylink_parse_mode the link is always inband...i tried to add a new state to have the configuration not FIXED or PHY or INBAND
drivers/net/phy/phylink.c
@@ -151,6 +151,7 @@ static const char *phylink_an_mode_str(unsigned int mode)
[MLO_AN_PHY] = "phy",
[MLO_AN_FIXED] = "fixed",
[MLO_AN_INBAND] = "inband",
+ [MLO_AN_INBAND_DISABLED] = "inband disabled",
};
include/linux/phylink.h
@@ -20,6 +20,7 @@ enum {
MLO_AN_PHY = 0, /* Conventional PHY */
MLO_AN_FIXED, /* Fixed-link mode */
MLO_AN_INBAND, /* In-band protocol */
+ MLO_AN_INBAND_DISABLED
is my start the right way?
i noticed that sfp-handling is always calling phylink_sfp_config_optical and this calls phylink_sfp_set_config with fixed MLO_AN_INBAND.
https://elixir.bootlin.com/linux/v6.3-rc1/source/drivers/net/phy/phylink.c#L3038
This looks wrong for me...
First not all sfp are optical (ethtool shows FIBRE for copper-sfps too) and not all use inband mode...
after changing this to my new state i see it in the configuration message.
@@ -3044,7 +3049,7 @@ static int phylink_sfp_config_optical(struct phylink *pl)
pl->link_port = pl->sfp_port;
- phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
+ phylink_sfp_set_config(pl, MLO_AN_INBAND_DISABLED, pl->sfp_support, &config);
return 0;
}
root@bpi-r3:~# ip link set eth1 up
[ 30.186811] mtk_soc_eth 15100000.ethernet eth1: configuring for inband disabled/2500base-x link mode
changing the mode itself is not enough for getting the link up...
have not found spacial handling of MLO_AN_INBAND except in phylink_mac_initial_config where i added my mode to the
MLO_AN_INBAND as fallthrough (there is not autoneg set/done). also disabled link_config.an_enabled whereever i've found,
but this does not bring up the link on the copper sfps...it looks like there must be a state-change...
but here i'm stuck with my limited knowledge ;(
regards Frank
On Sun, Mar 12, 2023 at 01:40:36PM +0100, Frank Wunderlich wrote:
> > Gesendet: Samstag, 11. M?rz 2023 um 21:30 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
>
> > On Sat, Mar 11, 2023 at 09:21:47PM +0100, Frank Wunderlich wrote:
> > > Am 11. M?rz 2023 21:00:20 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> > > >On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
> > >
> > > >> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> > >
> > > >> how can we add a quirk to support this?
> > > >
> > > >Why does it need a quirk?
> > >
> > > To disable the inband-mode for this 2.5g copper
> > > sfp. But have not found a way to set a flag which i
> > > can grab in phylink.
> >
> > We could make sfp_parse_support() set Autoneg, Pause, and Asym_Pause
> > in "modes" at the top of that function, and then use the SFP modes
> > quirk to clear the Autoneg bit for this SFP. Would that work for you?
>
> i already tried this (without moving the autoneg/pause to sfp_parse_support):
>
> static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
> unsigned long *modes,
> unsigned long *interfaces)
> {
> linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
> }
>
> quirk was executed, but no change (no link on 2g5 sfp).
It won't have any effect on its own - because sfp_parse_support() does
this:
if (bus->sfp_quirk && bus->sfp_quirk->modes)
bus->sfp_quirk->modes(id, modes, interfaces);
linkmode_or(support, support, modes);
phylink_set(support, Autoneg);
phylink_set(support, Pause);
phylink_set(support, Asym_Pause);
Which means clearing Autoneg in "modes" via the modes SFP quirk will
have *absolutely* *no* *effect* what so ever.
The fact that you replied having *not* followed my suggestion and then
itimiating that it doesn't work is very frustrating.
> i guess you mean moving code handling the dt-property for inband-mode in phylink_parse_mode (phylink.c) to the sfp-function (drivers/net/phy/sfp-bus.c)
No.
[rest of email cut because I can't be bothered to read it after this]
Please try what I suggested. You might find that it works.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Sun, Mar 12, 2023 at 05:50:48PM +0100, Frank Wunderlich wrote:
> Just to make it clear...the issue with the copper-sfps is no regression of this series it exists before.
> i only had none of them to test for until this weekend....my 1g fibre-sfp were working fine with the inband-flag.
>
> this patch tries to fix it in mtk driver, this was rejected (as far as i understand it should be handled in phylink core instead of pcs driver).
> and no more in the v13, so we try to fix it another way.
>
> whatever i do in phylink_parse_mode the link is always inband...i tried to add a new state to have the configuration not FIXED or PHY or INBAND
>
> drivers/net/phy/phylink.c
> @@ -151,6 +151,7 @@ static const char *phylink_an_mode_str(unsigned int mode)
> [MLO_AN_PHY] = "phy",
> [MLO_AN_FIXED] = "fixed",
> [MLO_AN_INBAND] = "inband",
> + [MLO_AN_INBAND_DISABLED] = "inband disabled",
> };
>
> include/linux/phylink.h
> @@ -20,6 +20,7 @@ enum {
> MLO_AN_PHY = 0, /* Conventional PHY */
> MLO_AN_FIXED, /* Fixed-link mode */
> MLO_AN_INBAND, /* In-band protocol */
> + MLO_AN_INBAND_DISABLED
>
> is my start the right way?
Oh ffs.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
On Sun, Mar 12, 2023 at 08:05:41PM +0000, Russell King (Oracle) wrote:
> On Sun, Mar 12, 2023 at 01:40:36PM +0100, Frank Wunderlich wrote:
> > > Gesendet: Samstag, 11. M?rz 2023 um 21:30 Uhr
> > > Von: "Russell King (Oracle)" <[email protected]>
> >
> > > On Sat, Mar 11, 2023 at 09:21:47PM +0100, Frank Wunderlich wrote:
> > > > Am 11. M?rz 2023 21:00:20 MEZ schrieb "Russell King (Oracle)" <[email protected]>:
> > > > >On Sat, Mar 11, 2023 at 01:05:37PM +0100, Frank Wunderlich wrote:
> > > >
> > > > >> i got the 2.5G copper sfps, and tried them...they work well with the v12 (including this patch), but not in v13...
> > > >
> > > > >> how can we add a quirk to support this?
> > > > >
> > > > >Why does it need a quirk?
> > > >
> > > > To disable the inband-mode for this 2.5g copper
> > > > sfp. But have not found a way to set a flag which i
> > > > can grab in phylink.
> > >
> > > We could make sfp_parse_support() set Autoneg, Pause, and Asym_Pause
> > > in "modes" at the top of that function, and then use the SFP modes
> > > quirk to clear the Autoneg bit for this SFP. Would that work for you?
> >
> > i already tried this (without moving the autoneg/pause to sfp_parse_support):
> >
> > static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
> > unsigned long *modes,
> > unsigned long *interfaces)
> > {
> > linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
> > }
> >
> > quirk was executed, but no change (no link on 2g5 sfp).
>
> It won't have any effect on its own - because sfp_parse_support() does
> this:
>
> if (bus->sfp_quirk && bus->sfp_quirk->modes)
> bus->sfp_quirk->modes(id, modes, interfaces);
>
> linkmode_or(support, support, modes);
>
> phylink_set(support, Autoneg);
> phylink_set(support, Pause);
> phylink_set(support, Asym_Pause);
>
> Which means clearing Autoneg in "modes" via the modes SFP quirk will
> have *absolutely* *no* *effect* what so ever.
>
> The fact that you replied having *not* followed my suggestion and then
> itimiating that it doesn't work is very frustrating.
>
> > i guess you mean moving code handling the dt-property for inband-mode in phylink_parse_mode (phylink.c) to the sfp-function (drivers/net/phy/sfp-bus.c)
>
> No.
>
> [rest of email cut because I can't be bothered to read it after this]
>
> Please try what I suggested. You might find that it works.
Since describing what I wanted you to test didn't work, here's a patch
instead, based upon the quirk that you provided (which is what I'd have
written anyway). Add a "#define DEBUG" to the top of
drivers/net/phy/phylink.c in addition to applying this patch, and please
test the resulting kernel, sending me the resulting kernel messages, and
also reporting whether this works or not.
Thanks.
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index daac293e8ede..1dd50f2ca05d 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -151,6 +151,10 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned int br_min, br_nom, br_max;
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+ phylink_set(modes, Autoneg);
+ phylink_set(modes, Pause);
+ phylink_set(modes, Asym_Pause);
+
/* Decode the bitrate information to MBd */
br_min = br_nom = br_max = 0;
if (id->base.br_nominal) {
@@ -329,10 +333,6 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
bus->sfp_quirk->modes(id, modes, interfaces);
linkmode_or(support, support, modes);
-
- phylink_set(support, Autoneg);
- phylink_set(support, Pause);
- phylink_set(support, Asym_Pause);
}
EXPORT_SYMBOL_GPL(sfp_parse_support);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 39e3095796d0..b054360bf636 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -360,6 +360,13 @@ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
__set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces);
}
+static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
+ unsigned long *modes,
+ unsigned long *interfaces)
+{
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
+}
+
static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
@@ -401,6 +408,7 @@ static const struct sfp_quirk sfp_quirks[] = {
SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
+ SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_disable_autoneg),
SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
> Gesendet: Montag, 13. März 2023 um 11:59 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
> Since describing what I wanted you to test didn't work, here's a patch
> instead, based upon the quirk that you provided (which is what I'd have
> written anyway). Add a "#define DEBUG" to the top of
> drivers/net/phy/phylink.c in addition to applying this patch, and please
> test the resulting kernel, sending me the resulting kernel messages, and
> also reporting whether this works or not.
Hi
thx for the patch...sorry for misunderstanding. i thought the sfp quirk only sets a flag and i need to change
something in phylink.c to do the same as done on userspace, so i tried to simulate the userspace call there only for testing.
here relevant parts of debug
[ 1.990637] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
[ 2.000147] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=]
[ 56.321102] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
[ 56.329543] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
[ 56.336144] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00000000,0000e240 pause=04 link=0 an=1
full log here:
https://pastebin.com/vaXtXFY8
unfortunately this does not bring link up
root@bpi-r3:~# ethtool eth1
Settings for eth1:
Supported ports: [ MII ]
Supported link modes: 2500baseX/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 2500baseX/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: Unknown!
Duplex: Unknown! (255)
Auto-negotiation: on
Port: MII
PHYAD: 0
Transceiver: internal
Current message level: 0x000000ff (255)
drv probe link timer ifdown ifup rx_err tx_err
Link detected: no
also after calling this link does not came up
root@bpi-r3:~# ethtool -s eth1 autoneg off
[ 542.690293] mtk_soc_eth 15100000.ethernet eth1: phylink_change_inband_advert: mode=inband/2500base-x adv=00,00000000,00000000,0000e200 pause=04
so it looks like it needs to be configured first in inband mode and then autoneg needs to be disabled.
regards Frank
On Mon, Mar 13, 2023 at 07:39:00PM +0100, Frank Wunderlich wrote:
> > Gesendet: Montag, 13. M?rz 2023 um 11:59 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
>
> > Since describing what I wanted you to test didn't work, here's a patch
> > instead, based upon the quirk that you provided (which is what I'd have
> > written anyway). Add a "#define DEBUG" to the top of
> > drivers/net/phy/phylink.c in addition to applying this patch, and please
> > test the resulting kernel, sending me the resulting kernel messages, and
> > also reporting whether this works or not.
>
> Hi
>
> thx for the patch...sorry for misunderstanding. i thought the sfp quirk only sets a flag and i need to change
> something in phylink.c to do the same as done on userspace, so i tried to simulate the userspace call there only for testing.
>
> here relevant parts of debug
>
> [ 1.990637] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> [ 2.000147] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=]
First thing... why are the SFP interfaces here empty? They should be
listing at least 22 for this SFP. Looking at the full log, you have
omitted:
[ 2.008678] mtk_soc_eth 15100000.ethernet eth1: unsupported SFP module: no common interface modes
which seems to suggest that we need more than what I provided - and
is a big pointer to why it isn't working... and I guess has been there
all along.
This means that the interface configuration never gets updated, so
its pointless trying to add quirks etc. Error messages are rather
a key point.
So everything after this is just not relevant. Let's fix that. Here's
an updated patch which sets an interface mode for this SFP and sets a
link mode for it (although we use 2500baseX rather than baseT here
just to test this). I'm guessing it also does rate adaption, which we
will have to work out later.
Thanks.
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 1a2f074685fa..08eeffa96ae4 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -3001,7 +3001,8 @@ static int phylink_sfp_config_optical(struct phylink *pl)
config.speed = SPEED_UNKNOWN;
config.duplex = DUPLEX_UNKNOWN;
config.pause = MLO_PAUSE_AN;
- config.an_enabled = true;
+ config.an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+ support);
/* For all the interfaces that are supported, reduce the sfp_support
* mask to only those link modes that can be supported.
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index daac293e8ede..1dd50f2ca05d 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -151,6 +151,10 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned int br_min, br_nom, br_max;
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+ phylink_set(modes, Autoneg);
+ phylink_set(modes, Pause);
+ phylink_set(modes, Asym_Pause);
+
/* Decode the bitrate information to MBd */
br_min = br_nom = br_max = 0;
if (id->base.br_nominal) {
@@ -329,10 +333,6 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
bus->sfp_quirk->modes(id, modes, interfaces);
linkmode_or(support, support, modes);
-
- phylink_set(support, Autoneg);
- phylink_set(support, Pause);
- phylink_set(support, Asym_Pause);
}
EXPORT_SYMBOL_GPL(sfp_parse_support);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 39e3095796d0..5910c0e936a0 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -360,6 +360,21 @@ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
__set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces);
}
+static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
+ unsigned long *modes,
+ unsigned long *interfaces)
+{
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
+}
+
+static void sfp_quirk_oem_2_5g(const struct sfp_eeprom_id *id,
+ unsigned long *modes,
+ unsigned long *interfaces)
+{
+ sfp_quirk_2500basex(id, modes, interfaces);
+ sfp_quirk_disable_autoneg(id, modes, interfaces);
+}
+
static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
@@ -401,6 +416,7 @@ static const struct sfp_quirk sfp_quirks[] = {
SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
+ SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Hi,
first i removed maintainers/reviewers and mtk people from this thread to (hopefully) no more disturb the review-process of daniels patch-series.
> Gesendet: Montag, 13. März 2023 um 23:57 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
>
> On Mon, Mar 13, 2023 at 07:39:00PM +0100, Frank Wunderlich wrote:
> > > Gesendet: Montag, 13. März 2023 um 11:59 Uhr
> > > Von: "Russell King (Oracle)" <[email protected]>
> >
> > > Since describing what I wanted you to test didn't work, here's a patch
> > > instead, based upon the quirk that you provided (which is what I'd have
> > > written anyway). Add a "#define DEBUG" to the top of
> > > drivers/net/phy/phylink.c in addition to applying this patch, and please
> > > test the resulting kernel, sending me the resulting kernel messages, and
> > > also reporting whether this works or not.
> >
> > Hi
> >
> > thx for the patch...sorry for misunderstanding. i thought the sfp quirk only sets a flag and i need to change
> > something in phylink.c to do the same as done on userspace, so i tried to simulate the userspace call there only for testing.
> >
> > here relevant parts of debug
> >
> > [ 1.990637] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> > [ 2.000147] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=]
>
> First thing... why are the SFP interfaces here empty? They should be
> listing at least 22 for this SFP. Looking at the full log, you have
> omitted:
>
> [ 2.008678] mtk_soc_eth 15100000.ethernet eth1: unsupported SFP module: no common interface modes
not sure why i have not added this as it should match the second grep for eth1 (sfp had not matched because of missing -i flag)
it was not intended to omit any relevant data, just wanted to pre-filter from full log.
> which seems to suggest that we need more than what I provided - and
> is a big pointer to why it isn't working... and I guess has been there
> all along.
>
> This means that the interface configuration never gets updated, so
> its pointless trying to add quirks etc. Error messages are rather
> a key point.
thats clear, but somehow missed this one, sorry
> So everything after this is just not relevant. Let's fix that. Here's
> an updated patch which sets an interface mode for this SFP and sets a
> link mode for it (although we use 2500baseX rather than baseT here
> just to test this). I'm guessing it also does rate adaption, which we
> will have to work out later.
many thanks for guiding through this ;)
at least the error-message is gone, and interface gets up when i call ethtoo to switch off autoneg.
root@bpi-r3:~# dmesg | grep -i 'sfp\|eth1'
[ 0.000000] Linux version 6.3.0-rc1-bpi-r3-sfp13 (frank@frank-G5) (aarch64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1 SMP Tue Mar 143
[ 1.653862] sfp sfp-1: Host maximum power 1.0W
[ 1.658862] sfp sfp-2: Host maximum power 1.0W
[ 1.812551] mtk_soc_eth 15100000.ethernet eth1: mediatek frame engine at 0xffffffc00b080000, irq 123
[ 1.991838] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
[ 2.001352] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=22]
[ 2.010059] mtk_soc_eth 15100000.ethernet eth1: optical SFP: chosen 2500base-x interface
[ 2.018145] mtk_soc_eth 15100000.ethernet eth1: requesting link mode inband/2500base-x with support 00,00000000,00000000,0000e400
[ 34.385814] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
[ 34.394259] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
[ 34.400860] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00000000,0000e400 pause=04 link=0 an=1
root@bpi-r3:~#
root@bpi-r3:~# ethtool -s eth1 autoneg off
root@bpi-r3:~# [ 131.031902] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 2.5Gbps/Full - flow control off
[ 131.040366] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
full log here:
https://pastebin.com/yDC7PuM2
i see that an is still 1..maybe because of the fixed value here?
https://elixir.bootlin.com/linux/v6.3-rc1/source/drivers/net/phy/phylink.c#L3038
ethtool output after autoneg workaround:
Settings for eth1:
Supported ports: [ FIBRE ]
Supported link modes: 2500baseX/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: No
Supported FEC modes: Not reported
Advertised link modes: 2500baseX/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: No
Advertised FEC modes: Not reported
Speed: 2500Mb/s
Duplex: Full
Auto-negotiation: off
Port: FIBRE
PHYAD: 0
Transceiver: internal
Current message level: 0x000000ff (255)
drv probe link timer ifdown ifup rx_err tx_err
Link detected: yes
and yes, module seems to do rate adaption (it is labeled with 100M/1G/2.5G), i tried it on a 1G-Port and link came up (with workaround patch from daniel),
traffic "works" but in tx-direction with massive retransmitts (i guess because pause-frames are ignored - pause was 00).
regards Frank
On Tue, Mar 14, 2023 at 09:51:12AM +0100, Frank Wunderlich wrote:
> Hi,
>
> at least the error-message is gone, and interface gets up when i call ethtoo to switch off autoneg.
>
> root@bpi-r3:~# dmesg | grep -i 'sfp\|eth1'
> [ 1.991838] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> [ 2.001352] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=22]
> [ 2.010059] mtk_soc_eth 15100000.ethernet eth1: optical SFP: chosen 2500base-x interface
> [ 2.018145] mtk_soc_eth 15100000.ethernet eth1: requesting link mode inband/2500base-x with support 00,00000000,00000000,0000e400
> [ 34.385814] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
> [ 34.394259] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
> [ 34.400860] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00000000,0000e400 pause=04 link=0 an=1
Looking good - apart from that pesky an=1 (which isn't used by the PCS
driver, and I've been thinking of killing it off anyway.) Until such
time that happens, we really ought to set that correctly, which means
an extra bit is needed in phylink_sfp_set_config(). However, this
should not affect anything.
> root@bpi-r3:~#
> root@bpi-r3:~# ethtool -s eth1 autoneg off
> root@bpi-r3:~# [ 131.031902] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 2.5Gbps/Full - flow control off
> [ 131.040366] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
>
> full log here:
> https://pastebin.com/yDC7PuM2
>
> i see that an is still 1..maybe because of the fixed value here?
>
> https://elixir.bootlin.com/linux/v6.3-rc1/source/drivers/net/phy/phylink.c#L3038
Not sure what that line has to do with it - this is what the above
points to:
phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
Anyway, the important thing is the Autoneg bit in the advertising mask
is now zero, which is what we want. That should set the PCS to disable
negotiation when in 2500baseX mode, the same as ethtool -s eth1 autoneg
off.
So I think the question becomes - what was the state that ethtool was
reporting before asking ethtool to set autoneg off, and why does that
make a difference.
> and yes, module seems to do rate adaption (it is labeled with 100M/1G/2.5G), i tried it on a 1G-Port and link came up (with workaround patch from daniel),
> traffic "works" but in tx-direction with massive retransmitts (i guess because pause-frames are ignored - pause was 00).
We'll see about addressing that later once we've got the module working
at 2.5G. However, thanks for the information.
The patch below should result in ethtool reporting 2500baseT rather than
2500baseX, and that an=1 should now be an=0. Please try it, and dump the
ethtool eth1 before asking for autoneg to be manually disabled, and also
report the kernel messages.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Hi
> Gesendet: Dienstag, 14. März 2023 um 10:12 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
> On Tue, Mar 14, 2023 at 09:51:12AM +0100, Frank Wunderlich wrote:
> > Hi,
> >
> > at least the error-message is gone, and interface gets up when i call ethtoo to switch off autoneg.
...
> > [ 34.400860] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00000000,0000e400 pause=04 link=0 an=1
>
> Looking good - apart from that pesky an=1 (which isn't used by the PCS
> driver, and I've been thinking of killing it off anyway.) Until such
> time that happens, we really ought to set that correctly, which means
> an extra bit is needed in phylink_sfp_set_config(). However, this
> should not affect anything.
>
> > root@bpi-r3:~#
> > root@bpi-r3:~# ethtool -s eth1 autoneg off
> > root@bpi-r3:~# [ 131.031902] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 2.5Gbps/Full - flow control off
> > [ 131.040366] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
> >
> > full log here:
> > https://pastebin.com/yDC7PuM2
> >
> > i see that an is still 1..maybe because of the fixed value here?
> >
> > https://elixir.bootlin.com/linux/v6.3-rc1/source/drivers/net/phy/phylink.c#L3038
>
> Not sure what that line has to do with it - this is what the above
> points to:
>
> phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
MLO_AN_INBAND => may cause the an=1 and mode=inband if previously (?) disabled :)
> Anyway, the important thing is the Autoneg bit in the advertising mask
> is now zero, which is what we want. That should set the PCS to disable
> negotiation when in 2500baseX mode, the same as ethtool -s eth1 autoneg
> off.
>
> So I think the question becomes - what was the state that ethtool was
> reporting before asking ethtool to set autoneg off, and why does that
> make a difference.
ok, i do ethtool output before and after on next test.
> > and yes, module seems to do rate adaption (it is labeled with 100M/1G/2.5G), i tried it on a 1G-Port and link came up (with workaround patch from daniel),
> > traffic "works" but in tx-direction with massive retransmitts (i guess because pause-frames are ignored - pause was 00).
>
> We'll see about addressing that later once we've got the module working
> at 2.5G. However, thanks for the information.
of course...step by step, just wanted to tell this behaviour
> The patch below should result in ethtool reporting 2500baseT rather than
> 2500baseX, and that an=1 should now be an=0. Please try it, and dump the
> ethtool eth1 before asking for autoneg to be manually disabled, and also
> report the kernel messages.
i see no Patch below ;)
regards Frank
On Tue, Mar 14, 2023 at 11:01:42AM +0100, Frank Wunderlich wrote:
> Hi
>
> > Gesendet: Dienstag, 14. M?rz 2023 um 10:12 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
> > On Tue, Mar 14, 2023 at 09:51:12AM +0100, Frank Wunderlich wrote:
> > > Hi,
> > >
> > > at least the error-message is gone, and interface gets up when i call ethtoo to switch off autoneg.
> ...
> > > [ 34.400860] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00000000,0000e400 pause=04 link=0 an=1
> >
> > Looking good - apart from that pesky an=1 (which isn't used by the PCS
> > driver, and I've been thinking of killing it off anyway.) Until such
> > time that happens, we really ought to set that correctly, which means
> > an extra bit is needed in phylink_sfp_set_config(). However, this
> > should not affect anything.
> >
> > > root@bpi-r3:~#
> > > root@bpi-r3:~# ethtool -s eth1 autoneg off
> > > root@bpi-r3:~# [ 131.031902] mtk_soc_eth 15100000.ethernet eth1: Link is Up - 2.5Gbps/Full - flow control off
> > > [ 131.040366] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
> > >
> > > full log here:
> > > https://pastebin.com/yDC7PuM2
> > >
> > > i see that an is still 1..maybe because of the fixed value here?
> > >
> > > https://elixir.bootlin.com/linux/v6.3-rc1/source/drivers/net/phy/phylink.c#L3038
> >
> > Not sure what that line has to do with it - this is what the above
> > points to:
> >
> > phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
>
> MLO_AN_INBAND => may cause the an=1 and mode=inband if previously (?) disabled :)
For 802.3z modes, MLO_AN_INBAND with Autoneg clear in the advertising mode
disables in-band negotiation. This is exactly how "ethtool -s ethX
autoneg off" works.
> > The patch below should result in ethtool reporting 2500baseT rather than
> > 2500baseX, and that an=1 should now be an=0. Please try it, and dump the
> > ethtool eth1 before asking for autoneg to be manually disabled, and also
> > report the kernel messages.
>
> i see no Patch below ;)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 1a2f074685fa..b8844dfcbf51 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2898,6 +2898,10 @@ static void phylink_sfp_set_config(struct phylink *pl, u8 mode,
changed = true;
}
+ if (pl->link_config.an_enabled != state->an_enabled)
+ changed = true;
+ pl->link_config.an_enabled = state->an_enabled;
+
if (pl->cur_link_an_mode != mode ||
pl->link_config.interface != state->interface) {
pl->cur_link_an_mode = mode;
@@ -3001,7 +3005,8 @@ static int phylink_sfp_config_optical(struct phylink *pl)
config.speed = SPEED_UNKNOWN;
config.duplex = DUPLEX_UNKNOWN;
config.pause = MLO_PAUSE_AN;
- config.an_enabled = true;
+ config.an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+ support);
/* For all the interfaces that are supported, reduce the sfp_support
* mask to only those link modes that can be supported.
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index daac293e8ede..1dd50f2ca05d 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -151,6 +151,10 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned int br_min, br_nom, br_max;
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+ phylink_set(modes, Autoneg);
+ phylink_set(modes, Pause);
+ phylink_set(modes, Asym_Pause);
+
/* Decode the bitrate information to MBd */
br_min = br_nom = br_max = 0;
if (id->base.br_nominal) {
@@ -329,10 +333,6 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
bus->sfp_quirk->modes(id, modes, interfaces);
linkmode_or(support, support, modes);
-
- phylink_set(support, Autoneg);
- phylink_set(support, Pause);
- phylink_set(support, Asym_Pause);
}
EXPORT_SYMBOL_GPL(sfp_parse_support);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 39e3095796d0..9c1fa0b1737f 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -360,6 +360,23 @@ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
__set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces);
}
+static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
+ unsigned long *modes,
+ unsigned long *interfaces)
+{
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
+}
+
+static void sfp_quirk_oem_2_5g(const struct sfp_eeprom_id *id,
+ unsigned long *modes,
+ unsigned long *interfaces)
+{
+ /* Copper 2.5G SFP */
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, modes);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, interfaces);
+ sfp_quirk_disable_autoneg(id, modes, interfaces);
+}
+
static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
@@ -401,6 +418,7 @@ static const struct sfp_quirk sfp_quirks[] = {
SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
+ SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Hi
very good...do not need the manual autoneg with the last Patch :)
> Gesendet: Dienstag, 14. März 2023 um 11:10 Uhr
> Von: "Russell King (Oracle)" <[email protected]>
> For 802.3z modes, MLO_AN_INBAND with Autoneg clear in the advertising mode
> disables in-band negotiation. This is exactly how "ethtool -s ethX
> autoneg off" works.
ok, this seems now correctly set.
> > > The patch below should result in ethtool reporting 2500baseT rather than
> > > 2500baseX, and that an=1 should now be an=0. Please try it, and dump the
> > > ethtool eth1 before asking for autoneg to be manually disabled, and also
> > > report the kernel messages.
root@bpi-r3:~# ip link set eth1 up
[ 91.624075] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
[ 91.632485] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
[ 91.639094] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00008000,00006400 pause=00 link=0 an=0
root@bpi-r3:~# [ 95.808983] mtk_soc_eth 15100000.ethernet eth1: Link is Up - Unknown/Unknown - flow control off
[ 95.817706] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
root@bpi-r3:~# ethtool eth1
Settings for eth1:
Supported ports: [ FIBRE ]
Supported link modes: 2500baseT/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: No
Supported FEC modes: Not reported
Advertised link modes: 2500baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: No
Advertised FEC modes: Not reported
Speed: Unknown!
Duplex: Unknown! (255)
Auto-negotiation: off
Port: FIBRE
PHYAD: 0
Transceiver: internal
Current message level: 0x000000ff (255)
drv probe link timer ifdown ifup rx_err tx_err
Link detected: yes
root@bpi-r3:~# dmesg | grep -i 'sfp\|eth1'
[ 0.000000] Linux version 6.3.0-rc1-bpi-r3-sfp13 (frank@frank-G5) (aarch64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #2 SMP Tue Mar 143
[ 1.658048] sfp sfp-1: Host maximum power 1.0W
[ 1.663128] sfp sfp-2: Host maximum power 1.0W
[ 1.812401] mtk_soc_eth 15100000.ethernet eth1: mediatek frame engine at 0xffffffc00af80000, irq 123
[ 2.001796] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
[ 2.011307] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=22]
[ 2.020000] mtk_soc_eth 15100000.ethernet eth1: optical SFP: chosen 2500base-x interface
[ 2.028080] mtk_soc_eth 15100000.ethernet eth1: requesting link mode inband/2500base-x with support 00,00000000,00008000,00006400
[ 91.624075] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
[ 91.632485] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
[ 91.639094] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00008000,00006400 pause=00 link=0 an=0
[ 95.808983] mtk_soc_eth 15100000.ethernet eth1: Link is Up - Unknown/Unknown - flow control off
[ 95.817706] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
so you can see the link-up comes directly after the interface up
does the ethtool-output look like expected? i see speed/duplex is set as supported/advertised but not active
Supported link modes: 2500baseT/Full
Advertised link modes: 2500baseT/Full
vs.
Speed: Unknown!
Duplex: Unknown! (255)
maybe because of the
@@ -3003,7 +3007,8 @@ static int phylink_sfp_config_optical(struct phylink *pl)
config.speed = SPEED_UNKNOWN;
config.duplex = DUPLEX_UNKNOWN;
config.pause = MLO_PAUSE_AN;
imho ETHTOOL_LINK_MODE_2500baseT_Full_BIT sets only the supported which intersected with the advertised from the other side maximum should be taken as actual mode...so this part seems not correctly working at the moment.
the "Supported ports: [ FIBRE ]" is also misleading for copper sfp, but imho all SFP are shown like this.
full log if needed:
https://pastebin.com/6yWe4Kyi
next step:
is it possible to have pause for rate adaption (handling rx pause frames correctly)?
regards Frank
On Tue, Mar 14, 2023 at 02:59:11PM +0100, Frank Wunderlich wrote:
> Hi
>
> very good...do not need the manual autoneg with the last Patch :)
Great news! Thanks for your patience.
> > Gesendet: Dienstag, 14. M?rz 2023 um 11:10 Uhr
> > Von: "Russell King (Oracle)" <[email protected]>
>
> > For 802.3z modes, MLO_AN_INBAND with Autoneg clear in the advertising mode
> > disables in-band negotiation. This is exactly how "ethtool -s ethX
> > autoneg off" works.
>
> ok, this seems now correctly set.
>
> > > > The patch below should result in ethtool reporting 2500baseT rather than
> > > > 2500baseX, and that an=1 should now be an=0. Please try it, and dump the
> > > > ethtool eth1 before asking for autoneg to be manually disabled, and also
> > > > report the kernel messages.
>
> root@bpi-r3:~# ip link set eth1 up
> [ 91.624075] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
> [ 91.632485] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
> [ 91.639094] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00008000,00006400 pause=00 link=0 an=0
> root@bpi-r3:~# [ 95.808983] mtk_soc_eth 15100000.ethernet eth1: Link is Up - Unknown/Unknown - flow control off
> [ 95.817706] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
>
> root@bpi-r3:~# ethtool eth1
> Settings for eth1:
> Supported ports: [ FIBRE ]
> Supported link modes: 2500baseT/Full
> Supported pause frame use: Symmetric Receive-only
> Supports auto-negotiation: No
> Supported FEC modes: Not reported
> Advertised link modes: 2500baseT/Full
> Advertised pause frame use: Symmetric Receive-only
> Advertised auto-negotiation: No
> Advertised FEC modes: Not reported
> Speed: Unknown!
> Duplex: Unknown! (255)
> Auto-negotiation: off
> Port: FIBRE
> PHYAD: 0
> Transceiver: internal
> Current message level: 0x000000ff (255)
> drv probe link timer ifdown ifup rx_err tx_err
> Link detected: yes
>
> root@bpi-r3:~# dmesg | grep -i 'sfp\|eth1'
> [ 0.000000] Linux version 6.3.0-rc1-bpi-r3-sfp13 (frank@frank-G5) (aarch64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #2 SMP Tue Mar 143
> [ 1.658048] sfp sfp-1: Host maximum power 1.0W
> [ 1.663128] sfp sfp-2: Host maximum power 1.0W
> [ 1.812401] mtk_soc_eth 15100000.ethernet eth1: mediatek frame engine at 0xffffffc00af80000, irq 123
> [ 2.001796] sfp sfp-1: module OEM SFP-2.5G-T rev 1.0 sn SK2301110008 dc 230110
> [ 2.011307] mtk_soc_eth 15100000.ethernet eth1: optical SFP: interfaces=[mac=2-4,21-22, sfp=22]
> [ 2.020000] mtk_soc_eth 15100000.ethernet eth1: optical SFP: chosen 2500base-x interface
> [ 2.028080] mtk_soc_eth 15100000.ethernet eth1: requesting link mode inband/2500base-x with support 00,00000000,00008000,00006400
> [ 91.624075] mtk_soc_eth 15100000.ethernet eth1: configuring for inband/2500base-x link mode
> [ 91.632485] mtk_soc_eth 15100000.ethernet eth1: major config 2500base-x
> [ 91.639094] mtk_soc_eth 15100000.ethernet eth1: phylink_mac_config: mode=inband/2500base-x/Unknown/Unknown/none adv=00,00000000,00008000,00006400 pause=00 link=0 an=0
> [ 95.808983] mtk_soc_eth 15100000.ethernet eth1: Link is Up - Unknown/Unknown - flow control off
> [ 95.817706] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
>
> so you can see the link-up comes directly after the interface up
>
> does the ethtool-output look like expected? i see speed/duplex is set as supported/advertised but not active
>
> Supported link modes: 2500baseT/Full
> Advertised link modes: 2500baseT/Full
> vs.
> Speed: Unknown!
> Duplex: Unknown! (255)
Yes, and I think that's reasonable given that the PHY is inaccessible,
and therefore we have no way to know what the PHY is actually doing.
> imho ETHTOOL_LINK_MODE_2500baseT_Full_BIT sets only the supported which intersected with the advertised from the other side maximum should be taken as actual mode...so this part seems not correctly working at the moment.
... except we don't know what "the other side" is doing because we
need to read that from the PHY in the SFP.
> the "Supported ports: [ FIBRE ]" is also misleading for copper sfp, but imho all SFP are shown like this.
... unless they have a PHY we can access.
> full log if needed:
> https://pastebin.com/6yWe4Kyi
>
> next step:
> is it possible to have pause for rate adaption (handling rx pause frames correctly)?
That's certainly the next issue to sort out. I'll send a patch when I've
sorted that out.
Thanks!
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!