X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=carlfw%2Fsrc%2Fwlan.c;h=c23831bd358ffad0f2a4d5453e4f838dbb85004f;hb=4b209fe6b104793582c9286c0367a1a9ff83e8e8;hp=a7c805b588908267541bd994f6c878a0abea16c2;hpb=d6ed9408251e62c85e9af7cac67dfdfd6afc3918;p=carl9170fw.git diff --git a/carlfw/src/wlan.c b/carlfw/src/wlan.c index a7c805b..c23831b 100644 --- a/carlfw/src/wlan.c +++ b/carlfw/src/wlan.c @@ -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; } @@ -358,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. @@ -533,7 +536,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. */ @@ -543,6 +546,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) + @@ -552,19 +556,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. @@ -574,8 +579,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; @@ -589,11 +594,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; @@ -627,22 +634,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)