If AR_CRCErr, AR_PHYErr, AR_DecryptCRCErr or AR_MichaelErr is indicated
in the rx status word, but AR_RxFrameOK is also set, the descriptor
contents are typically invalid. This can show up as a warning about
invalid MCS rates in a frame. Even with those checks in place, a
descriptor with invalid MCS rates can still sometimes make it through to
the driver (mostly on older hardware like AR91xx).
Detect such errors in the last descriptor of a frame and discard the
whole frame if present.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
                else if (ads.ds_rxstatus8 & AR_MichaelErr)
                        rs->rs_status |= ATH9K_RXERR_MIC;
+       } else {
+               if (ads.ds_rxstatus8 &
+                   (AR_CRCErr | AR_PHYErr | AR_DecryptCRCErr | AR_MichaelErr))
+                       rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC;
+
+               /* Only up to MCS16 supported, everything above is invalid */
+               if (rs->rs_rate >= 0x90)
+                       rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC;
        }
 
        if (ads.ds_rxstatus8 & AR_KeyMiss)
 
 #define ATH9K_RXERR_DECRYPT       0x08
 #define ATH9K_RXERR_MIC           0x10
 #define ATH9K_RXERR_KEYMISS       0x20
+#define ATH9K_RXERR_CORRUPT_DESC  0x40
 
 #define ATH9K_RX_MORE             0x01
 #define ATH9K_RX_MORE_AGGR        0x02
 
                        sc->rx.frag = skb;
                        goto requeue;
                }
+               if (rs.rs_status & ATH9K_RXERR_CORRUPT_DESC)
+                       goto requeue_drop_frag;
 
                if (sc->rx.frag) {
                        int space = skb->len - skb_tailroom(hdr_skb);