/* 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);
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 */
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);
*/
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);
}
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;
/* 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)