Message ID | 20210301111818.2081582-9-olteanv@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 3a5d12c9be6f30080600c8bacaf310194e37d029 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Fixes for NXP ENETC driver | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net |
netdev/subject_prefix | success | Link |
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 | success | total: 0 errors, 0 warnings, 0 checks, 8 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
>-----Original Message----- >From: Vladimir Oltean <olteanv@gmail.com> >Sent: Monday, March 1, 2021 1:18 PM >To: David S . Miller <davem@davemloft.net>; Jakub Kicinski ><kuba@kernel.org>; netdev@vger.kernel.org >Cc: Michael Walle <michael@walle.cc>; Claudiu Manoil ><claudiu.manoil@nxp.com>; Alexandru Marginean ><alexandru.marginean@nxp.com>; Andrew Lunn <andrew@lunn.ch>; >Vladimir Oltean <vladimir.oltean@nxp.com> >Subject: [PATCH v3 net 8/8] net: enetc: keep RX ring consumer index in sync >with hardware > Hi Vladimir, > >Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet >drivers") I just realized I introduced this regression with the MDIO workaround patch. I you look at the initial code from d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") , the consumer index is being updated with the value of next_to_use inside enetc_refill_rx_ring(): static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt) { [...] if (likely(j)) { rx_ring->next_to_alloc = i; /* keep track from page reuse */ rx_ring->next_to_use = i; /* update ENETC's consumer index */ enetc_wr_reg(rx_ring->rcir, i); } return j; } See: https://elixir.bootlin.com/linux/v5.4.101/source/drivers/net/ethernet/freescale/enetc/enetc.c#L434 enetc_refill_rx_ring() being called on both data path and init path (enetc_setup_rxbdr). With commit fd5736bf9f23 ("enetc: Workaround for MDIO register access issue") I messed this up: I moved this update outside refill_rx_ring(): @@ -515,8 +533,6 @@ static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt) if (likely(j)) { rx_ring->next_to_alloc = i; /* keep track from page reuse */ rx_ring->next_to_use = i; - /* update ENETC's consumer index */ - enetc_wr_reg(rx_ring->rcir, i); } [....] Updated the data path side accordingly (changing update to the new accessor) : @@ -684,23 +700,31 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, u32 bd_status; u16 size; + enetc_lock_mdio(); + if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt); + /* update ENETC's consumer index */ + enetc_wr_reg_hot(rx_ring->rcir, rx_ring->next_to_use); cleaned_cnt -= count; } [...] But on the init path I messed it up likely due to some merge conflict: @@ -1225,6 +1252,7 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) rx_ring->idr = hw->reg + ENETC_SIRXIDR; enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); + enetc_wr(hw, ENETC_SIRXIDR, rx_ring->next_to_use); Instead of: enetc_wr_reg(rx_ring->rcir, rx_ring->next_to_use); or enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use); ... if you prefer. Obviously writing to ENETC_SIRXIDR makes no sense, and just shows that something went wrong with that commit. So the blamed commit for this is: fd5736bf9f23 ("enetc: Workaround for MDIO register access issue"). And you could merge patches 7/8 and 8/8, as they both deal with fixing the (merge conflict) regression that I introduced with the MDIO w/a patch: Fixes: fd5736bf9f23 ("enetc: Workaround for MDIO register access issue"). Sorry for all this trouble. Thanks, Claudiu >Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> >--- >Changes in v3: >Patch is new. > > drivers/net/ethernet/freescale/enetc/enetc.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c >b/drivers/net/ethernet/freescale/enetc/enetc.c >index abb29ee81463..30d7d4e83900 100644 >--- a/drivers/net/ethernet/freescale/enetc/enetc.c >+++ b/drivers/net/ethernet/freescale/enetc/enetc.c >@@ -1212,6 +1212,8 @@ static void enetc_setup_rxbdr(struct enetc_hw >*hw, struct enetc_bdr *rx_ring) > rx_ring->idr = hw->reg + ENETC_SIRXIDR; > > enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); >+ /* update ENETC's consumer index */ >+ enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use); > > /* enable ring */ > enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); >-- >2.25.1
On Mon, Mar 01, 2021 at 01:18:18PM +0200, Vladimir Oltean wrote: > The simpler thing would be to put the write to the consumer index into > enetc_refill_rx_ring directly, but there are issues with the MDIO > locking: in the NAPI poll code we have the enetc_lock_mdio() taken from > top-level and we use the unlocked enetc_wr_reg_hot, whereas in > enetc_open, the enetc_lock_mdio() is not taken at the top level, but > instead by each individual enetc_wr_reg, so we are forced to put an > additional enetc_wr_reg in enetc_setup_rxbdr. Better organization of > the code is left as a refactoring exercise. > > Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> > --- Claudiu pointed out privately that this is exactly what was done prior to commit fd5736bf9f23 ("enetc: Workaround for MDIO register access issue"), and therefore, the driver used to work before that (I missed that during my assessment). So my Fixes: tag is actually incorrect. I will send a follow-up version where this is squashed with patch 7/8 and the Fixes: tag is adjusted.
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index abb29ee81463..30d7d4e83900 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1212,6 +1212,8 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) rx_ring->idr = hw->reg + ENETC_SIRXIDR; enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); + /* update ENETC's consumer index */ + enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use); /* enable ring */ enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);