wl12xx: discard corrupted packets in RX
authorArik Nemtsov <arik@wizery.com>
Tue, 26 Apr 2011 20:35:40 +0000 (23:35 +0300)
committerLuciano Coelho <coelho@ti.com>
Mon, 2 May 2011 07:27:25 +0000 (10:27 +0300)
When packets arrive with a RX descriptor indicating corruption, discard
them.

In general white-list the RX descriptor status to prevent rouge data
from being sent up.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/wl12xx/rx.c

index faf5a1d3c2c3cf4adef320c96eceb0ec6180c433..70091035e0199fc15fc18e1377e7b3e3eaf4d63f 100644 (file)
@@ -76,12 +76,15 @@ static void wl1271_rx_status(struct wl1271 *wl,
                                                      status->band);
 
        if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
-               status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+               u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK;
 
-               if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL)))
-                       status->flag |= RX_FLAG_DECRYPTED;
-               if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL))
+               status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
+                               RX_FLAG_DECRYPTED;
+
+               if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) {
                        status->flag |= RX_FLAG_MMIC_ERROR;
+                       wl1271_warning("Michael MIC error");
+               }
        }
 }
 
@@ -100,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
        if (unlikely(wl->state == WL1271_STATE_PLT))
                return -EINVAL;
 
+       /* the data read starts with the descriptor */
+       desc = (struct wl1271_rx_descriptor *) data;
+
+       switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
+       /* discard corrupted packets */
+       case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
+       case WL1271_RX_DESC_DECRYPT_FAIL:
+               wl1271_warning("corrupted packet in RX with status: 0x%x",
+                              desc->status & WL1271_RX_DESC_STATUS_MASK);
+               return -EINVAL;
+       case WL1271_RX_DESC_SUCCESS:
+       case WL1271_RX_DESC_MIC_FAIL:
+               break;
+       default:
+               wl1271_error("invalid RX descriptor status: 0x%x",
+                            desc->status & WL1271_RX_DESC_STATUS_MASK);
+               return -EINVAL;
+       }
+
        skb = __dev_alloc_skb(length, GFP_KERNEL);
        if (!skb) {
                wl1271_error("Couldn't allocate RX frame");
@@ -109,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
        buf = skb_put(skb, length);
        memcpy(buf, data, length);
 
-       /* the data read starts with the descriptor */
-       desc = (struct wl1271_rx_descriptor *) buf;
-
        /* now we pull the descriptor out of the buffer */
        skb_pull(skb, sizeof(*desc));