[driver][wlan] Hotfix for Ralink zero-padding for QoSData data frame
NET-297
Change-Id: I883118a7d34e25cce145f15f875872264238cabf
diff --git a/drivers/wlan/wlan/dispatcher.cpp b/drivers/wlan/wlan/dispatcher.cpp
index 4a466c8..748929e 100644
--- a/drivers/wlan/wlan/dispatcher.cpp
+++ b/drivers/wlan/wlan/dispatcher.cpp
@@ -189,7 +189,31 @@
return ZX_OK;
}
- auto llc = packet->field<LlcHeader>(hdr->len());
+ auto llc_offset = hdr->len();
+ { // TODO(porce): Factor out as a function.
+
+ // Ralink aligns the Mac frame header in 4 bytes,
+ // before passing it to the device driver.
+ // The rx frame's rx_descriptor has l2pad boolean flag
+ // to indicate if the frame was zero-padded.
+ // In case of data frame with subtype kQosData(8),
+ // two bytes of QoS Control field is appended
+ // after the Addr3, and BEFORE LLC header.
+ // This offset calculation should compensate that
+ // before the frame may be passed to next level.
+
+ // TODO(porce): Replace the conditional by rxinfo's upcoming field: l2pad
+ // Alignment size is 4 bytes. This is the case for Ralink implementation.
+ // Not necessarilly generally applicable to all chipsets.
+ constexpr size_t l2padding_align = 4; // bytes
+ if ((llc_offset % l2padding_align) != 0) { llc_offset += llc_offset % l2padding_align; }
+
+ // Alternative implementation:
+ // constexpr size_t l2padding_bytes = 2;
+ // if (hdr->fc.subtype() == kQosdata) { llc_offset += l2padding_bytes; }
+ }
+
+ auto llc = packet->field<LlcHeader>(llc_offset);
if (llc == nullptr) {
errorf("short data packet len=%zu\n", packet->len());
return ZX_ERR_IO;
@@ -198,7 +222,7 @@
errorf("short LLC packet len=%zu\n", packet->len());
return ZX_ERR_IO;
}
- size_t llc_len = packet->len() - hdr->len();
+ size_t llc_len = packet->len() - llc_offset;
auto frame = DataFrame<LlcHeader>(hdr, llc, llc_len);
return mlme_->HandleFrame(frame, *rxinfo);
}
diff --git a/drivers/wlan/wlan/station.cpp b/drivers/wlan/wlan/station.cpp
index 23a0497..76c7292 100644
--- a/drivers/wlan/wlan/station.cpp
+++ b/drivers/wlan/wlan/station.cpp
@@ -607,7 +607,6 @@
zx_status_t Station::HandleDataFrame(const DataFrame<LlcHeader>& frame,
const wlan_rx_info_t& rxinfo) {
debugfn();
- ZX_DEBUG_ASSERT(frame.hdr->fc.subtype() == 0);
ZX_DEBUG_ASSERT(bssid() != nullptr);
ZX_DEBUG_ASSERT(frame.hdr->addr2 == common::MacAddr(bss_->bssid.data()));
ZX_DEBUG_ASSERT(state_ == WlanState::kAssociated);