diff mbox series

ath10k: Fix channel info parsing for non tlv target

Message ID 1552044366-9186-1-git-send-email-pillair@codeaurora.org (mailing list archive)
State Accepted
Commit 6be6c04bcc2e8770b8637632789ff15765124894
Delegated to: Kalle Valo
Headers show
Series ath10k: Fix channel info parsing for non tlv target | expand

Commit Message

Rakesh Pillai March 8, 2019, 11:26 a.m. UTC
The tlv targets such as WCN3990 send more data in
the chan info event, which is not sent by the non tlv
targets. There is a minimum size check in the wmi event for
non-tlv targets and hence we cannot update the common
channel info structure.

If the common channel info structure is updated, the
size check for chan info event for non-tlv targets
will fail and return -EPROTO and we see the below
error messages

   ath10k_pci 0000:01:00.0: failed to parse chan info event: -71

Add tlv specific channel info structure and restore the
original size of the common channel info structure to
mitigate this issue.

Tested HW: WCN3990
	   QCA9887
Tested FW: WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1
	   10.2.4-1.0-00037

Fixes: 13104929d2ec ("ath10k: fill the channel survey results for WCN3990 correctly")
Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |  2 +-
 drivers/net/wireless/ath/ath10k/wmi-tlv.h | 16 ++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h     |  8 --------
 3 files changed, 17 insertions(+), 9 deletions(-)

Comments

Kalle Valo July 30, 2019, 8:40 a.m. UTC | #1
Rakesh Pillai <pillair@codeaurora.org> writes:

> The tlv targets such as WCN3990 send more data in
> the chan info event, which is not sent by the non tlv
> targets. There is a minimum size check in the wmi event for
> non-tlv targets and hence we cannot update the common
> channel info structure.
>
> If the common channel info structure is updated, the
> size check for chan info event for non-tlv targets
> will fail and return -EPROTO and we see the below
> error messages
>
>    ath10k_pci 0000:01:00.0: failed to parse chan info event: -71
>
> Add tlv specific channel info structure and restore the
> original size of the common channel info structure to
> mitigate this issue.
>
> Tested HW: WCN3990
> 	   QCA9887
> Tested FW: WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1
> 	   10.2.4-1.0-00037
>
> Fixes: 13104929d2ec ("ath10k: fill the channel survey results for WCN3990 correctly")
> Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>

I'll queue this v5.3, and also for stable v5.0 and later.
Kalle Valo Sept. 12, 2019, 1:41 p.m. UTC | #2
Rakesh Pillai <pillair@codeaurora.org> writes:

> The tlv targets such as WCN3990 send more data in
> the chan info event, which is not sent by the non tlv
> targets. There is a minimum size check in the wmi event for
> non-tlv targets and hence we cannot update the common
> channel info structure.
>
> If the common channel info structure is updated, the
> size check for chan info event for non-tlv targets
> will fail and return -EPROTO

This is the code in question:

static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb,
					 struct wmi_ch_info_ev_arg *arg)
{
	struct wmi_chan_info_event *ev = (void *)skb->data;

	if (skb->len < sizeof(*ev))
		return -EPROTO;

	skb_pull(skb, sizeof(*ev));
	arg->err_code = ev->err_code;
	arg->freq = ev->freq;
	arg->cmd_flags = ev->cmd_flags;
	arg->noise_floor = ev->noise_floor;
	arg->rx_clear_count = ev->rx_clear_count;
	arg->cycle_count = ev->cycle_count;

	return 0;
}

And here I see a disconnection between firmware and ath10k. The design
philosophy in firmware is that if the firmware does not provide all
fields, for example cycle_count in this event, the host driver is
supposed to replace the missing field with value zero and continue
normally. Obviously ath10k does not do that and instead it drops the
whole WMI event, which causes breakup like this.

The quick fix (having separate structs for TLV and 10.x interfaces) in
this patch is ok, but in the future if similar field additions arise we
need to remember to fix ath10k event parsing so that both new ath10k
will continue to work with older firmwares.
Kalle Valo Sept. 12, 2019, 3:05 p.m. UTC | #3
Rakesh Pillai <pillair@codeaurora.org> wrote:

> The tlv targets such as WCN3990 send more data in the chan info event, which is
> not sent by the non tlv targets. There is a minimum size check in the wmi event
> for non-tlv targets and hence we cannot update the common channel info
> structure as it was done in commit 13104929d2ec ("ath10k: fill the channel
> survey results for WCN3990 correctly"). This broke channel survey results on
> 10.x firmware versions.
> 
> If the common channel info structure is updated, the size check for chan info
> event for non-tlv targets will fail and return -EPROTO and we see the below
> error messages
> 
>    ath10k_pci 0000:01:00.0: failed to parse chan info event: -71
> 
> Add tlv specific channel info structure and restore the original size of the
> common channel info structure to mitigate this issue.
> 
> Tested HW: WCN3990
> 	   QCA9887
> Tested FW: WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1
> 	   10.2.4-1.0-00037
> 
> Fixes: 13104929d2ec ("ath10k: fill the channel survey results for WCN3990 correctly")
> Cc: stable@vger.kernel.org # 5.0
> Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

6be6c04bcc2e ath10k: fix channel info parsing for non tlv target
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 582fb11..a826acb 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -810,7 +810,7 @@  static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
 					     struct wmi_ch_info_ev_arg *arg)
 {
 	const void **tb;
-	const struct wmi_chan_info_event *ev;
+	const struct wmi_tlv_chan_info_event *ev;
 	int ret;
 
 	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 65e6aa5..4bdd655 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1607,6 +1607,22 @@  struct chan_info_params {
 
 #define WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL	BIT(9)
 
+struct wmi_tlv_chan_info_event {
+	__le32 err_code;
+	__le32 freq;
+	__le32 cmd_flags;
+	__le32 noise_floor;
+	__le32 rx_clear_count;
+	__le32 cycle_count;
+	__le32 chan_tx_pwr_range;
+	__le32 chan_tx_pwr_tp;
+	__le32 rx_frame_count;
+	__le32 my_bss_rx_cycle_count;
+	__le32 rx_11b_mode_data_duration;
+	__le32 tx_frame_cnt;
+	__le32 mac_clk_mhz;
+} __packed;
+
 struct wmi_tlv_mgmt_tx_compl_ev {
 	__le32 desc_id;
 	__le32 status;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index e1c40bb..d188a2c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -6523,14 +6523,6 @@  struct wmi_chan_info_event {
 	__le32 noise_floor;
 	__le32 rx_clear_count;
 	__le32 cycle_count;
-	__le32 chan_tx_pwr_range;
-	__le32 chan_tx_pwr_tp;
-	__le32 rx_frame_count;
-	__le32 my_bss_rx_cycle_count;
-	__le32 rx_11b_mode_data_duration;
-	__le32 tx_frame_cnt;
-	__le32 mac_clk_mhz;
-
 } __packed;
 
 struct wmi_10_4_chan_info_event {