]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/tx.c
mac80211: use oneshot blink API for LED triggers
[karo-tx-linux.git] / net / mac80211 / tx.c
index 9972e07a2f9650315521560cfb48267504476200..f65873f0c89f07ee33e41e28c80bc3b02295e85b 100644 (file)
@@ -40,12 +40,22 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                                 struct sk_buff *skb, int group_addr,
                                 int next_frag_len)
 {
-       int rate, mrate, erp, dur, i;
+       int rate, mrate, erp, dur, i, shift = 0;
        struct ieee80211_rate *txrate;
        struct ieee80211_local *local = tx->local;
        struct ieee80211_supported_band *sband;
        struct ieee80211_hdr *hdr;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       u32 rate_flags = 0;
+
+       rcu_read_lock();
+       chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
+       if (chanctx_conf) {
+               shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
+               rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
+       }
+       rcu_read_unlock();
 
        /* assume HW handles this */
        if (tx->rate.flags & IEEE80211_TX_RC_MCS)
@@ -122,8 +132,11 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                if (r->bitrate > txrate->bitrate)
                        break;
 
+               if ((rate_flags & r->flags) != rate_flags)
+                       continue;
+
                if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
-                       rate = r->bitrate;
+                       rate = DIV_ROUND_UP(r->bitrate, 1 << shift);
 
                switch (sband->band) {
                case IEEE80211_BAND_2GHZ: {
@@ -150,7 +163,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
        if (rate == -1) {
                /* No matching basic rate found; use highest suitable mandatory
                 * PHY rate */
-               rate = mrate;
+               rate = DIV_ROUND_UP(mrate, 1 << shift);
        }
 
        /* Don't calculate ACKs for QoS Frames with NoAck Policy set */
@@ -162,7 +175,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                 * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up
                 * to closest integer */
                dur = ieee80211_frame_duration(sband->band, 10, rate, erp,
-                               tx->sdata->vif.bss_conf.use_short_preamble);
+                               tx->sdata->vif.bss_conf.use_short_preamble,
+                               shift);
 
        if (next_frag_len) {
                /* Frame is fragmented: duration increases with time needed to
@@ -171,7 +185,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                /* next fragment */
                dur += ieee80211_frame_duration(sband->band, next_frag_len,
                                txrate->bitrate, erp,
-                               tx->sdata->vif.bss_conf.use_short_preamble);
+                               tx->sdata->vif.bss_conf.use_short_preamble,
+                               shift);
        }
 
        return cpu_to_le16(dur);
@@ -398,13 +413,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        if (ieee80211_has_order(hdr->frame_control))
                return TX_CONTINUE;
 
+       if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
+               info->hw_queue = tx->sdata->vif.cab_queue;
+
        /* no stations in PS mode */
        if (!atomic_read(&ps->num_sta_ps))
                return TX_CONTINUE;
 
        info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
-       if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
-               info->hw_queue = tx->sdata->vif.cab_queue;
 
        /* device releases frame after DTIM beacon */
        if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
@@ -1256,6 +1272,10 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
 
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MONITOR:
+               if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+                       vif = &sdata->vif;
+                       break;
+               }
                sdata = rcu_dereference(local->monitor_sdata);
                if (sdata) {
                        vif = &sdata->vif;
@@ -1280,7 +1300,6 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
                                    txpending);
 
        ieee80211_tpt_led_trig_tx(local, fc, led_len);
-       ieee80211_led_tx(local, 1);
 
        WARN_ON_ONCE(!skb_queue_empty(skbs));
 
@@ -1789,12 +1808,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                break;
 #ifdef CONFIG_MAC80211_MESH
        case NL80211_IFTYPE_MESH_POINT:
-               if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
-                       /* Do not send frames with mesh_ttl == 0 */
-                       sdata->u.mesh.mshstats.dropped_frames_ttl++;
-                       goto fail_rcu;
-               }
-
                if (!is_multicast_ether_addr(skb->data)) {
                        struct sta_info *next_hop;
                        bool mpp_lookup = true;