GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / net / wireless / ath / ath10k / wmi-tlv.c
1 /*
2  * Copyright (c) 2005-2011 Atheros Communications Inc.
3  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include "core.h"
19 #include "debug.h"
20 #include "mac.h"
21 #include "hw.h"
22 #include "mac.h"
23 #include "wmi.h"
24 #include "wmi-ops.h"
25 #include "wmi-tlv.h"
26 #include "p2p.h"
27 #include "testmode.h"
28
29 /***************/
30 /* TLV helpers */
31 /**************/
32
33 struct wmi_tlv_policy {
34         size_t min_len;
35 };
36
37 static const struct wmi_tlv_policy wmi_tlv_policies[] = {
38         [WMI_TLV_TAG_ARRAY_BYTE]
39                 = { .min_len = 0 },
40         [WMI_TLV_TAG_ARRAY_UINT32]
41                 = { .min_len = 0 },
42         [WMI_TLV_TAG_STRUCT_SCAN_EVENT]
43                 = { .min_len = sizeof(struct wmi_scan_event) },
44         [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]
45                 = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) },
46         [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]
47                 = { .min_len = sizeof(struct wmi_chan_info_event) },
48         [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]
49                 = { .min_len = sizeof(struct wmi_vdev_start_response_event) },
50         [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]
51                 = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
52         [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT]
53                 = { .min_len = sizeof(struct wmi_host_swba_event) },
54         [WMI_TLV_TAG_STRUCT_TIM_INFO]
55                 = { .min_len = sizeof(struct wmi_tim_info) },
56         [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]
57                 = { .min_len = sizeof(struct wmi_p2p_noa_info) },
58         [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]
59                 = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) },
60         [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]
61                 = { .min_len = sizeof(struct hal_reg_capabilities) },
62         [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ]
63                 = { .min_len = sizeof(struct wlan_host_mem_req) },
64         [WMI_TLV_TAG_STRUCT_READY_EVENT]
65                 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
66         [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
67                 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
68         [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
69                 = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
70         [WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT]
71                 = { .min_len = sizeof(struct wmi_tlv_p2p_noa_ev) },
72         [WMI_TLV_TAG_STRUCT_ROAM_EVENT]
73                 = { .min_len = sizeof(struct wmi_tlv_roam_ev) },
74         [WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO]
75                 = { .min_len = sizeof(struct wmi_tlv_wow_event_info) },
76         [WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT]
77                 = { .min_len = sizeof(struct wmi_tlv_tx_pause_ev) },
78 };
79
80 static int
81 ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
82                     int (*iter)(struct ath10k *ar, u16 tag, u16 len,
83                                 const void *ptr, void *data),
84                     void *data)
85 {
86         const void *begin = ptr;
87         const struct wmi_tlv *tlv;
88         u16 tlv_tag, tlv_len;
89         int ret;
90
91         while (len > 0) {
92                 if (len < sizeof(*tlv)) {
93                         ath10k_dbg(ar, ATH10K_DBG_WMI,
94                                    "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
95                                    ptr - begin, len, sizeof(*tlv));
96                         return -EINVAL;
97                 }
98
99                 tlv = ptr;
100                 tlv_tag = __le16_to_cpu(tlv->tag);
101                 tlv_len = __le16_to_cpu(tlv->len);
102                 ptr += sizeof(*tlv);
103                 len -= sizeof(*tlv);
104
105                 if (tlv_len > len) {
106                         ath10k_dbg(ar, ATH10K_DBG_WMI,
107                                    "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n",
108                                    tlv_tag, ptr - begin, len, tlv_len);
109                         return -EINVAL;
110                 }
111
112                 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
113                     wmi_tlv_policies[tlv_tag].min_len &&
114                     wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
115                         ath10k_dbg(ar, ATH10K_DBG_WMI,
116                                    "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n",
117                                    tlv_tag, ptr - begin, tlv_len,
118                                    wmi_tlv_policies[tlv_tag].min_len);
119                         return -EINVAL;
120                 }
121
122                 ret = iter(ar, tlv_tag, tlv_len, ptr, data);
123                 if (ret)
124                         return ret;
125
126                 ptr += tlv_len;
127                 len -= tlv_len;
128         }
129
130         return 0;
131 }
132
133 static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
134                                      const void *ptr, void *data)
135 {
136         const void **tb = data;
137
138         if (tag < WMI_TLV_TAG_MAX)
139                 tb[tag] = ptr;
140
141         return 0;
142 }
143
144 static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
145                                 const void *ptr, size_t len)
146 {
147         return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
148                                    (void *)tb);
149 }
150
151 static const void **
152 ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
153                            size_t len, gfp_t gfp)
154 {
155         const void **tb;
156         int ret;
157
158         tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp);
159         if (!tb)
160                 return ERR_PTR(-ENOMEM);
161
162         ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
163         if (ret) {
164                 kfree(tb);
165                 return ERR_PTR(ret);
166         }
167
168         return tb;
169 }
170
171 static u16 ath10k_wmi_tlv_len(const void *ptr)
172 {
173         return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
174 }
175
176 /**************/
177 /* TLV events */
178 /**************/
179 static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
180                                               struct sk_buff *skb)
181 {
182         const void **tb;
183         const struct wmi_tlv_bcn_tx_status_ev *ev;
184         struct ath10k_vif *arvif;
185         u32 vdev_id, tx_status;
186         int ret;
187
188         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
189         if (IS_ERR(tb)) {
190                 ret = PTR_ERR(tb);
191                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
192                 return ret;
193         }
194
195         ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT];
196         if (!ev) {
197                 kfree(tb);
198                 return -EPROTO;
199         }
200
201         tx_status = __le32_to_cpu(ev->tx_status);
202         vdev_id = __le32_to_cpu(ev->vdev_id);
203
204         switch (tx_status) {
205         case WMI_TLV_BCN_TX_STATUS_OK:
206                 break;
207         case WMI_TLV_BCN_TX_STATUS_XRETRY:
208         case WMI_TLV_BCN_TX_STATUS_DROP:
209         case WMI_TLV_BCN_TX_STATUS_FILTERED:
210                 /* FIXME: It's probably worth telling mac80211 to stop the
211                  * interface as it is crippled.
212                  */
213                 ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
214                             vdev_id, tx_status);
215                 break;
216         }
217
218         arvif = ath10k_get_arvif(ar, vdev_id);
219         if (arvif && arvif->is_up && arvif->vif->csa_active)
220                 ieee80211_queue_work(ar->hw, &arvif->ap_csa_work);
221
222         kfree(tb);
223         return 0;
224 }
225
226 static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
227                                           struct sk_buff *skb)
228 {
229         const void **tb;
230         const struct wmi_tlv_diag_data_ev *ev;
231         const struct wmi_tlv_diag_item *item;
232         const void *data;
233         int ret, num_items, len;
234
235         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
236         if (IS_ERR(tb)) {
237                 ret = PTR_ERR(tb);
238                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
239                 return ret;
240         }
241
242         ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
243         data = tb[WMI_TLV_TAG_ARRAY_BYTE];
244         if (!ev || !data) {
245                 kfree(tb);
246                 return -EPROTO;
247         }
248
249         num_items = __le32_to_cpu(ev->num_items);
250         len = ath10k_wmi_tlv_len(data);
251
252         while (num_items--) {
253                 if (len == 0)
254                         break;
255                 if (len < sizeof(*item)) {
256                         ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
257                         break;
258                 }
259
260                 item = data;
261
262                 if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
263                         ath10k_warn(ar, "failed to parse diag data: item is too long\n");
264                         break;
265                 }
266
267                 trace_ath10k_wmi_diag_container(ar,
268                                                 item->type,
269                                                 __le32_to_cpu(item->timestamp),
270                                                 __le32_to_cpu(item->code),
271                                                 __le16_to_cpu(item->len),
272                                                 item->payload);
273
274                 len -= sizeof(*item);
275                 len -= roundup(__le16_to_cpu(item->len), 4);
276
277                 data += sizeof(*item);
278                 data += roundup(__le16_to_cpu(item->len), 4);
279         }
280
281         if (num_items != -1 || len != 0)
282                 ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
283                             num_items, len);
284
285         kfree(tb);
286         return 0;
287 }
288
289 static int ath10k_wmi_tlv_event_diag(struct ath10k *ar,
290                                      struct sk_buff *skb)
291 {
292         const void **tb;
293         const void *data;
294         int ret, len;
295
296         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
297         if (IS_ERR(tb)) {
298                 ret = PTR_ERR(tb);
299                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
300                 return ret;
301         }
302
303         data = tb[WMI_TLV_TAG_ARRAY_BYTE];
304         if (!data) {
305                 kfree(tb);
306                 return -EPROTO;
307         }
308         len = ath10k_wmi_tlv_len(data);
309
310         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len);
311         trace_ath10k_wmi_diag(ar, data, len);
312
313         kfree(tb);
314         return 0;
315 }
316
317 static int ath10k_wmi_tlv_event_p2p_noa(struct ath10k *ar,
318                                         struct sk_buff *skb)
319 {
320         const void **tb;
321         const struct wmi_tlv_p2p_noa_ev *ev;
322         const struct wmi_p2p_noa_info *noa;
323         int ret, vdev_id;
324
325         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
326         if (IS_ERR(tb)) {
327                 ret = PTR_ERR(tb);
328                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
329                 return ret;
330         }
331
332         ev = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT];
333         noa = tb[WMI_TLV_TAG_STRUCT_P2P_NOA_INFO];
334
335         if (!ev || !noa) {
336                 kfree(tb);
337                 return -EPROTO;
338         }
339
340         vdev_id = __le32_to_cpu(ev->vdev_id);
341
342         ath10k_dbg(ar, ATH10K_DBG_WMI,
343                    "wmi tlv p2p noa vdev_id %i descriptors %hhu\n",
344                    vdev_id, noa->num_descriptors);
345
346         ath10k_p2p_noa_update_by_vdev_id(ar, vdev_id, noa);
347         kfree(tb);
348         return 0;
349 }
350
351 static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar,
352                                          struct sk_buff *skb)
353 {
354         const void **tb;
355         const struct wmi_tlv_tx_pause_ev *ev;
356         int ret, vdev_id;
357         u32 pause_id, action, vdev_map, peer_id, tid_map;
358
359         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
360         if (IS_ERR(tb)) {
361                 ret = PTR_ERR(tb);
362                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
363                 return ret;
364         }
365
366         ev = tb[WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT];
367         if (!ev) {
368                 kfree(tb);
369                 return -EPROTO;
370         }
371
372         pause_id = __le32_to_cpu(ev->pause_id);
373         action = __le32_to_cpu(ev->action);
374         vdev_map = __le32_to_cpu(ev->vdev_map);
375         peer_id = __le32_to_cpu(ev->peer_id);
376         tid_map = __le32_to_cpu(ev->tid_map);
377
378         ath10k_dbg(ar, ATH10K_DBG_WMI,
379                    "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n",
380                    pause_id, action, vdev_map, peer_id, tid_map);
381
382         switch (pause_id) {
383         case WMI_TLV_TX_PAUSE_ID_MCC:
384         case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
385         case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
386         case WMI_TLV_TX_PAUSE_ID_AP_PS:
387         case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
388                 for (vdev_id = 0; vdev_map; vdev_id++) {
389                         if (!(vdev_map & BIT(vdev_id)))
390                                 continue;
391
392                         vdev_map &= ~BIT(vdev_id);
393                         ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id,
394                                                         action);
395                 }
396                 break;
397         case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
398         case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
399         case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
400         case WMI_TLV_TX_PAUSE_ID_HOST:
401                 ath10k_dbg(ar, ATH10K_DBG_MAC,
402                            "mac ignoring unsupported tx pause id %d\n",
403                            pause_id);
404                 break;
405         default:
406                 ath10k_dbg(ar, ATH10K_DBG_MAC,
407                            "mac ignoring unknown tx pause vdev %d\n",
408                            pause_id);
409                 break;
410         }
411
412         kfree(tb);
413         return 0;
414 }
415
416 static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar,
417                                             struct sk_buff *skb)
418 {
419         const struct wmi_tlv_pdev_temperature_event *ev;
420
421         ev = (struct wmi_tlv_pdev_temperature_event *)skb->data;
422         if (WARN_ON(skb->len < sizeof(*ev)))
423                 return -EPROTO;
424
425         ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
426         return 0;
427 }
428
429 static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb)
430 {
431         struct ieee80211_sta *station;
432         const struct wmi_tlv_tdls_peer_event *ev;
433         const void **tb;
434         struct ath10k_vif *arvif;
435
436         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
437         if (IS_ERR(tb)) {
438                 ath10k_warn(ar, "tdls peer failed to parse tlv");
439                 return;
440         }
441         ev = tb[WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT];
442         if (!ev) {
443                 kfree(tb);
444                 ath10k_warn(ar, "tdls peer NULL event");
445                 return;
446         }
447
448         switch (__le32_to_cpu(ev->peer_reason)) {
449         case WMI_TDLS_TEARDOWN_REASON_TX:
450         case WMI_TDLS_TEARDOWN_REASON_RSSI:
451         case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
452                 rcu_read_lock();
453                 station = ieee80211_find_sta_by_ifaddr(ar->hw,
454                                                        ev->peer_macaddr.addr,
455                                                        NULL);
456                 if (!station) {
457                         ath10k_warn(ar, "did not find station from tdls peer event");
458                         goto exit;
459                 }
460                 arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id));
461                 ieee80211_tdls_oper_request(
462                                         arvif->vif, station->addr,
463                                         NL80211_TDLS_TEARDOWN,
464                                         WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE,
465                                         GFP_ATOMIC
466                                         );
467                 break;
468         default:
469                 kfree(tb);
470                 return;
471         }
472
473 exit:
474         rcu_read_unlock();
475         kfree(tb);
476 }
477
478 /***********/
479 /* TLV ops */
480 /***********/
481
482 static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
483 {
484         struct wmi_cmd_hdr *cmd_hdr;
485         enum wmi_tlv_event_id id;
486         bool consumed;
487
488         cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
489         id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
490
491         if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
492                 goto out;
493
494         trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
495
496         consumed = ath10k_tm_event_wmi(ar, id, skb);
497
498         /* Ready event must be handled normally also in UTF mode so that we
499          * know the UTF firmware has booted, others we are just bypass WMI
500          * events to testmode.
501          */
502         if (consumed && id != WMI_TLV_READY_EVENTID) {
503                 ath10k_dbg(ar, ATH10K_DBG_WMI,
504                            "wmi tlv testmode consumed 0x%x\n", id);
505                 goto out;
506         }
507
508         switch (id) {
509         case WMI_TLV_MGMT_RX_EVENTID:
510                 ath10k_wmi_event_mgmt_rx(ar, skb);
511                 /* mgmt_rx() owns the skb now! */
512                 return;
513         case WMI_TLV_SCAN_EVENTID:
514                 ath10k_wmi_event_scan(ar, skb);
515                 break;
516         case WMI_TLV_CHAN_INFO_EVENTID:
517                 ath10k_wmi_event_chan_info(ar, skb);
518                 break;
519         case WMI_TLV_ECHO_EVENTID:
520                 ath10k_wmi_event_echo(ar, skb);
521                 break;
522         case WMI_TLV_DEBUG_MESG_EVENTID:
523                 ath10k_wmi_event_debug_mesg(ar, skb);
524                 break;
525         case WMI_TLV_UPDATE_STATS_EVENTID:
526                 ath10k_wmi_event_update_stats(ar, skb);
527                 break;
528         case WMI_TLV_VDEV_START_RESP_EVENTID:
529                 ath10k_wmi_event_vdev_start_resp(ar, skb);
530                 break;
531         case WMI_TLV_VDEV_STOPPED_EVENTID:
532                 ath10k_wmi_event_vdev_stopped(ar, skb);
533                 break;
534         case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
535                 ath10k_wmi_event_peer_sta_kickout(ar, skb);
536                 break;
537         case WMI_TLV_HOST_SWBA_EVENTID:
538                 ath10k_wmi_event_host_swba(ar, skb);
539                 break;
540         case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
541                 ath10k_wmi_event_tbttoffset_update(ar, skb);
542                 break;
543         case WMI_TLV_PHYERR_EVENTID:
544                 ath10k_wmi_event_phyerr(ar, skb);
545                 break;
546         case WMI_TLV_ROAM_EVENTID:
547                 ath10k_wmi_event_roam(ar, skb);
548                 break;
549         case WMI_TLV_PROFILE_MATCH:
550                 ath10k_wmi_event_profile_match(ar, skb);
551                 break;
552         case WMI_TLV_DEBUG_PRINT_EVENTID:
553                 ath10k_wmi_event_debug_print(ar, skb);
554                 break;
555         case WMI_TLV_PDEV_QVIT_EVENTID:
556                 ath10k_wmi_event_pdev_qvit(ar, skb);
557                 break;
558         case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
559                 ath10k_wmi_event_wlan_profile_data(ar, skb);
560                 break;
561         case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
562                 ath10k_wmi_event_rtt_measurement_report(ar, skb);
563                 break;
564         case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
565                 ath10k_wmi_event_tsf_measurement_report(ar, skb);
566                 break;
567         case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
568                 ath10k_wmi_event_rtt_error_report(ar, skb);
569                 break;
570         case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
571                 ath10k_wmi_event_wow_wakeup_host(ar, skb);
572                 break;
573         case WMI_TLV_DCS_INTERFERENCE_EVENTID:
574                 ath10k_wmi_event_dcs_interference(ar, skb);
575                 break;
576         case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
577                 ath10k_wmi_event_pdev_tpc_config(ar, skb);
578                 break;
579         case WMI_TLV_PDEV_FTM_INTG_EVENTID:
580                 ath10k_wmi_event_pdev_ftm_intg(ar, skb);
581                 break;
582         case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
583                 ath10k_wmi_event_gtk_offload_status(ar, skb);
584                 break;
585         case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
586                 ath10k_wmi_event_gtk_rekey_fail(ar, skb);
587                 break;
588         case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
589                 ath10k_wmi_event_delba_complete(ar, skb);
590                 break;
591         case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
592                 ath10k_wmi_event_addba_complete(ar, skb);
593                 break;
594         case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
595                 ath10k_wmi_event_vdev_install_key_complete(ar, skb);
596                 break;
597         case WMI_TLV_SERVICE_READY_EVENTID:
598                 ath10k_wmi_event_service_ready(ar, skb);
599                 return;
600         case WMI_TLV_READY_EVENTID:
601                 ath10k_wmi_event_ready(ar, skb);
602                 break;
603         case WMI_TLV_SERVICE_AVAILABLE_EVENTID:
604                 ath10k_wmi_event_service_available(ar, skb);
605                 break;
606         case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
607                 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
608                 break;
609         case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
610                 ath10k_wmi_tlv_event_diag_data(ar, skb);
611                 break;
612         case WMI_TLV_DIAG_EVENTID:
613                 ath10k_wmi_tlv_event_diag(ar, skb);
614                 break;
615         case WMI_TLV_P2P_NOA_EVENTID:
616                 ath10k_wmi_tlv_event_p2p_noa(ar, skb);
617                 break;
618         case WMI_TLV_TX_PAUSE_EVENTID:
619                 ath10k_wmi_tlv_event_tx_pause(ar, skb);
620                 break;
621         case WMI_TLV_PDEV_TEMPERATURE_EVENTID:
622                 ath10k_wmi_tlv_event_temperature(ar, skb);
623                 break;
624         case WMI_TLV_TDLS_PEER_EVENTID:
625                 ath10k_wmi_event_tdls_peer(ar, skb);
626                 break;
627         case WMI_TLV_MGMT_TX_COMPLETION_EVENTID:
628                 ath10k_wmi_event_mgmt_tx_compl(ar, skb);
629                 break;
630         default:
631                 ath10k_warn(ar, "Unknown eventid: %d\n", id);
632                 break;
633         }
634
635 out:
636         dev_kfree_skb(skb);
637 }
638
639 static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
640                                           struct sk_buff *skb,
641                                           struct wmi_scan_ev_arg *arg)
642 {
643         const void **tb;
644         const struct wmi_scan_event *ev;
645         int ret;
646
647         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
648         if (IS_ERR(tb)) {
649                 ret = PTR_ERR(tb);
650                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
651                 return ret;
652         }
653
654         ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
655         if (!ev) {
656                 kfree(tb);
657                 return -EPROTO;
658         }
659
660         arg->event_type = ev->event_type;
661         arg->reason = ev->reason;
662         arg->channel_freq = ev->channel_freq;
663         arg->scan_req_id = ev->scan_req_id;
664         arg->scan_id = ev->scan_id;
665         arg->vdev_id = ev->vdev_id;
666
667         kfree(tb);
668         return 0;
669 }
670
671 static int
672 ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
673                                         struct wmi_tlv_mgmt_tx_compl_ev_arg *arg)
674 {
675         const void **tb;
676         const struct wmi_tlv_mgmt_tx_compl_ev *ev;
677         int ret;
678
679         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
680         if (IS_ERR(tb)) {
681                 ret = PTR_ERR(tb);
682                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
683                 return ret;
684         }
685
686         ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
687
688         arg->desc_id = ev->desc_id;
689         arg->status = ev->status;
690         arg->pdev_id = ev->pdev_id;
691
692         kfree(tb);
693         return 0;
694 }
695
696 static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
697                                              struct sk_buff *skb,
698                                              struct wmi_mgmt_rx_ev_arg *arg)
699 {
700         const void **tb;
701         const struct wmi_tlv_mgmt_rx_ev *ev;
702         const u8 *frame;
703         u32 msdu_len;
704         int ret;
705
706         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
707         if (IS_ERR(tb)) {
708                 ret = PTR_ERR(tb);
709                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
710                 return ret;
711         }
712
713         ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
714         frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
715
716         if (!ev || !frame) {
717                 kfree(tb);
718                 return -EPROTO;
719         }
720
721         arg->channel = ev->channel;
722         arg->buf_len = ev->buf_len;
723         arg->status = ev->status;
724         arg->snr = ev->snr;
725         arg->phy_mode = ev->phy_mode;
726         arg->rate = ev->rate;
727
728         msdu_len = __le32_to_cpu(arg->buf_len);
729
730         if (skb->len < (frame - skb->data) + msdu_len) {
731                 kfree(tb);
732                 return -EPROTO;
733         }
734
735         /* shift the sk_buff to point to `frame` */
736         skb_trim(skb, 0);
737         skb_put(skb, frame - skb->data);
738         skb_pull(skb, frame - skb->data);
739         skb_put(skb, msdu_len);
740
741         kfree(tb);
742         return 0;
743 }
744
745 static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
746                                              struct sk_buff *skb,
747                                              struct wmi_ch_info_ev_arg *arg)
748 {
749         const void **tb;
750         const struct wmi_chan_info_event *ev;
751         int ret;
752
753         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
754         if (IS_ERR(tb)) {
755                 ret = PTR_ERR(tb);
756                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
757                 return ret;
758         }
759
760         ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
761         if (!ev) {
762                 kfree(tb);
763                 return -EPROTO;
764         }
765
766         arg->err_code = ev->err_code;
767         arg->freq = ev->freq;
768         arg->cmd_flags = ev->cmd_flags;
769         arg->noise_floor = ev->noise_floor;
770         arg->rx_clear_count = ev->rx_clear_count;
771         arg->cycle_count = ev->cycle_count;
772
773         kfree(tb);
774         return 0;
775 }
776
777 static int
778 ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
779                                      struct wmi_vdev_start_ev_arg *arg)
780 {
781         const void **tb;
782         const struct wmi_vdev_start_response_event *ev;
783         int ret;
784
785         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
786         if (IS_ERR(tb)) {
787                 ret = PTR_ERR(tb);
788                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
789                 return ret;
790         }
791
792         ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
793         if (!ev) {
794                 kfree(tb);
795                 return -EPROTO;
796         }
797
798         skb_pull(skb, sizeof(*ev));
799         arg->vdev_id = ev->vdev_id;
800         arg->req_id = ev->req_id;
801         arg->resp_type = ev->resp_type;
802         arg->status = ev->status;
803
804         kfree(tb);
805         return 0;
806 }
807
808 static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
809                                                struct sk_buff *skb,
810                                                struct wmi_peer_kick_ev_arg *arg)
811 {
812         const void **tb;
813         const struct wmi_peer_sta_kickout_event *ev;
814         int ret;
815
816         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
817         if (IS_ERR(tb)) {
818                 ret = PTR_ERR(tb);
819                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
820                 return ret;
821         }
822
823         ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
824         if (!ev) {
825                 kfree(tb);
826                 return -EPROTO;
827         }
828
829         arg->mac_addr = ev->peer_macaddr.addr;
830
831         kfree(tb);
832         return 0;
833 }
834
835 struct wmi_tlv_swba_parse {
836         const struct wmi_host_swba_event *ev;
837         bool tim_done;
838         bool noa_done;
839         size_t n_tim;
840         size_t n_noa;
841         struct wmi_swba_ev_arg *arg;
842 };
843
844 static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
845                                          const void *ptr, void *data)
846 {
847         struct wmi_tlv_swba_parse *swba = data;
848         struct wmi_tim_info_arg *tim_info_arg;
849         const struct wmi_tim_info *tim_info_ev = ptr;
850
851         if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
852                 return -EPROTO;
853
854         if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
855                 return -ENOBUFS;
856
857         if (__le32_to_cpu(tim_info_ev->tim_len) >
858              sizeof(tim_info_ev->tim_bitmap)) {
859                 ath10k_warn(ar, "refusing to parse invalid swba structure\n");
860                 return -EPROTO;
861         }
862
863         tim_info_arg = &swba->arg->tim_info[swba->n_tim];
864         tim_info_arg->tim_len = tim_info_ev->tim_len;
865         tim_info_arg->tim_mcast = tim_info_ev->tim_mcast;
866         tim_info_arg->tim_bitmap = tim_info_ev->tim_bitmap;
867         tim_info_arg->tim_changed = tim_info_ev->tim_changed;
868         tim_info_arg->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
869
870         swba->n_tim++;
871
872         return 0;
873 }
874
875 static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
876                                          const void *ptr, void *data)
877 {
878         struct wmi_tlv_swba_parse *swba = data;
879
880         if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
881                 return -EPROTO;
882
883         if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
884                 return -ENOBUFS;
885
886         swba->arg->noa_info[swba->n_noa++] = ptr;
887         return 0;
888 }
889
890 static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
891                                      const void *ptr, void *data)
892 {
893         struct wmi_tlv_swba_parse *swba = data;
894         int ret;
895
896         switch (tag) {
897         case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
898                 swba->ev = ptr;
899                 break;
900         case WMI_TLV_TAG_ARRAY_STRUCT:
901                 if (!swba->tim_done) {
902                         swba->tim_done = true;
903                         ret = ath10k_wmi_tlv_iter(ar, ptr, len,
904                                                   ath10k_wmi_tlv_swba_tim_parse,
905                                                   swba);
906                         if (ret)
907                                 return ret;
908                 } else if (!swba->noa_done) {
909                         swba->noa_done = true;
910                         ret = ath10k_wmi_tlv_iter(ar, ptr, len,
911                                                   ath10k_wmi_tlv_swba_noa_parse,
912                                                   swba);
913                         if (ret)
914                                 return ret;
915                 }
916                 break;
917         default:
918                 break;
919         }
920         return 0;
921 }
922
923 static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
924                                           struct sk_buff *skb,
925                                           struct wmi_swba_ev_arg *arg)
926 {
927         struct wmi_tlv_swba_parse swba = { .arg = arg };
928         u32 map;
929         size_t n_vdevs;
930         int ret;
931
932         ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
933                                   ath10k_wmi_tlv_swba_parse, &swba);
934         if (ret) {
935                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
936                 return ret;
937         }
938
939         if (!swba.ev)
940                 return -EPROTO;
941
942         arg->vdev_map = swba.ev->vdev_map;
943
944         for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
945                 if (map & BIT(0))
946                         n_vdevs++;
947
948         if (n_vdevs != swba.n_tim ||
949             n_vdevs != swba.n_noa)
950                 return -EPROTO;
951
952         return 0;
953 }
954
955 static int ath10k_wmi_tlv_op_pull_phyerr_ev_hdr(struct ath10k *ar,
956                                                 struct sk_buff *skb,
957                                                 struct wmi_phyerr_hdr_arg *arg)
958 {
959         const void **tb;
960         const struct wmi_tlv_phyerr_ev *ev;
961         const void *phyerrs;
962         int ret;
963
964         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
965         if (IS_ERR(tb)) {
966                 ret = PTR_ERR(tb);
967                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
968                 return ret;
969         }
970
971         ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
972         phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
973
974         if (!ev || !phyerrs) {
975                 kfree(tb);
976                 return -EPROTO;
977         }
978
979         arg->num_phyerrs  = __le32_to_cpu(ev->num_phyerrs);
980         arg->tsf_l32 = __le32_to_cpu(ev->tsf_l32);
981         arg->tsf_u32 = __le32_to_cpu(ev->tsf_u32);
982         arg->buf_len = __le32_to_cpu(ev->buf_len);
983         arg->phyerrs = phyerrs;
984
985         kfree(tb);
986         return 0;
987 }
988
989 #define WMI_TLV_ABI_VER_NS0 0x5F414351
990 #define WMI_TLV_ABI_VER_NS1 0x00004C4D
991 #define WMI_TLV_ABI_VER_NS2 0x00000000
992 #define WMI_TLV_ABI_VER_NS3 0x00000000
993
994 #define WMI_TLV_ABI_VER0_MAJOR 1
995 #define WMI_TLV_ABI_VER0_MINOR 0
996 #define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
997                           (((WMI_TLV_ABI_VER0_MINOR) <<  0) & 0x00FFFFFF))
998 #define WMI_TLV_ABI_VER1 53
999
1000 static int
1001 ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
1002                               const void *ptr, void *data)
1003 {
1004         struct wmi_svc_rdy_ev_arg *arg = data;
1005         int i;
1006
1007         if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
1008                 return -EPROTO;
1009
1010         for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
1011                 if (!arg->mem_reqs[i]) {
1012                         arg->mem_reqs[i] = ptr;
1013                         return 0;
1014                 }
1015         }
1016
1017         return -ENOMEM;
1018 }
1019
1020 struct wmi_tlv_svc_rdy_parse {
1021         const struct hal_reg_capabilities *reg;
1022         const struct wmi_tlv_svc_rdy_ev *ev;
1023         const __le32 *svc_bmap;
1024         const struct wlan_host_mem_req *mem_reqs;
1025         bool svc_bmap_done;
1026         bool dbs_hw_mode_done;
1027 };
1028
1029 static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
1030                                         const void *ptr, void *data)
1031 {
1032         struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
1033
1034         switch (tag) {
1035         case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
1036                 svc_rdy->ev = ptr;
1037                 break;
1038         case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
1039                 svc_rdy->reg = ptr;
1040                 break;
1041         case WMI_TLV_TAG_ARRAY_STRUCT:
1042                 svc_rdy->mem_reqs = ptr;
1043                 break;
1044         case WMI_TLV_TAG_ARRAY_UINT32:
1045                 if (!svc_rdy->svc_bmap_done) {
1046                         svc_rdy->svc_bmap_done = true;
1047                         svc_rdy->svc_bmap = ptr;
1048                 } else if (!svc_rdy->dbs_hw_mode_done) {
1049                         svc_rdy->dbs_hw_mode_done = true;
1050                 }
1051                 break;
1052         default:
1053                 break;
1054         }
1055         return 0;
1056 }
1057
1058 static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
1059                                              struct sk_buff *skb,
1060                                              struct wmi_svc_rdy_ev_arg *arg)
1061 {
1062         const struct hal_reg_capabilities *reg;
1063         const struct wmi_tlv_svc_rdy_ev *ev;
1064         const __le32 *svc_bmap;
1065         const struct wlan_host_mem_req *mem_reqs;
1066         struct wmi_tlv_svc_rdy_parse svc_rdy = { };
1067         int ret;
1068
1069         ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
1070                                   ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
1071         if (ret) {
1072                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1073                 return ret;
1074         }
1075
1076         ev = svc_rdy.ev;
1077         reg = svc_rdy.reg;
1078         svc_bmap = svc_rdy.svc_bmap;
1079         mem_reqs = svc_rdy.mem_reqs;
1080
1081         if (!ev || !reg || !svc_bmap || !mem_reqs)
1082                 return -EPROTO;
1083
1084         /* This is an internal ABI compatibility check for WMI TLV so check it
1085          * here instead of the generic WMI code.
1086          */
1087         ath10k_dbg(ar, ATH10K_DBG_WMI,
1088                    "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n",
1089                    __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
1090                    __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
1091                    __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
1092                    __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
1093                    __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
1094
1095         if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
1096             __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
1097             __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
1098             __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
1099             __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
1100                 return -ENOTSUPP;
1101         }
1102
1103         arg->min_tx_power = ev->hw_min_tx_power;
1104         arg->max_tx_power = ev->hw_max_tx_power;
1105         arg->ht_cap = ev->ht_cap_info;
1106         arg->vht_cap = ev->vht_cap_info;
1107         arg->sw_ver0 = ev->abi.abi_ver0;
1108         arg->sw_ver1 = ev->abi.abi_ver1;
1109         arg->fw_build = ev->fw_build_vers;
1110         arg->phy_capab = ev->phy_capability;
1111         arg->num_rf_chains = ev->num_rf_chains;
1112         arg->eeprom_rd = reg->eeprom_rd;
1113         arg->low_5ghz_chan = reg->low_5ghz_chan;
1114         arg->high_5ghz_chan = reg->high_5ghz_chan;
1115         arg->num_mem_reqs = ev->num_mem_reqs;
1116         arg->service_map = svc_bmap;
1117         arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
1118
1119         ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
1120                                   ath10k_wmi_tlv_parse_mem_reqs, arg);
1121         if (ret) {
1122                 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
1123                 return ret;
1124         }
1125
1126         return 0;
1127 }
1128
1129 static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
1130                                          struct sk_buff *skb,
1131                                          struct wmi_rdy_ev_arg *arg)
1132 {
1133         const void **tb;
1134         const struct wmi_tlv_rdy_ev *ev;
1135         int ret;
1136
1137         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1138         if (IS_ERR(tb)) {
1139                 ret = PTR_ERR(tb);
1140                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1141                 return ret;
1142         }
1143
1144         ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
1145         if (!ev) {
1146                 kfree(tb);
1147                 return -EPROTO;
1148         }
1149
1150         arg->sw_version = ev->abi.abi_ver0;
1151         arg->abi_version = ev->abi.abi_ver1;
1152         arg->status = ev->status;
1153         arg->mac_addr = ev->mac_addr.addr;
1154
1155         kfree(tb);
1156         return 0;
1157 }
1158
1159 static int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len,
1160                                           const void *ptr, void *data)
1161 {
1162         struct wmi_svc_avail_ev_arg *arg = data;
1163
1164         switch (tag) {
1165         case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT:
1166                 arg->service_map_ext_valid = true;
1167                 arg->service_map_ext_len = *(__le32 *)ptr;
1168                 arg->service_map_ext = ptr + sizeof(__le32);
1169                 return 0;
1170         default:
1171                 break;
1172         }
1173
1174         return 0;
1175 }
1176
1177 static int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar,
1178                                             struct sk_buff *skb,
1179                                             struct wmi_svc_avail_ev_arg *arg)
1180 {
1181         int ret;
1182
1183         ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
1184                                   ath10k_wmi_tlv_svc_avail_parse, arg);
1185
1186         if (ret) {
1187                 ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret);
1188                 return ret;
1189         }
1190
1191         return 0;
1192 }
1193
1194 static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
1195                                            struct ath10k_fw_stats_vdev *dst)
1196 {
1197         int i;
1198
1199         dst->vdev_id = __le32_to_cpu(src->vdev_id);
1200         dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
1201         dst->data_snr = __le32_to_cpu(src->data_snr);
1202         dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
1203         dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
1204         dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
1205         dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
1206         dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
1207         dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
1208
1209         for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
1210                 dst->num_tx_frames[i] =
1211                         __le32_to_cpu(src->num_tx_frames[i]);
1212
1213         for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
1214                 dst->num_tx_frames_retries[i] =
1215                         __le32_to_cpu(src->num_tx_frames_retries[i]);
1216
1217         for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
1218                 dst->num_tx_frames_failures[i] =
1219                         __le32_to_cpu(src->num_tx_frames_failures[i]);
1220
1221         for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
1222                 dst->tx_rate_history[i] =
1223                         __le32_to_cpu(src->tx_rate_history[i]);
1224
1225         for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
1226                 dst->beacon_rssi_history[i] =
1227                         __le32_to_cpu(src->beacon_rssi_history[i]);
1228 }
1229
1230 static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
1231                                            struct sk_buff *skb,
1232                                            struct ath10k_fw_stats *stats)
1233 {
1234         const void **tb;
1235         const struct wmi_tlv_stats_ev *ev;
1236         const void *data;
1237         u32 num_pdev_stats;
1238         u32 num_vdev_stats;
1239         u32 num_peer_stats;
1240         u32 num_bcnflt_stats;
1241         u32 num_chan_stats;
1242         size_t data_len;
1243         int ret;
1244         int i;
1245
1246         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1247         if (IS_ERR(tb)) {
1248                 ret = PTR_ERR(tb);
1249                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1250                 return ret;
1251         }
1252
1253         ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
1254         data = tb[WMI_TLV_TAG_ARRAY_BYTE];
1255
1256         if (!ev || !data) {
1257                 kfree(tb);
1258                 return -EPROTO;
1259         }
1260
1261         data_len = ath10k_wmi_tlv_len(data);
1262         num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
1263         num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
1264         num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
1265         num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
1266         num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
1267
1268         ath10k_dbg(ar, ATH10K_DBG_WMI,
1269                    "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n",
1270                    num_pdev_stats, num_vdev_stats, num_peer_stats,
1271                    num_bcnflt_stats, num_chan_stats);
1272
1273         for (i = 0; i < num_pdev_stats; i++) {
1274                 const struct wmi_pdev_stats *src;
1275                 struct ath10k_fw_stats_pdev *dst;
1276
1277                 src = data;
1278                 if (data_len < sizeof(*src)) {
1279                         kfree(tb);
1280                         return -EPROTO;
1281                 }
1282
1283                 data += sizeof(*src);
1284                 data_len -= sizeof(*src);
1285
1286                 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1287                 if (!dst)
1288                         continue;
1289
1290                 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
1291                 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
1292                 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
1293                 list_add_tail(&dst->list, &stats->pdevs);
1294         }
1295
1296         for (i = 0; i < num_vdev_stats; i++) {
1297                 const struct wmi_tlv_vdev_stats *src;
1298                 struct ath10k_fw_stats_vdev *dst;
1299
1300                 src = data;
1301                 if (data_len < sizeof(*src)) {
1302                         kfree(tb);
1303                         return -EPROTO;
1304                 }
1305
1306                 data += sizeof(*src);
1307                 data_len -= sizeof(*src);
1308
1309                 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1310                 if (!dst)
1311                         continue;
1312
1313                 ath10k_wmi_tlv_pull_vdev_stats(src, dst);
1314                 list_add_tail(&dst->list, &stats->vdevs);
1315         }
1316
1317         for (i = 0; i < num_peer_stats; i++) {
1318                 const struct wmi_10x_peer_stats *src;
1319                 struct ath10k_fw_stats_peer *dst;
1320
1321                 src = data;
1322                 if (data_len < sizeof(*src)) {
1323                         kfree(tb);
1324                         return -EPROTO;
1325                 }
1326
1327                 data += sizeof(*src);
1328                 data_len -= sizeof(*src);
1329
1330                 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1331                 if (!dst)
1332                         continue;
1333
1334                 ath10k_wmi_pull_peer_stats(&src->old, dst);
1335                 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
1336                 list_add_tail(&dst->list, &stats->peers);
1337         }
1338
1339         kfree(tb);
1340         return 0;
1341 }
1342
1343 static int ath10k_wmi_tlv_op_pull_roam_ev(struct ath10k *ar,
1344                                           struct sk_buff *skb,
1345                                           struct wmi_roam_ev_arg *arg)
1346 {
1347         const void **tb;
1348         const struct wmi_tlv_roam_ev *ev;
1349         int ret;
1350
1351         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1352         if (IS_ERR(tb)) {
1353                 ret = PTR_ERR(tb);
1354                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1355                 return ret;
1356         }
1357
1358         ev = tb[WMI_TLV_TAG_STRUCT_ROAM_EVENT];
1359         if (!ev) {
1360                 kfree(tb);
1361                 return -EPROTO;
1362         }
1363
1364         arg->vdev_id = ev->vdev_id;
1365         arg->reason = ev->reason;
1366         arg->rssi = ev->rssi;
1367
1368         kfree(tb);
1369         return 0;
1370 }
1371
1372 static int
1373 ath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb,
1374                               struct wmi_wow_ev_arg *arg)
1375 {
1376         const void **tb;
1377         const struct wmi_tlv_wow_event_info *ev;
1378         int ret;
1379
1380         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1381         if (IS_ERR(tb)) {
1382                 ret = PTR_ERR(tb);
1383                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1384                 return ret;
1385         }
1386
1387         ev = tb[WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO];
1388         if (!ev) {
1389                 kfree(tb);
1390                 return -EPROTO;
1391         }
1392
1393         arg->vdev_id = __le32_to_cpu(ev->vdev_id);
1394         arg->flag = __le32_to_cpu(ev->flag);
1395         arg->wake_reason = __le32_to_cpu(ev->wake_reason);
1396         arg->data_len = __le32_to_cpu(ev->data_len);
1397
1398         kfree(tb);
1399         return 0;
1400 }
1401
1402 static int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar,
1403                                           struct sk_buff *skb,
1404                                           struct wmi_echo_ev_arg *arg)
1405 {
1406         const void **tb;
1407         const struct wmi_echo_event *ev;
1408         int ret;
1409
1410         tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1411         if (IS_ERR(tb)) {
1412                 ret = PTR_ERR(tb);
1413                 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1414                 return ret;
1415         }
1416
1417         ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT];
1418         if (!ev) {
1419                 kfree(tb);
1420                 return -EPROTO;
1421         }
1422
1423         arg->value = ev->value;
1424
1425         kfree(tb);
1426         return 0;
1427 }
1428
1429 static struct sk_buff *
1430 ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
1431 {
1432         struct wmi_tlv_pdev_suspend *cmd;
1433         struct wmi_tlv *tlv;
1434         struct sk_buff *skb;
1435
1436         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1437         if (!skb)
1438                 return ERR_PTR(-ENOMEM);
1439
1440         tlv = (void *)skb->data;
1441         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
1442         tlv->len = __cpu_to_le16(sizeof(*cmd));
1443         cmd = (void *)tlv->value;
1444         cmd->opt = __cpu_to_le32(opt);
1445
1446         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
1447         return skb;
1448 }
1449
1450 static struct sk_buff *
1451 ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
1452 {
1453         struct wmi_tlv_resume_cmd *cmd;
1454         struct wmi_tlv *tlv;
1455         struct sk_buff *skb;
1456
1457         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1458         if (!skb)
1459                 return ERR_PTR(-ENOMEM);
1460
1461         tlv = (void *)skb->data;
1462         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
1463         tlv->len = __cpu_to_le16(sizeof(*cmd));
1464         cmd = (void *)tlv->value;
1465         cmd->reserved = __cpu_to_le32(0);
1466
1467         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
1468         return skb;
1469 }
1470
1471 static struct sk_buff *
1472 ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
1473                                   u16 rd, u16 rd2g, u16 rd5g,
1474                                   u16 ctl2g, u16 ctl5g,
1475                                   enum wmi_dfs_region dfs_reg)
1476 {
1477         struct wmi_tlv_pdev_set_rd_cmd *cmd;
1478         struct wmi_tlv *tlv;
1479         struct sk_buff *skb;
1480
1481         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1482         if (!skb)
1483                 return ERR_PTR(-ENOMEM);
1484
1485         tlv = (void *)skb->data;
1486         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
1487         tlv->len = __cpu_to_le16(sizeof(*cmd));
1488         cmd = (void *)tlv->value;
1489         cmd->regd = __cpu_to_le32(rd);
1490         cmd->regd_2ghz = __cpu_to_le32(rd2g);
1491         cmd->regd_5ghz = __cpu_to_le32(rd5g);
1492         cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
1493         cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
1494
1495         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
1496         return skb;
1497 }
1498
1499 static enum wmi_txbf_conf ath10k_wmi_tlv_txbf_conf_scheme(struct ath10k *ar)
1500 {
1501         return WMI_TXBF_CONF_AFTER_ASSOC;
1502 }
1503
1504 static struct sk_buff *
1505 ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
1506                                      u32 param_value)
1507 {
1508         struct wmi_tlv_pdev_set_param_cmd *cmd;
1509         struct wmi_tlv *tlv;
1510         struct sk_buff *skb;
1511
1512         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1513         if (!skb)
1514                 return ERR_PTR(-ENOMEM);
1515
1516         tlv = (void *)skb->data;
1517         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
1518         tlv->len = __cpu_to_le16(sizeof(*cmd));
1519         cmd = (void *)tlv->value;
1520         cmd->param_id = __cpu_to_le32(param_id);
1521         cmd->param_value = __cpu_to_le32(param_value);
1522
1523         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param\n");
1524         return skb;
1525 }
1526
1527 static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
1528 {
1529         struct sk_buff *skb;
1530         struct wmi_tlv *tlv;
1531         struct wmi_tlv_init_cmd *cmd;
1532         struct wmi_tlv_resource_config *cfg;
1533         struct wmi_host_mem_chunks *chunks;
1534         size_t len, chunks_len;
1535         void *ptr;
1536
1537         chunks_len = ar->wmi.num_mem_chunks * sizeof(struct host_memory_chunk);
1538         len = (sizeof(*tlv) + sizeof(*cmd)) +
1539               (sizeof(*tlv) + sizeof(*cfg)) +
1540               (sizeof(*tlv) + chunks_len);
1541
1542         skb = ath10k_wmi_alloc_skb(ar, len);
1543         if (!skb)
1544                 return ERR_PTR(-ENOMEM);
1545
1546         ptr = skb->data;
1547
1548         tlv = ptr;
1549         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
1550         tlv->len = __cpu_to_le16(sizeof(*cmd));
1551         cmd = (void *)tlv->value;
1552         ptr += sizeof(*tlv);
1553         ptr += sizeof(*cmd);
1554
1555         tlv = ptr;
1556         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
1557         tlv->len = __cpu_to_le16(sizeof(*cfg));
1558         cfg = (void *)tlv->value;
1559         ptr += sizeof(*tlv);
1560         ptr += sizeof(*cfg);
1561
1562         tlv = ptr;
1563         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1564         tlv->len = __cpu_to_le16(chunks_len);
1565         chunks = (void *)tlv->value;
1566
1567         ptr += sizeof(*tlv);
1568         ptr += chunks_len;
1569
1570         cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
1571         cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
1572         cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
1573         cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
1574         cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
1575         cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
1576         cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
1577
1578         cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1579
1580         cfg->num_peers = __cpu_to_le32(ar->hw_params.num_peers);
1581         cfg->ast_skid_limit = __cpu_to_le32(ar->hw_params.ast_skid_limit);
1582         cfg->num_wds_entries = __cpu_to_le32(ar->hw_params.num_wds_entries);
1583
1584         if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) {
1585                 cfg->num_offload_peers = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1586                 cfg->num_offload_reorder_bufs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1587         } else {
1588                 cfg->num_offload_peers = __cpu_to_le32(0);
1589                 cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
1590         }
1591
1592         cfg->num_peer_keys = __cpu_to_le32(2);
1593         cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
1594         cfg->tx_chain_mask = __cpu_to_le32(0x7);
1595         cfg->rx_chain_mask = __cpu_to_le32(0x7);
1596         cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
1597         cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
1598         cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
1599         cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
1600         cfg->rx_decap_mode = __cpu_to_le32(ar->wmi.rx_decap_mode);
1601         cfg->scan_max_pending_reqs = __cpu_to_le32(4);
1602         cfg->bmiss_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1603         cfg->roam_offload_max_vdev = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1604         cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
1605         cfg->num_mcast_groups = __cpu_to_le32(0);
1606         cfg->num_mcast_table_elems = __cpu_to_le32(0);
1607         cfg->mcast2ucast_mode = __cpu_to_le32(0);
1608         cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
1609         cfg->dma_burst_size = __cpu_to_le32(0);
1610         cfg->mac_aggr_delim = __cpu_to_le32(0);
1611         cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
1612         cfg->vow_config = __cpu_to_le32(0);
1613         cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
1614         cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
1615         cfg->max_frag_entries = __cpu_to_le32(2);
1616         cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
1617         cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
1618         cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
1619         cfg->num_multicast_filter_entries = __cpu_to_le32(5);
1620         cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns);
1621         cfg->num_keep_alive_pattern = __cpu_to_le32(6);
1622         cfg->keep_alive_pattern_size = __cpu_to_le32(0);
1623         cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
1624         cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
1625         cfg->wmi_send_separate = __cpu_to_le32(0);
1626         cfg->num_ocb_vdevs = __cpu_to_le32(0);
1627         cfg->num_ocb_channels = __cpu_to_le32(0);
1628         cfg->num_ocb_schedules = __cpu_to_le32(0);
1629         cfg->host_capab = __cpu_to_le32(0);
1630
1631         ath10k_wmi_put_host_mem_chunks(ar, chunks);
1632
1633         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
1634         return skb;
1635 }
1636
1637 static struct sk_buff *
1638 ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
1639                                  const struct wmi_start_scan_arg *arg)
1640 {
1641         struct wmi_tlv_start_scan_cmd *cmd;
1642         struct wmi_tlv *tlv;
1643         struct sk_buff *skb;
1644         size_t len, chan_len, ssid_len, bssid_len, ie_len;
1645         __le32 *chans;
1646         struct wmi_ssid *ssids;
1647         struct wmi_mac_addr *addrs;
1648         void *ptr;
1649         int i, ret;
1650
1651         ret = ath10k_wmi_start_scan_verify(arg);
1652         if (ret)
1653                 return ERR_PTR(ret);
1654
1655         chan_len = arg->n_channels * sizeof(__le32);
1656         ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
1657         bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
1658         ie_len = roundup(arg->ie_len, 4);
1659         len = (sizeof(*tlv) + sizeof(*cmd)) +
1660               sizeof(*tlv) + chan_len +
1661               sizeof(*tlv) + ssid_len +
1662               sizeof(*tlv) + bssid_len +
1663               sizeof(*tlv) + ie_len;
1664
1665         skb = ath10k_wmi_alloc_skb(ar, len);
1666         if (!skb)
1667                 return ERR_PTR(-ENOMEM);
1668
1669         ptr = (void *)skb->data;
1670         tlv = ptr;
1671         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
1672         tlv->len = __cpu_to_le16(sizeof(*cmd));
1673         cmd = (void *)tlv->value;
1674
1675         ath10k_wmi_put_start_scan_common(&cmd->common, arg);
1676         cmd->burst_duration_ms = __cpu_to_le32(arg->burst_duration_ms);
1677         cmd->num_channels = __cpu_to_le32(arg->n_channels);
1678         cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
1679         cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
1680         cmd->ie_len = __cpu_to_le32(arg->ie_len);
1681         cmd->num_probes = __cpu_to_le32(3);
1682         ether_addr_copy(cmd->mac_addr.addr, arg->mac_addr.addr);
1683         ether_addr_copy(cmd->mac_mask.addr, arg->mac_mask.addr);
1684
1685         /* FIXME: There are some scan flag inconsistencies across firmwares,
1686          * e.g. WMI-TLV inverts the logic behind the following flag.
1687          */
1688         cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
1689
1690         ptr += sizeof(*tlv);
1691         ptr += sizeof(*cmd);
1692
1693         tlv = ptr;
1694         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1695         tlv->len = __cpu_to_le16(chan_len);
1696         chans = (void *)tlv->value;
1697         for (i = 0; i < arg->n_channels; i++)
1698                 chans[i] = __cpu_to_le32(arg->channels[i]);
1699
1700         ptr += sizeof(*tlv);
1701         ptr += chan_len;
1702
1703         tlv = ptr;
1704         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1705         tlv->len = __cpu_to_le16(ssid_len);
1706         ssids = (void *)tlv->value;
1707         for (i = 0; i < arg->n_ssids; i++) {
1708                 ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
1709                 memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
1710         }
1711
1712         ptr += sizeof(*tlv);
1713         ptr += ssid_len;
1714
1715         tlv = ptr;
1716         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1717         tlv->len = __cpu_to_le16(bssid_len);
1718         addrs = (void *)tlv->value;
1719         for (i = 0; i < arg->n_bssids; i++)
1720                 ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
1721
1722         ptr += sizeof(*tlv);
1723         ptr += bssid_len;
1724
1725         tlv = ptr;
1726         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1727         tlv->len = __cpu_to_le16(ie_len);
1728         memcpy(tlv->value, arg->ie, arg->ie_len);
1729
1730         ptr += sizeof(*tlv);
1731         ptr += ie_len;
1732
1733         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
1734         return skb;
1735 }
1736
1737 static struct sk_buff *
1738 ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
1739                                 const struct wmi_stop_scan_arg *arg)
1740 {
1741         struct wmi_stop_scan_cmd *cmd;
1742         struct wmi_tlv *tlv;
1743         struct sk_buff *skb;
1744         u32 scan_id;
1745         u32 req_id;
1746
1747         if (arg->req_id > 0xFFF)
1748                 return ERR_PTR(-EINVAL);
1749         if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
1750                 return ERR_PTR(-EINVAL);
1751
1752         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1753         if (!skb)
1754                 return ERR_PTR(-ENOMEM);
1755
1756         scan_id = arg->u.scan_id;
1757         scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
1758
1759         req_id = arg->req_id;
1760         req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
1761
1762         tlv = (void *)skb->data;
1763         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
1764         tlv->len = __cpu_to_le16(sizeof(*cmd));
1765         cmd = (void *)tlv->value;
1766         cmd->req_type = __cpu_to_le32(arg->req_type);
1767         cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
1768         cmd->scan_id = __cpu_to_le32(scan_id);
1769         cmd->scan_req_id = __cpu_to_le32(req_id);
1770
1771         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
1772         return skb;
1773 }
1774
1775 static struct sk_buff *
1776 ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
1777                                   u32 vdev_id,
1778                                   enum wmi_vdev_type vdev_type,
1779                                   enum wmi_vdev_subtype vdev_subtype,
1780                                   const u8 mac_addr[ETH_ALEN])
1781 {
1782         struct wmi_vdev_create_cmd *cmd;
1783         struct wmi_tlv *tlv;
1784         struct sk_buff *skb;
1785
1786         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1787         if (!skb)
1788                 return ERR_PTR(-ENOMEM);
1789
1790         tlv = (void *)skb->data;
1791         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
1792         tlv->len = __cpu_to_le16(sizeof(*cmd));
1793         cmd = (void *)tlv->value;
1794         cmd->vdev_id = __cpu_to_le32(vdev_id);
1795         cmd->vdev_type = __cpu_to_le32(vdev_type);
1796         cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
1797         ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
1798
1799         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
1800         return skb;
1801 }
1802
1803 static struct sk_buff *
1804 ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
1805 {
1806         struct wmi_vdev_delete_cmd *cmd;
1807         struct wmi_tlv *tlv;
1808         struct sk_buff *skb;
1809
1810         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1811         if (!skb)
1812                 return ERR_PTR(-ENOMEM);
1813
1814         tlv = (void *)skb->data;
1815         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
1816         tlv->len = __cpu_to_le16(sizeof(*cmd));
1817         cmd = (void *)tlv->value;
1818         cmd->vdev_id = __cpu_to_le32(vdev_id);
1819
1820         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
1821         return skb;
1822 }
1823
1824 static struct sk_buff *
1825 ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
1826                                  const struct wmi_vdev_start_request_arg *arg,
1827                                  bool restart)
1828 {
1829         struct wmi_tlv_vdev_start_cmd *cmd;
1830         struct wmi_channel *ch;
1831         struct wmi_tlv *tlv;
1832         struct sk_buff *skb;
1833         size_t len;
1834         void *ptr;
1835         u32 flags = 0;
1836
1837         if (WARN_ON(arg->hidden_ssid && !arg->ssid))
1838                 return ERR_PTR(-EINVAL);
1839         if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
1840                 return ERR_PTR(-EINVAL);
1841
1842         len = (sizeof(*tlv) + sizeof(*cmd)) +
1843               (sizeof(*tlv) + sizeof(*ch)) +
1844               (sizeof(*tlv) + 0);
1845         skb = ath10k_wmi_alloc_skb(ar, len);
1846         if (!skb)
1847                 return ERR_PTR(-ENOMEM);
1848
1849         if (arg->hidden_ssid)
1850                 flags |= WMI_VDEV_START_HIDDEN_SSID;
1851         if (arg->pmf_enabled)
1852                 flags |= WMI_VDEV_START_PMF_ENABLED;
1853
1854         ptr = (void *)skb->data;
1855
1856         tlv = ptr;
1857         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
1858         tlv->len = __cpu_to_le16(sizeof(*cmd));
1859         cmd = (void *)tlv->value;
1860         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1861         cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
1862         cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
1863         cmd->flags = __cpu_to_le32(flags);
1864         cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
1865         cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
1866         cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
1867
1868         if (arg->ssid) {
1869                 cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
1870                 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
1871         }
1872
1873         ptr += sizeof(*tlv);
1874         ptr += sizeof(*cmd);
1875
1876         tlv = ptr;
1877         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1878         tlv->len = __cpu_to_le16(sizeof(*ch));
1879         ch = (void *)tlv->value;
1880         ath10k_wmi_put_wmi_channel(ch, &arg->channel);
1881
1882         ptr += sizeof(*tlv);
1883         ptr += sizeof(*ch);
1884
1885         tlv = ptr;
1886         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1887         tlv->len = 0;
1888
1889         /* Note: This is a nested TLV containing:
1890          * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
1891          */
1892
1893         ptr += sizeof(*tlv);
1894         ptr += 0;
1895
1896         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
1897         return skb;
1898 }
1899
1900 static struct sk_buff *
1901 ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
1902 {
1903         struct wmi_vdev_stop_cmd *cmd;
1904         struct wmi_tlv *tlv;
1905         struct sk_buff *skb;
1906
1907         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1908         if (!skb)
1909                 return ERR_PTR(-ENOMEM);
1910
1911         tlv = (void *)skb->data;
1912         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
1913         tlv->len = __cpu_to_le16(sizeof(*cmd));
1914         cmd = (void *)tlv->value;
1915         cmd->vdev_id = __cpu_to_le32(vdev_id);
1916
1917         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
1918         return skb;
1919 }
1920
1921 static struct sk_buff *
1922 ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
1923                               const u8 *bssid)
1924
1925 {
1926         struct wmi_vdev_up_cmd *cmd;
1927         struct wmi_tlv *tlv;
1928         struct sk_buff *skb;
1929
1930         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1931         if (!skb)
1932                 return ERR_PTR(-ENOMEM);
1933
1934         tlv = (void *)skb->data;
1935         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
1936         tlv->len = __cpu_to_le16(sizeof(*cmd));
1937         cmd = (void *)tlv->value;
1938         cmd->vdev_id = __cpu_to_le32(vdev_id);
1939         cmd->vdev_assoc_id = __cpu_to_le32(aid);
1940         ether_addr_copy(cmd->vdev_bssid.addr, bssid);
1941
1942         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
1943         return skb;
1944 }
1945
1946 static struct sk_buff *
1947 ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
1948 {
1949         struct wmi_vdev_down_cmd *cmd;
1950         struct wmi_tlv *tlv;
1951         struct sk_buff *skb;
1952
1953         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1954         if (!skb)
1955                 return ERR_PTR(-ENOMEM);
1956
1957         tlv = (void *)skb->data;
1958         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
1959         tlv->len = __cpu_to_le16(sizeof(*cmd));
1960         cmd = (void *)tlv->value;
1961         cmd->vdev_id = __cpu_to_le32(vdev_id);
1962
1963         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
1964         return skb;
1965 }
1966
1967 static struct sk_buff *
1968 ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
1969                                      u32 param_id, u32 param_value)
1970 {
1971         struct wmi_vdev_set_param_cmd *cmd;
1972         struct wmi_tlv *tlv;
1973         struct sk_buff *skb;
1974
1975         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1976         if (!skb)
1977                 return ERR_PTR(-ENOMEM);
1978
1979         tlv = (void *)skb->data;
1980         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
1981         tlv->len = __cpu_to_le16(sizeof(*cmd));
1982         cmd = (void *)tlv->value;
1983         cmd->vdev_id = __cpu_to_le32(vdev_id);
1984         cmd->param_id = __cpu_to_le32(param_id);
1985         cmd->param_value = __cpu_to_le32(param_value);
1986
1987         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev set param\n");
1988         return skb;
1989 }
1990
1991 static struct sk_buff *
1992 ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
1993                                        const struct wmi_vdev_install_key_arg *arg)
1994 {
1995         struct wmi_vdev_install_key_cmd *cmd;
1996         struct wmi_tlv *tlv;
1997         struct sk_buff *skb;
1998         size_t len;
1999         void *ptr;
2000
2001         if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
2002                 return ERR_PTR(-EINVAL);
2003         if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
2004                 return ERR_PTR(-EINVAL);
2005
2006         len = sizeof(*tlv) + sizeof(*cmd) +
2007               sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
2008         skb = ath10k_wmi_alloc_skb(ar, len);
2009         if (!skb)
2010                 return ERR_PTR(-ENOMEM);
2011
2012         ptr = (void *)skb->data;
2013         tlv = ptr;
2014         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
2015         tlv->len = __cpu_to_le16(sizeof(*cmd));
2016         cmd = (void *)tlv->value;
2017         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
2018         cmd->key_idx = __cpu_to_le32(arg->key_idx);
2019         cmd->key_flags = __cpu_to_le32(arg->key_flags);
2020         cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
2021         cmd->key_len = __cpu_to_le32(arg->key_len);
2022         cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
2023         cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
2024
2025         if (arg->macaddr)
2026                 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
2027
2028         ptr += sizeof(*tlv);
2029         ptr += sizeof(*cmd);
2030
2031         tlv = ptr;
2032         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2033         tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
2034         if (arg->key_data)
2035                 memcpy(tlv->value, arg->key_data, arg->key_len);
2036
2037         ptr += sizeof(*tlv);
2038         ptr += roundup(arg->key_len, sizeof(__le32));
2039
2040         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
2041         return skb;
2042 }
2043
2044 static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr,
2045                                          const struct wmi_sta_uapsd_auto_trig_arg *arg)
2046 {
2047         struct wmi_sta_uapsd_auto_trig_param *ac;
2048         struct wmi_tlv *tlv;
2049
2050         tlv = ptr;
2051         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM);
2052         tlv->len = __cpu_to_le16(sizeof(*ac));
2053         ac = (void *)tlv->value;
2054
2055         ac->wmm_ac = __cpu_to_le32(arg->wmm_ac);
2056         ac->user_priority = __cpu_to_le32(arg->user_priority);
2057         ac->service_interval = __cpu_to_le32(arg->service_interval);
2058         ac->suspend_interval = __cpu_to_le32(arg->suspend_interval);
2059         ac->delay_interval = __cpu_to_le32(arg->delay_interval);
2060
2061         ath10k_dbg(ar, ATH10K_DBG_WMI,
2062                    "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n",
2063                    ac->wmm_ac, ac->user_priority, ac->service_interval,
2064                    ac->suspend_interval, ac->delay_interval);
2065
2066         return ptr + sizeof(*tlv) + sizeof(*ac);
2067 }
2068
2069 static struct sk_buff *
2070 ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
2071                                      const u8 peer_addr[ETH_ALEN],
2072                                      const struct wmi_sta_uapsd_auto_trig_arg *args,
2073                                      u32 num_ac)
2074 {
2075         struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
2076         struct wmi_sta_uapsd_auto_trig_param *ac;
2077         struct wmi_tlv *tlv;
2078         struct sk_buff *skb;
2079         size_t len;
2080         size_t ac_tlv_len;
2081         void *ptr;
2082         int i;
2083
2084         ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac));
2085         len = sizeof(*tlv) + sizeof(*cmd) +
2086               sizeof(*tlv) + ac_tlv_len;
2087         skb = ath10k_wmi_alloc_skb(ar, len);
2088         if (!skb)
2089                 return ERR_PTR(-ENOMEM);
2090
2091         ptr = (void *)skb->data;
2092         tlv = ptr;
2093         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD);
2094         tlv->len = __cpu_to_le16(sizeof(*cmd));
2095         cmd = (void *)tlv->value;
2096         cmd->vdev_id = __cpu_to_le32(vdev_id);
2097         cmd->num_ac = __cpu_to_le32(num_ac);
2098         ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
2099
2100         ptr += sizeof(*tlv);
2101         ptr += sizeof(*cmd);
2102
2103         tlv = ptr;
2104         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
2105         tlv->len = __cpu_to_le16(ac_tlv_len);
2106         ac = (void *)tlv->value;
2107
2108         ptr += sizeof(*tlv);
2109         for (i = 0; i < num_ac; i++)
2110                 ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]);
2111
2112         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n");
2113         return skb;
2114 }
2115
2116 static void *ath10k_wmi_tlv_put_wmm(void *ptr,
2117                                     const struct wmi_wmm_params_arg *arg)
2118 {
2119         struct wmi_wmm_params *wmm;
2120         struct wmi_tlv *tlv;
2121
2122         tlv = ptr;
2123         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
2124         tlv->len = __cpu_to_le16(sizeof(*wmm));
2125         wmm = (void *)tlv->value;
2126         ath10k_wmi_set_wmm_param(wmm, arg);
2127
2128         return ptr + sizeof(*tlv) + sizeof(*wmm);
2129 }
2130
2131 static struct sk_buff *
2132 ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
2133                                     const struct wmi_wmm_params_all_arg *arg)
2134 {
2135         struct wmi_tlv_vdev_set_wmm_cmd *cmd;
2136         struct wmi_tlv *tlv;
2137         struct sk_buff *skb;
2138         size_t len;
2139         void *ptr;
2140
2141         len = sizeof(*tlv) + sizeof(*cmd);
2142         skb = ath10k_wmi_alloc_skb(ar, len);
2143         if (!skb)
2144                 return ERR_PTR(-ENOMEM);
2145
2146         ptr = (void *)skb->data;
2147         tlv = ptr;
2148         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD);
2149         tlv->len = __cpu_to_le16(sizeof(*cmd));
2150         cmd = (void *)tlv->value;
2151         cmd->vdev_id = __cpu_to_le32(vdev_id);
2152
2153         ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
2154         ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
2155         ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
2156         ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
2157
2158         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
2159         return skb;
2160 }
2161
2162 static struct sk_buff *
2163 ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
2164                                     const struct wmi_sta_keepalive_arg *arg)
2165 {
2166         struct wmi_tlv_sta_keepalive_cmd *cmd;
2167         struct wmi_sta_keepalive_arp_resp *arp;
2168         struct sk_buff *skb;
2169         struct wmi_tlv *tlv;
2170         void *ptr;
2171         size_t len;
2172
2173         len = sizeof(*tlv) + sizeof(*cmd) +
2174               sizeof(*tlv) + sizeof(*arp);
2175         skb = ath10k_wmi_alloc_skb(ar, len);
2176         if (!skb)
2177                 return ERR_PTR(-ENOMEM);
2178
2179         ptr = (void *)skb->data;
2180         tlv = ptr;
2181         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD);
2182         tlv->len = __cpu_to_le16(sizeof(*cmd));
2183         cmd = (void *)tlv->value;
2184         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
2185         cmd->enabled = __cpu_to_le32(arg->enabled);
2186         cmd->method = __cpu_to_le32(arg->method);
2187         cmd->interval = __cpu_to_le32(arg->interval);
2188
2189         ptr += sizeof(*tlv);
2190         ptr += sizeof(*cmd);
2191
2192         tlv = ptr;
2193         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE);
2194         tlv->len = __cpu_to_le16(sizeof(*arp));
2195         arp = (void *)tlv->value;
2196
2197         arp->src_ip4_addr = arg->src_ip4_addr;
2198         arp->dest_ip4_addr = arg->dest_ip4_addr;
2199         ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
2200
2201         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d interval %d\n",
2202                    arg->vdev_id, arg->enabled, arg->method, arg->interval);
2203         return skb;
2204 }
2205
2206 static struct sk_buff *
2207 ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
2208                                   const u8 peer_addr[ETH_ALEN],
2209                                   enum wmi_peer_type peer_type)
2210 {
2211         struct wmi_tlv_peer_create_cmd *cmd;
2212         struct wmi_tlv *tlv;
2213         struct sk_buff *skb;
2214
2215         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2216         if (!skb)
2217                 return ERR_PTR(-ENOMEM);
2218
2219         tlv = (void *)skb->data;
2220         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
2221         tlv->len = __cpu_to_le16(sizeof(*cmd));
2222         cmd = (void *)tlv->value;
2223         cmd->vdev_id = __cpu_to_le32(vdev_id);
2224         cmd->peer_type = __cpu_to_le32(peer_type);
2225         ether_addr_copy(cmd->peer_addr.addr, peer_addr);
2226
2227         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
2228         return skb;
2229 }
2230
2231 static struct sk_buff *
2232 ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
2233                                   const u8 peer_addr[ETH_ALEN])
2234 {
2235         struct wmi_peer_delete_cmd *cmd;
2236         struct wmi_tlv *tlv;
2237         struct sk_buff *skb;
2238
2239         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2240         if (!skb)
2241                 return ERR_PTR(-ENOMEM);
2242
2243         tlv = (void *)skb->data;
2244         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
2245         tlv->len = __cpu_to_le16(sizeof(*cmd));
2246         cmd = (void *)tlv->value;
2247         cmd->vdev_id = __cpu_to_le32(vdev_id);
2248         ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
2249
2250         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
2251         return skb;
2252 }
2253
2254 static struct sk_buff *
2255 ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
2256                                  const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
2257 {
2258         struct wmi_peer_flush_tids_cmd *cmd;
2259         struct wmi_tlv *tlv;
2260         struct sk_buff *skb;
2261
2262         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2263         if (!skb)
2264                 return ERR_PTR(-ENOMEM);
2265
2266         tlv = (void *)skb->data;
2267         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
2268         tlv->len = __cpu_to_le16(sizeof(*cmd));
2269         cmd = (void *)tlv->value;
2270         cmd->vdev_id = __cpu_to_le32(vdev_id);
2271         cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
2272         ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
2273
2274         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
2275         return skb;
2276 }
2277
2278 static struct sk_buff *
2279 ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
2280                                      const u8 *peer_addr,
2281                                      enum wmi_peer_param param_id,
2282                                      u32 param_value)
2283 {
2284         struct wmi_peer_set_param_cmd *cmd;
2285         struct wmi_tlv *tlv;
2286         struct sk_buff *skb;
2287
2288         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2289         if (!skb)
2290                 return ERR_PTR(-ENOMEM);
2291
2292         tlv = (void *)skb->data;
2293         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
2294         tlv->len = __cpu_to_le16(sizeof(*cmd));
2295         cmd = (void *)tlv->value;
2296         cmd->vdev_id = __cpu_to_le32(vdev_id);
2297         cmd->param_id = __cpu_to_le32(param_id);
2298         cmd->param_value = __cpu_to_le32(param_value);
2299         ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
2300
2301         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer set param\n");
2302         return skb;
2303 }
2304
2305 static struct sk_buff *
2306 ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
2307                                  const struct wmi_peer_assoc_complete_arg *arg)
2308 {
2309         struct wmi_tlv_peer_assoc_cmd *cmd;
2310         struct wmi_vht_rate_set *vht_rate;
2311         struct wmi_tlv *tlv;
2312         struct sk_buff *skb;
2313         size_t len, legacy_rate_len, ht_rate_len;
2314         void *ptr;
2315
2316         if (arg->peer_mpdu_density > 16)
2317                 return ERR_PTR(-EINVAL);
2318         if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
2319                 return ERR_PTR(-EINVAL);
2320         if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
2321                 return ERR_PTR(-EINVAL);
2322
2323         legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
2324                                   sizeof(__le32));
2325         ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
2326         len = (sizeof(*tlv) + sizeof(*cmd)) +
2327               (sizeof(*tlv) + legacy_rate_len) +
2328               (sizeof(*tlv) + ht_rate_len) +
2329               (sizeof(*tlv) + sizeof(*vht_rate));
2330         skb = ath10k_wmi_alloc_skb(ar, len);
2331         if (!skb)
2332                 return ERR_PTR(-ENOMEM);
2333
2334         ptr = (void *)skb->data;
2335         tlv = ptr;
2336         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
2337         tlv->len = __cpu_to_le16(sizeof(*cmd));
2338         cmd = (void *)tlv->value;
2339
2340         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
2341         cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
2342         cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
2343         cmd->flags = __cpu_to_le32(arg->peer_flags);
2344         cmd->caps = __cpu_to_le32(arg->peer_caps);
2345         cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
2346         cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
2347         cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
2348         cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
2349         cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
2350         cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
2351         cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
2352         cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
2353         cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
2354         cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
2355         ether_addr_copy(cmd->mac_addr.addr, arg->addr);
2356
2357         ptr += sizeof(*tlv);
2358         ptr += sizeof(*cmd);
2359
2360         tlv = ptr;
2361         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2362         tlv->len = __cpu_to_le16(legacy_rate_len);
2363         memcpy(tlv->value, arg->peer_legacy_rates.rates,
2364                arg->peer_legacy_rates.num_rates);
2365
2366         ptr += sizeof(*tlv);
2367         ptr += legacy_rate_len;
2368
2369         tlv = ptr;
2370         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2371         tlv->len = __cpu_to_le16(ht_rate_len);
2372         memcpy(tlv->value, arg->peer_ht_rates.rates,
2373                arg->peer_ht_rates.num_rates);
2374
2375         ptr += sizeof(*tlv);
2376         ptr += ht_rate_len;
2377
2378         tlv = ptr;
2379         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
2380         tlv->len = __cpu_to_le16(sizeof(*vht_rate));
2381         vht_rate = (void *)tlv->value;
2382
2383         vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
2384         vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
2385         vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
2386         vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
2387
2388         ptr += sizeof(*tlv);
2389         ptr += sizeof(*vht_rate);
2390
2391         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
2392         return skb;
2393 }
2394
2395 static struct sk_buff *
2396 ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
2397                                  enum wmi_sta_ps_mode psmode)
2398 {
2399         struct wmi_sta_powersave_mode_cmd *cmd;
2400         struct wmi_tlv *tlv;
2401         struct sk_buff *skb;
2402
2403         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2404         if (!skb)
2405                 return ERR_PTR(-ENOMEM);
2406
2407         tlv = (void *)skb->data;
2408         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
2409         tlv->len = __cpu_to_le16(sizeof(*cmd));
2410         cmd = (void *)tlv->value;
2411         cmd->vdev_id = __cpu_to_le32(vdev_id);
2412         cmd->sta_ps_mode = __cpu_to_le32(psmode);
2413
2414         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
2415         return skb;
2416 }
2417
2418 static struct sk_buff *
2419 ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
2420                                  enum wmi_sta_powersave_param param_id,
2421                                  u32 param_value)
2422 {
2423         struct wmi_sta_powersave_param_cmd *cmd;
2424         struct wmi_tlv *tlv;
2425         struct sk_buff *skb;
2426
2427         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2428         if (!skb)
2429                 return ERR_PTR(-ENOMEM);
2430
2431         tlv = (void *)skb->data;
2432         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
2433         tlv->len = __cpu_to_le16(sizeof(*cmd));
2434         cmd = (void *)tlv->value;
2435         cmd->vdev_id = __cpu_to_le32(vdev_id);
2436         cmd->param_id = __cpu_to_le32(param_id);
2437         cmd->param_value = __cpu_to_le32(param_value);
2438
2439         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
2440         return skb;
2441 }
2442
2443 static struct sk_buff *
2444 ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
2445                                 enum wmi_ap_ps_peer_param param_id, u32 value)
2446 {
2447         struct wmi_ap_ps_peer_cmd *cmd;
2448         struct wmi_tlv *tlv;
2449         struct sk_buff *skb;
2450
2451         if (!mac)
2452                 return ERR_PTR(-EINVAL);
2453
2454         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2455         if (!skb)
2456                 return ERR_PTR(-ENOMEM);
2457
2458         tlv = (void *)skb->data;
2459         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
2460         tlv->len = __cpu_to_le16(sizeof(*cmd));
2461         cmd = (void *)tlv->value;
2462         cmd->vdev_id = __cpu_to_le32(vdev_id);
2463         cmd->param_id = __cpu_to_le32(param_id);
2464         cmd->param_value = __cpu_to_le32(value);
2465         ether_addr_copy(cmd->peer_macaddr.addr, mac);
2466
2467         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
2468         return skb;
2469 }
2470
2471 static struct sk_buff *
2472 ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
2473                                      const struct wmi_scan_chan_list_arg *arg)
2474 {
2475         struct wmi_tlv_scan_chan_list_cmd *cmd;
2476         struct wmi_channel *ci;
2477         struct wmi_channel_arg *ch;
2478         struct wmi_tlv *tlv;
2479         struct sk_buff *skb;
2480         size_t chans_len, len;
2481         int i;
2482         void *ptr, *chans;
2483
2484         chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
2485         len = (sizeof(*tlv) + sizeof(*cmd)) +
2486               (sizeof(*tlv) + chans_len);
2487
2488         skb = ath10k_wmi_alloc_skb(ar, len);
2489         if (!skb)
2490                 return ERR_PTR(-ENOMEM);
2491
2492         ptr = (void *)skb->data;
2493         tlv = ptr;
2494         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
2495         tlv->len = __cpu_to_le16(sizeof(*cmd));
2496         cmd = (void *)tlv->value;
2497         cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
2498
2499         ptr += sizeof(*tlv);
2500         ptr += sizeof(*cmd);
2501
2502         tlv = ptr;
2503         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
2504         tlv->len = __cpu_to_le16(chans_len);
2505         chans = (void *)tlv->value;
2506
2507         for (i = 0; i < arg->n_channels; i++) {
2508                 ch = &arg->channels[i];
2509
2510                 tlv = chans;
2511                 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
2512                 tlv->len = __cpu_to_le16(sizeof(*ci));
2513                 ci = (void *)tlv->value;
2514
2515                 ath10k_wmi_put_wmi_channel(ci, ch);
2516
2517                 chans += sizeof(*tlv);
2518                 chans += sizeof(*ci);
2519         }
2520
2521         ptr += sizeof(*tlv);
2522         ptr += chans_len;
2523
2524         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
2525         return skb;
2526 }
2527
2528 static struct sk_buff *
2529 ath10k_wmi_tlv_op_gen_scan_prob_req_oui(struct ath10k *ar, u32 prob_req_oui)
2530 {
2531         struct wmi_scan_prob_req_oui_cmd *cmd;
2532         struct wmi_tlv *tlv;
2533         struct sk_buff *skb;
2534
2535         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2536         if (!skb)
2537                 return ERR_PTR(-ENOMEM);
2538
2539         tlv = (void *)skb->data;
2540         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD);
2541         tlv->len = __cpu_to_le16(sizeof(*cmd));
2542         cmd = (void *)tlv->value;
2543         cmd->prob_req_oui = __cpu_to_le32(prob_req_oui);
2544
2545         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan prob req oui\n");
2546         return skb;
2547 }
2548
2549 static struct sk_buff *
2550 ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id,
2551                                  const void *bcn, size_t bcn_len,
2552                                  u32 bcn_paddr, bool dtim_zero,
2553                                  bool deliver_cab)
2554
2555 {
2556         struct wmi_bcn_tx_ref_cmd *cmd;
2557         struct wmi_tlv *tlv;
2558         struct sk_buff *skb;
2559         struct ieee80211_hdr *hdr;
2560         u16 fc;
2561
2562         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2563         if (!skb)
2564                 return ERR_PTR(-ENOMEM);
2565
2566         hdr = (struct ieee80211_hdr *)bcn;
2567         fc = le16_to_cpu(hdr->frame_control);
2568
2569         tlv = (void *)skb->data;
2570         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
2571         tlv->len = __cpu_to_le16(sizeof(*cmd));
2572         cmd = (void *)tlv->value;
2573         cmd->vdev_id = __cpu_to_le32(vdev_id);
2574         cmd->data_len = __cpu_to_le32(bcn_len);
2575         cmd->data_ptr = __cpu_to_le32(bcn_paddr);
2576         cmd->msdu_id = 0;
2577         cmd->frame_control = __cpu_to_le32(fc);
2578         cmd->flags = 0;
2579
2580         if (dtim_zero)
2581                 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
2582
2583         if (deliver_cab)
2584                 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
2585
2586         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
2587         return skb;
2588 }
2589
2590 static struct sk_buff *
2591 ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
2592                                    const struct wmi_wmm_params_all_arg *arg)
2593 {
2594         struct wmi_tlv_pdev_set_wmm_cmd *cmd;
2595         struct wmi_wmm_params *wmm;
2596         struct wmi_tlv *tlv;
2597         struct sk_buff *skb;
2598         size_t len;
2599         void *ptr;
2600
2601         len = (sizeof(*tlv) + sizeof(*cmd)) +
2602               (4 * (sizeof(*tlv) + sizeof(*wmm)));
2603         skb = ath10k_wmi_alloc_skb(ar, len);
2604         if (!skb)
2605                 return ERR_PTR(-ENOMEM);
2606
2607         ptr = (void *)skb->data;
2608
2609         tlv = ptr;
2610         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
2611         tlv->len = __cpu_to_le16(sizeof(*cmd));
2612         cmd = (void *)tlv->value;
2613
2614         /* nothing to set here */
2615
2616         ptr += sizeof(*tlv);
2617         ptr += sizeof(*cmd);
2618
2619         ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
2620         ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
2621         ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
2622         ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
2623
2624         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
2625         return skb;
2626 }
2627
2628 static struct sk_buff *
2629 ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
2630 {
2631         struct wmi_request_stats_cmd *cmd;
2632         struct wmi_tlv *tlv;
2633         struct sk_buff *skb;
2634
2635         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2636         if (!skb)
2637                 return ERR_PTR(-ENOMEM);
2638
2639         tlv = (void *)skb->data;
2640         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
2641         tlv->len = __cpu_to_le16(sizeof(*cmd));
2642         cmd = (void *)tlv->value;
2643         cmd->stats_id = __cpu_to_le32(stats_mask);
2644
2645         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
2646         return skb;
2647 }
2648
2649 static int
2650 ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
2651                                        struct sk_buff *msdu)
2652 {
2653         struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
2654         struct ath10k_wmi *wmi = &ar->wmi;
2655
2656         idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
2657
2658         return 0;
2659 }
2660
2661 static int
2662 ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb,
2663                                  dma_addr_t paddr)
2664 {
2665         struct ath10k_wmi *wmi = &ar->wmi;
2666         struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
2667         int ret;
2668
2669         pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC);
2670         if (!pkt_addr)
2671                 return -ENOMEM;
2672
2673         pkt_addr->vaddr = skb;
2674         pkt_addr->paddr = paddr;
2675
2676         spin_lock_bh(&ar->data_lock);
2677         ret = idr_alloc(&wmi->mgmt_pending_tx, pkt_addr, 0,
2678                         wmi->mgmt_max_num_pending_tx, GFP_ATOMIC);
2679         spin_unlock_bh(&ar->data_lock);
2680
2681         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx alloc msdu_id ret %d\n", ret);
2682         return ret;
2683 }
2684
2685 static struct sk_buff *
2686 ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu,
2687                                    dma_addr_t paddr)
2688 {
2689         struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
2690         struct wmi_tlv_mgmt_tx_cmd *cmd;
2691         struct ieee80211_hdr *hdr;
2692         struct ath10k_vif *arvif;
2693         u32 buf_len = msdu->len;
2694         struct wmi_tlv *tlv;
2695         struct sk_buff *skb;
2696         int len, desc_id;
2697         u32 vdev_id;
2698         void *ptr;
2699
2700         if (!cb->vif)
2701                 return ERR_PTR(-EINVAL);
2702
2703         hdr = (struct ieee80211_hdr *)msdu->data;
2704         arvif = (void *)cb->vif->drv_priv;
2705         vdev_id = arvif->vdev_id;
2706
2707         if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
2708                 return ERR_PTR(-EINVAL);
2709
2710         len = sizeof(*cmd) + 2 * sizeof(*tlv);
2711
2712         if ((ieee80211_is_action(hdr->frame_control) ||
2713              ieee80211_is_deauth(hdr->frame_control) ||
2714              ieee80211_is_disassoc(hdr->frame_control)) &&
2715              ieee80211_has_protected(hdr->frame_control)) {
2716                 skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
2717                 buf_len += IEEE80211_CCMP_MIC_LEN;
2718         }
2719
2720         buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN);
2721         buf_len = round_up(buf_len, 4);
2722
2723         len += buf_len;
2724         len = round_up(len, 4);
2725         skb = ath10k_wmi_alloc_skb(ar, len);
2726         if (!skb)
2727                 return ERR_PTR(-ENOMEM);
2728
2729         desc_id = ath10k_wmi_mgmt_tx_alloc_msdu_id(ar, msdu, paddr);
2730         if (desc_id < 0)
2731                 goto err_free_skb;
2732
2733         cb->msdu_id = desc_id;
2734
2735         ptr = (void *)skb->data;
2736         tlv = ptr;
2737         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD);
2738         tlv->len = __cpu_to_le16(sizeof(*cmd));
2739         cmd = (void *)tlv->value;
2740         cmd->vdev_id = __cpu_to_le32(vdev_id);
2741         cmd->desc_id = __cpu_to_le32(desc_id);
2742         cmd->chanfreq = 0;
2743         cmd->buf_len = __cpu_to_le32(buf_len);
2744         cmd->frame_len = __cpu_to_le32(msdu->len);
2745         cmd->paddr = __cpu_to_le64(paddr);
2746
2747         ptr += sizeof(*tlv);
2748         ptr += sizeof(*cmd);
2749
2750         tlv = ptr;
2751         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2752         tlv->len = __cpu_to_le16(buf_len);
2753
2754         ptr += sizeof(*tlv);
2755         memcpy(ptr, msdu->data, buf_len);
2756
2757         return skb;
2758
2759 err_free_skb:
2760         dev_kfree_skb(skb);
2761         return ERR_PTR(desc_id);
2762 }
2763
2764 static struct sk_buff *
2765 ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
2766                                     enum wmi_force_fw_hang_type type,
2767                                     u32 delay_ms)
2768 {
2769         struct wmi_force_fw_hang_cmd *cmd;
2770         struct wmi_tlv *tlv;
2771         struct sk_buff *skb;
2772
2773         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2774         if (!skb)
2775                 return ERR_PTR(-ENOMEM);
2776
2777         tlv = (void *)skb->data;
2778         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
2779         tlv->len = __cpu_to_le16(sizeof(*cmd));
2780         cmd = (void *)tlv->value;
2781         cmd->type = __cpu_to_le32(type);
2782         cmd->delay_ms = __cpu_to_le32(delay_ms);
2783
2784         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
2785         return skb;
2786 }
2787
2788 static struct sk_buff *
2789 ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
2790                                  u32 log_level)
2791 {
2792         struct wmi_tlv_dbglog_cmd *cmd;
2793         struct wmi_tlv *tlv;
2794         struct sk_buff *skb;
2795         size_t len, bmap_len;
2796         u32 value;
2797         void *ptr;
2798
2799         if (module_enable) {
2800                 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
2801                                 module_enable,
2802                                 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
2803         } else {
2804                 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
2805                                 WMI_TLV_DBGLOG_ALL_MODULES,
2806                                 WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
2807         }
2808
2809         bmap_len = 0;
2810         len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
2811         skb = ath10k_wmi_alloc_skb(ar, len);
2812         if (!skb)
2813                 return ERR_PTR(-ENOMEM);
2814
2815         ptr = (void *)skb->data;
2816
2817         tlv = ptr;
2818         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
2819         tlv->len = __cpu_to_le16(sizeof(*cmd));
2820         cmd = (void *)tlv->value;
2821         cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
2822         cmd->value = __cpu_to_le32(value);
2823
2824         ptr += sizeof(*tlv);
2825         ptr += sizeof(*cmd);
2826
2827         tlv = ptr;
2828         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
2829         tlv->len = __cpu_to_le16(bmap_len);
2830
2831         /* nothing to do here */
2832
2833         ptr += sizeof(*tlv);
2834         ptr += sizeof(bmap_len);
2835
2836         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
2837         return skb;
2838 }
2839
2840 static struct sk_buff *
2841 ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
2842 {
2843         struct wmi_tlv_pktlog_enable *cmd;
2844         struct wmi_tlv *tlv;
2845         struct sk_buff *skb;
2846         void *ptr;
2847         size_t len;
2848
2849         len = sizeof(*tlv) + sizeof(*cmd);
2850         skb = ath10k_wmi_alloc_skb(ar, len);
2851         if (!skb)
2852                 return ERR_PTR(-ENOMEM);
2853
2854         ptr = (void *)skb->data;
2855         tlv = ptr;
2856         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
2857         tlv->len = __cpu_to_le16(sizeof(*cmd));
2858         cmd = (void *)tlv->value;
2859         cmd->filter = __cpu_to_le32(filter);
2860
2861         ptr += sizeof(*tlv);
2862         ptr += sizeof(*cmd);
2863
2864         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
2865                    filter);
2866         return skb;
2867 }
2868
2869 static struct sk_buff *
2870 ath10k_wmi_tlv_op_gen_pdev_get_temperature(struct ath10k *ar)
2871 {
2872         struct wmi_tlv_pdev_get_temp_cmd *cmd;
2873         struct wmi_tlv *tlv;
2874         struct sk_buff *skb;
2875
2876         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2877         if (!skb)
2878                 return ERR_PTR(-ENOMEM);
2879
2880         tlv = (void *)skb->data;
2881         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD);
2882         tlv->len = __cpu_to_le16(sizeof(*cmd));
2883         cmd = (void *)tlv->value;
2884         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature tlv\n");
2885         return skb;
2886 }
2887
2888 static struct sk_buff *
2889 ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
2890 {
2891         struct wmi_tlv_pktlog_disable *cmd;
2892         struct wmi_tlv *tlv;
2893         struct sk_buff *skb;
2894         void *ptr;
2895         size_t len;
2896
2897         len = sizeof(*tlv) + sizeof(*cmd);
2898         skb = ath10k_wmi_alloc_skb(ar, len);
2899         if (!skb)
2900                 return ERR_PTR(-ENOMEM);
2901
2902         ptr = (void *)skb->data;
2903         tlv = ptr;
2904         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
2905         tlv->len = __cpu_to_le16(sizeof(*cmd));
2906         cmd = (void *)tlv->value;
2907
2908         ptr += sizeof(*tlv);
2909         ptr += sizeof(*cmd);
2910
2911         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
2912         return skb;
2913 }
2914
2915 static struct sk_buff *
2916 ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
2917                                u32 tim_ie_offset, struct sk_buff *bcn,
2918                                u32 prb_caps, u32 prb_erp, void *prb_ies,
2919                                size_t prb_ies_len)
2920 {
2921         struct wmi_tlv_bcn_tmpl_cmd *cmd;
2922         struct wmi_tlv_bcn_prb_info *info;
2923         struct wmi_tlv *tlv;
2924         struct sk_buff *skb;
2925         void *ptr;
2926         size_t len;
2927
2928         if (WARN_ON(prb_ies_len > 0 && !prb_ies))
2929                 return ERR_PTR(-EINVAL);
2930
2931         len = sizeof(*tlv) + sizeof(*cmd) +
2932               sizeof(*tlv) + sizeof(*info) + prb_ies_len +
2933               sizeof(*tlv) + roundup(bcn->len, 4);
2934         skb = ath10k_wmi_alloc_skb(ar, len);
2935         if (!skb)
2936                 return ERR_PTR(-ENOMEM);
2937
2938         ptr = (void *)skb->data;
2939         tlv = ptr;
2940         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
2941         tlv->len = __cpu_to_le16(sizeof(*cmd));
2942         cmd = (void *)tlv->value;
2943         cmd->vdev_id = __cpu_to_le32(vdev_id);
2944         cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
2945         cmd->buf_len = __cpu_to_le32(bcn->len);
2946
2947         ptr += sizeof(*tlv);
2948         ptr += sizeof(*cmd);
2949
2950         /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
2951          * then it is then impossible to pass original ie len.
2952          * This chunk is not used yet so if setting probe resp template yields
2953          * problems with beaconing or crashes firmware look here.
2954          */
2955         tlv = ptr;
2956         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
2957         tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
2958         info = (void *)tlv->value;
2959         info->caps = __cpu_to_le32(prb_caps);
2960         info->erp = __cpu_to_le32(prb_erp);
2961         memcpy(info->ies, prb_ies, prb_ies_len);
2962
2963         ptr += sizeof(*tlv);
2964         ptr += sizeof(*info);
2965         ptr += prb_ies_len;
2966
2967         tlv = ptr;
2968         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2969         tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
2970         memcpy(tlv->value, bcn->data, bcn->len);
2971
2972         /* FIXME: Adjust TSF? */
2973
2974         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
2975                    vdev_id);
2976         return skb;
2977 }
2978
2979 static struct sk_buff *
2980 ath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id,
2981                                struct sk_buff *prb)
2982 {
2983         struct wmi_tlv_prb_tmpl_cmd *cmd;
2984         struct wmi_tlv_bcn_prb_info *info;
2985         struct wmi_tlv *tlv;
2986         struct sk_buff *skb;
2987         void *ptr;
2988         size_t len;
2989
2990         len = sizeof(*tlv) + sizeof(*cmd) +
2991               sizeof(*tlv) + sizeof(*info) +
2992               sizeof(*tlv) + roundup(prb->len, 4);
2993         skb = ath10k_wmi_alloc_skb(ar, len);
2994         if (!skb)
2995                 return ERR_PTR(-ENOMEM);
2996
2997         ptr = (void *)skb->data;
2998         tlv = ptr;
2999         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD);
3000         tlv->len = __cpu_to_le16(sizeof(*cmd));
3001         cmd = (void *)tlv->value;
3002         cmd->vdev_id = __cpu_to_le32(vdev_id);
3003         cmd->buf_len = __cpu_to_le32(prb->len);
3004
3005         ptr += sizeof(*tlv);
3006         ptr += sizeof(*cmd);
3007
3008         tlv = ptr;
3009         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
3010         tlv->len = __cpu_to_le16(sizeof(*info));
3011         info = (void *)tlv->value;
3012         info->caps = 0;
3013         info->erp = 0;
3014
3015         ptr += sizeof(*tlv);
3016         ptr += sizeof(*info);
3017
3018         tlv = ptr;
3019         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
3020         tlv->len = __cpu_to_le16(roundup(prb->len, 4));
3021         memcpy(tlv->value, prb->data, prb->len);
3022
3023         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n",
3024                    vdev_id);
3025         return skb;
3026 }
3027
3028 static struct sk_buff *
3029 ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
3030                                     const u8 *p2p_ie)
3031 {
3032         struct wmi_tlv_p2p_go_bcn_ie *cmd;
3033         struct wmi_tlv *tlv;
3034         struct sk_buff *skb;
3035         void *ptr;
3036         size_t len;
3037
3038         len = sizeof(*tlv) + sizeof(*cmd) +
3039               sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4);
3040         skb = ath10k_wmi_alloc_skb(ar, len);
3041         if (!skb)
3042                 return ERR_PTR(-ENOMEM);
3043
3044         ptr = (void *)skb->data;
3045         tlv = ptr;
3046         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE);
3047         tlv->len = __cpu_to_le16(sizeof(*cmd));
3048         cmd = (void *)tlv->value;
3049         cmd->vdev_id = __cpu_to_le32(vdev_id);
3050         cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2);
3051
3052         ptr += sizeof(*tlv);
3053         ptr += sizeof(*cmd);
3054
3055         tlv = ptr;
3056         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
3057         tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4));
3058         memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2);
3059
3060         ptr += sizeof(*tlv);
3061         ptr += roundup(p2p_ie[1] + 2, 4);
3062
3063         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n",
3064                    vdev_id);
3065         return skb;
3066 }
3067
3068 static struct sk_buff *
3069 ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
3070                                            enum wmi_tdls_state state)
3071 {
3072         struct wmi_tdls_set_state_cmd *cmd;
3073         struct wmi_tlv *tlv;
3074         struct sk_buff *skb;
3075         void *ptr;
3076         size_t len;
3077         /* Set to options from wmi_tlv_tdls_options,
3078          * for now none of them are enabled.
3079          */
3080         u32 options = 0;
3081
3082         if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
3083                 options |=  WMI_TLV_TDLS_BUFFER_STA_EN;
3084
3085         /* WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL means firm will handle TDLS
3086          * link inactivity detecting logic.
3087          */
3088         if (state == WMI_TDLS_ENABLE_ACTIVE)
3089                 state = WMI_TDLS_ENABLE_ACTIVE_EXTERNAL_CONTROL;
3090
3091         len = sizeof(*tlv) + sizeof(*cmd);
3092         skb = ath10k_wmi_alloc_skb(ar, len);
3093         if (!skb)
3094                 return ERR_PTR(-ENOMEM);
3095
3096         ptr = (void *)skb->data;
3097         tlv = ptr;
3098         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
3099         tlv->len = __cpu_to_le16(sizeof(*cmd));
3100
3101         cmd = (void *)tlv->value;
3102         cmd->vdev_id = __cpu_to_le32(vdev_id);
3103         cmd->state = __cpu_to_le32(state);
3104         cmd->notification_interval_ms = __cpu_to_le32(5000);
3105         cmd->tx_discovery_threshold = __cpu_to_le32(100);
3106         cmd->tx_teardown_threshold = __cpu_to_le32(5);
3107         cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
3108         cmd->rssi_delta = __cpu_to_le32(-20);
3109         cmd->tdls_options = __cpu_to_le32(options);
3110         cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
3111         cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
3112         cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
3113         cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
3114         cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
3115
3116         ptr += sizeof(*tlv);
3117         ptr += sizeof(*cmd);
3118
3119         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
3120                    state, vdev_id);
3121         return skb;
3122 }
3123
3124 static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
3125 {
3126         u32 peer_qos = 0;
3127
3128         if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
3129                 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
3130         if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
3131                 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
3132         if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
3133                 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
3134         if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
3135                 peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
3136
3137         peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
3138
3139         return peer_qos;
3140 }
3141
3142 static struct sk_buff *
3143 ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
3144                                        const struct wmi_tdls_peer_update_cmd_arg *arg,
3145                                        const struct wmi_tdls_peer_capab_arg *cap,
3146                                        const struct wmi_channel_arg *chan_arg)
3147 {
3148         struct wmi_tdls_peer_update_cmd *cmd;
3149         struct wmi_tdls_peer_capab *peer_cap;
3150         struct wmi_channel *chan;
3151         struct wmi_tlv *tlv;
3152         struct sk_buff *skb;
3153         u32 peer_qos;
3154         void *ptr;
3155         int len;
3156         int i;
3157
3158         len = sizeof(*tlv) + sizeof(*cmd) +
3159               sizeof(*tlv) + sizeof(*peer_cap) +
3160               sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
3161
3162         skb = ath10k_wmi_alloc_skb(ar, len);
3163         if (!skb)
3164                 return ERR_PTR(-ENOMEM);
3165
3166         ptr = (void *)skb->data;
3167         tlv = ptr;
3168         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
3169         tlv->len = __cpu_to_le16(sizeof(*cmd));
3170
3171         cmd = (void *)tlv->value;
3172         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
3173         ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
3174         cmd->peer_state = __cpu_to_le32(arg->peer_state);
3175
3176         ptr += sizeof(*tlv);
3177         ptr += sizeof(*cmd);
3178
3179         tlv = ptr;
3180         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
3181         tlv->len = __cpu_to_le16(sizeof(*peer_cap));
3182         peer_cap = (void *)tlv->value;
3183         peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
3184                                                    cap->peer_max_sp);
3185         peer_cap->peer_qos = __cpu_to_le32(peer_qos);
3186         peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
3187         peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
3188         peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
3189         peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
3190         peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
3191         peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
3192
3193         for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
3194                 peer_cap->peer_operclass[i] = cap->peer_operclass[i];
3195
3196         peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
3197         peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
3198         peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
3199
3200         ptr += sizeof(*tlv);
3201         ptr += sizeof(*peer_cap);
3202
3203         tlv = ptr;
3204         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
3205         tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
3206
3207         ptr += sizeof(*tlv);
3208
3209         for (i = 0; i < cap->peer_chan_len; i++) {
3210                 tlv = ptr;
3211                 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
3212                 tlv->len = __cpu_to_le16(sizeof(*chan));
3213                 chan = (void *)tlv->value;
3214                 ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
3215
3216                 ptr += sizeof(*tlv);
3217                 ptr += sizeof(*chan);
3218         }
3219
3220         ath10k_dbg(ar, ATH10K_DBG_WMI,
3221                    "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
3222                    arg->vdev_id, arg->peer_state, cap->peer_chan_len);
3223         return skb;
3224 }
3225
3226 static struct sk_buff *
3227 ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
3228                                           u32 duration, u32 next_offset,
3229                                           u32 enabled)
3230 {
3231         struct wmi_tlv_set_quiet_cmd *cmd;
3232         struct wmi_tlv *tlv;
3233         struct sk_buff *skb;
3234
3235         skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
3236         if (!skb)
3237                 return ERR_PTR(-ENOMEM);
3238
3239         tlv = (void *)skb->data;
3240         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD);
3241         tlv->len = __cpu_to_le16(sizeof(*cmd));
3242         cmd = (void *)tlv->value;
3243
3244         /* vdev_id is not in use, set to 0 */
3245         cmd->vdev_id = __cpu_to_le32(0);
3246         cmd->period = __cpu_to_le32(period);
3247         cmd->duration = __cpu_to_le32(duration);
3248         cmd->next_start = __cpu_to_le32(next_offset);
3249         cmd->enabled = __cpu_to_le32(enabled);
3250
3251         ath10k_dbg(ar, ATH10K_DBG_WMI,
3252                    "wmi tlv quiet param: period %u duration %u enabled %d\n",
3253                    period, duration, enabled);
3254         return skb;
3255 }
3256
3257 static struct sk_buff *
3258 ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
3259 {
3260         struct wmi_tlv_wow_enable_cmd *cmd;
3261         struct wmi_tlv *tlv;
3262         struct sk_buff *skb;
3263         size_t len;
3264
3265         len = sizeof(*tlv) + sizeof(*cmd);
3266         skb = ath10k_wmi_alloc_skb(ar, len);
3267         if (!skb)
3268                 return ERR_PTR(-ENOMEM);
3269
3270         tlv = (struct wmi_tlv *)skb->data;
3271         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD);
3272         tlv->len = __cpu_to_le16(sizeof(*cmd));
3273         cmd = (void *)tlv->value;
3274
3275         cmd->enable = __cpu_to_le32(1);
3276
3277         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
3278         return skb;
3279 }
3280
3281 static struct sk_buff *
3282 ath10k_wmi_tlv_op_gen_wow_add_wakeup_event(struct ath10k *ar,
3283                                            u32 vdev_id,
3284                                            enum wmi_wow_wakeup_event event,
3285                                            u32 enable)
3286 {
3287         struct wmi_tlv_wow_add_del_event_cmd *cmd;
3288         struct wmi_tlv *tlv;
3289         struct sk_buff *skb;
3290         size_t len;
3291
3292         len = sizeof(*tlv) + sizeof(*cmd);
3293         skb = ath10k_wmi_alloc_skb(ar, len);
3294         if (!skb)
3295                 return ERR_PTR(-ENOMEM);
3296
3297         tlv = (struct wmi_tlv *)skb->data;
3298         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD);
3299         tlv->len = __cpu_to_le16(sizeof(*cmd));
3300         cmd = (void *)tlv->value;
3301
3302         cmd->vdev_id = __cpu_to_le32(vdev_id);
3303         cmd->is_add = __cpu_to_le32(enable);
3304         cmd->event_bitmap = __cpu_to_le32(1 << event);
3305
3306         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n",
3307                    wow_wakeup_event(event), enable, vdev_id);
3308         return skb;
3309 }
3310
3311 static struct sk_buff *
3312 ath10k_wmi_tlv_gen_wow_host_wakeup_ind(struct ath10k *ar)
3313 {
3314         struct wmi_tlv_wow_host_wakeup_ind *cmd;
3315         struct wmi_tlv *tlv;
3316         struct sk_buff *skb;
3317         size_t len;
3318
3319         len = sizeof(*tlv) + sizeof(*cmd);
3320         skb = ath10k_wmi_alloc_skb(ar, len);
3321         if (!skb)
3322                 return ERR_PTR(-ENOMEM);
3323
3324         tlv = (struct wmi_tlv *)skb->data;
3325         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD);
3326         tlv->len = __cpu_to_le16(sizeof(*cmd));
3327         cmd = (void *)tlv->value;
3328
3329         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow host wakeup ind\n");
3330         return skb;
3331 }
3332
3333 static struct sk_buff *
3334 ath10k_wmi_tlv_op_gen_wow_add_pattern(struct ath10k *ar, u32 vdev_id,
3335                                       u32 pattern_id, const u8 *pattern,
3336                                       const u8 *bitmask, int pattern_len,
3337                                       int pattern_offset)
3338 {
3339         struct wmi_tlv_wow_add_pattern_cmd *cmd;
3340         struct wmi_tlv_wow_bitmap_pattern *bitmap;
3341         struct wmi_tlv *tlv;
3342         struct sk_buff *skb;
3343         void *ptr;
3344         size_t len;
3345
3346         len = sizeof(*tlv) + sizeof(*cmd) +
3347               sizeof(*tlv) +                    /* array struct */
3348               sizeof(*tlv) + sizeof(*bitmap) +  /* bitmap */
3349               sizeof(*tlv) +                    /* empty ipv4 sync */
3350               sizeof(*tlv) +                    /* empty ipv6 sync */
3351               sizeof(*tlv) +                    /* empty magic */
3352               sizeof(*tlv) +                    /* empty info timeout */
3353               sizeof(*tlv) + sizeof(u32);       /* ratelimit interval */
3354
3355         skb = ath10k_wmi_alloc_skb(ar, len);
3356         if (!skb)
3357                 return ERR_PTR(-ENOMEM);
3358
3359         /* cmd */
3360         ptr = (void *)skb->data;
3361         tlv = ptr;
3362         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD);
3363         tlv->len = __cpu_to_le16(sizeof(*cmd));
3364         cmd = (void *)tlv->value;
3365
3366         cmd->vdev_id = __cpu_to_le32(vdev_id);
3367         cmd->pattern_id = __cpu_to_le32(pattern_id);
3368         cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
3369
3370         ptr += sizeof(*tlv);
3371         ptr += sizeof(*cmd);
3372
3373         /* bitmap */
3374         tlv = ptr;
3375         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
3376         tlv->len = __cpu_to_le16(sizeof(*tlv) + sizeof(*bitmap));
3377
3378         ptr += sizeof(*tlv);
3379
3380         tlv = ptr;
3381         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T);
3382         tlv->len = __cpu_to_le16(sizeof(*bitmap));
3383         bitmap = (void *)tlv->value;
3384
3385         memcpy(bitmap->patternbuf, pattern, pattern_len);
3386         memcpy(bitmap->bitmaskbuf, bitmask, pattern_len);
3387         bitmap->pattern_offset = __cpu_to_le32(pattern_offset);
3388         bitmap->pattern_len = __cpu_to_le32(pattern_len);
3389         bitmap->bitmask_len = __cpu_to_le32(pattern_len);
3390         bitmap->pattern_id = __cpu_to_le32(pattern_id);
3391
3392         ptr += sizeof(*tlv);
3393         ptr += sizeof(*bitmap);
3394
3395         /* ipv4 sync */
3396         tlv = ptr;
3397         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
3398         tlv->len = __cpu_to_le16(0);
3399
3400         ptr += sizeof(*tlv);
3401
3402         /* ipv6 sync */
3403         tlv = ptr;
3404         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
3405         tlv->len = __cpu_to_le16(0);
3406
3407         ptr += sizeof(*tlv);
3408
3409         /* magic */
3410         tlv = ptr;
3411         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
3412         tlv->len = __cpu_to_le16(0);
3413
3414         ptr += sizeof(*tlv);
3415
3416         /* pattern info timeout */
3417         tlv = ptr;
3418         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
3419         tlv->len = __cpu_to_le16(0);
3420
3421         ptr += sizeof(*tlv);
3422
3423         /* ratelimit interval */
3424         tlv = ptr;
3425         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
3426         tlv->len = __cpu_to_le16(sizeof(u32));
3427
3428         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow add pattern vdev_id %d pattern_id %d, pattern_offset %d\n",
3429                    vdev_id, pattern_id, pattern_offset);
3430         return skb;
3431 }
3432
3433 static struct sk_buff *
3434 ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id,
3435                                       u32 pattern_id)
3436 {
3437         struct wmi_tlv_wow_del_pattern_cmd *cmd;
3438         struct wmi_tlv *tlv;
3439         struct sk_buff *skb;
3440         size_t len;
3441
3442         len = sizeof(*tlv) + sizeof(*cmd);
3443         skb = ath10k_wmi_alloc_skb(ar, len);
3444         if (!skb)
3445                 return ERR_PTR(-ENOMEM);
3446
3447         tlv = (struct wmi_tlv *)skb->data;
3448         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD);
3449         tlv->len = __cpu_to_le16(sizeof(*cmd));
3450         cmd = (void *)tlv->value;
3451
3452         cmd->vdev_id = __cpu_to_le32(vdev_id);
3453         cmd->pattern_id = __cpu_to_le32(pattern_id);
3454         cmd->pattern_type = __cpu_to_le32(WOW_BITMAP_PATTERN);
3455
3456         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n",
3457                    vdev_id, pattern_id);
3458         return skb;
3459 }
3460
3461 static struct sk_buff *
3462 ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable)
3463 {
3464         struct wmi_tlv_adaptive_qcs *cmd;
3465         struct wmi_tlv *tlv;
3466         struct sk_buff *skb;
3467         void *ptr;
3468         size_t len;
3469
3470         len = sizeof(*tlv) + sizeof(*cmd);
3471         skb = ath10k_wmi_alloc_skb(ar, len);
3472         if (!skb)
3473                 return ERR_PTR(-ENOMEM);
3474
3475         ptr = (void *)skb->data;
3476         tlv = ptr;
3477         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD);
3478         tlv->len = __cpu_to_le16(sizeof(*cmd));
3479         cmd = (void *)tlv->value;
3480         cmd->enable = __cpu_to_le32(enable ? 1 : 0);
3481
3482         ptr += sizeof(*tlv);
3483         ptr += sizeof(*cmd);
3484
3485         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv adaptive qcs %d\n", enable);
3486         return skb;
3487 }
3488
3489 static struct sk_buff *
3490 ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
3491 {
3492         struct wmi_echo_cmd *cmd;
3493         struct wmi_tlv *tlv;
3494         struct sk_buff *skb;
3495         void *ptr;
3496         size_t len;
3497
3498         len = sizeof(*tlv) + sizeof(*cmd);
3499         skb = ath10k_wmi_alloc_skb(ar, len);
3500         if (!skb)
3501                 return ERR_PTR(-ENOMEM);
3502
3503         ptr = (void *)skb->data;
3504         tlv = ptr;
3505         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD);
3506         tlv->len = __cpu_to_le16(sizeof(*cmd));
3507         cmd = (void *)tlv->value;
3508         cmd->value = cpu_to_le32(value);
3509
3510         ptr += sizeof(*tlv);
3511         ptr += sizeof(*cmd);
3512
3513         ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value);
3514         return skb;
3515 }
3516
3517 static struct sk_buff *
3518 ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
3519                                          const struct wmi_vdev_spectral_conf_arg *arg)
3520 {
3521         struct wmi_vdev_spectral_conf_cmd *cmd;
3522         struct sk_buff *skb;
3523         struct wmi_tlv *tlv;
3524         void *ptr;
3525         size_t len;
3526
3527         len = sizeof(*tlv) + sizeof(*cmd);
3528         skb = ath10k_wmi_alloc_skb(ar, len);
3529         if (!skb)
3530                 return ERR_PTR(-ENOMEM);
3531
3532         ptr = (void *)skb->data;
3533         tlv = ptr;
3534         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
3535         tlv->len = __cpu_to_le16(sizeof(*cmd));
3536         cmd = (void *)tlv->value;
3537         cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
3538         cmd->scan_count = __cpu_to_le32(arg->scan_count);
3539         cmd->scan_period = __cpu_to_le32(arg->scan_period);
3540         cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
3541         cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
3542         cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
3543         cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
3544         cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
3545         cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
3546         cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
3547         cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
3548         cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
3549         cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
3550         cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
3551         cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
3552         cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
3553         cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
3554         cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
3555         cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
3556
3557         return skb;
3558 }
3559
3560 static struct sk_buff *
3561 ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
3562                                            u32 trigger, u32 enable)
3563 {
3564         struct wmi_vdev_spectral_enable_cmd *cmd;
3565         struct sk_buff *skb;
3566         struct wmi_tlv *tlv;
3567         void *ptr;
3568         size_t len;
3569
3570         len = sizeof(*tlv) + sizeof(*cmd);
3571         skb = ath10k_wmi_alloc_skb(ar, len);
3572         if (!skb)
3573                 return ERR_PTR(-ENOMEM);
3574
3575         ptr = (void *)skb->data;
3576         tlv = ptr;
3577         tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
3578         tlv->len = __cpu_to_le16(sizeof(*cmd));
3579         cmd = (void *)tlv->value;
3580         cmd->vdev_id = __cpu_to_le32(vdev_id);
3581         cmd->trigger_cmd = __cpu_to_le32(trigger);
3582         cmd->enable_cmd = __cpu_to_le32(enable);
3583
3584         return skb;
3585 }
3586
3587 /****************/
3588 /* TLV mappings */
3589 /****************/
3590
3591 static struct wmi_cmd_map wmi_tlv_cmd_map = {
3592         .init_cmdid = WMI_TLV_INIT_CMDID,
3593         .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
3594         .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
3595         .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
3596         .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
3597         .scan_prob_req_oui_cmdid = WMI_TLV_SCAN_PROB_REQ_OUI_CMDID,
3598         .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
3599         .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
3600         .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
3601         .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
3602         .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
3603         .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
3604         .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
3605         .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
3606         .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
3607         .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
3608         .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
3609         .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
3610         .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
3611         .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
3612         .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
3613         .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
3614         .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
3615         .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
3616         .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
3617         .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
3618         .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
3619         .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
3620         .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
3621         .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
3622         .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
3623         .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
3624         .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
3625         .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
3626         .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
3627         .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
3628         .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
3629         .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
3630         .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
3631         .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
3632         .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
3633         .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
3634         .mgmt_tx_send_cmdid = WMI_TLV_MGMT_TX_SEND_CMD,
3635         .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
3636         .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
3637         .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
3638         .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
3639         .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
3640         .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
3641         .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
3642         .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
3643         .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
3644         .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
3645         .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
3646         .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
3647         .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
3648         .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
3649         .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
3650         .roam_scan_rssi_change_threshold =
3651                                 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
3652         .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
3653         .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
3654         .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
3655         .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
3656         .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
3657         .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
3658         .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
3659         .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
3660         .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
3661         .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
3662         .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
3663         .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
3664         .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
3665         .wlan_profile_set_hist_intvl_cmdid =
3666                                 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
3667         .wlan_profile_get_profile_data_cmdid =
3668                                 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3669         .wlan_profile_enable_profile_id_cmdid =
3670                                 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
3671         .wlan_profile_list_profile_id_cmdid =
3672                                 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
3673         .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
3674         .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
3675         .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
3676         .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
3677         .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
3678         .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
3679         .wow_enable_disable_wake_event_cmdid =
3680                                 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
3681         .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
3682         .wow_hostwakeup_from_sleep_cmdid =
3683                                 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
3684         .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
3685         .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
3686         .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
3687         .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
3688         .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
3689         .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
3690         .network_list_offload_config_cmdid =
3691                                 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
3692         .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
3693         .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
3694         .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
3695         .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
3696         .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
3697         .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
3698         .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
3699         .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
3700         .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
3701         .echo_cmdid = WMI_TLV_ECHO_CMDID,
3702         .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
3703         .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
3704         .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
3705         .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
3706         .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
3707         .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
3708         .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
3709         .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
3710         .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
3711         .pdev_get_temperature_cmdid = WMI_TLV_PDEV_GET_TEMPERATURE_CMDID,
3712         .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
3713         .tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
3714         .tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
3715         .adaptive_qcs_cmdid = WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID,
3716         .scan_update_request_cmdid = WMI_CMD_UNSUPPORTED,
3717         .vdev_standby_response_cmdid = WMI_CMD_UNSUPPORTED,
3718         .vdev_resume_response_cmdid = WMI_CMD_UNSUPPORTED,
3719         .wlan_peer_caching_add_peer_cmdid = WMI_CMD_UNSUPPORTED,
3720         .wlan_peer_caching_evict_peer_cmdid = WMI_CMD_UNSUPPORTED,
3721         .wlan_peer_caching_restore_peer_cmdid = WMI_CMD_UNSUPPORTED,
3722         .wlan_peer_caching_print_all_peers_info_cmdid = WMI_CMD_UNSUPPORTED,
3723         .peer_update_wds_entry_cmdid = WMI_CMD_UNSUPPORTED,
3724         .peer_add_proxy_sta_entry_cmdid = WMI_CMD_UNSUPPORTED,
3725         .rtt_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
3726         .oem_req_cmdid = WMI_CMD_UNSUPPORTED,
3727         .nan_cmdid = WMI_CMD_UNSUPPORTED,
3728         .vdev_ratemask_cmdid = WMI_CMD_UNSUPPORTED,
3729         .qboost_cfg_cmdid = WMI_CMD_UNSUPPORTED,
3730         .pdev_smart_ant_enable_cmdid = WMI_CMD_UNSUPPORTED,
3731         .pdev_smart_ant_set_rx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
3732         .peer_smart_ant_set_tx_antenna_cmdid = WMI_CMD_UNSUPPORTED,
3733         .peer_smart_ant_set_train_info_cmdid = WMI_CMD_UNSUPPORTED,
3734         .peer_smart_ant_set_node_config_ops_cmdid = WMI_CMD_UNSUPPORTED,
3735         .pdev_set_antenna_switch_table_cmdid = WMI_CMD_UNSUPPORTED,
3736         .pdev_set_ctl_table_cmdid = WMI_CMD_UNSUPPORTED,
3737         .pdev_set_mimogain_table_cmdid = WMI_CMD_UNSUPPORTED,
3738         .pdev_ratepwr_table_cmdid = WMI_CMD_UNSUPPORTED,
3739         .pdev_ratepwr_chainmsk_table_cmdid = WMI_CMD_UNSUPPORTED,
3740         .pdev_fips_cmdid = WMI_CMD_UNSUPPORTED,
3741         .tt_set_conf_cmdid = WMI_CMD_UNSUPPORTED,
3742         .fwtest_cmdid = WMI_CMD_UNSUPPORTED,
3743         .vdev_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
3744         .peer_atf_request_cmdid = WMI_CMD_UNSUPPORTED,
3745         .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
3746         .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
3747         .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
3748 };
3749
3750 static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
3751         .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
3752         .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
3753         .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
3754         .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
3755         .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
3756         .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
3757         .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
3758         .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
3759         .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
3760         .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
3761         .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
3762         .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
3763         .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
3764         .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
3765         .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
3766         .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
3767         .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
3768         .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
3769         .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
3770         .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
3771         .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
3772         .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
3773         .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
3774         .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
3775         .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
3776         .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
3777         .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
3778         .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
3779         .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
3780         .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
3781         .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
3782         .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
3783         .bcnflt_stats_update_period =
3784                                 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
3785         .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
3786         .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
3787         .dcs = WMI_TLV_PDEV_PARAM_DCS,
3788         .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
3789         .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
3790         .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
3791         .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
3792         .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
3793         .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
3794         .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
3795         .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
3796         .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
3797         .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
3798         .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
3799         .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
3800         .cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
3801         .aggr_burst = WMI_PDEV_PARAM_UNSUPPORTED,
3802         .rx_decap_mode = WMI_PDEV_PARAM_UNSUPPORTED,
3803         .smart_antenna_default_antenna = WMI_PDEV_PARAM_UNSUPPORTED,
3804         .igmpmld_override = WMI_PDEV_PARAM_UNSUPPORTED,
3805         .igmpmld_tid = WMI_PDEV_PARAM_UNSUPPORTED,
3806         .antenna_gain = WMI_PDEV_PARAM_UNSUPPORTED,
3807         .rx_filter = WMI_PDEV_PARAM_UNSUPPORTED,
3808         .set_mcast_to_ucast_tid = WMI_PDEV_PARAM_UNSUPPORTED,
3809         .proxy_sta_mode = WMI_PDEV_PARAM_UNSUPPORTED,
3810         .set_mcast2ucast_mode = WMI_PDEV_PARAM_UNSUPPORTED,
3811         .set_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
3812         .remove_mcast2ucast_buffer = WMI_PDEV_PARAM_UNSUPPORTED,
3813         .peer_sta_ps_statechg_enable = WMI_PDEV_PARAM_UNSUPPORTED,
3814         .igmpmld_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
3815         .block_interbss = WMI_PDEV_PARAM_UNSUPPORTED,
3816         .set_disable_reset_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3817         .set_msdu_ttl_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3818         .set_ppdu_duration_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3819         .txbf_sound_period_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3820         .set_promisc_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3821         .set_burst_mode_cmdid = WMI_PDEV_PARAM_UNSUPPORTED,
3822         .en_stats = WMI_PDEV_PARAM_UNSUPPORTED,
3823         .mu_group_policy = WMI_PDEV_PARAM_UNSUPPORTED,
3824         .noise_detection = WMI_PDEV_PARAM_UNSUPPORTED,
3825         .noise_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
3826         .dpd_enable = WMI_PDEV_PARAM_UNSUPPORTED,
3827         .set_mcast_bcast_echo = WMI_PDEV_PARAM_UNSUPPORTED,
3828         .atf_strict_sch = WMI_PDEV_PARAM_UNSUPPORTED,
3829         .atf_sched_duration = WMI_PDEV_PARAM_UNSUPPORTED,
3830         .ant_plzn = WMI_PDEV_PARAM_UNSUPPORTED,
3831         .mgmt_retry_limit = WMI_PDEV_PARAM_UNSUPPORTED,
3832         .sensitivity_level = WMI_PDEV_PARAM_UNSUPPORTED,
3833         .signed_txpower_2g = WMI_PDEV_PARAM_UNSUPPORTED,
3834         .signed_txpower_5g = WMI_PDEV_PARAM_UNSUPPORTED,
3835         .enable_per_tid_amsdu = WMI_PDEV_PARAM_UNSUPPORTED,
3836         .enable_per_tid_ampdu = WMI_PDEV_PARAM_UNSUPPORTED,
3837         .cca_threshold = WMI_PDEV_PARAM_UNSUPPORTED,
3838         .rts_fixed_rate = WMI_PDEV_PARAM_UNSUPPORTED,
3839         .pdev_reset = WMI_PDEV_PARAM_UNSUPPORTED,
3840         .wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED,
3841         .arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED,
3842         .arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED,
3843 };
3844
3845 static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
3846         .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
3847         .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
3848         .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
3849         .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
3850         .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
3851         .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
3852         .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
3853         .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
3854         .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
3855         .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
3856         .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
3857         .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
3858         .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
3859         .wmi_vdev_oc_scheduler_air_time_limit =
3860                                 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
3861         .wds = WMI_TLV_VDEV_PARAM_WDS,
3862         .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
3863         .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
3864         .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
3865         .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
3866         .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
3867         .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
3868         .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
3869         .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
3870         .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
3871         .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
3872         .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
3873         .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
3874         .sgi = WMI_TLV_VDEV_PARAM_SGI,
3875         .ldpc = WMI_TLV_VDEV_PARAM_LDPC,
3876         .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
3877         .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
3878         .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
3879         .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
3880         .nss = WMI_TLV_VDEV_PARAM_NSS,
3881         .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
3882         .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
3883         .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
3884         .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
3885         .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
3886         .ap_keepalive_min_idle_inactive_time_secs =
3887                 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
3888         .ap_keepalive_max_idle_inactive_time_secs =
3889                 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
3890         .ap_keepalive_max_unresponsive_time_secs =
3891                 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
3892         .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
3893         .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
3894         .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
3895         .txbf = WMI_TLV_VDEV_PARAM_TXBF,
3896         .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
3897         .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
3898         .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
3899         .ap_detect_out_of_sync_sleeping_sta_time_secs =
3900                                         WMI_TLV_VDEV_PARAM_UNSUPPORTED,
3901         .rc_num_retries = WMI_VDEV_PARAM_UNSUPPORTED,
3902         .cabq_maxdur = WMI_VDEV_PARAM_UNSUPPORTED,
3903         .mfptest_set = WMI_VDEV_PARAM_UNSUPPORTED,
3904         .rts_fixed_rate = WMI_VDEV_PARAM_UNSUPPORTED,
3905         .vht_sgimask = WMI_VDEV_PARAM_UNSUPPORTED,
3906         .vht80_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
3907         .early_rx_adjust_enable = WMI_VDEV_PARAM_UNSUPPORTED,
3908         .early_rx_tgt_bmiss_num = WMI_VDEV_PARAM_UNSUPPORTED,
3909         .early_rx_bmiss_sample_cycle = WMI_VDEV_PARAM_UNSUPPORTED,
3910         .early_rx_slop_step = WMI_VDEV_PARAM_UNSUPPORTED,
3911         .early_rx_init_slop = WMI_VDEV_PARAM_UNSUPPORTED,
3912         .early_rx_adjust_pause = WMI_VDEV_PARAM_UNSUPPORTED,
3913         .proxy_sta = WMI_VDEV_PARAM_UNSUPPORTED,
3914         .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
3915         .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
3916         .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
3917 };
3918
3919 static const struct wmi_ops wmi_tlv_ops = {
3920         .rx = ath10k_wmi_tlv_op_rx,
3921         .map_svc = wmi_tlv_svc_map,
3922         .map_svc_ext = wmi_tlv_svc_map_ext,
3923
3924         .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
3925         .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
3926         .pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev,
3927         .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
3928         .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
3929         .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
3930         .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
3931         .pull_phyerr_hdr = ath10k_wmi_tlv_op_pull_phyerr_ev_hdr,
3932         .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
3933         .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
3934         .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
3935         .pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail,
3936         .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
3937         .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
3938         .pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev,
3939         .pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev,
3940         .get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme,
3941
3942         .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
3943         .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
3944         .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
3945         .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
3946         .gen_init = ath10k_wmi_tlv_op_gen_init,
3947         .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
3948         .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
3949         .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
3950         .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
3951         .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
3952         .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
3953         .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
3954         .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
3955         .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
3956         .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
3957         .gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf,
3958         .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
3959         .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
3960         .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
3961         .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
3962         .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
3963         .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
3964         .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
3965         .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
3966         .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
3967         .gen_scan_prob_req_oui = ath10k_wmi_tlv_op_gen_scan_prob_req_oui,
3968         .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
3969         .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
3970         .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
3971         .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
3972         /* .gen_mgmt_tx = not implemented; HTT is used */
3973         .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send,
3974         .cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send,
3975         .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
3976         .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
3977         .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
3978         .gen_pdev_set_quiet_mode = ath10k_wmi_tlv_op_gen_pdev_set_quiet_mode,
3979         .gen_pdev_get_temperature = ath10k_wmi_tlv_op_gen_pdev_get_temperature,
3980         /* .gen_addba_clear_resp not implemented */
3981         /* .gen_addba_send not implemented */
3982         /* .gen_addba_set_resp not implemented */
3983         /* .gen_delba_send not implemented */
3984         .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
3985         .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl,
3986         .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
3987         .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
3988         .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
3989         .gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable,
3990         .gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event,
3991         .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,
3992         .gen_wow_add_pattern = ath10k_wmi_tlv_op_gen_wow_add_pattern,
3993         .gen_wow_del_pattern = ath10k_wmi_tlv_op_gen_wow_del_pattern,
3994         .gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
3995         .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
3996         .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
3997         .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
3998         .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
3999         .gen_echo = ath10k_wmi_tlv_op_gen_echo,
4000         .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
4001         .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
4002 };
4003
4004 static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
4005         .auth = WMI_TLV_PEER_AUTH,
4006         .qos = WMI_TLV_PEER_QOS,
4007         .need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY,
4008         .need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY,
4009         .apsd = WMI_TLV_PEER_APSD,
4010         .ht = WMI_TLV_PEER_HT,
4011         .bw40 = WMI_TLV_PEER_40MHZ,
4012         .stbc = WMI_TLV_PEER_STBC,
4013         .ldbc = WMI_TLV_PEER_LDPC,
4014         .dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS,
4015         .static_mimops = WMI_TLV_PEER_STATIC_MIMOPS,
4016         .spatial_mux = WMI_TLV_PEER_SPATIAL_MUX,
4017         .vht = WMI_TLV_PEER_VHT,
4018         .bw80 = WMI_TLV_PEER_80MHZ,
4019         .pmf = WMI_TLV_PEER_PMF,
4020         .bw160 = WMI_TLV_PEER_160MHZ,
4021 };
4022
4023 /************/
4024 /* TLV init */
4025 /************/
4026
4027 void ath10k_wmi_tlv_attach(struct ath10k *ar)
4028 {
4029         ar->wmi.cmd = &wmi_tlv_cmd_map;
4030         ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
4031         ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
4032         ar->wmi.ops = &wmi_tlv_ops;
4033         ar->wmi.peer_flags = &wmi_tlv_peer_flags_map;
4034 }