Two bugs in the same loop in ixgbe_validate_rtr():

1. When extracting 3-bit traffic class values from the IXGBE_RTRUP2TC
   register the shifted value was assigned directly to a u8, silently
   truncating any bits above bit 7.  Mask with IXGBE_RTRUP2TC_UP_MASK
   before the assignment so only the intended 3 bits are kept.

2. When clearing an out-of-bounds entry the mask was always shifted by
   the fixed constant IXGBE_RTRUP2TC_UP_SHIFT (== 3), regardless of
   which loop iteration was being processed.  This means only the entry
   at bit position 3 was ever cleared; entries at bit positions 0, 6, 9,
   ..., 21 were left unreset.  Use i * IXGBE_RTRUP2TC_UP_SHIFT to target
   the correct field for each iteration.

Also replace the hardcoded 0x7 literal with the IXGBE_RTRUP2TC_UP_MASK
constant for consistency with other parts of the driver.

Signed-off-by: Aleksandr Loktionov <[email protected]>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 9aec66c..53b82a5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9798,11 +9798,12 @@ static void ixgbe_validate_rtr(struct ixgbe_adapter 
*adapter, u8 tc)
        rsave = reg;
 
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
-               u8 up2tc = reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT);
+               u8 up2tc = IXGBE_RTRUP2TC_UP_MASK &
+                          (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
 
                /* If up2tc is out of bounds default to zero */
                if (up2tc > tc)
-                       reg &= ~(0x7 << IXGBE_RTRUP2TC_UP_SHIFT);
+                       reg &= ~(IXGBE_RTRUP2TC_UP_MASK << (i * 
IXGBE_RTRUP2TC_UP_SHIFT));
        }
 
        if (reg != rsave)
-- 
2.52.0

Reply via email to