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