Skip to content

Commit bc64d05

Browse files
Maharaja KennadyrajanKalle Valo
authored andcommitted
ath10k: debugfs support to get final TPC stats for 10.4 variants
Export the final Transmit Power Control (TPC) value, which is the minimum of control power and existing TPC value to user space via a new debugfs file "tpc_stats_final" to help with debugging. It works with the new wmi cmd and event introduced in 10.4 firmware branch. WMI command ID: WMI_PDEV_GET_TPC_TABLE_CMDID WMI event ID: WMI_PDEV_TPC_TABLE_EVENTID cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final $ cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final TPC config for channel 5180 mode 10 CTL = 0x 0 Reg. Domain = 58 Antenna Gain = 0 Reg. Max Antenna Gain = 0 Power Limit = 60 Reg. Max Power = 60 Num tx chains = 2 Num supported rates = 109 ******************* CDD POWER TABLE **************** No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3 0 CCK 0x40 0 0 1 CCK 0x41 0 0 [...] 107 HTCUP 0x 0 46 46 108 HTCUP 0x 0 46 46 ******************* STBC POWER TABLE **************** No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3 0 CCK 0x40 0 0 1 CCK 0x41 0 0 [...] 107 HTCUP 0x 0 46 46 108 HTCUP 0x 0 46 46 *********************************** TXBF not supported ********************************** The existing tpc_stats debugfs file provides the dump which is minimum of target power and regulatory domain. cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats Hardware_used: QCA4019 Firmware version: firmware-5.bin_10.4-3.0-00209 Signed-off-by: Maharaja Kennadyrajan <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent caee728 commit bc64d05

File tree

6 files changed

+518
-15
lines changed

6 files changed

+518
-15
lines changed

drivers/net/wireless/ath/ath10k/core.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,27 @@ struct ath10k_tpc_stats {
325325
struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG];
326326
};
327327

328+
struct ath10k_tpc_table_final {
329+
u32 pream_idx[WMI_TPC_FINAL_RATE_MAX];
330+
u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
331+
char tpc_value[WMI_TPC_FINAL_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
332+
};
333+
334+
struct ath10k_tpc_stats_final {
335+
u32 reg_domain;
336+
u32 chan_freq;
337+
u32 phy_mode;
338+
u32 twice_antenna_reduction;
339+
u32 twice_max_rd_power;
340+
s32 twice_antenna_gain;
341+
u32 power_limit;
342+
u32 num_tx_chain;
343+
u32 ctl;
344+
u32 rate_max;
345+
u8 flag[WMI_TPC_FLAG];
346+
struct ath10k_tpc_table_final tpc_table_final[WMI_TPC_FLAG];
347+
};
348+
328349
struct ath10k_dfs_stats {
329350
u32 phy_errors;
330351
u32 pulses_total;
@@ -530,6 +551,7 @@ struct ath10k_debug {
530551

531552
/* used for tpc-dump storage, protected by data-lock */
532553
struct ath10k_tpc_stats *tpc_stats;
554+
struct ath10k_tpc_stats_final *tpc_stats_final;
533555

534556
struct completion tpc_complete;
535557

drivers/net/wireless/ath/ath10k/debug.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,19 @@ void ath10k_debug_tpc_stats_process(struct ath10k *ar,
14801480
spin_unlock_bh(&ar->data_lock);
14811481
}
14821482

1483+
void
1484+
ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
1485+
struct ath10k_tpc_stats_final *tpc_stats)
1486+
{
1487+
spin_lock_bh(&ar->data_lock);
1488+
1489+
kfree(ar->debug.tpc_stats_final);
1490+
ar->debug.tpc_stats_final = tpc_stats;
1491+
complete(&ar->debug.tpc_complete);
1492+
1493+
spin_unlock_bh(&ar->data_lock);
1494+
}
1495+
14831496
static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
14841497
unsigned int j, char *buf, size_t *len)
14851498
{
@@ -2185,6 +2198,95 @@ static const struct file_operations fops_sta_tid_stats_mask = {
21852198
.llseek = default_llseek,
21862199
};
21872200

2201+
static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
2202+
{
2203+
int ret;
2204+
unsigned long time_left;
2205+
2206+
lockdep_assert_held(&ar->conf_mutex);
2207+
2208+
reinit_completion(&ar->debug.tpc_complete);
2209+
2210+
ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
2211+
if (ret) {
2212+
ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
2213+
return ret;
2214+
}
2215+
2216+
time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
2217+
1 * HZ);
2218+
if (time_left == 0)
2219+
return -ETIMEDOUT;
2220+
2221+
return 0;
2222+
}
2223+
2224+
static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
2225+
{
2226+
struct ath10k *ar = inode->i_private;
2227+
void *buf;
2228+
int ret;
2229+
2230+
mutex_lock(&ar->conf_mutex);
2231+
2232+
if (ar->state != ATH10K_STATE_ON) {
2233+
ret = -ENETDOWN;
2234+
goto err_unlock;
2235+
}
2236+
2237+
buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
2238+
if (!buf) {
2239+
ret = -ENOMEM;
2240+
goto err_unlock;
2241+
}
2242+
2243+
ret = ath10k_debug_tpc_stats_final_request(ar);
2244+
if (ret) {
2245+
ath10k_warn(ar, "failed to request tpc stats final: %d\n",
2246+
ret);
2247+
goto err_free;
2248+
}
2249+
2250+
ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
2251+
file->private_data = buf;
2252+
2253+
mutex_unlock(&ar->conf_mutex);
2254+
return 0;
2255+
2256+
err_free:
2257+
vfree(buf);
2258+
2259+
err_unlock:
2260+
mutex_unlock(&ar->conf_mutex);
2261+
return ret;
2262+
}
2263+
2264+
static int ath10k_tpc_stats_final_release(struct inode *inode,
2265+
struct file *file)
2266+
{
2267+
vfree(file->private_data);
2268+
2269+
return 0;
2270+
}
2271+
2272+
static ssize_t ath10k_tpc_stats_final_read(struct file *file,
2273+
char __user *user_buf,
2274+
size_t count, loff_t *ppos)
2275+
{
2276+
const char *buf = file->private_data;
2277+
unsigned int len = strlen(buf);
2278+
2279+
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2280+
}
2281+
2282+
static const struct file_operations fops_tpc_stats_final = {
2283+
.open = ath10k_tpc_stats_final_open,
2284+
.release = ath10k_tpc_stats_final_release,
2285+
.read = ath10k_tpc_stats_final_read,
2286+
.owner = THIS_MODULE,
2287+
.llseek = default_llseek,
2288+
};
2289+
21882290
int ath10k_debug_create(struct ath10k *ar)
21892291
{
21902292
ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
@@ -2305,6 +2407,11 @@ int ath10k_debug_register(struct ath10k *ar)
23052407
ar->debug.debugfs_phy,
23062408
ar, &fops_sta_tid_stats_mask);
23072409

2410+
if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
2411+
debugfs_create_file("tpc_stats_final", 0400,
2412+
ar->debug.debugfs_phy, ar,
2413+
&fops_tpc_stats_final);
2414+
23082415
return 0;
23092416
}
23102417

drivers/net/wireless/ath/ath10k/debug.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ void ath10k_debug_unregister(struct ath10k *ar);
102102
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
103103
void ath10k_debug_tpc_stats_process(struct ath10k *ar,
104104
struct ath10k_tpc_stats *tpc_stats);
105+
void
106+
ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
107+
struct ath10k_tpc_stats_final *tpc_stats);
105108
void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
106109

107110
#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
@@ -165,6 +168,13 @@ static inline void ath10k_debug_tpc_stats_process(struct ath10k *ar,
165168
kfree(tpc_stats);
166169
}
167170

171+
static inline void
172+
ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
173+
struct ath10k_tpc_stats_final *tpc_stats)
174+
{
175+
kfree(tpc_stats);
176+
}
177+
168178
static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
169179
int len)
170180
{

drivers/net/wireless/ath/ath10k/wmi-ops.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ struct wmi_ops {
201201
(struct ath10k *ar,
202202
enum wmi_bss_survey_req_type type);
203203
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
204+
struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
205+
u32 param);
206+
204207
};
205208

206209
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1445,4 +1448,21 @@ ath10k_wmi_echo(struct ath10k *ar, u32 value)
14451448
return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
14461449
}
14471450

1451+
static inline int
1452+
ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
1453+
{
1454+
struct sk_buff *skb;
1455+
1456+
if (!ar->wmi.ops->gen_pdev_get_tpc_table_cmdid)
1457+
return -EOPNOTSUPP;
1458+
1459+
skb = ar->wmi.ops->gen_pdev_get_tpc_table_cmdid(ar, param);
1460+
1461+
if (IS_ERR(skb))
1462+
return PTR_ERR(skb);
1463+
1464+
return ath10k_wmi_cmd_send(ar, skb,
1465+
ar->wmi.cmd->pdev_get_tpc_table_cmdid);
1466+
}
1467+
14481468
#endif

0 commit comments

Comments
 (0)