| From foo@baz Sat Jan 26 10:22:50 CET 2019 |
| From: "Lendacky, Thomas" <Thomas.Lendacky@amd.com> |
| Date: Thu, 17 Jan 2019 14:20:14 +0000 |
| Subject: amd-xgbe: Fix mdio access for non-zero ports and clause 45 PHYs |
| |
| From: "Lendacky, Thomas" <Thomas.Lendacky@amd.com> |
| |
| [ Upstream commit 5ab3121beeb76aa6090195b67d237115860dd9ec ] |
| |
| The XGBE hardware has support for performing MDIO operations using an |
| MDIO command request. The driver mistakenly uses the mdio port address |
| as the MDIO command request device address instead of the MDIO command |
| request port address. Additionally, the driver does not properly check |
| for and create a clause 45 MDIO command. |
| |
| Check the supplied MDIO register to determine if the request is a clause |
| 45 operation (MII_ADDR_C45). For a clause 45 operation, extract the device |
| address and register number from the supplied MDIO register and use them |
| to set the MDIO command request device address and register number fields. |
| For a clause 22 operation, the MDIO request device address is set to zero |
| and the MDIO command request register number is set to the supplied MDIO |
| register. In either case, the supplied MDIO port address is used as the |
| MDIO command request port address. |
| |
| Fixes: 732f2ab7afb9 ("amd-xgbe: Add support for MDIO attached PHYs") |
| Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> |
| Tested-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/amd/xgbe/xgbe-common.h | 2 -- |
| drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 22 ++++++++++++++++------ |
| 2 files changed, 16 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h |
| +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h |
| @@ -431,8 +431,6 @@ |
| #define MAC_MDIOSCAR_PA_WIDTH 5 |
| #define MAC_MDIOSCAR_RA_INDEX 0 |
| #define MAC_MDIOSCAR_RA_WIDTH 16 |
| -#define MAC_MDIOSCAR_REG_INDEX 0 |
| -#define MAC_MDIOSCAR_REG_WIDTH 21 |
| #define MAC_MDIOSCCDR_BUSY_INDEX 22 |
| #define MAC_MDIOSCCDR_BUSY_WIDTH 1 |
| #define MAC_MDIOSCCDR_CMD_INDEX 16 |
| --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c |
| +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c |
| @@ -1284,6 +1284,20 @@ static void xgbe_write_mmd_regs(struct x |
| } |
| } |
| |
| +static unsigned int xgbe_create_mdio_sca(int port, int reg) |
| +{ |
| + unsigned int mdio_sca, da; |
| + |
| + da = (reg & MII_ADDR_C45) ? reg >> 16 : 0; |
| + |
| + mdio_sca = 0; |
| + XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg); |
| + XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port); |
| + XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, da); |
| + |
| + return mdio_sca; |
| +} |
| + |
| static int xgbe_write_ext_mii_regs(struct xgbe_prv_data *pdata, int addr, |
| int reg, u16 val) |
| { |
| @@ -1291,9 +1305,7 @@ static int xgbe_write_ext_mii_regs(struc |
| |
| reinit_completion(&pdata->mdio_complete); |
| |
| - mdio_sca = 0; |
| - XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg); |
| - XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr); |
| + mdio_sca = xgbe_create_mdio_sca(addr, reg); |
| XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca); |
| |
| mdio_sccd = 0; |
| @@ -1317,9 +1329,7 @@ static int xgbe_read_ext_mii_regs(struct |
| |
| reinit_completion(&pdata->mdio_complete); |
| |
| - mdio_sca = 0; |
| - XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg); |
| - XGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr); |
| + mdio_sca = xgbe_create_mdio_sca(addr, reg); |
| XGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca); |
| |
| mdio_sccd = 0; |