From 6dcfb19f60e151d4659d1759fecb0d01bc5d1fc7 Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Mon, 30 May 2022 17:30:12 +0800 Subject: [PATCH] net/ngbe: fix reading M88E1512 PHY mode For M88E1512 PHY mixed mode, PXE driver overrides PHY mode at load time. To workaround this problem, change to read PHY mode from flash instead of register. Fixes: 1c44384fce76 ("net/ngbe: support custom PHY interfaces") Cc: stable@dpdk.org Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_hw.c | 37 ++++++++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_hw.h | 3 +++ drivers/net/ngbe/base/ngbe_phy_mvl.c | 9 ++++--- drivers/net/ngbe/base/ngbe_phy_mvl.h | 1 + 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index fa2d749240..050649e0a6 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -1805,6 +1805,43 @@ s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval) return 0; } +/* cmd_addr is used for some special command: + * 1. to be sector address, when implemented erase sector command + * 2. to be flash address when implemented read, write flash address + */ +u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr) +{ + u32 cmd_val = 0; + u32 i = 0; + + cmd_val = NGBE_SPICMD_CMD(cmd) | NGBE_SPICMD_CLK(3) | cmd_addr; + wr32(hw, NGBE_SPICMD, cmd_val); + + for (i = 0; i < 10000; i++) { + if (rd32(hw, NGBE_SPISTAT) & NGBE_SPISTAT_OPDONE) + break; + + usec_delay(10); + } + if (i == 10000) + return 1; + + return 0; +} + +u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr) +{ + u32 status = 0; + + status = ngbe_fmgr_cmd_op(hw, 1, addr); + if (status) { + DEBUGOUT("Read flash timeout."); + return status; + } + + return rd32(hw, NGBE_SPIDAT); +} + void ngbe_map_device_id(struct ngbe_hw *hw) { u16 oem = hw->sub_system_id & NGBE_OEM_MASK; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index 7e0e23b195..2813e72d60 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -83,4 +83,7 @@ s32 ngbe_init_phy(struct ngbe_hw *hw); s32 ngbe_enable_rx_dma(struct ngbe_hw *hw, u32 regval); void ngbe_map_device_id(struct ngbe_hw *hw); +u32 ngbe_fmgr_cmd_op(struct ngbe_hw *hw, u32 cmd, u32 cmd_addr); +u32 ngbe_flash_read_dword(struct ngbe_hw *hw, u32 addr); + #endif /* _NGBE_HW_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c index 85af6bc99c..c5256359ed 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.c +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.c @@ -50,11 +50,12 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, s32 ngbe_check_phy_mode_mvl(struct ngbe_hw *hw) { - u16 value = 0; + u8 value = 0; + u32 phy_mode = 0; + + phy_mode = ngbe_flash_read_dword(hw, 0xFF010); + value = (u8)(phy_mode >> (hw->bus.lan_id * 8)); - /* select page 18 reg 20 */ - ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18); - ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &value); if (MVL_GEN_CTL_MODE(value) == MVL_GEN_CTL_MODE_COPPER) { /* mode select to RGMII-to-copper */ hw->phy.type = ngbe_phy_mvl; diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h index ab07c99fe4..1cf49ac8c5 100644 --- a/drivers/net/ngbe/base/ngbe_phy_mvl.h +++ b/drivers/net/ngbe/base/ngbe_phy_mvl.h @@ -3,6 +3,7 @@ */ #include "ngbe_phy.h" +#include "ngbe_hw.h" #ifndef _NGBE_PHY_MVL_H_ #define _NGBE_PHY_MVL_H_ -- 2.39.5