Merge tag 'mac80211-next-for-davem-2015-10-05' of git://git.kernel.org/pub/scm/linux...
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / tx.c
index b8233505bf9fd3bb4945c126eebee069f2b94878..464ba1a625bdc9aa82f4de53d60cdc341b0d0565 100644 (file)
@@ -311,9 +311,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
        if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
                return TX_CONTINUE;
 
-       if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
-               return TX_CONTINUE;
-
        if (tx->flags & IEEE80211_TX_PS_BUFFERED)
                return TX_CONTINUE;
 
@@ -610,7 +607,6 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
        if (tx->key) {
                bool skip_hw = false;
 
-               tx->key->tx_rx_count++;
                /* TODO: add threshold stuff again */
 
                switch (tx->key->conf.cipher) {
@@ -690,7 +686,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 
        txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
                    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
-                   tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
+                   tx->sdata->vif.type == NL80211_IFTYPE_ADHOC ||
+                   tx->sdata->vif.type == NL80211_IFTYPE_OCB);
 
        /* set up RTS protection if desired */
        if (len > tx->local->hw.wiphy->rts_threshold) {
@@ -2770,14 +2767,19 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
 
        if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
                *ieee80211_get_qos_ctl(hdr) = tid;
-               hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
+               if (!sta->sta.txq[0])
+                       hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
        } else {
                info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
                hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);
                sdata->sequence_number += 0x10;
        }
 
-       sta->tx_msdu[tid]++;
+       if (skb_shinfo(skb)->gso_size)
+               sta->tx_msdu[tid] +=
+                       DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size);
+       else
+               sta->tx_msdu[tid]++;
 
        info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
 
@@ -3213,6 +3215,16 @@ static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata,
        rcu_read_unlock();
 }
 
+static u8 __ieee80211_csa_update_counter(struct beacon_data *beacon)
+{
+       beacon->csa_current_counter--;
+
+       /* the counter should never reach 0 */
+       WARN_ON_ONCE(!beacon->csa_current_counter);
+
+       return beacon->csa_current_counter;
+}
+
 u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -3231,11 +3243,7 @@ u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
        if (!beacon)
                goto unlock;
 
-       beacon->csa_current_counter--;
-
-       /* the counter should never reach 0 */
-       WARN_ON_ONCE(!beacon->csa_current_counter);
-       count = beacon->csa_current_counter;
+       count = __ieee80211_csa_update_counter(beacon);
 
 unlock:
        rcu_read_unlock();
@@ -3335,7 +3343,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
                if (beacon) {
                        if (beacon->csa_counter_offsets[0]) {
                                if (!is_template)
-                                       ieee80211_csa_update_counter(vif);
+                                       __ieee80211_csa_update_counter(beacon);
 
                                ieee80211_set_csa(sdata, beacon);
                        }
@@ -3381,7 +3389,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
 
                if (beacon->csa_counter_offsets[0]) {
                        if (!is_template)
-                               ieee80211_csa_update_counter(vif);
+                               __ieee80211_csa_update_counter(beacon);
 
                        ieee80211_set_csa(sdata, beacon);
                }
@@ -3411,7 +3419,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
                                 * for now we leave it consistent with overall
                                 * mac80211's behavior.
                                 */
-                               ieee80211_csa_update_counter(vif);
+                               __ieee80211_csa_update_counter(beacon);
 
                        ieee80211_set_csa(sdata, beacon);
                }
@@ -3505,6 +3513,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 {
        struct ieee80211_mutable_offsets offs = {};
        struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false);
+       struct sk_buff *copy;
+       struct ieee80211_supported_band *sband;
+       int shift;
+
+       if (!bcn)
+               return bcn;
 
        if (tim_offset)
                *tim_offset = offs.tim_offset;
@@ -3512,6 +3526,19 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
        if (tim_length)
                *tim_length = offs.tim_length;
 
+       if (ieee80211_hw_check(hw, BEACON_TX_STATUS) ||
+           !hw_to_local(hw)->monitors)
+               return bcn;
+
+       /* send a copy to monitor interfaces */
+       copy = skb_copy(bcn, GFP_ATOMIC);
+       if (!copy)
+               return bcn;
+
+       shift = ieee80211_vif_get_shift(vif);
+       sband = hw->wiphy->bands[ieee80211_get_sdata_band(vif_to_sdata(vif))];
+       ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
+
        return bcn;
 }
 EXPORT_SYMBOL(ieee80211_beacon_get_tim);