X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=carlfw%2Fsrc%2Fwlan.c;h=b8d4ec436fca3f54ed5708c80407c4b9fc75e4cb;hb=38ec506630dd92a5e6a03e6caca08fb926be85ae;hp=94ed62250d806ed262cdc86c316d2df4370fa35c;hpb=a9df280e9edf83ab1596a81c1bf47cd2e72f3d50;p=carl9170fw.git diff --git a/carlfw/src/wlan.c b/carlfw/src/wlan.c index 94ed622..b8d4ec4 100644 --- a/carlfw/src/wlan.c +++ b/carlfw/src/wlan.c @@ -345,6 +345,16 @@ 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); @@ -447,6 +457,18 @@ static bool wlan_tx_status(struct dma_queue *queue, fw.wlan.cab_queue_len[super->s.vif_id]--; #endif /* CONFIG_CARL9170FW_CAB_QUEUE */ + if (unlikely(ieee80211_is_back_req(super->f.data.i3e.frame_control))) { + /* + * As explained above, the hardware seems to be + * incapable of matching BA to BARs. This is a + * problem especially with mac80211, because it + * does resent failed BARs which of course cause + * some mayhem in the receiver buffer at the HT + * peer on the other end. + */ + success = true; + } + wlan_tx_complete(super, success); /* recycle freed descriptors */ @@ -546,16 +568,15 @@ 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); @@ -567,11 +588,7 @@ static void wlan_send_buffered_ba(void) */ memset(ba->bitmap, 0x0, sizeof(ba->bitmap)); - /* - * NB: - * not entirely sure if this is 100% correct?! - */ - ba->control = ctx->control | cpu_to_le16(1); + ba->control = ctx->control; ba->start_seq_num = ctx->start_seq_num; wlan_tx_fw(&baf->s, NULL); } @@ -589,7 +606,7 @@ static struct carl9170_bar_ctx *wlan_get_bar_cache_buffer(void) 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; @@ -626,19 +643,8 @@ static void handle_bar(struct dma_desc *desc, struct ieee80211_hdr *hdr, /* 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); + 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)