kernel: bump 4.14 to 4.14.72
[openwrt/staging/wigyori.git] / package / kernel / mac80211 / patches / 380-0003-ath10k-debugfs-support-to-get-final-TPC-stats-for-10.patch
1 From bc64d05220f3e34cf432a166b83c8fff14cd7a3d Mon Sep 17 00:00:00 2001
2 From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
3 Date: Wed, 14 Mar 2018 12:14:08 +0200
4 Subject: [PATCH] ath10k: debugfs support to get final TPC stats for 10.4
5 variants
6
7 Export the final Transmit Power Control (TPC) value, which is the
8 minimum of control power and existing TPC value to user space via
9 a new debugfs file "tpc_stats_final" to help with debugging.
10 It works with the new wmi cmd and event introduced in 10.4 firmware
11 branch.
12
13 WMI command ID: WMI_PDEV_GET_TPC_TABLE_CMDID
14 WMI event ID: WMI_PDEV_TPC_TABLE_EVENTID
15
16 cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final
17
18 $ cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final
19
20 TPC config for channel 5180 mode 10
21
22 CTL = 0x 0 Reg. Domain = 58
23 Antenna Gain = 0 Reg. Max Antenna Gain = 0
24 Power Limit = 60 Reg. Max Power = 60
25 Num tx chains = 2 Num supported rates = 109
26
27 ******************* CDD POWER TABLE ****************
28
29 No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3
30 0 CCK 0x40 0 0
31 1 CCK 0x41 0 0
32 [...]
33 107 HTCUP 0x 0 46 46
34 108 HTCUP 0x 0 46 46
35
36 ******************* STBC POWER TABLE ****************
37
38 No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3
39 0 CCK 0x40 0 0
40 1 CCK 0x41 0 0
41 [...]
42 107 HTCUP 0x 0 46 46
43 108 HTCUP 0x 0 46 46
44
45 ***********************************
46 TXBF not supported
47 **********************************
48
49 The existing tpc_stats debugfs file provides the dump
50 which is minimum of target power and regulatory domain.
51
52 cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats
53
54 Hardware_used: QCA4019
55 Firmware version: firmware-5.bin_10.4-3.0-00209
56
57 Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
58 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
59 ---
60 drivers/net/wireless/ath/ath10k/core.h | 22 +++
61 drivers/net/wireless/ath/ath10k/debug.c | 107 +++++++++++
62 drivers/net/wireless/ath/ath10k/debug.h | 10 +
63 drivers/net/wireless/ath/ath10k/wmi-ops.h | 20 ++
64 drivers/net/wireless/ath/ath10k/wmi.c | 308 ++++++++++++++++++++++++++++--
65 drivers/net/wireless/ath/ath10k/wmi.h | 66 +++++++
66 6 files changed, 518 insertions(+), 15 deletions(-)
67
68 --- a/drivers/net/wireless/ath/ath10k/core.h
69 +++ b/drivers/net/wireless/ath/ath10k/core.h
70 @@ -322,6 +322,27 @@ struct ath10k_tpc_stats {
71 struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG];
72 };
73
74 +struct ath10k_tpc_table_final {
75 + u32 pream_idx[WMI_TPC_FINAL_RATE_MAX];
76 + u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
77 + char tpc_value[WMI_TPC_FINAL_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
78 +};
79 +
80 +struct ath10k_tpc_stats_final {
81 + u32 reg_domain;
82 + u32 chan_freq;
83 + u32 phy_mode;
84 + u32 twice_antenna_reduction;
85 + u32 twice_max_rd_power;
86 + s32 twice_antenna_gain;
87 + u32 power_limit;
88 + u32 num_tx_chain;
89 + u32 ctl;
90 + u32 rate_max;
91 + u8 flag[WMI_TPC_FLAG];
92 + struct ath10k_tpc_table_final tpc_table_final[WMI_TPC_FLAG];
93 +};
94 +
95 struct ath10k_dfs_stats {
96 u32 phy_errors;
97 u32 pulses_total;
98 @@ -482,6 +503,7 @@ struct ath10k_debug {
99
100 /* used for tpc-dump storage, protected by data-lock */
101 struct ath10k_tpc_stats *tpc_stats;
102 + struct ath10k_tpc_stats_final *tpc_stats_final;
103
104 struct completion tpc_complete;
105
106 --- a/drivers/net/wireless/ath/ath10k/debug.c
107 +++ b/drivers/net/wireless/ath/ath10k/debug.c
108 @@ -1737,6 +1737,19 @@ void ath10k_debug_tpc_stats_process(stru
109 spin_unlock_bh(&ar->data_lock);
110 }
111
112 +void
113 +ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
114 + struct ath10k_tpc_stats_final *tpc_stats)
115 +{
116 + spin_lock_bh(&ar->data_lock);
117 +
118 + kfree(ar->debug.tpc_stats_final);
119 + ar->debug.tpc_stats_final = tpc_stats;
120 + complete(&ar->debug.tpc_complete);
121 +
122 + spin_unlock_bh(&ar->data_lock);
123 +}
124 +
125 static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
126 unsigned int j, char *buf, size_t *len)
127 {
128 @@ -2400,6 +2413,95 @@ static const struct file_operations fops
129 .llseek = default_llseek,
130 };
131
132 +static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
133 +{
134 + int ret;
135 + unsigned long time_left;
136 +
137 + lockdep_assert_held(&ar->conf_mutex);
138 +
139 + reinit_completion(&ar->debug.tpc_complete);
140 +
141 + ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
142 + if (ret) {
143 + ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
144 + return ret;
145 + }
146 +
147 + time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
148 + 1 * HZ);
149 + if (time_left == 0)
150 + return -ETIMEDOUT;
151 +
152 + return 0;
153 +}
154 +
155 +static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
156 +{
157 + struct ath10k *ar = inode->i_private;
158 + void *buf;
159 + int ret;
160 +
161 + mutex_lock(&ar->conf_mutex);
162 +
163 + if (ar->state != ATH10K_STATE_ON) {
164 + ret = -ENETDOWN;
165 + goto err_unlock;
166 + }
167 +
168 + buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
169 + if (!buf) {
170 + ret = -ENOMEM;
171 + goto err_unlock;
172 + }
173 +
174 + ret = ath10k_debug_tpc_stats_final_request(ar);
175 + if (ret) {
176 + ath10k_warn(ar, "failed to request tpc stats final: %d\n",
177 + ret);
178 + goto err_free;
179 + }
180 +
181 + ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
182 + file->private_data = buf;
183 +
184 + mutex_unlock(&ar->conf_mutex);
185 + return 0;
186 +
187 +err_free:
188 + vfree(buf);
189 +
190 +err_unlock:
191 + mutex_unlock(&ar->conf_mutex);
192 + return ret;
193 +}
194 +
195 +static int ath10k_tpc_stats_final_release(struct inode *inode,
196 + struct file *file)
197 +{
198 + vfree(file->private_data);
199 +
200 + return 0;
201 +}
202 +
203 +static ssize_t ath10k_tpc_stats_final_read(struct file *file,
204 + char __user *user_buf,
205 + size_t count, loff_t *ppos)
206 +{
207 + const char *buf = file->private_data;
208 + unsigned int len = strlen(buf);
209 +
210 + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
211 +}
212 +
213 +static const struct file_operations fops_tpc_stats_final = {
214 + .open = ath10k_tpc_stats_final_open,
215 + .release = ath10k_tpc_stats_final_release,
216 + .read = ath10k_tpc_stats_final_read,
217 + .owner = THIS_MODULE,
218 + .llseek = default_llseek,
219 +};
220 +
221 int ath10k_debug_create(struct ath10k *ar)
222 {
223 ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
224 @@ -2525,6 +2627,11 @@ int ath10k_debug_register(struct ath10k
225 debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
226 &fops_fw_checksums);
227
228 + if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
229 + debugfs_create_file("tpc_stats_final", 0400,
230 + ar->debug.debugfs_phy, ar,
231 + &fops_tpc_stats_final);
232 +
233 return 0;
234 }
235
236 --- a/drivers/net/wireless/ath/ath10k/debug.h
237 +++ b/drivers/net/wireless/ath/ath10k/debug.h
238 @@ -84,6 +84,9 @@ void ath10k_debug_unregister(struct ath1
239 void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
240 void ath10k_debug_tpc_stats_process(struct ath10k *ar,
241 struct ath10k_tpc_stats *tpc_stats);
242 +void
243 +ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
244 + struct ath10k_tpc_stats_final *tpc_stats);
245 struct ath10k_fw_crash_data *
246 ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
247
248 @@ -151,6 +154,13 @@ static inline void ath10k_debug_tpc_stat
249 {
250 kfree(tpc_stats);
251 }
252 +
253 +static inline void
254 +ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
255 + struct ath10k_tpc_stats_final *tpc_stats)
256 +{
257 + kfree(tpc_stats);
258 +}
259
260 static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
261 int len)
262 --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
263 +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
264 @@ -197,6 +197,9 @@ struct wmi_ops {
265 (struct ath10k *ar,
266 enum wmi_bss_survey_req_type type);
267 struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
268 + struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
269 + u32 param);
270 +
271 };
272
273 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
274 @@ -1418,4 +1421,21 @@ ath10k_wmi_echo(struct ath10k *ar, u32 v
275 return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
276 }
277
278 +static inline int
279 +ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
280 +{
281 + struct sk_buff *skb;
282 +
283 + if (!ar->wmi.ops->gen_pdev_get_tpc_table_cmdid)
284 + return -EOPNOTSUPP;
285 +
286 + skb = ar->wmi.ops->gen_pdev_get_tpc_table_cmdid(ar, param);
287 +
288 + if (IS_ERR(skb))
289 + return PTR_ERR(skb);
290 +
291 + return ath10k_wmi_cmd_send(ar, skb,
292 + ar->wmi.cmd->pdev_get_tpc_table_cmdid);
293 +}
294 +
295 #endif
296 --- a/drivers/net/wireless/ath/ath10k/wmi.c
297 +++ b/drivers/net/wireless/ath/ath10k/wmi.c
298 @@ -1,6 +1,7 @@
299 /*
300 * Copyright (c) 2005-2011 Atheros Communications Inc.
301 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
302 + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
303 *
304 * Permission to use, copy, modify, and/or distribute this software for any
305 * purpose with or without fee is hereby granted, provided that the above
306 @@ -196,6 +197,7 @@ static struct wmi_cmd_map wmi_cmd_map =
307 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
308 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
309 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
310 + .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
311 };
312
313 /* 10.X WMI cmd track */
314 @@ -362,6 +364,7 @@ static struct wmi_cmd_map wmi_10x_cmd_ma
315 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
316 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
317 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
318 + .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
319 };
320
321 /* 10.2.4 WMI cmd track */
322 @@ -528,6 +531,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd
323 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
324 .pdev_bss_chan_info_request_cmdid =
325 WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
326 + .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
327 };
328
329 /* 10.4 WMI cmd track */
330 @@ -1480,6 +1484,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_m
331 .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
332 .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
333 .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
334 + .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
335 };
336
337 static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
338 @@ -4313,19 +4318,11 @@ static void ath10k_tpc_config_disp_table
339 }
340 }
341
342 -void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
343 +void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
344 + u32 num_tx_chain)
345 {
346 - u32 i, j, pream_idx, num_tx_chain;
347 - u8 rate_code[WMI_TPC_RATE_MAX], rate_idx;
348 - u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
349 - struct wmi_pdev_tpc_config_event *ev;
350 - struct ath10k_tpc_stats *tpc_stats;
351 -
352 - ev = (struct wmi_pdev_tpc_config_event *)skb->data;
353 -
354 - tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
355 - if (!tpc_stats)
356 - return;
357 + u32 i, j, pream_idx;
358 + u8 rate_idx;
359
360 /* Create the rate code table based on the chains supported */
361 rate_idx = 0;
362 @@ -4349,8 +4346,6 @@ void ath10k_wmi_event_pdev_tpc_config(st
363 pream_table[pream_idx] = rate_idx;
364 pream_idx++;
365
366 - num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
367 -
368 /* Fill HT20 rate code */
369 for (i = 0; i < num_tx_chain; i++) {
370 for (j = 0; j < 8; j++) {
371 @@ -4374,7 +4369,7 @@ void ath10k_wmi_event_pdev_tpc_config(st
372 pream_idx++;
373
374 /* Fill VHT20 rate code */
375 - for (i = 0; i < __le32_to_cpu(ev->num_tx_chain); i++) {
376 + for (i = 0; i < num_tx_chain; i++) {
377 for (j = 0; j < 10; j++) {
378 rate_code[rate_idx] =
379 ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
380 @@ -4418,6 +4413,26 @@ void ath10k_wmi_event_pdev_tpc_config(st
381 ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
382
383 pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END;
384 +}
385 +
386 +void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
387 +{
388 + u32 num_tx_chain;
389 + u8 rate_code[WMI_TPC_RATE_MAX];
390 + u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
391 + struct wmi_pdev_tpc_config_event *ev;
392 + struct ath10k_tpc_stats *tpc_stats;
393 +
394 + ev = (struct wmi_pdev_tpc_config_event *)skb->data;
395 +
396 + tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
397 + if (!tpc_stats)
398 + return;
399 +
400 + num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
401 +
402 + ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
403 + num_tx_chain);
404
405 tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
406 tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
407 @@ -4457,6 +4472,246 @@ void ath10k_wmi_event_pdev_tpc_config(st
408 __le32_to_cpu(ev->rate_max));
409 }
410
411 +static u8
412 +ath10k_wmi_tpc_final_get_rate(struct ath10k *ar,
413 + struct wmi_pdev_tpc_final_table_event *ev,
414 + u32 rate_idx, u32 num_chains,
415 + u32 rate_code, u8 type, u32 pream_idx)
416 +{
417 + u8 tpc, num_streams, preamble, ch, stm_idx;
418 + s8 pow_agcdd, pow_agstbc, pow_agtxbf;
419 + int pream;
420 +
421 + num_streams = ATH10K_HW_NSS(rate_code);
422 + preamble = ATH10K_HW_PREAMBLE(rate_code);
423 + ch = num_chains - 1;
424 + stm_idx = num_streams - 1;
425 + pream = -1;
426 +
427 + if (__le32_to_cpu(ev->chan_freq) <= 2483) {
428 + switch (pream_idx) {
429 + case WMI_TPC_PREAM_2GHZ_CCK:
430 + pream = 0;
431 + break;
432 + case WMI_TPC_PREAM_2GHZ_OFDM:
433 + pream = 1;
434 + break;
435 + case WMI_TPC_PREAM_2GHZ_HT20:
436 + case WMI_TPC_PREAM_2GHZ_VHT20:
437 + pream = 2;
438 + break;
439 + case WMI_TPC_PREAM_2GHZ_HT40:
440 + case WMI_TPC_PREAM_2GHZ_VHT40:
441 + pream = 3;
442 + break;
443 + case WMI_TPC_PREAM_2GHZ_VHT80:
444 + pream = 4;
445 + break;
446 + default:
447 + pream = -1;
448 + break;
449 + }
450 + }
451 +
452 + if (__le32_to_cpu(ev->chan_freq) >= 5180) {
453 + switch (pream_idx) {
454 + case WMI_TPC_PREAM_5GHZ_OFDM:
455 + pream = 0;
456 + break;
457 + case WMI_TPC_PREAM_5GHZ_HT20:
458 + case WMI_TPC_PREAM_5GHZ_VHT20:
459 + pream = 1;
460 + break;
461 + case WMI_TPC_PREAM_5GHZ_HT40:
462 + case WMI_TPC_PREAM_5GHZ_VHT40:
463 + pream = 2;
464 + break;
465 + case WMI_TPC_PREAM_5GHZ_VHT80:
466 + pream = 3;
467 + break;
468 + case WMI_TPC_PREAM_5GHZ_HTCUP:
469 + pream = 4;
470 + break;
471 + default:
472 + pream = -1;
473 + break;
474 + }
475 + }
476 +
477 + if (pream == 4)
478 + tpc = min_t(u8, ev->rates_array[rate_idx],
479 + ev->max_reg_allow_pow[ch]);
480 + else
481 + tpc = min_t(u8, min_t(u8, ev->rates_array[rate_idx],
482 + ev->max_reg_allow_pow[ch]),
483 + ev->ctl_power_table[0][pream][stm_idx]);
484 +
485 + if (__le32_to_cpu(ev->num_tx_chain) <= 1)
486 + goto out;
487 +
488 + if (preamble == WMI_RATE_PREAMBLE_CCK)
489 + goto out;
490 +
491 + if (num_chains <= num_streams)
492 + goto out;
493 +
494 + switch (type) {
495 + case WMI_TPC_TABLE_TYPE_STBC:
496 + pow_agstbc = ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx];
497 + if (pream == 4)
498 + tpc = min_t(u8, tpc, pow_agstbc);
499 + else
500 + tpc = min_t(u8, min_t(u8, tpc, pow_agstbc),
501 + ev->ctl_power_table[0][pream][stm_idx]);
502 + break;
503 + case WMI_TPC_TABLE_TYPE_TXBF:
504 + pow_agtxbf = ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx];
505 + if (pream == 4)
506 + tpc = min_t(u8, tpc, pow_agtxbf);
507 + else
508 + tpc = min_t(u8, min_t(u8, tpc, pow_agtxbf),
509 + ev->ctl_power_table[1][pream][stm_idx]);
510 + break;
511 + case WMI_TPC_TABLE_TYPE_CDD:
512 + pow_agcdd = ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx];
513 + if (pream == 4)
514 + tpc = min_t(u8, tpc, pow_agcdd);
515 + else
516 + tpc = min_t(u8, min_t(u8, tpc, pow_agcdd),
517 + ev->ctl_power_table[0][pream][stm_idx]);
518 + break;
519 + default:
520 + ath10k_warn(ar, "unknown wmi tpc final table type: %d\n", type);
521 + tpc = 0;
522 + break;
523 + }
524 +
525 +out:
526 + return tpc;
527 +}
528 +
529 +static void
530 +ath10k_wmi_tpc_stats_final_disp_tables(struct ath10k *ar,
531 + struct wmi_pdev_tpc_final_table_event *ev,
532 + struct ath10k_tpc_stats_final *tpc_stats,
533 + u8 *rate_code, u16 *pream_table, u8 type)
534 +{
535 + u32 i, j, pream_idx, flags;
536 + u8 tpc[WMI_TPC_TX_N_CHAIN];
537 + char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
538 + char buff[WMI_TPC_BUF_SIZE];
539 +
540 + flags = __le32_to_cpu(ev->flags);
541 +
542 + switch (type) {
543 + case WMI_TPC_TABLE_TYPE_CDD:
544 + if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
545 + ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
546 + tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
547 + return;
548 + }
549 + break;
550 + case WMI_TPC_TABLE_TYPE_STBC:
551 + if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
552 + ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
553 + tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
554 + return;
555 + }
556 + break;
557 + case WMI_TPC_TABLE_TYPE_TXBF:
558 + if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
559 + ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
560 + tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
561 + return;
562 + }
563 + break;
564 + default:
565 + ath10k_dbg(ar, ATH10K_DBG_WMI,
566 + "invalid table type in wmi tpc event: %d\n", type);
567 + return;
568 + }
569 +
570 + pream_idx = 0;
571 + for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) {
572 + memset(tpc_value, 0, sizeof(tpc_value));
573 + memset(buff, 0, sizeof(buff));
574 + if (i == pream_table[pream_idx])
575 + pream_idx++;
576 +
577 + for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) {
578 + if (j >= __le32_to_cpu(ev->num_tx_chain))
579 + break;
580 +
581 + tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1,
582 + rate_code[i],
583 + type, pream_idx);
584 + snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
585 + strncat(tpc_value, buff, strlen(buff));
586 + }
587 + tpc_stats->tpc_table_final[type].pream_idx[i] = pream_idx;
588 + tpc_stats->tpc_table_final[type].rate_code[i] = rate_code[i];
589 + memcpy(tpc_stats->tpc_table_final[type].tpc_value[i],
590 + tpc_value, sizeof(tpc_value));
591 + }
592 +}
593 +
594 +void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb)
595 +{
596 + u32 num_tx_chain;
597 + u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
598 + u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
599 + struct wmi_pdev_tpc_final_table_event *ev;
600 + struct ath10k_tpc_stats_final *tpc_stats;
601 +
602 + ev = (struct wmi_pdev_tpc_final_table_event *)skb->data;
603 +
604 + tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
605 + if (!tpc_stats)
606 + return;
607 +
608 + num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
609 +
610 + ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
611 + num_tx_chain);
612 +
613 + tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
614 + tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
615 + tpc_stats->ctl = __le32_to_cpu(ev->ctl);
616 + tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
617 + tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
618 + tpc_stats->twice_antenna_reduction =
619 + __le32_to_cpu(ev->twice_antenna_reduction);
620 + tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
621 + tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
622 + tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
623 + tpc_stats->rate_max = __le32_to_cpu(ev->rate_max);
624 +
625 + ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
626 + rate_code, pream_table,
627 + WMI_TPC_TABLE_TYPE_CDD);
628 + ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
629 + rate_code, pream_table,
630 + WMI_TPC_TABLE_TYPE_STBC);
631 + ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
632 + rate_code, pream_table,
633 + WMI_TPC_TABLE_TYPE_TXBF);
634 +
635 + ath10k_debug_tpc_stats_final_process(ar, tpc_stats);
636 +
637 + ath10k_dbg(ar, ATH10K_DBG_WMI,
638 + "wmi event tpc final table channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
639 + __le32_to_cpu(ev->chan_freq),
640 + __le32_to_cpu(ev->phy_mode),
641 + __le32_to_cpu(ev->ctl),
642 + __le32_to_cpu(ev->reg_domain),
643 + a_sle32_to_cpu(ev->twice_antenna_gain),
644 + __le32_to_cpu(ev->twice_antenna_reduction),
645 + __le32_to_cpu(ev->power_limit),
646 + __le32_to_cpu(ev->twice_max_rd_power) / 2,
647 + __le32_to_cpu(ev->num_tx_chain),
648 + __le32_to_cpu(ev->rate_max));
649 +}
650 +
651 static void
652 ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb)
653 {
654 @@ -5550,6 +5805,9 @@ static void ath10k_wmi_10_4_op_rx(struct
655 case WMI_10_4_TDLS_PEER_EVENTID:
656 ath10k_wmi_handle_tdls_peer_event(ar, skb);
657 break;
658 + case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
659 + ath10k_wmi_event_tpc_final_table(ar, skb);
660 + break;
661 default:
662 ath10k_warn(ar, "Unknown eventid: %d\n", id);
663 break;
664 @@ -7990,6 +8248,24 @@ static u32 ath10k_wmi_prepare_peer_qos(u
665 }
666
667 static struct sk_buff *
668 +ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
669 +{
670 + struct wmi_pdev_get_tpc_table_cmd *cmd;
671 + struct sk_buff *skb;
672 +
673 + skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
674 + if (!skb)
675 + return ERR_PTR(-ENOMEM);
676 +
677 + cmd = (struct wmi_pdev_get_tpc_table_cmd *)skb->data;
678 + cmd->param = __cpu_to_le32(param);
679 +
680 + ath10k_dbg(ar, ATH10K_DBG_WMI,
681 + "wmi pdev get tpc table param:%d\n", param);
682 + return skb;
683 +}
684 +
685 +static struct sk_buff *
686 ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
687 const struct wmi_tdls_peer_update_cmd_arg *arg,
688 const struct wmi_tdls_peer_capab_arg *cap,
689 @@ -8430,6 +8706,8 @@ static const struct wmi_ops wmi_10_4_ops
690 .ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
691 .gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state,
692 .gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
693 + .gen_pdev_get_tpc_table_cmdid =
694 + ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
695
696 /* shared with 10.2 */
697 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
698 --- a/drivers/net/wireless/ath/ath10k/wmi.h
699 +++ b/drivers/net/wireless/ath/ath10k/wmi.h
700 @@ -1,6 +1,7 @@
701 /*
702 * Copyright (c) 2005-2011 Atheros Communications Inc.
703 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
704 + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
705 *
706 * Permission to use, copy, modify, and/or distribute this software for any
707 * purpose with or without fee is hereby granted, provided that the above
708 @@ -197,6 +198,9 @@ enum wmi_service {
709 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
710 WMI_SERVICE_MGMT_TX_WMI,
711 WMI_SERVICE_TDLS_WIDER_BANDWIDTH,
712 + WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
713 + WMI_SERVICE_HOST_DFS_CHECK_SUPPORT,
714 + WMI_SERVICE_TPC_STATS_FINAL,
715
716 /* keep last */
717 WMI_SERVICE_MAX,
718 @@ -339,6 +343,9 @@ enum wmi_10_4_service {
719 WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
720 WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
721 WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
722 + WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
723 + WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
724 + WMI_10_4_SERVICE_TPC_STATS_FINAL,
725 };
726
727 static inline char *wmi_service_name(int service_id)
728 @@ -448,6 +455,9 @@ static inline char *wmi_service_name(int
729 SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
730 SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
731 SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
732 + SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
733 + SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
734 + SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
735 default:
736 return NULL;
737 }
738 @@ -746,6 +756,12 @@ static inline void wmi_10_4_svc_map(cons
739 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
740 SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
741 WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len);
742 + SVCMAP(WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
743 + WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
744 + SVCMAP(WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
745 + WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len);
746 + SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL,
747 + WMI_SERVICE_TPC_STATS_FINAL, len);
748 }
749
750 #undef SVCMAP
751 @@ -3992,10 +4008,12 @@ struct wmi_pdev_get_tpc_config_cmd {
752
753 #define WMI_TPC_CONFIG_PARAM 1
754 #define WMI_TPC_RATE_MAX 160
755 +#define WMI_TPC_FINAL_RATE_MAX 240
756 #define WMI_TPC_TX_N_CHAIN 4
757 #define WMI_TPC_PREAM_TABLE_MAX 10
758 #define WMI_TPC_FLAG 3
759 #define WMI_TPC_BUF_SIZE 10
760 +#define WMI_TPC_BEAMFORMING 2
761
762 enum wmi_tpc_table_type {
763 WMI_TPC_TABLE_TYPE_CDD = 0,
764 @@ -4038,6 +4056,51 @@ enum wmi_tp_scale {
765 WMI_TP_SCALE_SIZE = 5, /* max num of enum */
766 };
767
768 +struct wmi_pdev_tpc_final_table_event {
769 + __le32 reg_domain;
770 + __le32 chan_freq;
771 + __le32 phy_mode;
772 + __le32 twice_antenna_reduction;
773 + __le32 twice_max_rd_power;
774 + a_sle32 twice_antenna_gain;
775 + __le32 power_limit;
776 + __le32 rate_max;
777 + __le32 num_tx_chain;
778 + __le32 ctl;
779 + __le32 flags;
780 + s8 max_reg_allow_pow[WMI_TPC_TX_N_CHAIN];
781 + s8 max_reg_allow_pow_agcdd[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
782 + s8 max_reg_allow_pow_agstbc[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
783 + s8 max_reg_allow_pow_agtxbf[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
784 + u8 rates_array[WMI_TPC_FINAL_RATE_MAX];
785 + u8 ctl_power_table[WMI_TPC_BEAMFORMING][WMI_TPC_TX_N_CHAIN]
786 + [WMI_TPC_TX_N_CHAIN];
787 +} __packed;
788 +
789 +struct wmi_pdev_get_tpc_table_cmd {
790 + __le32 param;
791 +} __packed;
792 +
793 +enum wmi_tpc_pream_2ghz {
794 + WMI_TPC_PREAM_2GHZ_CCK = 0,
795 + WMI_TPC_PREAM_2GHZ_OFDM,
796 + WMI_TPC_PREAM_2GHZ_HT20,
797 + WMI_TPC_PREAM_2GHZ_HT40,
798 + WMI_TPC_PREAM_2GHZ_VHT20,
799 + WMI_TPC_PREAM_2GHZ_VHT40,
800 + WMI_TPC_PREAM_2GHZ_VHT80,
801 +};
802 +
803 +enum wmi_tpc_pream_5ghz {
804 + WMI_TPC_PREAM_5GHZ_OFDM = 1,
805 + WMI_TPC_PREAM_5GHZ_HT20,
806 + WMI_TPC_PREAM_5GHZ_HT40,
807 + WMI_TPC_PREAM_5GHZ_VHT20,
808 + WMI_TPC_PREAM_5GHZ_VHT40,
809 + WMI_TPC_PREAM_5GHZ_VHT80,
810 + WMI_TPC_PREAM_5GHZ_HTCUP,
811 +};
812 +
813 struct wmi_pdev_chanlist_update_event {
814 /* number of channels */
815 __le32 num_chan;
816 @@ -6977,5 +7040,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(st
817 int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
818 enum wmi_vdev_subtype subtype);
819 int ath10k_wmi_barrier(struct ath10k *ar);
820 +void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
821 + u32 num_tx_chain);
822 +void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb);
823
824 #endif /* _WMI_H_ */