carl9170 firmware: remove CONFIG_CARL9170FW_CAB_QUEUE
[carl9170fw.git] / carlfw / src / wlan.c
index 69d90e628d97062ac968aaadc025e8d4617ed3d8..3d879bd3c4be5e2a1a06c1a96db4865cd2072a6f 100644 (file)
@@ -292,25 +292,12 @@ static void __wlan_tx(struct dma_desc *desc)
 
        wlan_tx_ampdu(super);
 
-#if (defined CONFIG_CARL9170FW_LOOPBACK) || (defined CONFIG_CARL9170FW_DISCARD)
-       wlan_tx_complete(super, true);
-       unhide_super(desc);
-# ifdef CONFIG_CARL9170FW_LOOPBACK
-       dma_put(&fw.pta.up_queue, desc);
-       up_trigger();
-# elif CONFIG_CARL9170FW_DISCARD
-       dma_reclaim(&fw.pta.down_queue, desc);
-       down_trigger();
-# endif
-#else /* CONFIG_CARL9170FW_LOOPBACK */
-
-# ifdef CONFIG_CARL9170FW_DEBUG
+#ifdef CONFIG_CARL9170FW_DEBUG
        BUG_ON(fw.phy.psm.state != CARL9170_PSM_WAKE);
-# endif /* CONFIG_CARL9170FW_DEBUG */
+#endif /* CONFIG_CARL9170FW_DEBUG */
 
        /* insert desc into the right queue */
        dma_put(&fw.wlan.tx_queue[super->s.queue], desc);
-#endif /* CONFIG_CARL9170FW_LOOPBACK */
 }
 
 static void wlan_assign_seq(struct ieee80211_hdr *hdr, unsigned int vif)
@@ -318,7 +305,7 @@ static void wlan_assign_seq(struct ieee80211_hdr *hdr, unsigned int vif)
        hdr->seq_ctrl &= cpu_to_le16(~IEEE80211_SCTL_SEQ);
        hdr->seq_ctrl |= cpu_to_le16(fw.wlan.sequence[vif]);
 
-       if (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)))
+       if (ieee80211_is_first_frag(hdr->seq_ctrl))
                fw.wlan.sequence[vif] += 0x10;
 }
 
@@ -343,8 +330,6 @@ static void _wlan_tx(struct dma_desc *desc)
                            get(AR9170_MAC_REG_AMPDU_FACTOR),
                            8 << super->s.ampdu_factor));
        }
-
-       __wlan_tx(desc);
 }
 
 /* propagate transmission status back to the driver */
@@ -360,12 +345,28 @@ static bool wlan_tx_status(struct dma_queue *queue,
        /* update hangcheck */
        fw.wlan.last_super_num[qidx] = 0;
 
+       /*
+        * Note:
+        * There could be a corner case when the TXFAIL is set
+        * even though the frame was properly ACKed by the peer:
+        *   a BlockAckReq with the immediate policy will cause
+        *   the receiving peer to produce a BlockACK unfortunately
+        *   the MAC in this chip seems to be expecting a legacy
+        *   ACK and marks the BAR as failed!
+        */
+
        if (!!(desc->ctrl & AR9170_CTRL_FAIL)) {
                txfail = !!(desc->ctrl & AR9170_CTRL_TXFAIL);
 
                /* reset retry indicator flags */
                desc->ctrl &= ~(AR9170_CTRL_TXFAIL | AR9170_CTRL_BAFAIL);
 
+               /*
+                * Note: wlan_tx_consume_retry will override the old
+                * phy [CCK,OFDM, HT, BW20/40, MCS...] and mac vectors
+                * [AMPDU,RTS/CTS,...] therefore be careful when they
+                * are used.
+                */
                if (wlan_tx_consume_retry(super)) {
                        /*
                         * retry for simple and aggregated 802.11 frames.
@@ -410,7 +411,11 @@ static bool wlan_tx_status(struct dma_queue *queue,
                                 * be aware of this so the frames don't get lost.
                                 */
 
+#ifndef CONFIG_CARL9170FW_DEBUG
                                dma_unlink_head(queue);
+#else /* CONFIG_CARL9170FW_DEBUG */
+                               BUG_ON(dma_unlink_head(queue) != desc);
+#endif /* CONFIG_CARL9170FW_DEBUG */
                                dma_put(&fw.wlan.tx_retry, desc);
                                return true;
                        }
@@ -420,7 +425,11 @@ static bool wlan_tx_status(struct dma_queue *queue,
                }
        }
 
+#ifndef CONFIG_CARL9170FW_DEBUG
        dma_unlink_head(queue);
+#else /* CONFIG_CARL9170FW_DEBUG */
+       BUG_ON(dma_unlink_head(queue) != desc);
+#endif /* CONFIG_CARL9170FW_DEBUG */
        if (txfail) {
                /*
                 * Issue the queue bump,
@@ -443,13 +452,15 @@ static bool wlan_tx_status(struct dma_queue *queue,
                return true;
        }
 
-#ifdef CONFIG_CARL9170FW_CAB_QUEUE
        if (unlikely(super->s.cab))
                fw.wlan.cab_queue_len[super->s.vif_id]--;
-#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
        wlan_tx_complete(super, success);
 
+       if (ieee80211_is_back_req(super->f.data.i3e.frame_control)) {
+               fw.wlan.queued_bar--;
+       }
+
        /* recycle freed descriptors */
        dma_reclaim(&fw.pta.down_queue, desc);
        down_trigger();
@@ -469,7 +480,6 @@ static void handle_tx_completion(void)
                        }
                }
 
-
                wlan_tx_ampdu_reset(i);
 
                for_each_desc(desc, &fw.wlan.tx_retry)
@@ -485,20 +495,23 @@ void __hot wlan_tx(struct dma_desc *desc)
 {
        struct carl9170_tx_superframe *super = DESC_PAYLOAD(desc);
 
+       if (ieee80211_is_back_req(super->f.data.i3e.frame_control)) {
+               fw.wlan.queued_bar++;
+       }
+
        /* initialize rate control struct */
        super->s.rix = 0;
        super->s.cnt = 1;
        hide_super(desc);
 
-#ifdef CONFIG_CARL9170FW_CAB_QUEUE
        if (unlikely(super->s.cab)) {
                fw.wlan.cab_queue_len[super->s.vif_id]++;
                dma_put(&fw.wlan.cab_queue[super->s.vif_id], desc);
                return;
        }
-#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
        _wlan_tx(desc);
+       __wlan_tx(desc);
        wlan_trigger(BIT(super->s.queue));
 }
 
@@ -527,7 +540,7 @@ static void wlan_send_buffered_ba(void)
        struct ieee80211_ba *ba = (struct ieee80211_ba *) &baf->f.ba;
        struct carl9170_bar_ctx *ctx;
 
-       if (likely(fw.wlan.ba_head_idx == fw.wlan.ba_tail_idx))
+       if (likely(!fw.wlan.queued_ba))
                return;
 
        /* there's no point to continue when the ba_desc is not available. */
@@ -537,6 +550,7 @@ static void wlan_send_buffered_ba(void)
        ctx = &fw.wlan.ba_cache[fw.wlan.ba_head_idx];
        fw.wlan.ba_head_idx++;
        fw.wlan.ba_head_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
+       fw.wlan.queued_ba--;
 
        baf->s.len = sizeof(struct carl9170_tx_superdesc) +
                     sizeof(struct ar9170_tx_hwdesc) +
@@ -546,19 +560,20 @@ static void wlan_send_buffered_ba(void)
        baf->s.queue = AR9170_TXQ_VO;
        baf->f.hdr.length = sizeof(struct ieee80211_ba) + FCS_LEN;
 
-       /* HW Duration / Backoff */
-       baf->f.hdr.mac.backoff = 1;
-       baf->f.hdr.mac.hw_duration = 1;
+       baf->f.hdr.mac.no_ack = 1;
 
-       /* take the TX rate from the RX'd BAR */
-       baf->f.hdr.phy.set = ctx->phy;
-       baf->f.hdr.phy.tx_power = 29; /* 14.5 dBm */
+       baf->f.hdr.phy.modulation = 1; /* OFDM */
+       baf->f.hdr.phy.tx_power = 34; /* 17 dBm */
+       baf->f.hdr.phy.chains = 1;
+       baf->f.hdr.phy.mcs = AR9170_TXRX_PHY_RATE_OFDM_6M;
 
        /* format outgoing BA */
-       ba->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_NULLFUNC);
+       ba->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);
        ba->duration = cpu_to_le16(0);
-       memcpy(ba->ta, ctx->ta, 6);
-       memcpy(ba->ra, ctx->ra, 6);
+
+       /* the BAR contains all necessary MACs. All we need is to swap them */
+       memcpy(ba->ra, ctx->ta, 6);
+       memcpy(ba->ta, ctx->ra, 6);
 
        /*
         * Unfortunately, we cannot look into the hardware's scoreboard.
@@ -568,8 +583,8 @@ static void wlan_send_buffered_ba(void)
        memset(ba->bitmap, 0x0, sizeof(ba->bitmap));
 
        /*
-        * NB:
-        * not entirely sure if this is 100% correct?!
+        * Both, the original firmare and ath9k set the NO ACK flag in
+        * the BA Ack Policy subfield.
         */
        ba->control = ctx->control | cpu_to_le16(1);
        ba->start_seq_num = ctx->start_seq_num;
@@ -583,11 +598,13 @@ static struct carl9170_bar_ctx *wlan_get_bar_cache_buffer(void)
        tmp = &fw.wlan.ba_cache[fw.wlan.ba_tail_idx];
        fw.wlan.ba_tail_idx++;
        fw.wlan.ba_tail_idx %= CONFIG_CARL9170FW_BACK_REQS_NUM;
+       if (fw.wlan.queued_ba < CONFIG_CARL9170FW_BACK_REQS_NUM)
+               fw.wlan.queued_ba++;
 
        return tmp;
 }
 
-static void handle_bar(struct dma_desc *desc, struct ieee80211_hdr *hdr,
+static void handle_bar(struct dma_desc *desc __unused, struct ieee80211_hdr *hdr,
                       unsigned int len, unsigned int mac_err)
 {
        struct ieee80211_bar *bar;
@@ -621,22 +638,10 @@ static void handle_bar(struct dma_desc *desc, struct ieee80211_hdr *hdr,
 
        ctx = wlan_get_bar_cache_buffer();
 
-       /* Brilliant! The BAR provides all necessary MACs! */
-       memcpy(ctx->ra, bar->ta, 6);
-       memcpy(ctx->ta, bar->ra, 6);
-
-       /*
-        * NB:
-        * not entirely sure if this is 100% correct to force the
-        * imm ack bit or not...
-        */
-       ctx->control = bar->control | cpu_to_le16(1);
+       memcpy(ctx->ra, bar->ra, 6);
+       memcpy(ctx->ta, bar->ta, 6);
+       ctx->control = bar->control;
        ctx->start_seq_num = bar->start_seq_num;
-       ctx->phy = ar9170_rx_to_phy(desc);
-       if (unlikely(!ctx->phy)) {
-               /* provide a backup, in case ar9170_rx_to_phy fails */
-               ctx->phy = cpu_to_le32(0x2cc301);
-       }
 }
 
 static void wlan_check_rx_overrun(void)
@@ -692,12 +697,22 @@ static unsigned int wlan_rx_filter(struct dma_desc *desc)
                switch (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) {
                case IEEE80211_STYPE_BACK_REQ:
                        handle_bar(desc, hdr, data_len, mac_err);
-                       /* fallthrough */
                        rx_filter |= CARL9170_RX_FILTER_CTL_BACKR;
                        break;
                case IEEE80211_STYPE_PSPOLL:
                        rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL;
                        break;
+               case IEEE80211_STYPE_BACK:
+                       if (fw.wlan.queued_bar) {
+                               /*
+                                * Don't filter block acks when the application
+                                * has queued BARs. This is because the firmware
+                                * can't do the accouting and the application
+                                * has to sort out if the BA belongs to any BARs.
+                                */
+                               break;
+                       }
+                       /* otherwise fall through */
                default:
                        rx_filter |= CARL9170_RX_FILTER_CTL_OTHER;
                        break;
@@ -707,12 +722,10 @@ static unsigned int wlan_rx_filter(struct dma_desc *desc)
                rx_filter |= CARL9170_RX_FILTER_MGMT;
        }
 
-#ifdef CONFIG_CARL9170FW_WOL
        if (unlikely(fw.suspend_mode == CARL9170_HOST_SUSPENDED)) {
                wol_rx(rx_filter, hdr, min(data_len,
                        (unsigned int)AR9170_BLOCK_SIZE));
        }
-#endif /* CONFIG_CARL9170FW_WOL */
 
 #undef AR9170_RX_ERROR_BAD
 
@@ -734,7 +747,6 @@ static void handle_rx(void)
        }
 }
 
-#ifdef CONFIG_CARL9170FW_CAB_QUEUE
 void wlan_cab_flush_queue(const unsigned int vif)
 {
        struct dma_queue *cab_queue = &fw.wlan.cab_queue[vif];
@@ -762,6 +774,7 @@ void wlan_cab_flush_queue(const unsigned int vif)
 
                /* ready to roll! */
                _wlan_tx(desc);
+               __wlan_tx(desc);
                wlan_trigger(BIT(super->s.queue));
        }
 }
@@ -854,7 +867,6 @@ static void wlan_send_buffered_cab(void)
 
        }
 }
-#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
 static void handle_beacon_config(void)
 {
@@ -867,9 +879,7 @@ static void handle_beacon_config(void)
 
 static void handle_pretbtt(void)
 {
-#ifdef CONFIG_CARL9170FW_CAB_QUEUE
        fw.wlan.cab_flush_time = get_clock_counter();
-#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
        rf_psm();
@@ -902,9 +912,7 @@ static void handle_radar(void)
 
 static void wlan_janitor(void)
 {
-#ifdef CONFIG_CARL9170FW_CAB_QUEUE
        wlan_send_buffered_cab();
-#endif /* CONFIG_CARL9170FW_CAB_QUEUE */
 
        wlan_send_buffered_tx_status();