mac80211: backport and update patches for ath10k
[openwrt/staging/wigyori.git] / package / kernel / mac80211 / patches / 380-0001-ath10k-wmi-modify-svc-bitmap-parsing-for-wcn3990.patch
1 From 229329ff345f80c95202eaf2d7a0f2910c06144e Mon Sep 17 00:00:00 2001
2 From: Rakesh Pillai <pillair@qti.qualcomm.com>
3 Date: Mon, 11 Dec 2017 19:52:52 +0530
4 Subject: [PATCH] ath10k: wmi: modify svc bitmap parsing for wcn3990
5
6 Due to the limitation of wmi tlv parsing logic, if there are
7 two parameters in a wmi event with same tlv tag, we can get only
8 the last value, as it overwrites the prev value of the same tlv tag.
9
10 The service ready event in wcn3990 contains two parameters of the
11 same tag UINT32, due to which the svc bitmap is overwritten with the
12 DBS support parameter.
13
14 Refactor the service ready event parsing to allow parsing two tlv
15 of the same tag UINT32 for wcn3990.
16
17 Signed-off-by: Rakesh Pillai <pillair@qti.qualcomm.com>
18 Signed-off-by: Govind Singh <govinds@qti.qualcomm.com>
19 Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
20 ---
21 drivers/net/wireless/ath/ath10k/mac.c | 4 +-
22 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 61 ++++++++++++++++++++++++-------
23 drivers/net/wireless/ath/ath10k/wmi-tlv.h | 46 +++++++++++++++++++++++
24 drivers/net/wireless/ath/ath10k/wmi.h | 1 +
25 4 files changed, 97 insertions(+), 15 deletions(-)
26
27 --- a/drivers/net/wireless/ath/ath10k/mac.c
28 +++ b/drivers/net/wireless/ath/ath10k/mac.c
29 @@ -3574,7 +3574,9 @@ ath10k_mac_tx_h_get_txpath(struct ath10k
30 return ATH10K_MAC_TX_HTT;
31 case ATH10K_HW_TXRX_MGMT:
32 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
33 - ar->running_fw->fw_file.fw_features))
34 + ar->running_fw->fw_file.fw_features) ||
35 + test_bit(WMI_SERVICE_MGMT_TX_WMI,
36 + ar->wmi.svc_map))
37 return ATH10K_MAC_TX_WMI_MGMT;
38 else if (ar->htt.target_version_major >= 3)
39 return ATH10K_MAC_TX_HTT;
40 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
41 +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
42 @@ -917,33 +917,69 @@ ath10k_wmi_tlv_parse_mem_reqs(struct ath
43 return -ENOMEM;
44 }
45
46 +struct wmi_tlv_svc_rdy_parse {
47 + const struct hal_reg_capabilities *reg;
48 + const struct wmi_tlv_svc_rdy_ev *ev;
49 + const __le32 *svc_bmap;
50 + const struct wlan_host_mem_req *mem_reqs;
51 + bool svc_bmap_done;
52 + bool dbs_hw_mode_done;
53 +};
54 +
55 +static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
56 + const void *ptr, void *data)
57 +{
58 + struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
59 +
60 + switch (tag) {
61 + case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
62 + svc_rdy->ev = ptr;
63 + break;
64 + case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
65 + svc_rdy->reg = ptr;
66 + break;
67 + case WMI_TLV_TAG_ARRAY_STRUCT:
68 + svc_rdy->mem_reqs = ptr;
69 + break;
70 + case WMI_TLV_TAG_ARRAY_UINT32:
71 + if (!svc_rdy->svc_bmap_done) {
72 + svc_rdy->svc_bmap_done = true;
73 + svc_rdy->svc_bmap = ptr;
74 + } else if (!svc_rdy->dbs_hw_mode_done) {
75 + svc_rdy->dbs_hw_mode_done = true;
76 + }
77 + break;
78 + default:
79 + break;
80 + }
81 + return 0;
82 +}
83 +
84 static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
85 struct sk_buff *skb,
86 struct wmi_svc_rdy_ev_arg *arg)
87 {
88 - const void **tb;
89 const struct hal_reg_capabilities *reg;
90 const struct wmi_tlv_svc_rdy_ev *ev;
91 const __le32 *svc_bmap;
92 const struct wlan_host_mem_req *mem_reqs;
93 + struct wmi_tlv_svc_rdy_parse svc_rdy = { };
94 int ret;
95
96 - tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
97 - if (IS_ERR(tb)) {
98 - ret = PTR_ERR(tb);
99 + ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
100 + ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
101 + if (ret) {
102 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
103 return ret;
104 }
105
106 - ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
107 - reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
108 - svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
109 - mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
110 + ev = svc_rdy.ev;
111 + reg = svc_rdy.reg;
112 + svc_bmap = svc_rdy.svc_bmap;
113 + mem_reqs = svc_rdy.mem_reqs;
114
115 - if (!ev || !reg || !svc_bmap || !mem_reqs) {
116 - kfree(tb);
117 + if (!ev || !reg || !svc_bmap || !mem_reqs)
118 return -EPROTO;
119 - }
120
121 /* This is an internal ABI compatibility check for WMI TLV so check it
122 * here instead of the generic WMI code.
123 @@ -961,7 +997,6 @@ static int ath10k_wmi_tlv_op_pull_svc_rd
124 __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
125 __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
126 __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
127 - kfree(tb);
128 return -ENOTSUPP;
129 }
130
131 @@ -982,12 +1017,10 @@ static int ath10k_wmi_tlv_op_pull_svc_rd
132 ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
133 ath10k_wmi_tlv_parse_mem_reqs, arg);
134 if (ret) {
135 - kfree(tb);
136 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
137 return ret;
138 }
139
140 - kfree(tb);
141 return 0;
142 }
143
144 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
145 +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
146 @@ -965,6 +965,50 @@ enum wmi_tlv_service {
147 WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
148 WMI_TLV_SERVICE_MDNS_OFFLOAD,
149 WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
150 + WMI_TLV_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT,
151 + WMI_TLV_SERVICE_OCB,
152 + WMI_TLV_SERVICE_AP_ARPNS_OFFLOAD,
153 + WMI_TLV_SERVICE_PER_BAND_CHAINMASK_SUPPORT,
154 + WMI_TLV_SERVICE_PACKET_FILTER_OFFLOAD,
155 + WMI_TLV_SERVICE_MGMT_TX_HTT,
156 + WMI_TLV_SERVICE_MGMT_TX_WMI,
157 + WMI_TLV_SERVICE_EXT_MSG,
158 + WMI_TLV_SERVICE_MAWC,
159 + WMI_TLV_SERVICE_PEER_ASSOC_CONF,
160 + WMI_TLV_SERVICE_EGAP,
161 + WMI_TLV_SERVICE_STA_PMF_OFFLOAD,
162 + WMI_TLV_SERVICE_UNIFIED_WOW_CAPABILITY,
163 + WMI_TLV_SERVICE_ENHANCED_PROXY_STA,
164 + WMI_TLV_SERVICE_ATF,
165 + WMI_TLV_SERVICE_COEX_GPIO,
166 + WMI_TLV_SERVICE_AUX_SPECTRAL_INTF,
167 + WMI_TLV_SERVICE_AUX_CHAN_LOAD_INTF,
168 + WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64,
169 + WMI_TLV_SERVICE_ENTERPRISE_MESH,
170 + WMI_TLV_SERVICE_RESTRT_CHNL_SUPPORT,
171 + WMI_TLV_SERVICE_BPF_OFFLOAD,
172 + WMI_TLV_SERVICE_SYNC_DELETE_CMDS,
173 + WMI_TLV_SERVICE_SMART_ANTENNA_SW_SUPPORT,
174 + WMI_TLV_SERVICE_SMART_ANTENNA_HW_SUPPORT,
175 + WMI_TLV_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES,
176 + WMI_TLV_SERVICE_NAN_DATA,
177 + WMI_TLV_SERVICE_NAN_RTT,
178 + WMI_TLV_SERVICE_11AX,
179 + WMI_TLV_SERVICE_DEPRECATED_REPLACE,
180 + WMI_TLV_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
181 + WMI_TLV_SERVICE_ENHANCED_MCAST_FILTER,
182 + WMI_TLV_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
183 + WMI_TLV_SERVICE_MESH_11S,
184 + WMI_TLV_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT,
185 + WMI_TLV_SERVICE_VDEV_RX_FILTER,
186 + WMI_TLV_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT,
187 + WMI_TLV_SERVICE_MARK_FIRST_WAKEUP_PACKET,
188 + WMI_TLV_SERVICE_MULTIPLE_MCAST_FILTER_SET,
189 + WMI_TLV_SERVICE_HOST_MANAGED_RX_REORDER,
190 + WMI_TLV_SERVICE_FLASH_RDWR_SUPPORT,
191 + WMI_TLV_SERVICE_WLAN_STATS_REPORT,
192 + WMI_TLV_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT,
193 + WMI_TLV_SERVICE_DFS_PHYERR_OFFLOAD,
194 };
195
196 #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
197 @@ -1121,6 +1165,8 @@ wmi_tlv_svc_map(const __le32 *in, unsign
198 WMI_SERVICE_MDNS_OFFLOAD, len);
199 SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
200 WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
201 + SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI,
202 + WMI_SERVICE_MGMT_TX_WMI, len);
203 }
204
205 #undef SVCMAP
206 --- a/drivers/net/wireless/ath/ath10k/wmi.h
207 +++ b/drivers/net/wireless/ath/ath10k/wmi.h
208 @@ -195,6 +195,7 @@ enum wmi_service {
209 WMI_SERVICE_SMART_LOGGING_SUPPORT,
210 WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
211 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
212 + WMI_SERVICE_MGMT_TX_WMI,
213
214 /* keep last */
215 WMI_SERVICE_MAX,