[driver][wlan] Fix HT capability negotiation for Ralink

 - Correct the false claim of LDPC for Ralink chipset
 - Reflects the BlockAck Session buffer size of the Ralink chipset
 - Enable a primitive negotiation on the BlockAck buffer size
   between the originator (AP) and the responder (Client)
 - Add warning notes and TODOs

APs from different vendors exhibited different behaviors in this regards.
Aruba AP has been most stringent. This CL unblocks that case.
As a result, Fuchsia with Ralink WiFi chipset can receive the HT MCS
frames sent from Aruba AP.

NET-232 #done
NET-208 #done

Change-Id: I8427bd38a01cd69783e1e3b82210f48622900105
diff --git a/drivers/wlan/mediatek/ralink/device.cpp b/drivers/wlan/mediatek/ralink/device.cpp
index 9345598..8a43179 100644
--- a/drivers/wlan/mediatek/ralink/device.cpp
+++ b/drivers/wlan/mediatek/ralink/device.cpp
@@ -2831,9 +2831,7 @@
     uint8_t rate = 0;            // Mbps * 2
     uint8_t rate_tbl_idx = 255;  // Init with invalid idx.
 
-    if (phy_mode >= fbl::count_of(kDataRates)) {
-        return rate;
-    }
+    if (phy_mode >= fbl::count_of(kDataRates)) { return rate; }
 
     switch (phy_mode) {
     case PhyMode::kLegacyCck:
@@ -2885,9 +2883,7 @@
         constexpr uint8_t subcarriers_data_20 = 52;   // counts
         rate = rate * subcarriers_data_40 / subcarriers_data_20;
     }
-    if (is_sgi) {
-        rate = static_cast<uint8_t>((static_cast<uint16_t>(rate) * 10) / 9);
-    }
+    if (is_sgi) { rate = static_cast<uint8_t>((static_cast<uint16_t>(rate) * 10) / 9); }
 
     return rate;
 }
@@ -2940,7 +2936,7 @@
     info->chan_width = rxwi1.bw() ? WLAN_CHAN_WIDTH_40MHZ : WLAN_CHAN_WIDTH_20MHZ;
 
     uint8_t phy_mode = rxwi1.phy_mode();
-    bool is_ht = phy_mode == PhyMode::kHtMixMode || phy_mode == PhyMode::kHtMixMode;
+    bool is_ht = phy_mode == PhyMode::kHtMixMode || phy_mode == PhyMode::kHtGreenfield;
     if (is_ht && rxwi1.mcs() < kMaxHtMcs) {
         info->valid_fields |= WLAN_RX_INFO_VALID_MCS;
         info->mcs = rxwi1.mcs();
@@ -3167,7 +3163,7 @@
     if (pkt->packet_tail != nullptr) {
         uint8_t* tail_data = static_cast<uint8_t*>(pkt->packet_tail->data);
         std::memcpy(dest + pkt->packet_head->len, tail_data + pkt->tail_offset,
-                pkt->packet_tail->len - pkt->tail_offset);
+                    pkt->packet_tail->len - pkt->tail_offset);
     }
 }
 
@@ -3176,9 +3172,7 @@
 
     size_t len = pkt->packet_head->len;
     if (pkt->packet_tail != nullptr) {
-        if (pkt->packet_tail->len < pkt->tail_offset) {
-            return ZX_ERR_INVALID_ARGS;
-        }
+        if (pkt->packet_tail->len < pkt->tail_offset) { return ZX_ERR_INVALID_ARGS; }
         len += pkt->packet_tail->len - pkt->tail_offset;
     }
 
@@ -3249,8 +3243,8 @@
     }
     txwi0.set_mcs(mcs);
 
-    if (pkt->info.valid_fields & WLAN_TX_INFO_VALID_CHAN_WIDTH
-            && pkt->info.chan_width == WLAN_CHAN_WIDTH_40MHZ) {
+    if (pkt->info.valid_fields & WLAN_TX_INFO_VALID_CHAN_WIDTH &&
+        pkt->info.chan_width == WLAN_CHAN_WIDTH_40MHZ) {
         txwi0.set_bw(1);  // for 40 Mhz
     } else {
         txwi0.set_bw(0);  // for 20 Mhz
@@ -3268,13 +3262,20 @@
         txwi0.set_phy_mode(PhyMode::kLegacyOfdm);
     }
 
+    // TODO(porce): Incorporate this into pkt->info
+    // txwi0.set_phy_mode(PhyMode::kHtMixMode);
+
     // The frame header is always in the packet head.
-    auto wcid = LookupTxWcid(static_cast<const uint8_t*>(pkt->packet_head->data),
-            pkt->packet_head->len);
+    auto wcid =
+        LookupTxWcid(static_cast<const uint8_t*>(pkt->packet_head->data), pkt->packet_head->len);
     Txwi1& txwi1 = packet->txwi1;
     txwi1.set_ack(0);
     txwi1.set_nseq(0);
-    txwi1.set_ba_win_size(0);
+
+    // TODO(porce): Study if BlockAck window size can change without resetting the radio
+    // upon completing the BlockAck session negotiation at MLME layer.
+    // Separate the workflow for the BlockAck originator case from the responder case.
+    txwi1.set_ba_win_size(64);
     txwi1.set_wcid(wcid);
     txwi1.set_mpdu_total_byte_count(len);
     txwi1.set_tx_packet_id(10);
diff --git a/drivers/wlan/wlan/station.cpp b/drivers/wlan/wlan/station.cpp
index 1e448fc..23a0497 100644
--- a/drivers/wlan/wlan/station.cpp
+++ b/drivers/wlan/wlan/station.cpp
@@ -252,6 +252,7 @@
     // request.
     auto assoc = packet->mut_field<AssociationRequest>(sizeof(MgmtFrameHeader));
     assoc->cap.set_ess(1);
+    assoc->cap.set_short_preamble(1);
     assoc->listen_interval = 0;
     ElementWriter w(assoc->elements,
                     packet->len() - sizeof(MgmtFrameHeader) - sizeof(AssociationRequest));
@@ -548,17 +549,24 @@
     resp->action = action::BaAction::kAddBaResponse;
     resp->dialog_token = addbar->dialog_token;
 
-    // TODO(porce): Research this.
-    // Use kSuccess to refuse, instead of kRefused.
-    // Aruba APs are persistent in asking again after refusal.
-    // resp->status_code = status_code::kRefused;
+    // TODO(porce): Implement DelBa as a response to AddBar for decline
+
+    // Note: Returning AddBaResponse with status_code::kRefused seems ineffective.
+    // ArubaAP is persistent not honoring that.
     resp->status_code = status_code::kSuccess;
 
+    // TODO(porce): Query the radio chipset capability to build the response.
     resp->params.set_amsdu(0);
     resp->params.set_policy(BlockAckParameters::kImmediate);
     resp->params.set_tid(addbar->params.tid());
-    resp->params.set_buffer_size(addbar->params.buffer_size());
-    resp->params.set_buffer_size(0);
+
+    // TODO(porce): Once chipset capability is ready, refactor below buffer_size
+    // calculation.
+    auto buffer_size_ap = addbar->params.buffer_size();
+    constexpr size_t buffer_size_ralink = 64;
+    auto buffer_size = (buffer_size_ap <= buffer_size_ralink) ? buffer_size_ap : buffer_size_ralink;
+    resp->params.set_buffer_size(buffer_size);
+
     resp->timeout = addbar->timeout;
 
     zx_status_t status = device_->SendWlan(std::move(packet));
@@ -1235,7 +1243,7 @@
     HtCapabilities htc;
     HtCapabilityInfo& hci = htc.ht_cap_info;
 
-    hci.set_ldpc_coding_cap(1);
+    hci.set_ldpc_coding_cap(0);  // Ralink RT5370 is incapable of LDPC.
     hci.set_chan_width_set(HtCapabilityInfo::TWENTY_ONLY);
     // hci.set_chan_width_set(HtCapabilityInfo::TWENTY_FORTY);
     hci.set_sm_power_save(HtCapabilityInfo::DISABLED);