blob: 08a9b2b35d067d587be8f886129d7f7464a13e12 [file] [log] [blame]
Michal Kaziorca996ec2014-12-03 10:11:32 +02001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#include "core.h"
18#include "debug.h"
19#include "hw.h"
20#include "wmi.h"
21#include "wmi-ops.h"
22#include "wmi-tlv.h"
23
24/***************/
25/* TLV helpers */
26/**************/
27
28struct wmi_tlv_policy {
29 size_t min_len;
30};
31
32static const struct wmi_tlv_policy wmi_tlv_policies[] = {
33 [WMI_TLV_TAG_ARRAY_BYTE]
34 = { .min_len = sizeof(u8) },
35 [WMI_TLV_TAG_ARRAY_UINT32]
36 = { .min_len = sizeof(u32) },
37 [WMI_TLV_TAG_STRUCT_SCAN_EVENT]
38 = { .min_len = sizeof(struct wmi_scan_event) },
39 [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]
40 = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) },
41 [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]
42 = { .min_len = sizeof(struct wmi_chan_info_event) },
43 [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]
44 = { .min_len = sizeof(struct wmi_vdev_start_response_event) },
45 [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]
46 = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
47 [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT]
48 = { .min_len = sizeof(struct wmi_host_swba_event) },
49 [WMI_TLV_TAG_STRUCT_TIM_INFO]
50 = { .min_len = sizeof(struct wmi_tim_info) },
51 [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]
52 = { .min_len = sizeof(struct wmi_p2p_noa_info) },
53 [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]
54 = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) },
55 [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]
56 = { .min_len = sizeof(struct hal_reg_capabilities) },
57 [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ]
58 = { .min_len = sizeof(struct wlan_host_mem_req) },
59 [WMI_TLV_TAG_STRUCT_READY_EVENT]
60 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
Michal Kazior6bf12062015-01-13 16:30:10 +020061 [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
62 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
Michal Kaziorca996ec2014-12-03 10:11:32 +020063};
64
65static int
66ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
67 int (*iter)(struct ath10k *ar, u16 tag, u16 len,
68 const void *ptr, void *data),
69 void *data)
70{
71 const void *begin = ptr;
72 const struct wmi_tlv *tlv;
73 u16 tlv_tag, tlv_len;
74 int ret;
75
76 while (len > 0) {
77 if (len < sizeof(*tlv)) {
78 ath10k_dbg(ar, ATH10K_DBG_WMI,
79 "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
80 ptr - begin, len, sizeof(*tlv));
81 return -EINVAL;
82 }
83
84 tlv = ptr;
85 tlv_tag = __le16_to_cpu(tlv->tag);
86 tlv_len = __le16_to_cpu(tlv->len);
87 ptr += sizeof(*tlv);
88 len -= sizeof(*tlv);
89
90 if (tlv_len > len) {
91 ath10k_dbg(ar, ATH10K_DBG_WMI,
92 "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n",
93 tlv_tag, ptr - begin, len, tlv_len);
94 return -EINVAL;
95 }
96
97 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
98 wmi_tlv_policies[tlv_tag].min_len &&
99 wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
100 ath10k_dbg(ar, ATH10K_DBG_WMI,
101 "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n",
102 tlv_tag, ptr - begin, tlv_len,
103 wmi_tlv_policies[tlv_tag].min_len);
104 return -EINVAL;
105 }
106
107 ret = iter(ar, tlv_tag, tlv_len, ptr, data);
108 if (ret)
109 return ret;
110
111 ptr += tlv_len;
112 len -= tlv_len;
113 }
114
115 return 0;
116}
117
118static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
119 const void *ptr, void *data)
120{
121 const void **tb = data;
122
123 if (tag < WMI_TLV_TAG_MAX)
124 tb[tag] = ptr;
125
126 return 0;
127}
128
129static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
130 const void *ptr, size_t len)
131{
132 return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
133 (void *)tb);
134}
135
136static const void **
137ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
138 size_t len, gfp_t gfp)
139{
140 const void **tb;
141 int ret;
142
143 tb = kzalloc(sizeof(*tb) * WMI_TLV_TAG_MAX, gfp);
144 if (!tb)
145 return ERR_PTR(-ENOMEM);
146
147 ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
148 if (ret) {
149 kfree(tb);
150 return ERR_PTR(ret);
151 }
152
153 return tb;
154}
155
156static u16 ath10k_wmi_tlv_len(const void *ptr)
157{
158 return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
159}
160
Michal Kazior6bf12062015-01-13 16:30:10 +0200161/**************/
162/* TLV events */
163/**************/
164static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
165 struct sk_buff *skb)
166{
167 const void **tb;
168 const struct wmi_tlv_bcn_tx_status_ev *ev;
169 u32 vdev_id, tx_status;
170 int ret;
171
172 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
173 if (IS_ERR(tb)) {
174 ret = PTR_ERR(tb);
175 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
176 return ret;
177 }
178
179 ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT];
180 if (!ev) {
181 kfree(tb);
182 return -EPROTO;
183 }
184
185 tx_status = __le32_to_cpu(ev->tx_status);
186 vdev_id = __le32_to_cpu(ev->vdev_id);
187
188 switch (tx_status) {
189 case WMI_TLV_BCN_TX_STATUS_OK:
190 break;
191 case WMI_TLV_BCN_TX_STATUS_XRETRY:
192 case WMI_TLV_BCN_TX_STATUS_DROP:
193 case WMI_TLV_BCN_TX_STATUS_FILTERED:
194 /* FIXME: It's probably worth telling mac80211 to stop the
195 * interface as it is crippled.
196 */
197 ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
198 vdev_id, tx_status);
199 break;
200 }
201
202 kfree(tb);
203 return 0;
204}
205
Michal Kaziorca996ec2014-12-03 10:11:32 +0200206/***********/
207/* TLV ops */
208/***********/
209
210static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
211{
212 struct wmi_cmd_hdr *cmd_hdr;
213 enum wmi_tlv_event_id id;
214
215 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
216 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
217
218 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
219 return;
220
221 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
222
223 switch (id) {
224 case WMI_TLV_MGMT_RX_EVENTID:
225 ath10k_wmi_event_mgmt_rx(ar, skb);
226 /* mgmt_rx() owns the skb now! */
227 return;
228 case WMI_TLV_SCAN_EVENTID:
229 ath10k_wmi_event_scan(ar, skb);
230 break;
231 case WMI_TLV_CHAN_INFO_EVENTID:
232 ath10k_wmi_event_chan_info(ar, skb);
233 break;
234 case WMI_TLV_ECHO_EVENTID:
235 ath10k_wmi_event_echo(ar, skb);
236 break;
237 case WMI_TLV_DEBUG_MESG_EVENTID:
238 ath10k_wmi_event_debug_mesg(ar, skb);
239 break;
240 case WMI_TLV_UPDATE_STATS_EVENTID:
241 ath10k_wmi_event_update_stats(ar, skb);
242 break;
243 case WMI_TLV_VDEV_START_RESP_EVENTID:
244 ath10k_wmi_event_vdev_start_resp(ar, skb);
245 break;
246 case WMI_TLV_VDEV_STOPPED_EVENTID:
247 ath10k_wmi_event_vdev_stopped(ar, skb);
248 break;
249 case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
250 ath10k_wmi_event_peer_sta_kickout(ar, skb);
251 break;
252 case WMI_TLV_HOST_SWBA_EVENTID:
253 ath10k_wmi_event_host_swba(ar, skb);
254 break;
255 case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
256 ath10k_wmi_event_tbttoffset_update(ar, skb);
257 break;
258 case WMI_TLV_PHYERR_EVENTID:
259 ath10k_wmi_event_phyerr(ar, skb);
260 break;
261 case WMI_TLV_ROAM_EVENTID:
262 ath10k_wmi_event_roam(ar, skb);
263 break;
264 case WMI_TLV_PROFILE_MATCH:
265 ath10k_wmi_event_profile_match(ar, skb);
266 break;
267 case WMI_TLV_DEBUG_PRINT_EVENTID:
268 ath10k_wmi_event_debug_print(ar, skb);
269 break;
270 case WMI_TLV_PDEV_QVIT_EVENTID:
271 ath10k_wmi_event_pdev_qvit(ar, skb);
272 break;
273 case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
274 ath10k_wmi_event_wlan_profile_data(ar, skb);
275 break;
276 case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
277 ath10k_wmi_event_rtt_measurement_report(ar, skb);
278 break;
279 case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
280 ath10k_wmi_event_tsf_measurement_report(ar, skb);
281 break;
282 case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
283 ath10k_wmi_event_rtt_error_report(ar, skb);
284 break;
285 case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
286 ath10k_wmi_event_wow_wakeup_host(ar, skb);
287 break;
288 case WMI_TLV_DCS_INTERFERENCE_EVENTID:
289 ath10k_wmi_event_dcs_interference(ar, skb);
290 break;
291 case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
292 ath10k_wmi_event_pdev_tpc_config(ar, skb);
293 break;
294 case WMI_TLV_PDEV_FTM_INTG_EVENTID:
295 ath10k_wmi_event_pdev_ftm_intg(ar, skb);
296 break;
297 case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
298 ath10k_wmi_event_gtk_offload_status(ar, skb);
299 break;
300 case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
301 ath10k_wmi_event_gtk_rekey_fail(ar, skb);
302 break;
303 case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
304 ath10k_wmi_event_delba_complete(ar, skb);
305 break;
306 case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
307 ath10k_wmi_event_addba_complete(ar, skb);
308 break;
309 case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
310 ath10k_wmi_event_vdev_install_key_complete(ar, skb);
311 break;
312 case WMI_TLV_SERVICE_READY_EVENTID:
313 ath10k_wmi_event_service_ready(ar, skb);
314 break;
315 case WMI_TLV_READY_EVENTID:
316 ath10k_wmi_event_ready(ar, skb);
317 break;
Michal Kazior6bf12062015-01-13 16:30:10 +0200318 case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
319 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
320 break;
Michal Kaziorca996ec2014-12-03 10:11:32 +0200321 default:
322 ath10k_warn(ar, "Unknown eventid: %d\n", id);
323 break;
324 }
325
326 dev_kfree_skb(skb);
327}
328
329static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
330 struct sk_buff *skb,
331 struct wmi_scan_ev_arg *arg)
332{
333 const void **tb;
334 const struct wmi_scan_event *ev;
335 int ret;
336
337 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
338 if (IS_ERR(tb)) {
339 ret = PTR_ERR(tb);
340 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
341 return ret;
342 }
343
344 ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
345 if (!ev) {
346 kfree(tb);
347 return -EPROTO;
348 }
349
350 arg->event_type = ev->event_type;
351 arg->reason = ev->reason;
352 arg->channel_freq = ev->channel_freq;
353 arg->scan_req_id = ev->scan_req_id;
354 arg->scan_id = ev->scan_id;
355 arg->vdev_id = ev->vdev_id;
356
357 kfree(tb);
358 return 0;
359}
360
361static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
362 struct sk_buff *skb,
363 struct wmi_mgmt_rx_ev_arg *arg)
364{
365 const void **tb;
366 const struct wmi_tlv_mgmt_rx_ev *ev;
367 const u8 *frame;
368 u32 msdu_len;
369 int ret;
370
371 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
372 if (IS_ERR(tb)) {
373 ret = PTR_ERR(tb);
374 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
375 return ret;
376 }
377
378 ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
379 frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
380
381 if (!ev || !frame) {
382 kfree(tb);
383 return -EPROTO;
384 }
385
386 arg->channel = ev->channel;
387 arg->buf_len = ev->buf_len;
388 arg->status = ev->status;
389 arg->snr = ev->snr;
390 arg->phy_mode = ev->phy_mode;
391 arg->rate = ev->rate;
392
393 msdu_len = __le32_to_cpu(arg->buf_len);
394
395 if (skb->len < (frame - skb->data) + msdu_len) {
396 kfree(tb);
397 return -EPROTO;
398 }
399
400 /* shift the sk_buff to point to `frame` */
401 skb_trim(skb, 0);
402 skb_put(skb, frame - skb->data);
403 skb_pull(skb, frame - skb->data);
404 skb_put(skb, msdu_len);
405
406 kfree(tb);
407 return 0;
408}
409
410static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
411 struct sk_buff *skb,
412 struct wmi_ch_info_ev_arg *arg)
413{
414 const void **tb;
415 const struct wmi_chan_info_event *ev;
416 int ret;
417
418 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
419 if (IS_ERR(tb)) {
420 ret = PTR_ERR(tb);
421 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
422 return ret;
423 }
424
425 ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
426 if (!ev) {
427 kfree(tb);
428 return -EPROTO;
429 }
430
431 arg->err_code = ev->err_code;
432 arg->freq = ev->freq;
433 arg->cmd_flags = ev->cmd_flags;
434 arg->noise_floor = ev->noise_floor;
435 arg->rx_clear_count = ev->rx_clear_count;
436 arg->cycle_count = ev->cycle_count;
437
438 kfree(tb);
439 return 0;
440}
441
442static int
443ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
444 struct wmi_vdev_start_ev_arg *arg)
445{
446 const void **tb;
447 const struct wmi_vdev_start_response_event *ev;
448 int ret;
449
450 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
451 if (IS_ERR(tb)) {
452 ret = PTR_ERR(tb);
453 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
454 return ret;
455 }
456
457 ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
458 if (!ev) {
459 kfree(tb);
460 return -EPROTO;
461 }
462
463 skb_pull(skb, sizeof(*ev));
464 arg->vdev_id = ev->vdev_id;
465 arg->req_id = ev->req_id;
466 arg->resp_type = ev->resp_type;
467 arg->status = ev->status;
468
469 kfree(tb);
470 return 0;
471}
472
473static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
474 struct sk_buff *skb,
475 struct wmi_peer_kick_ev_arg *arg)
476{
477 const void **tb;
478 const struct wmi_peer_sta_kickout_event *ev;
479 int ret;
480
481 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
482 if (IS_ERR(tb)) {
483 ret = PTR_ERR(tb);
484 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
485 return ret;
486 }
487
488 ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
489 if (!ev) {
490 kfree(tb);
491 return -EPROTO;
492 }
493
494 arg->mac_addr = ev->peer_macaddr.addr;
495
496 kfree(tb);
497 return 0;
498}
499
500struct wmi_tlv_swba_parse {
501 const struct wmi_host_swba_event *ev;
502 bool tim_done;
503 bool noa_done;
504 size_t n_tim;
505 size_t n_noa;
506 struct wmi_swba_ev_arg *arg;
507};
508
509static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
510 const void *ptr, void *data)
511{
512 struct wmi_tlv_swba_parse *swba = data;
513
514 if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
515 return -EPROTO;
516
517 if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
518 return -ENOBUFS;
519
520 swba->arg->tim_info[swba->n_tim++] = ptr;
521 return 0;
522}
523
524static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
525 const void *ptr, void *data)
526{
527 struct wmi_tlv_swba_parse *swba = data;
528
529 if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
530 return -EPROTO;
531
532 if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
533 return -ENOBUFS;
534
535 swba->arg->noa_info[swba->n_noa++] = ptr;
536 return 0;
537}
538
539static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
540 const void *ptr, void *data)
541{
542 struct wmi_tlv_swba_parse *swba = data;
543 int ret;
544
545 switch (tag) {
546 case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
547 swba->ev = ptr;
548 break;
549 case WMI_TLV_TAG_ARRAY_STRUCT:
550 if (!swba->tim_done) {
551 swba->tim_done = true;
552 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
553 ath10k_wmi_tlv_swba_tim_parse,
554 swba);
555 if (ret)
556 return ret;
557 } else if (!swba->noa_done) {
558 swba->noa_done = true;
559 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
560 ath10k_wmi_tlv_swba_noa_parse,
561 swba);
562 if (ret)
563 return ret;
564 }
565 break;
566 default:
567 break;
568 }
569 return 0;
570}
571
572static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
573 struct sk_buff *skb,
574 struct wmi_swba_ev_arg *arg)
575{
576 struct wmi_tlv_swba_parse swba = { .arg = arg };
577 u32 map;
578 size_t n_vdevs;
579 int ret;
580
581 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
582 ath10k_wmi_tlv_swba_parse, &swba);
583 if (ret) {
584 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
585 return ret;
586 }
587
588 if (!swba.ev)
589 return -EPROTO;
590
591 arg->vdev_map = swba.ev->vdev_map;
592
593 for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
594 if (map & BIT(0))
595 n_vdevs++;
596
597 if (n_vdevs != swba.n_tim ||
598 n_vdevs != swba.n_noa)
599 return -EPROTO;
600
601 return 0;
602}
603
604static int ath10k_wmi_tlv_op_pull_phyerr_ev(struct ath10k *ar,
605 struct sk_buff *skb,
606 struct wmi_phyerr_ev_arg *arg)
607{
608 const void **tb;
609 const struct wmi_tlv_phyerr_ev *ev;
610 const void *phyerrs;
611 int ret;
612
613 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
614 if (IS_ERR(tb)) {
615 ret = PTR_ERR(tb);
616 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
617 return ret;
618 }
619
620 ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
621 phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
622
623 if (!ev || !phyerrs) {
624 kfree(tb);
625 return -EPROTO;
626 }
627
628 arg->num_phyerrs = ev->num_phyerrs;
629 arg->tsf_l32 = ev->tsf_l32;
630 arg->tsf_u32 = ev->tsf_u32;
631 arg->buf_len = ev->buf_len;
632 arg->phyerrs = phyerrs;
633
634 kfree(tb);
635 return 0;
636}
637
638#define WMI_TLV_ABI_VER_NS0 0x5F414351
639#define WMI_TLV_ABI_VER_NS1 0x00004C4D
640#define WMI_TLV_ABI_VER_NS2 0x00000000
641#define WMI_TLV_ABI_VER_NS3 0x00000000
642
643#define WMI_TLV_ABI_VER0_MAJOR 1
644#define WMI_TLV_ABI_VER0_MINOR 0
645#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
646 (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF))
647#define WMI_TLV_ABI_VER1 53
648
649static int
650ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
651 const void *ptr, void *data)
652{
653 struct wmi_svc_rdy_ev_arg *arg = data;
654 int i;
655
656 if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
657 return -EPROTO;
658
659 for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
660 if (!arg->mem_reqs[i]) {
661 arg->mem_reqs[i] = ptr;
662 return 0;
663 }
664 }
665
666 return -ENOMEM;
667}
668
669static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
670 struct sk_buff *skb,
671 struct wmi_svc_rdy_ev_arg *arg)
672{
673 const void **tb;
674 const struct hal_reg_capabilities *reg;
675 const struct wmi_tlv_svc_rdy_ev *ev;
676 const __le32 *svc_bmap;
677 const struct wlan_host_mem_req *mem_reqs;
678 int ret;
679
680 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
681 if (IS_ERR(tb)) {
682 ret = PTR_ERR(tb);
683 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
684 return ret;
685 }
686
687 ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
688 reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
689 svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
690 mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
691
692 if (!ev || !reg || !svc_bmap || !mem_reqs) {
693 kfree(tb);
694 return -EPROTO;
695 }
696
697 /* This is an internal ABI compatibility check for WMI TLV so check it
698 * here instead of the generic WMI code.
699 */
700 ath10k_dbg(ar, ATH10K_DBG_WMI,
701 "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n",
702 __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
703 __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
704 __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
705 __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
706 __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
707
708 if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
709 __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
710 __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
711 __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
712 __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
713 kfree(tb);
714 return -ENOTSUPP;
715 }
716
717 arg->min_tx_power = ev->hw_min_tx_power;
718 arg->max_tx_power = ev->hw_max_tx_power;
719 arg->ht_cap = ev->ht_cap_info;
720 arg->vht_cap = ev->vht_cap_info;
721 arg->sw_ver0 = ev->abi.abi_ver0;
722 arg->sw_ver1 = ev->abi.abi_ver1;
723 arg->fw_build = ev->fw_build_vers;
724 arg->phy_capab = ev->phy_capability;
725 arg->num_rf_chains = ev->num_rf_chains;
726 arg->eeprom_rd = reg->eeprom_rd;
727 arg->num_mem_reqs = ev->num_mem_reqs;
728 arg->service_map = svc_bmap;
729 arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
730
731 ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
732 ath10k_wmi_tlv_parse_mem_reqs, arg);
733 if (ret) {
734 kfree(tb);
735 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
736 return ret;
737 }
738
739 kfree(tb);
740 return 0;
741}
742
743static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
744 struct sk_buff *skb,
745 struct wmi_rdy_ev_arg *arg)
746{
747 const void **tb;
748 const struct wmi_tlv_rdy_ev *ev;
749 int ret;
750
751 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
752 if (IS_ERR(tb)) {
753 ret = PTR_ERR(tb);
754 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
755 return ret;
756 }
757
758 ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
759 if (!ev) {
760 kfree(tb);
761 return -EPROTO;
762 }
763
764 arg->sw_version = ev->abi.abi_ver0;
765 arg->abi_version = ev->abi.abi_ver1;
766 arg->status = ev->status;
767 arg->mac_addr = ev->mac_addr.addr;
768
769 kfree(tb);
770 return 0;
771}
772
773static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
774 struct sk_buff *skb,
775 struct ath10k_fw_stats *stats)
776{
777 const void **tb;
778 const struct wmi_stats_event *ev;
779 const void *data;
780 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
781 size_t data_len;
782 int ret;
783
784 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
785 if (IS_ERR(tb)) {
786 ret = PTR_ERR(tb);
787 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
788 return ret;
789 }
790
791 ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
792 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
793
794 if (!ev || !data) {
795 kfree(tb);
796 return -EPROTO;
797 }
798
799 data_len = ath10k_wmi_tlv_len(data);
800 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
801 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
802 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
803
804 WARN_ON(1); /* FIXME: not implemented yet */
805
806 kfree(tb);
807 return 0;
808}
809
810static struct sk_buff *
811ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
812{
813 struct wmi_tlv_pdev_suspend *cmd;
814 struct wmi_tlv *tlv;
815 struct sk_buff *skb;
816
817 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
818 if (!skb)
819 return ERR_PTR(-ENOMEM);
820
821 tlv = (void *)skb->data;
822 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
823 tlv->len = __cpu_to_le16(sizeof(*cmd));
824 cmd = (void *)tlv->value;
825 cmd->opt = __cpu_to_le32(opt);
826
827 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
828 return skb;
829}
830
831static struct sk_buff *
832ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
833{
834 struct wmi_tlv_resume_cmd *cmd;
835 struct wmi_tlv *tlv;
836 struct sk_buff *skb;
837
838 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
839 if (!skb)
840 return ERR_PTR(-ENOMEM);
841
842 tlv = (void *)skb->data;
843 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
844 tlv->len = __cpu_to_le16(sizeof(*cmd));
845 cmd = (void *)tlv->value;
846 cmd->reserved = __cpu_to_le32(0);
847
848 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
849 return skb;
850}
851
852static struct sk_buff *
853ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
854 u16 rd, u16 rd2g, u16 rd5g,
855 u16 ctl2g, u16 ctl5g,
856 enum wmi_dfs_region dfs_reg)
857{
858 struct wmi_tlv_pdev_set_rd_cmd *cmd;
859 struct wmi_tlv *tlv;
860 struct sk_buff *skb;
861
862 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
863 if (!skb)
864 return ERR_PTR(-ENOMEM);
865
866 tlv = (void *)skb->data;
867 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
868 tlv->len = __cpu_to_le16(sizeof(*cmd));
869 cmd = (void *)tlv->value;
870 cmd->regd = __cpu_to_le32(rd);
871 cmd->regd_2ghz = __cpu_to_le32(rd2g);
872 cmd->regd_5ghz = __cpu_to_le32(rd5g);
873 cmd->conform_limit_2ghz = __cpu_to_le32(rd2g);
874 cmd->conform_limit_5ghz = __cpu_to_le32(rd5g);
875
876 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
877 return skb;
878}
879
880static struct sk_buff *
881ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
882 u32 param_value)
883{
884 struct wmi_tlv_pdev_set_param_cmd *cmd;
885 struct wmi_tlv *tlv;
886 struct sk_buff *skb;
887
888 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
889 if (!skb)
890 return ERR_PTR(-ENOMEM);
891
892 tlv = (void *)skb->data;
893 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
894 tlv->len = __cpu_to_le16(sizeof(*cmd));
895 cmd = (void *)tlv->value;
896 cmd->param_id = __cpu_to_le32(param_id);
897 cmd->param_value = __cpu_to_le32(param_value);
898
899 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param\n");
900 return skb;
901}
902
903static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
904{
905 struct sk_buff *skb;
906 struct wmi_tlv *tlv;
907 struct wmi_tlv_init_cmd *cmd;
908 struct wmi_tlv_resource_config *cfg;
909 struct wmi_host_mem_chunks *chunks;
910 size_t len, chunks_len;
911 void *ptr;
912
913 chunks_len = ar->wmi.num_mem_chunks * sizeof(struct host_memory_chunk);
914 len = (sizeof(*tlv) + sizeof(*cmd)) +
915 (sizeof(*tlv) + sizeof(*cfg)) +
916 (sizeof(*tlv) + chunks_len);
917
918 skb = ath10k_wmi_alloc_skb(ar, len);
919 if (!skb)
920 return ERR_PTR(-ENOMEM);
921
922 ptr = skb->data;
923
924 tlv = ptr;
925 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
926 tlv->len = __cpu_to_le16(sizeof(*cmd));
927 cmd = (void *)tlv->value;
928 ptr += sizeof(*tlv);
929 ptr += sizeof(*cmd);
930
931 tlv = ptr;
932 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
933 tlv->len = __cpu_to_le16(sizeof(*cfg));
934 cfg = (void *)tlv->value;
935 ptr += sizeof(*tlv);
936 ptr += sizeof(*cfg);
937
938 tlv = ptr;
939 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
940 tlv->len = __cpu_to_le16(chunks_len);
941 chunks = (void *)tlv->value;
942
943 ptr += sizeof(*tlv);
944 ptr += chunks_len;
945
946 cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
947 cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
948 cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
949 cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
950 cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
951 cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
952 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
953
954 cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
955 cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
956 cfg->num_offload_peers = __cpu_to_le32(0);
957 cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
958 cfg->num_peer_keys = __cpu_to_le32(2);
959 cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
960 cfg->ast_skid_limit = __cpu_to_le32(0x10);
961 cfg->tx_chain_mask = __cpu_to_le32(0x7);
962 cfg->rx_chain_mask = __cpu_to_le32(0x7);
963 cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
964 cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
965 cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
966 cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
967 cfg->rx_decap_mode = __cpu_to_le32(1);
968 cfg->scan_max_pending_reqs = __cpu_to_le32(4);
969 cfg->bmiss_offload_max_vdev = __cpu_to_le32(3);
970 cfg->roam_offload_max_vdev = __cpu_to_le32(3);
971 cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
972 cfg->num_mcast_groups = __cpu_to_le32(0);
973 cfg->num_mcast_table_elems = __cpu_to_le32(0);
974 cfg->mcast2ucast_mode = __cpu_to_le32(0);
975 cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
976 cfg->num_wds_entries = __cpu_to_le32(0x20);
977 cfg->dma_burst_size = __cpu_to_le32(0);
978 cfg->mac_aggr_delim = __cpu_to_le32(0);
979 cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
980 cfg->vow_config = __cpu_to_le32(0);
981 cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
982 cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
983 cfg->max_frag_entries = __cpu_to_le32(2);
984 cfg->num_tdls_vdevs = __cpu_to_le32(1);
985 cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
986 cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
987 cfg->num_multicast_filter_entries = __cpu_to_le32(5);
988 cfg->num_wow_filters = __cpu_to_le32(0x16);
989 cfg->num_keep_alive_pattern = __cpu_to_le32(6);
990 cfg->keep_alive_pattern_size = __cpu_to_le32(0);
991 cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
992 cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
993
994 ath10k_wmi_put_host_mem_chunks(ar, chunks);
995
996 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
997 return skb;
998}
999
1000static struct sk_buff *
1001ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
1002 const struct wmi_start_scan_arg *arg)
1003{
1004 struct wmi_tlv_start_scan_cmd *cmd;
1005 struct wmi_tlv *tlv;
1006 struct sk_buff *skb;
1007 size_t len, chan_len, ssid_len, bssid_len, ie_len;
1008 __le32 *chans;
1009 struct wmi_ssid *ssids;
1010 struct wmi_mac_addr *addrs;
1011 void *ptr;
1012 int i, ret;
1013
1014 ret = ath10k_wmi_start_scan_verify(arg);
1015 if (ret)
1016 return ERR_PTR(ret);
1017
1018 chan_len = arg->n_channels * sizeof(__le32);
1019 ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
1020 bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
1021 ie_len = roundup(arg->ie_len, 4);
1022 len = (sizeof(*tlv) + sizeof(*cmd)) +
1023 (arg->n_channels ? sizeof(*tlv) + chan_len : 0) +
1024 (arg->n_ssids ? sizeof(*tlv) + ssid_len : 0) +
1025 (arg->n_bssids ? sizeof(*tlv) + bssid_len : 0) +
1026 (arg->ie_len ? sizeof(*tlv) + ie_len : 0);
1027
1028 skb = ath10k_wmi_alloc_skb(ar, len);
1029 if (!skb)
1030 return ERR_PTR(-ENOMEM);
1031
1032 ptr = (void *)skb->data;
1033 tlv = ptr;
1034 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
1035 tlv->len = __cpu_to_le16(sizeof(*cmd));
1036 cmd = (void *)tlv->value;
1037
1038 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
1039 cmd->burst_duration_ms = __cpu_to_le32(0);
1040 cmd->num_channels = __cpu_to_le32(arg->n_channels);
1041 cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
1042 cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
1043 cmd->ie_len = __cpu_to_le32(arg->ie_len);
1044 cmd->num_probes = __cpu_to_le32(3);
1045
1046 /* FIXME: There are some scan flag inconsistencies across firmwares,
1047 * e.g. WMI-TLV inverts the logic behind the following flag.
1048 */
1049 cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
1050
1051 ptr += sizeof(*tlv);
1052 ptr += sizeof(*cmd);
1053
1054 tlv = ptr;
1055 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1056 tlv->len = __cpu_to_le16(chan_len);
1057 chans = (void *)tlv->value;
1058 for (i = 0; i < arg->n_channels; i++)
1059 chans[i] = __cpu_to_le32(arg->channels[i]);
1060
1061 ptr += sizeof(*tlv);
1062 ptr += chan_len;
1063
1064 tlv = ptr;
1065 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1066 tlv->len = __cpu_to_le16(ssid_len);
1067 ssids = (void *)tlv->value;
1068 for (i = 0; i < arg->n_ssids; i++) {
1069 ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
1070 memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
1071 }
1072
1073 ptr += sizeof(*tlv);
1074 ptr += ssid_len;
1075
1076 tlv = ptr;
1077 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1078 tlv->len = __cpu_to_le16(bssid_len);
1079 addrs = (void *)tlv->value;
1080 for (i = 0; i < arg->n_bssids; i++)
1081 ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
1082
1083 ptr += sizeof(*tlv);
1084 ptr += bssid_len;
1085
1086 tlv = ptr;
1087 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1088 tlv->len = __cpu_to_le16(ie_len);
1089 memcpy(tlv->value, arg->ie, arg->ie_len);
1090
1091 ptr += sizeof(*tlv);
1092 ptr += ie_len;
1093
1094 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
1095 return skb;
1096}
1097
1098static struct sk_buff *
1099ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
1100 const struct wmi_stop_scan_arg *arg)
1101{
1102 struct wmi_stop_scan_cmd *cmd;
1103 struct wmi_tlv *tlv;
1104 struct sk_buff *skb;
1105 u32 scan_id;
1106 u32 req_id;
1107
1108 if (arg->req_id > 0xFFF)
1109 return ERR_PTR(-EINVAL);
1110 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
1111 return ERR_PTR(-EINVAL);
1112
1113 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1114 if (!skb)
1115 return ERR_PTR(-ENOMEM);
1116
1117 scan_id = arg->u.scan_id;
1118 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
1119
1120 req_id = arg->req_id;
1121 req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
1122
1123 tlv = (void *)skb->data;
1124 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
1125 tlv->len = __cpu_to_le16(sizeof(*cmd));
1126 cmd = (void *)tlv->value;
1127 cmd->req_type = __cpu_to_le32(arg->req_type);
1128 cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
1129 cmd->scan_id = __cpu_to_le32(scan_id);
1130 cmd->scan_req_id = __cpu_to_le32(req_id);
1131
1132 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
1133 return skb;
1134}
1135
1136static struct sk_buff *
1137ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
1138 u32 vdev_id,
1139 enum wmi_vdev_type vdev_type,
1140 enum wmi_vdev_subtype vdev_subtype,
1141 const u8 mac_addr[ETH_ALEN])
1142{
1143 struct wmi_vdev_create_cmd *cmd;
1144 struct wmi_tlv *tlv;
1145 struct sk_buff *skb;
1146
1147 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1148 if (!skb)
1149 return ERR_PTR(-ENOMEM);
1150
1151 tlv = (void *)skb->data;
1152 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
1153 tlv->len = __cpu_to_le16(sizeof(*cmd));
1154 cmd = (void *)tlv->value;
1155 cmd->vdev_id = __cpu_to_le32(vdev_id);
1156 cmd->vdev_type = __cpu_to_le32(vdev_type);
1157 cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
1158 ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
1159
1160 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
1161 return skb;
1162}
1163
1164static struct sk_buff *
1165ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
1166{
1167 struct wmi_vdev_delete_cmd *cmd;
1168 struct wmi_tlv *tlv;
1169 struct sk_buff *skb;
1170
1171 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1172 if (!skb)
1173 return ERR_PTR(-ENOMEM);
1174
1175 tlv = (void *)skb->data;
1176 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
1177 tlv->len = __cpu_to_le16(sizeof(*cmd));
1178 cmd = (void *)tlv->value;
1179 cmd->vdev_id = __cpu_to_le32(vdev_id);
1180
1181 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
1182 return skb;
1183}
1184
1185static struct sk_buff *
1186ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
1187 const struct wmi_vdev_start_request_arg *arg,
1188 bool restart)
1189{
1190 struct wmi_tlv_vdev_start_cmd *cmd;
1191 struct wmi_channel *ch;
1192 struct wmi_p2p_noa_descriptor *noa;
1193 struct wmi_tlv *tlv;
1194 struct sk_buff *skb;
1195 size_t len;
1196 void *ptr;
1197 u32 flags = 0;
1198
1199 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
1200 return ERR_PTR(-EINVAL);
1201 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
1202 return ERR_PTR(-EINVAL);
1203 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
1204 return ERR_PTR(-EINVAL);
1205
1206 len = (sizeof(*tlv) + sizeof(*cmd)) +
1207 (sizeof(*tlv) + sizeof(*ch)) +
1208 (sizeof(*tlv) + 0);
1209 skb = ath10k_wmi_alloc_skb(ar, len);
1210 if (!skb)
1211 return ERR_PTR(-ENOMEM);
1212
1213 if (arg->hidden_ssid)
1214 flags |= WMI_VDEV_START_HIDDEN_SSID;
1215 if (arg->pmf_enabled)
1216 flags |= WMI_VDEV_START_PMF_ENABLED;
1217
1218 ptr = (void *)skb->data;
1219
1220 tlv = ptr;
1221 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
1222 tlv->len = __cpu_to_le16(sizeof(*cmd));
1223 cmd = (void *)tlv->value;
1224 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1225 cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
1226 cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
1227 cmd->flags = __cpu_to_le32(flags);
1228 cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
1229 cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
1230 cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
1231
1232 if (arg->ssid) {
1233 cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
1234 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
1235 }
1236
1237 ptr += sizeof(*tlv);
1238 ptr += sizeof(*cmd);
1239
1240 tlv = ptr;
1241 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1242 tlv->len = __cpu_to_le16(sizeof(*ch));
1243 ch = (void *)tlv->value;
1244 ath10k_wmi_put_wmi_channel(ch, &arg->channel);
1245
1246 ptr += sizeof(*tlv);
1247 ptr += sizeof(*ch);
1248
1249 tlv = ptr;
1250 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1251 tlv->len = 0;
1252 noa = (void *)tlv->value;
1253
1254 /* Note: This is a nested TLV containing:
1255 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
1256 */
1257
1258 ptr += sizeof(*tlv);
1259 ptr += 0;
1260
1261 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
1262 return skb;
1263}
1264
1265static struct sk_buff *
1266ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
1267{
1268 struct wmi_vdev_stop_cmd *cmd;
1269 struct wmi_tlv *tlv;
1270 struct sk_buff *skb;
1271
1272 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1273 if (!skb)
1274 return ERR_PTR(-ENOMEM);
1275
1276 tlv = (void *)skb->data;
1277 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
1278 tlv->len = __cpu_to_le16(sizeof(*cmd));
1279 cmd = (void *)tlv->value;
1280 cmd->vdev_id = __cpu_to_le32(vdev_id);
1281
1282 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
1283 return skb;
1284}
1285
1286static struct sk_buff *
1287ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
1288 const u8 *bssid)
1289
1290{
1291 struct wmi_vdev_up_cmd *cmd;
1292 struct wmi_tlv *tlv;
1293 struct sk_buff *skb;
1294
1295 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1296 if (!skb)
1297 return ERR_PTR(-ENOMEM);
1298
1299 tlv = (void *)skb->data;
1300 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
1301 tlv->len = __cpu_to_le16(sizeof(*cmd));
1302 cmd = (void *)tlv->value;
1303 cmd->vdev_id = __cpu_to_le32(vdev_id);
1304 cmd->vdev_assoc_id = __cpu_to_le32(aid);
1305 ether_addr_copy(cmd->vdev_bssid.addr, bssid);
1306
1307 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
1308 return skb;
1309}
1310
1311static struct sk_buff *
1312ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
1313{
1314 struct wmi_vdev_down_cmd *cmd;
1315 struct wmi_tlv *tlv;
1316 struct sk_buff *skb;
1317
1318 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1319 if (!skb)
1320 return ERR_PTR(-ENOMEM);
1321
1322 tlv = (void *)skb->data;
1323 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
1324 tlv->len = __cpu_to_le16(sizeof(*cmd));
1325 cmd = (void *)tlv->value;
1326 cmd->vdev_id = __cpu_to_le32(vdev_id);
1327
1328 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
1329 return skb;
1330}
1331
1332static struct sk_buff *
1333ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
1334 u32 param_id, u32 param_value)
1335{
1336 struct wmi_vdev_set_param_cmd *cmd;
1337 struct wmi_tlv *tlv;
1338 struct sk_buff *skb;
1339
1340 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1341 if (!skb)
1342 return ERR_PTR(-ENOMEM);
1343
1344 tlv = (void *)skb->data;
1345 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
1346 tlv->len = __cpu_to_le16(sizeof(*cmd));
1347 cmd = (void *)tlv->value;
1348 cmd->vdev_id = __cpu_to_le32(vdev_id);
1349 cmd->param_id = __cpu_to_le32(param_id);
1350 cmd->param_value = __cpu_to_le32(param_value);
1351
1352 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev set param\n");
1353 return skb;
1354}
1355
1356static struct sk_buff *
1357ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
1358 const struct wmi_vdev_install_key_arg *arg)
1359{
1360 struct wmi_vdev_install_key_cmd *cmd;
1361 struct wmi_tlv *tlv;
1362 struct sk_buff *skb;
1363 size_t len;
1364 void *ptr;
1365
1366 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
1367 return ERR_PTR(-EINVAL);
1368 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
1369 return ERR_PTR(-EINVAL);
1370
1371 len = sizeof(*tlv) + sizeof(*cmd) +
1372 sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
1373 skb = ath10k_wmi_alloc_skb(ar, len);
1374 if (!skb)
1375 return ERR_PTR(-ENOMEM);
1376
1377 ptr = (void *)skb->data;
1378 tlv = ptr;
1379 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
1380 tlv->len = __cpu_to_le16(sizeof(*cmd));
1381 cmd = (void *)tlv->value;
1382 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1383 cmd->key_idx = __cpu_to_le32(arg->key_idx);
1384 cmd->key_flags = __cpu_to_le32(arg->key_flags);
1385 cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
1386 cmd->key_len = __cpu_to_le32(arg->key_len);
1387 cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
1388 cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
1389
1390 if (arg->macaddr)
1391 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
1392
1393 ptr += sizeof(*tlv);
1394 ptr += sizeof(*cmd);
1395
1396 tlv = ptr;
1397 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1398 tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
1399 if (arg->key_data)
1400 memcpy(tlv->value, arg->key_data, arg->key_len);
1401
1402 ptr += sizeof(*tlv);
1403 ptr += roundup(arg->key_len, sizeof(__le32));
1404
1405 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
1406 return skb;
1407}
1408
1409static struct sk_buff *
1410ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
1411 const u8 peer_addr[ETH_ALEN])
1412{
1413 struct wmi_tlv_peer_create_cmd *cmd;
1414 struct wmi_tlv *tlv;
1415 struct sk_buff *skb;
1416
1417 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1418 if (!skb)
1419 return ERR_PTR(-ENOMEM);
1420
1421 tlv = (void *)skb->data;
1422 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
1423 tlv->len = __cpu_to_le16(sizeof(*cmd));
1424 cmd = (void *)tlv->value;
1425 cmd->vdev_id = __cpu_to_le32(vdev_id);
1426 cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */
1427 ether_addr_copy(cmd->peer_addr.addr, peer_addr);
1428
1429 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
1430 return skb;
1431}
1432
1433static struct sk_buff *
1434ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
1435 const u8 peer_addr[ETH_ALEN])
1436{
1437 struct wmi_peer_delete_cmd *cmd;
1438 struct wmi_tlv *tlv;
1439 struct sk_buff *skb;
1440
1441 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1442 if (!skb)
1443 return ERR_PTR(-ENOMEM);
1444
1445 tlv = (void *)skb->data;
1446 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
1447 tlv->len = __cpu_to_le16(sizeof(*cmd));
1448 cmd = (void *)tlv->value;
1449 cmd->vdev_id = __cpu_to_le32(vdev_id);
1450 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1451
1452 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
1453 return skb;
1454}
1455
1456static struct sk_buff *
1457ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
1458 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
1459{
1460 struct wmi_peer_flush_tids_cmd *cmd;
1461 struct wmi_tlv *tlv;
1462 struct sk_buff *skb;
1463
1464 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1465 if (!skb)
1466 return ERR_PTR(-ENOMEM);
1467
1468 tlv = (void *)skb->data;
1469 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
1470 tlv->len = __cpu_to_le16(sizeof(*cmd));
1471 cmd = (void *)tlv->value;
1472 cmd->vdev_id = __cpu_to_le32(vdev_id);
1473 cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
1474 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1475
1476 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
1477 return skb;
1478}
1479
1480static struct sk_buff *
1481ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
1482 const u8 *peer_addr,
1483 enum wmi_peer_param param_id,
1484 u32 param_value)
1485{
1486 struct wmi_peer_set_param_cmd *cmd;
1487 struct wmi_tlv *tlv;
1488 struct sk_buff *skb;
1489
1490 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1491 if (!skb)
1492 return ERR_PTR(-ENOMEM);
1493
1494 tlv = (void *)skb->data;
1495 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
1496 tlv->len = __cpu_to_le16(sizeof(*cmd));
1497 cmd = (void *)tlv->value;
1498 cmd->vdev_id = __cpu_to_le32(vdev_id);
1499 cmd->param_id = __cpu_to_le32(param_id);
1500 cmd->param_value = __cpu_to_le32(param_value);
1501 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1502
1503 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer set param\n");
1504 return skb;
1505}
1506
1507static struct sk_buff *
1508ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
1509 const struct wmi_peer_assoc_complete_arg *arg)
1510{
1511 struct wmi_tlv_peer_assoc_cmd *cmd;
1512 struct wmi_vht_rate_set *vht_rate;
1513 struct wmi_tlv *tlv;
1514 struct sk_buff *skb;
1515 size_t len, legacy_rate_len, ht_rate_len;
1516 void *ptr;
1517
1518 if (arg->peer_mpdu_density > 16)
1519 return ERR_PTR(-EINVAL);
1520 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
1521 return ERR_PTR(-EINVAL);
1522 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
1523 return ERR_PTR(-EINVAL);
1524
1525 legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
1526 sizeof(__le32));
1527 ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
1528 len = (sizeof(*tlv) + sizeof(*cmd)) +
1529 (sizeof(*tlv) + legacy_rate_len) +
1530 (sizeof(*tlv) + ht_rate_len) +
1531 (sizeof(*tlv) + sizeof(*vht_rate));
1532 skb = ath10k_wmi_alloc_skb(ar, len);
1533 if (!skb)
1534 return ERR_PTR(-ENOMEM);
1535
1536 ptr = (void *)skb->data;
1537 tlv = ptr;
1538 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
1539 tlv->len = __cpu_to_le16(sizeof(*cmd));
1540 cmd = (void *)tlv->value;
1541
1542 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1543 cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
1544 cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
1545 cmd->flags = __cpu_to_le32(arg->peer_flags);
1546 cmd->caps = __cpu_to_le32(arg->peer_caps);
1547 cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
1548 cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
1549 cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
1550 cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
1551 cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
1552 cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
1553 cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
1554 cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
1555 cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
1556 cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
1557 ether_addr_copy(cmd->mac_addr.addr, arg->addr);
1558
1559 ptr += sizeof(*tlv);
1560 ptr += sizeof(*cmd);
1561
1562 tlv = ptr;
1563 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1564 tlv->len = __cpu_to_le16(legacy_rate_len);
1565 memcpy(tlv->value, arg->peer_legacy_rates.rates,
1566 arg->peer_legacy_rates.num_rates);
1567
1568 ptr += sizeof(*tlv);
1569 ptr += legacy_rate_len;
1570
1571 tlv = ptr;
1572 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1573 tlv->len = __cpu_to_le16(ht_rate_len);
1574 memcpy(tlv->value, arg->peer_ht_rates.rates,
1575 arg->peer_ht_rates.num_rates);
1576
1577 ptr += sizeof(*tlv);
1578 ptr += ht_rate_len;
1579
1580 tlv = ptr;
1581 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
1582 tlv->len = __cpu_to_le16(sizeof(*vht_rate));
1583 vht_rate = (void *)tlv->value;
1584
1585 vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
1586 vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
1587 vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
1588 vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
1589
1590 ptr += sizeof(*tlv);
1591 ptr += sizeof(*vht_rate);
1592
1593 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
1594 return skb;
1595}
1596
1597static struct sk_buff *
1598ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
1599 enum wmi_sta_ps_mode psmode)
1600{
1601 struct wmi_sta_powersave_mode_cmd *cmd;
1602 struct wmi_tlv *tlv;
1603 struct sk_buff *skb;
1604
1605 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1606 if (!skb)
1607 return ERR_PTR(-ENOMEM);
1608
1609 tlv = (void *)skb->data;
1610 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
1611 tlv->len = __cpu_to_le16(sizeof(*cmd));
1612 cmd = (void *)tlv->value;
1613 cmd->vdev_id = __cpu_to_le32(vdev_id);
1614 cmd->sta_ps_mode = __cpu_to_le32(psmode);
1615
1616 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
1617 return skb;
1618}
1619
1620static struct sk_buff *
1621ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
1622 enum wmi_sta_powersave_param param_id,
1623 u32 param_value)
1624{
1625 struct wmi_sta_powersave_param_cmd *cmd;
1626 struct wmi_tlv *tlv;
1627 struct sk_buff *skb;
1628
1629 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1630 if (!skb)
1631 return ERR_PTR(-ENOMEM);
1632
1633 tlv = (void *)skb->data;
1634 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
1635 tlv->len = __cpu_to_le16(sizeof(*cmd));
1636 cmd = (void *)tlv->value;
1637 cmd->vdev_id = __cpu_to_le32(vdev_id);
1638 cmd->param_id = __cpu_to_le32(param_id);
1639 cmd->param_value = __cpu_to_le32(param_value);
1640
1641 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
1642 return skb;
1643}
1644
1645static struct sk_buff *
1646ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
1647 enum wmi_ap_ps_peer_param param_id, u32 value)
1648{
1649 struct wmi_ap_ps_peer_cmd *cmd;
1650 struct wmi_tlv *tlv;
1651 struct sk_buff *skb;
1652
1653 if (!mac)
1654 return ERR_PTR(-EINVAL);
1655
1656 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
1657 if (!skb)
1658 return ERR_PTR(-ENOMEM);
1659
1660 tlv = (void *)skb->data;
1661 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
1662 tlv->len = __cpu_to_le16(sizeof(*cmd));
1663 cmd = (void *)tlv->value;
1664 cmd->vdev_id = __cpu_to_le32(vdev_id);
1665 cmd->param_id = __cpu_to_le32(param_id);
1666 cmd->param_value = __cpu_to_le32(value);
1667 ether_addr_copy(cmd->peer_macaddr.addr, mac);
1668
1669 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
1670 return skb;
1671}
1672
1673static struct sk_buff *
1674ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
1675 const struct wmi_scan_chan_list_arg *arg)
1676{
1677 struct wmi_tlv_scan_chan_list_cmd *cmd;
1678 struct wmi_channel *ci;
1679 struct wmi_channel_arg *ch;
1680 struct wmi_tlv *tlv;
1681 struct sk_buff *skb;
1682 size_t chans_len, len;
1683 int i;
1684 void *ptr, *chans;
1685
1686 chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
1687 len = (sizeof(*tlv) + sizeof(*cmd)) +
1688 (sizeof(*tlv) + chans_len);
1689
1690 skb = ath10k_wmi_alloc_skb(ar, len);
1691 if (!skb)
1692 return ERR_PTR(-ENOMEM);
1693
1694 ptr = (void *)skb->data;
1695 tlv = ptr;
1696 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
1697 tlv->len = __cpu_to_le16(sizeof(*cmd));
1698 cmd = (void *)tlv->value;
1699 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
1700
1701 ptr += sizeof(*tlv);
1702 ptr += sizeof(*cmd);
1703
1704 tlv = ptr;
1705 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1706 tlv->len = __cpu_to_le16(chans_len);
1707 chans = (void *)tlv->value;
1708
1709 for (i = 0; i < arg->n_channels; i++) {
1710 ch = &arg->channels[i];
1711
1712 tlv = chans;
1713 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1714 tlv->len = __cpu_to_le16(sizeof(*ci));
1715 ci = (void *)tlv->value;
1716
1717 ath10k_wmi_put_wmi_channel(ci, ch);
1718
1719 chans += sizeof(*tlv);
1720 chans += sizeof(*ci);
1721 }
1722
1723 ptr += sizeof(*tlv);
1724 ptr += chans_len;
1725
1726 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
1727 return skb;
1728}
1729
1730static struct sk_buff *
1731ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k_vif *arvif)
1732{
1733 struct ath10k *ar = arvif->ar;
1734 struct wmi_bcn_tx_ref_cmd *cmd;
1735 struct wmi_tlv *tlv;
1736 struct sk_buff *skb;
1737 struct sk_buff *beacon = arvif->beacon;
1738 struct ieee80211_hdr *hdr;
1739 u16 fc;
1740
1741 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1742 if (!skb)
1743 return ERR_PTR(-ENOMEM);
1744
1745 hdr = (struct ieee80211_hdr *)beacon->data;
1746 fc = le16_to_cpu(hdr->frame_control);
1747
1748 tlv = (void *)skb->data;
1749 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
1750 tlv->len = __cpu_to_le16(sizeof(*cmd));
1751 cmd = (void *)tlv->value;
1752 cmd->vdev_id = __cpu_to_le32(arvif->vdev_id);
1753 cmd->data_len = __cpu_to_le32(beacon->len);
1754 cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr);
1755 cmd->msdu_id = 0;
1756 cmd->frame_control = __cpu_to_le32(fc);
1757 cmd->flags = 0;
1758
1759 if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero)
1760 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
1761
1762 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab)
1763 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
1764
1765 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
1766 return skb;
1767}
1768
1769static void *ath10k_wmi_tlv_put_wmm(void *ptr,
1770 const struct wmi_wmm_params_arg *arg)
1771{
1772 struct wmi_wmm_params *wmm;
1773 struct wmi_tlv *tlv;
1774
1775 tlv = ptr;
1776 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
1777 tlv->len = __cpu_to_le16(sizeof(*wmm));
1778 wmm = (void *)tlv->value;
1779 ath10k_wmi_pdev_set_wmm_param(wmm, arg);
1780
1781 return ptr + sizeof(*tlv) + sizeof(*wmm);
1782}
1783
1784static struct sk_buff *
1785ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
1786 const struct wmi_pdev_set_wmm_params_arg *arg)
1787{
1788 struct wmi_tlv_pdev_set_wmm_cmd *cmd;
1789 struct wmi_wmm_params *wmm;
1790 struct wmi_tlv *tlv;
1791 struct sk_buff *skb;
1792 size_t len;
1793 void *ptr;
1794
1795 len = (sizeof(*tlv) + sizeof(*cmd)) +
1796 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1797 skb = ath10k_wmi_alloc_skb(ar, len);
1798 if (!skb)
1799 return ERR_PTR(-ENOMEM);
1800
1801 ptr = (void *)skb->data;
1802
1803 tlv = ptr;
1804 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
1805 tlv->len = __cpu_to_le16(sizeof(*cmd));
1806 cmd = (void *)tlv->value;
1807
1808 /* nothing to set here */
1809
1810 ptr += sizeof(*tlv);
1811 ptr += sizeof(*cmd);
1812
1813 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
1814 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1815 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1816 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1817
1818 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
1819 return skb;
1820}
1821
1822static struct sk_buff *
1823ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
1824 enum wmi_stats_id stats_id)
1825{
1826 struct wmi_request_stats_cmd *cmd;
1827 struct wmi_tlv *tlv;
1828 struct sk_buff *skb;
1829
1830 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1831 if (!skb)
1832 return ERR_PTR(-ENOMEM);
1833
1834 tlv = (void *)skb->data;
1835 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
1836 tlv->len = __cpu_to_le16(sizeof(*cmd));
1837 cmd = (void *)tlv->value;
1838 cmd->stats_id = __cpu_to_le32(stats_id);
1839
1840 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
1841 return skb;
1842}
1843
1844static struct sk_buff *
1845ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
1846 enum wmi_force_fw_hang_type type,
1847 u32 delay_ms)
1848{
1849 struct wmi_force_fw_hang_cmd *cmd;
1850 struct wmi_tlv *tlv;
1851 struct sk_buff *skb;
1852
1853 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1854 if (!skb)
1855 return ERR_PTR(-ENOMEM);
1856
1857 tlv = (void *)skb->data;
1858 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
1859 tlv->len = __cpu_to_le16(sizeof(*cmd));
1860 cmd = (void *)tlv->value;
1861 cmd->type = __cpu_to_le32(type);
1862 cmd->delay_ms = __cpu_to_le32(delay_ms);
1863
1864 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
1865 return skb;
1866}
1867
1868static struct sk_buff *
1869ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable)
1870{
1871 struct wmi_tlv_dbglog_cmd *cmd;
1872 struct wmi_tlv *tlv;
1873 struct sk_buff *skb;
1874 size_t len, bmap_len;
1875 u32 value;
1876 void *ptr;
1877
1878 if (module_enable) {
1879 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
1880 module_enable,
1881 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
1882 } else {
1883 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
1884 WMI_TLV_DBGLOG_ALL_MODULES,
1885 WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
1886 }
1887
1888 bmap_len = 0;
1889 len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
1890 skb = ath10k_wmi_alloc_skb(ar, len);
1891 if (!skb)
1892 return ERR_PTR(-ENOMEM);
1893
1894 ptr = (void *)skb->data;
1895
1896 tlv = ptr;
1897 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
1898 tlv->len = __cpu_to_le16(sizeof(*cmd));
1899 cmd = (void *)tlv->value;
1900 cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
1901 cmd->value = __cpu_to_le32(value);
1902
1903 ptr += sizeof(*tlv);
1904 ptr += sizeof(*cmd);
1905
1906 tlv = ptr;
1907 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1908 tlv->len = __cpu_to_le16(bmap_len);
1909
1910 /* nothing to do here */
1911
1912 ptr += sizeof(*tlv);
1913 ptr += sizeof(bmap_len);
1914
1915 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
1916 return skb;
1917}
1918
1919static struct sk_buff *
1920ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
1921{
1922 struct wmi_tlv_pktlog_enable *cmd;
1923 struct wmi_tlv *tlv;
1924 struct sk_buff *skb;
1925 void *ptr;
1926 size_t len;
1927
1928 len = sizeof(*tlv) + sizeof(*cmd);
1929 skb = ath10k_wmi_alloc_skb(ar, len);
1930 if (!skb)
1931 return ERR_PTR(-ENOMEM);
1932
1933 ptr = (void *)skb->data;
1934 tlv = ptr;
1935 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
1936 tlv->len = __cpu_to_le16(sizeof(*cmd));
1937 cmd = (void *)tlv->value;
1938 cmd->filter = __cpu_to_le32(filter);
1939
1940 ptr += sizeof(*tlv);
1941 ptr += sizeof(*cmd);
1942
1943 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
1944 filter);
1945 return skb;
1946}
1947
1948static struct sk_buff *
1949ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
1950{
1951 struct wmi_tlv_pktlog_disable *cmd;
1952 struct wmi_tlv *tlv;
1953 struct sk_buff *skb;
1954 void *ptr;
1955 size_t len;
1956
1957 len = sizeof(*tlv) + sizeof(*cmd);
1958 skb = ath10k_wmi_alloc_skb(ar, len);
1959 if (!skb)
1960 return ERR_PTR(-ENOMEM);
1961
1962 ptr = (void *)skb->data;
1963 tlv = ptr;
1964 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
1965 tlv->len = __cpu_to_le16(sizeof(*cmd));
1966 cmd = (void *)tlv->value;
1967
1968 ptr += sizeof(*tlv);
1969 ptr += sizeof(*cmd);
1970
1971 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
1972 return skb;
1973}
1974
Michal Kaziorbe9ce9d2015-01-13 16:30:11 +02001975static struct sk_buff *
1976ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
1977 u32 tim_ie_offset, struct sk_buff *bcn,
1978 u32 prb_caps, u32 prb_erp, void *prb_ies,
1979 size_t prb_ies_len)
1980{
1981 struct wmi_tlv_bcn_tmpl_cmd *cmd;
1982 struct wmi_tlv_bcn_prb_info *info;
1983 struct wmi_tlv *tlv;
1984 struct sk_buff *skb;
1985 void *ptr;
1986 size_t len;
1987
1988 if (WARN_ON(prb_ies_len > 0 && !prb_ies))
1989 return ERR_PTR(-EINVAL);
1990
1991 len = sizeof(*tlv) + sizeof(*cmd) +
1992 sizeof(*tlv) + sizeof(*info) + prb_ies_len +
1993 sizeof(*tlv) + roundup(bcn->len, 4);
1994 skb = ath10k_wmi_alloc_skb(ar, len);
1995 if (!skb)
1996 return ERR_PTR(-ENOMEM);
1997
1998 ptr = (void *)skb->data;
1999 tlv = ptr;
2000 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
2001 tlv->len = __cpu_to_le16(sizeof(*cmd));
2002 cmd = (void *)tlv->value;
2003 cmd->vdev_id = __cpu_to_le32(vdev_id);
2004 cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
2005 cmd->buf_len = __cpu_to_le32(bcn->len);
2006
2007 ptr += sizeof(*tlv);
2008 ptr += sizeof(*cmd);
2009
2010 /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
2011 * then it is then impossible to pass original ie len.
2012 * This chunk is not used yet so if setting probe resp template yields
2013 * problems with beaconing or crashes firmware look here.
2014 */
2015 tlv = ptr;
2016 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
2017 tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
2018 info = (void *)tlv->value;
2019 info->caps = __cpu_to_le32(prb_caps);
2020 info->erp = __cpu_to_le32(prb_erp);
2021 memcpy(info->ies, prb_ies, prb_ies_len);
2022
2023 ptr += sizeof(*tlv);
2024 ptr += sizeof(*info);
2025 ptr += prb_ies_len;
2026
2027 tlv = ptr;
2028 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2029 tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
2030 memcpy(tlv->value, bcn->data, bcn->len);
2031
2032 /* FIXME: Adjust TSF? */
2033
2034 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
2035 vdev_id);
2036 return skb;
2037}
2038
Michal Kaziorca996ec2014-12-03 10:11:32 +02002039/****************/
2040/* TLV mappings */
2041/****************/
2042
2043static struct wmi_cmd_map wmi_tlv_cmd_map = {
2044 .init_cmdid = WMI_TLV_INIT_CMDID,
2045 .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
2046 .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
2047 .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
2048 .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
2049 .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
2050 .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
2051 .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
2052 .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
2053 .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
2054 .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
2055 .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
2056 .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
2057 .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
2058 .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
2059 .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
2060 .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
2061 .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
2062 .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
2063 .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
2064 .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
2065 .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
2066 .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
2067 .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
2068 .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
2069 .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
2070 .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
2071 .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
2072 .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
2073 .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
2074 .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
2075 .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
2076 .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
2077 .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
2078 .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
2079 .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
2080 .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
2081 .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
2082 .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
2083 .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
2084 .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
2085 .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
2086 .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
2087 .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
2088 .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
2089 .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
2090 .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
2091 .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
2092 .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
2093 .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
2094 .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
2095 .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
2096 .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
2097 .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
2098 .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
2099 .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
2100 .roam_scan_rssi_change_threshold =
2101 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
2102 .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
2103 .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
2104 .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
2105 .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
2106 .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
2107 .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
2108 .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
2109 .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
2110 .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
2111 .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
2112 .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
2113 .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
2114 .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
2115 .wlan_profile_set_hist_intvl_cmdid =
2116 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2117 .wlan_profile_get_profile_data_cmdid =
2118 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
2119 .wlan_profile_enable_profile_id_cmdid =
2120 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2121 .wlan_profile_list_profile_id_cmdid =
2122 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
2123 .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
2124 .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
2125 .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
2126 .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
2127 .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
2128 .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
2129 .wow_enable_disable_wake_event_cmdid =
2130 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
2131 .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
2132 .wow_hostwakeup_from_sleep_cmdid =
2133 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
2134 .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
2135 .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
2136 .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
2137 .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
2138 .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
2139 .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
2140 .network_list_offload_config_cmdid =
2141 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
2142 .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
2143 .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
2144 .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
2145 .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
2146 .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
2147 .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
2148 .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
2149 .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
2150 .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
2151 .echo_cmdid = WMI_TLV_ECHO_CMDID,
2152 .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
2153 .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
2154 .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
2155 .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
2156 .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
2157 .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
2158 .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
2159 .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
2160 .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
Rajkumar Manoharana57a6a22014-12-17 12:22:17 +02002161 .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
Michal Kaziorca996ec2014-12-03 10:11:32 +02002162};
2163
2164static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
2165 .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
2166 .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
2167 .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
2168 .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
2169 .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
2170 .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
2171 .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
2172 .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
2173 .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
2174 .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
2175 .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
2176 .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
2177 .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
2178 .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
2179 .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
2180 .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
2181 .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
2182 .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
2183 .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
2184 .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
2185 .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
2186 .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
2187 .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
2188 .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
2189 .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
2190 .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
2191 .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2192 .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2193 .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
2194 .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
2195 .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
2196 .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
2197 .bcnflt_stats_update_period =
2198 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
2199 .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
2200 .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
2201 .dcs = WMI_TLV_PDEV_PARAM_DCS,
2202 .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
2203 .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
2204 .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
2205 .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
2206 .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
2207 .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
2208 .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
2209 .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
2210 .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
2211 .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
2212 .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
2213 .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
Peter Oha7bd3e92014-12-02 13:07:14 +02002214 .cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
Michal Kaziorca996ec2014-12-03 10:11:32 +02002215};
2216
2217static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
2218 .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
2219 .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
2220 .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
2221 .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
2222 .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
2223 .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
2224 .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
2225 .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
2226 .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
2227 .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
2228 .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
2229 .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
2230 .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
2231 .wmi_vdev_oc_scheduler_air_time_limit =
2232 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
2233 .wds = WMI_TLV_VDEV_PARAM_WDS,
2234 .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
2235 .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
2236 .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
2237 .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
2238 .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
2239 .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
2240 .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
2241 .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
2242 .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
2243 .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
2244 .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
2245 .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
2246 .sgi = WMI_TLV_VDEV_PARAM_SGI,
2247 .ldpc = WMI_TLV_VDEV_PARAM_LDPC,
2248 .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
2249 .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
2250 .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
2251 .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
2252 .nss = WMI_TLV_VDEV_PARAM_NSS,
2253 .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
2254 .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
2255 .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
2256 .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
2257 .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
2258 .ap_keepalive_min_idle_inactive_time_secs =
2259 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
2260 .ap_keepalive_max_idle_inactive_time_secs =
2261 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
2262 .ap_keepalive_max_unresponsive_time_secs =
2263 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
2264 .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
2265 .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2266 .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
2267 .txbf = WMI_TLV_VDEV_PARAM_TXBF,
2268 .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
2269 .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
2270 .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
2271 .ap_detect_out_of_sync_sleeping_sta_time_secs =
2272 WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2273};
2274
2275static const struct wmi_ops wmi_tlv_ops = {
2276 .rx = ath10k_wmi_tlv_op_rx,
2277 .map_svc = wmi_tlv_svc_map,
2278
2279 .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
2280 .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
2281 .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
2282 .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
2283 .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
2284 .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
2285 .pull_phyerr = ath10k_wmi_tlv_op_pull_phyerr_ev,
2286 .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
2287 .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
2288 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
2289
2290 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
2291 .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
2292 .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
2293 .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
2294 .gen_init = ath10k_wmi_tlv_op_gen_init,
2295 .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
2296 .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
2297 .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
2298 .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
2299 .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
2300 .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
2301 .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
2302 .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
2303 .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
2304 .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
2305 .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
2306 .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
2307 .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
2308 .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
2309 .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
2310 .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
2311 .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
2312 .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
2313 .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
2314 .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
2315 .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
2316 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
2317 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
2318 /* .gen_mgmt_tx = not implemented; HTT is used */
2319 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
2320 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
2321 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
Rajkumar Manoharanffdd7382014-12-17 12:21:40 +02002322 /* .gen_pdev_set_quiet_mode not implemented */
Rajkumar Manoharana57a6a22014-12-17 12:22:17 +02002323 /* .gen_pdev_get_temperature not implemented */
Rajkumar Manoharandc8ab272015-01-12 14:07:25 +02002324 /* .gen_addba_clear_resp not implemented */
Rajkumar Manoharan65c08932015-01-12 14:07:26 +02002325 /* .gen_addba_send not implemented */
Rajkumar Manoharan11597412015-01-12 14:07:26 +02002326 /* .gen_addba_set_resp not implemented */
Rajkumar Manoharan50abef82015-01-12 14:07:26 +02002327 /* .gen_delba_send not implemented */
Michal Kaziorbe9ce9d2015-01-13 16:30:11 +02002328 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
Michal Kaziorca996ec2014-12-03 10:11:32 +02002329};
2330
2331/************/
2332/* TLV init */
2333/************/
2334
2335void ath10k_wmi_tlv_attach(struct ath10k *ar)
2336{
2337 ar->wmi.cmd = &wmi_tlv_cmd_map;
2338 ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
2339 ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
2340 ar->wmi.ops = &wmi_tlv_ops;
2341}