mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 04:42:20 +00:00
110 lines
2.9 KiB
Diff
110 lines
2.9 KiB
Diff
From 0acc603ee1fbbeca1109e695f493179986b18c34 Mon Sep 17 00:00:00 2001
|
|
From: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
|
|
Date: Wed, 6 Jul 2022 14:42:29 +0530
|
|
Subject: [PATCH 2/2] ath11k: Fix invalid mgmt rx frame length issue
|
|
|
|
The wmi mgmt rx event has multiple arrays of tlvs,
|
|
but the common wmi tlv parser won't handle mulitple tlv tags of same type.
|
|
So the mulitple array tags of wmi mgmt rx tlv is parsed incorrectly and
|
|
the length calculated becomes wrong,
|
|
|
|
Add seperate tlv parser to handle mulitple arrays for wmi mgmt rx tlv.
|
|
This fixes invalid length issue.
|
|
|
|
Signed-off-by: Bhagavathi Perumal S <quic_bperumal@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/wmi.c | 38 ++++++++++++++++++++++++++---------
|
|
drivers/net/wireless/ath/ath11k/wmi.h | 6 ++++++
|
|
2 files changed, 34 insertions(+), 10 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -6430,28 +6430,48 @@ static int ath11k_pull_vdev_stopped_para
|
|
return 0;
|
|
}
|
|
|
|
+static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab,
|
|
+ u16 tag, u16 len,
|
|
+ const void *ptr, void *data)
|
|
+{
|
|
+ struct wmi_tlv_mgmt_rx_parse *parse = data;
|
|
+
|
|
+ switch (tag) {
|
|
+ case WMI_TAG_MGMT_RX_HDR:
|
|
+ parse->fixed = ptr;
|
|
+ break;
|
|
+ case WMI_TAG_ARRAY_BYTE:
|
|
+ if (!parse->frame_buf_done) {
|
|
+ parse->frame_buf = ptr;
|
|
+ parse->frame_buf_done = true;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab,
|
|
struct sk_buff *skb,
|
|
struct mgmt_rx_event_params *hdr)
|
|
{
|
|
- const void **tb;
|
|
+ struct wmi_tlv_mgmt_rx_parse parse = { };
|
|
const struct wmi_mgmt_rx_hdr *ev;
|
|
const u8 *frame;
|
|
int ret;
|
|
|
|
- tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
|
- if (IS_ERR(tb)) {
|
|
- ret = PTR_ERR(tb);
|
|
- ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
|
+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
|
|
+ ath11k_wmi_tlv_mgmt_rx_parse,
|
|
+ &parse);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
- ev = tb[WMI_TAG_MGMT_RX_HDR];
|
|
- frame = tb[WMI_TAG_ARRAY_BYTE];
|
|
+ ev = parse.fixed;
|
|
+ frame = parse.frame_buf;
|
|
|
|
if (!ev || !frame) {
|
|
ath11k_warn(ab, "failed to fetch mgmt rx hdr");
|
|
- kfree(tb);
|
|
return -EPROTO;
|
|
}
|
|
|
|
@@ -6470,7 +6490,6 @@ static int ath11k_pull_mgmt_rx_params_tl
|
|
|
|
if (skb->len < (frame - skb->data) + hdr->buf_len) {
|
|
ath11k_warn(ab, "invalid length in mgmt rx hdr ev");
|
|
- kfree(tb);
|
|
return -EPROTO;
|
|
}
|
|
|
|
@@ -6482,7 +6501,6 @@ static int ath11k_pull_mgmt_rx_params_tl
|
|
|
|
ath11k_ce_byte_swap(skb->data, hdr->buf_len);
|
|
|
|
- kfree(tb);
|
|
return 0;
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
|
@@ -5169,6 +5169,12 @@ struct wmi_mgmt_rx_hdr {
|
|
u32 chan_freq;
|
|
} __packed;
|
|
|
|
+struct wmi_tlv_mgmt_rx_parse {
|
|
+ struct wmi_mgmt_rx_hdr *fixed;
|
|
+ u8 *frame_buf;
|
|
+ bool frame_buf_done;
|
|
+};
|
|
+
|
|
#define MAX_ANTENNA_EIGHT 8
|
|
|
|
struct wmi_rssi_ctl_ext {
|