mac80211: drop frames for sta with no valid rate
[pandora-kernel.git] / net / mac80211 / tx.c
index d238a89..f3efd4f 100644 (file)
@@ -512,6 +512,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        int i, len;
        bool inval = false, rts = false, short_preamble = false;
        struct ieee80211_tx_rate_control txrc;
+       u32 sta_flags;
 
        memset(&txrc, 0, sizeof(txrc));
 
@@ -544,7 +545,26 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
             (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
                txrc.short_preamble = short_preamble = true;
 
+       sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+
+       /*
+        * Lets not bother rate control if we're associated and cannot
+        * talk to the sta. This should not happen.
+        */
+       if (WARN((tx->local->sw_scanning) &&
+                (sta_flags & WLAN_STA_ASSOC) &&
+                !rate_usable_index_exists(sband, &tx->sta->sta),
+                "%s: Dropped data frame as no usable bitrate found while "
+                "scanning and associated. Target station: "
+                "%pM on %d GHz band\n",
+                tx->dev->name, hdr->addr1,
+                tx->channel->band ? 5 : 2))
+               return TX_DROP;
 
+       /*
+        * If we're associated with the sta at this point we know we can at
+        * least send the frame at the lowest bit rate.
+        */
        rate_control_get_rate(tx->sdata, tx->sta, &txrc);
 
        if (unlikely(info->control.rates[0].idx < 0))
@@ -1455,7 +1475,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
                monitor_iface = UNKNOWN_ADDRESS;
 
                len_rthdr = ieee80211_get_radiotap_len(skb->data);
-               hdr = (struct ieee80211_hdr *)skb->data + len_rthdr;
+               hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
                hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
                /* check the header is complete in the frame */
@@ -1627,7 +1647,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        u32 sta_flags = 0;
 
        if (unlikely(skb->len < ETH_HLEN)) {
-               ret = 0;
+               ret = NETDEV_TX_OK;
                goto fail;
        }
 
@@ -1664,7 +1684,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
                        /* Do not send frames with mesh_ttl == 0 */
                        sdata->u.mesh.mshstats.dropped_frames_ttl++;
-                       ret = 0;
+                       ret = NETDEV_TX_OK;
                        goto fail;
                }
                memset(&mesh_hdr, 0, sizeof(mesh_hdr));
@@ -1724,7 +1744,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                hdrlen = 24;
                break;
        default:
-               ret = 0;
+               ret = NETDEV_TX_OK;
                goto fail;
        }
 
@@ -1766,7 +1786,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 
                I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
 
-               ret = 0;
+               ret = NETDEV_TX_OK;
                goto fail;
        }
 
@@ -1858,10 +1878,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        dev->trans_start = jiffies;
        dev_queue_xmit(skb);
 
-       return 0;
+       return NETDEV_TX_OK;
 
  fail:
-       if (!ret)
+       if (ret == NETDEV_TX_OK)
                dev_kfree_skb(skb);
 
        return ret;