Message ID | 20210212180010.221129-2-Shyam-sundar.S-k@amd.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Bug fixes to amd-xgbe driver | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Guessed tree name to be net-next |
netdev/subject_prefix | warning | Target tree name not specified in the subject |
netdev/cc_maintainers | success | CCed 4 of 4 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | warning | WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On 2/12/21 12:00 PM, Shyam Sundar S K wrote: > Sometimes mailbox commands timeout when the RX data path becomes > unresponsive. This prevents the submission of new mailbox commands to DXIO. > This patch identifies the timeout and resets the RX data path so that the > next message can be submitted properly. > > Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> > Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> I believe you need a Co-developed-by: before Sudheesh's Signed-off-by: if he was a co-developer. > --- > drivers/net/ethernet/amd/xgbe/xgbe-common.h | 13 +++++++++++ > drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 25 ++++++++++++++++++++- > 2 files changed, 37 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h > index b40d4377cc71..318817450fbd 100644 > --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h > +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h > @@ -1279,10 +1279,18 @@ > #define MDIO_PMA_10GBR_FECCTRL 0x00ab > #endif > > +#ifndef MDIO_PMA_RX_CTRL1 > +#define MDIO_PMA_RX_CTRL1 0x8051 > +#endif > + > #ifndef MDIO_PCS_DIG_CTRL > #define MDIO_PCS_DIG_CTRL 0x8000 > #endif > > +#ifndef MDIO_PCS_DIGITAL_STAT > +#define MDIO_PCS_DIGITAL_STAT 0x8010 > +#endif > + > #ifndef MDIO_AN_XNP > #define MDIO_AN_XNP 0x0016 > #endif > @@ -1358,6 +1366,7 @@ > #define XGBE_KR_TRAINING_ENABLE BIT(1) > > #define XGBE_PCS_CL37_BP BIT(12) > +#define XGBE_PCS_PSEQ_STATE_BIT 0x10 See comment below, this is a 3-bit field. > > #define XGBE_AN_CL37_INT_CMPLT BIT(0) > #define XGBE_AN_CL37_INT_MASK 0x01 > @@ -1375,6 +1384,10 @@ > #define XGBE_PMA_CDR_TRACK_EN_OFF 0x00 > #define XGBE_PMA_CDR_TRACK_EN_ON 0x01 > > +#define XGBE_PMA_RX_RST_0_MASK BIT(4) > +#define XGBE_PMA_RX_RST_0_RESET_ON 0x10 > +#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00 > + > /* Bit setting and getting macros > * The get macro will extract the current bit field value from within > * the variable > diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c > index 859ded0c06b0..489f1f86df99 100644 > --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c > +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c > @@ -1953,6 +1953,24 @@ static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata) > xgbe_phy_put_comm_ownership(pdata); > } > > +static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) > +{ > + int reg; > + > + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT); > + if (reg & XGBE_PCS_PSEQ_STATE_BIT) { The PSEQ_STATE field is a 3 bit field and I believe you're looking for a POWER_GOOD state, so this should be: reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT XGBE_PCS_PSEQ_STATE_MASK); if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) { where the constants define in xgbe-common.h should be: #define XGBE_PCS_PSEQ_STATE_MASK 0x1c #define XGBE_PCS_PSEQ_STATE_POWER_GOOD 0x10 > + /* mailbox command timed out, reset Rx block */ > + /* Assert reset bit for 8ns and wait for 40us */ Please combine this comment and be sure to capitalize appropriately. > + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, > + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON); > + ndelay(20); This time doesn't match the comment of 8ns... which one is correct? > + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, > + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF); > + usleep_range(40, 50); > + netif_err(pdata, link, pdata->netdev, "firmware mailbox reset performed\n"); > + } > +} > + > static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, > unsigned int cmd, unsigned int sub_cmd) > { > @@ -1960,9 +1978,11 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, > unsigned int wait; > > /* Log if a previous command did not complete */ > - if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) > + if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) { > netif_dbg(pdata, link, pdata->netdev, > "firmware mailbox not ready for command\n"); > + xgbe_phy_rx_reset(pdata); An extra tab here. Thanks, Tom > + } > > /* Construct the command */ > XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd); > @@ -1984,6 +2004,9 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, > > netif_dbg(pdata, link, pdata->netdev, > "firmware mailbox command did not complete\n"); > + > + /* Reset on error */ > + xgbe_phy_rx_reset(pdata); > } > > static void xgbe_phy_rrc(struct xgbe_prv_data *pdata) >
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index b40d4377cc71..318817450fbd 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -1279,10 +1279,18 @@ #define MDIO_PMA_10GBR_FECCTRL 0x00ab #endif +#ifndef MDIO_PMA_RX_CTRL1 +#define MDIO_PMA_RX_CTRL1 0x8051 +#endif + #ifndef MDIO_PCS_DIG_CTRL #define MDIO_PCS_DIG_CTRL 0x8000 #endif +#ifndef MDIO_PCS_DIGITAL_STAT +#define MDIO_PCS_DIGITAL_STAT 0x8010 +#endif + #ifndef MDIO_AN_XNP #define MDIO_AN_XNP 0x0016 #endif @@ -1358,6 +1366,7 @@ #define XGBE_KR_TRAINING_ENABLE BIT(1) #define XGBE_PCS_CL37_BP BIT(12) +#define XGBE_PCS_PSEQ_STATE_BIT 0x10 #define XGBE_AN_CL37_INT_CMPLT BIT(0) #define XGBE_AN_CL37_INT_MASK 0x01 @@ -1375,6 +1384,10 @@ #define XGBE_PMA_CDR_TRACK_EN_OFF 0x00 #define XGBE_PMA_CDR_TRACK_EN_ON 0x01 +#define XGBE_PMA_RX_RST_0_MASK BIT(4) +#define XGBE_PMA_RX_RST_0_RESET_ON 0x10 +#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00 + /* Bit setting and getting macros * The get macro will extract the current bit field value from within * the variable diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 859ded0c06b0..489f1f86df99 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -1953,6 +1953,24 @@ static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata) xgbe_phy_put_comm_ownership(pdata); } +static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) +{ + int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT); + if (reg & XGBE_PCS_PSEQ_STATE_BIT) { + /* mailbox command timed out, reset Rx block */ + /* Assert reset bit for 8ns and wait for 40us */ + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON); + ndelay(20); + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF); + usleep_range(40, 50); + netif_err(pdata, link, pdata->netdev, "firmware mailbox reset performed\n"); + } +} + static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd, unsigned int sub_cmd) { @@ -1960,9 +1978,11 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int wait; /* Log if a previous command did not complete */ - if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) + if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) { netif_dbg(pdata, link, pdata->netdev, "firmware mailbox not ready for command\n"); + xgbe_phy_rx_reset(pdata); + } /* Construct the command */ XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd); @@ -1984,6 +2004,9 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, netif_dbg(pdata, link, pdata->netdev, "firmware mailbox command did not complete\n"); + + /* Reset on error */ + xgbe_phy_rx_reset(pdata); } static void xgbe_phy_rrc(struct xgbe_prv_data *pdata)