0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "htc.h"
0018
0019 static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
0020 size_t count, loff_t *ppos)
0021 {
0022 struct ath9k_htc_priv *priv = file->private_data;
0023 struct ath9k_htc_target_int_stats cmd_rsp;
0024 char buf[512];
0025 unsigned int len = 0;
0026 int ret = 0;
0027
0028 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
0029
0030 ath9k_htc_ps_wakeup(priv);
0031
0032 WMI_CMD(WMI_INT_STATS_CMDID);
0033 if (ret) {
0034 ath9k_htc_ps_restore(priv);
0035 return -EINVAL;
0036 }
0037
0038 ath9k_htc_ps_restore(priv);
0039
0040 len += scnprintf(buf + len, sizeof(buf) - len,
0041 "%20s : %10u\n", "RX",
0042 be32_to_cpu(cmd_rsp.rx));
0043
0044 len += scnprintf(buf + len, sizeof(buf) - len,
0045 "%20s : %10u\n", "RXORN",
0046 be32_to_cpu(cmd_rsp.rxorn));
0047
0048 len += scnprintf(buf + len, sizeof(buf) - len,
0049 "%20s : %10u\n", "RXEOL",
0050 be32_to_cpu(cmd_rsp.rxeol));
0051
0052 len += scnprintf(buf + len, sizeof(buf) - len,
0053 "%20s : %10u\n", "TXURN",
0054 be32_to_cpu(cmd_rsp.txurn));
0055
0056 len += scnprintf(buf + len, sizeof(buf) - len,
0057 "%20s : %10u\n", "TXTO",
0058 be32_to_cpu(cmd_rsp.txto));
0059
0060 len += scnprintf(buf + len, sizeof(buf) - len,
0061 "%20s : %10u\n", "CST",
0062 be32_to_cpu(cmd_rsp.cst));
0063
0064 if (len > sizeof(buf))
0065 len = sizeof(buf);
0066
0067 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0068 }
0069
0070 static const struct file_operations fops_tgt_int_stats = {
0071 .read = read_file_tgt_int_stats,
0072 .open = simple_open,
0073 .owner = THIS_MODULE,
0074 .llseek = default_llseek,
0075 };
0076
0077 static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
0078 size_t count, loff_t *ppos)
0079 {
0080 struct ath9k_htc_priv *priv = file->private_data;
0081 struct ath9k_htc_target_tx_stats cmd_rsp;
0082 char buf[512];
0083 unsigned int len = 0;
0084 int ret = 0;
0085
0086 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
0087
0088 ath9k_htc_ps_wakeup(priv);
0089
0090 WMI_CMD(WMI_TX_STATS_CMDID);
0091 if (ret) {
0092 ath9k_htc_ps_restore(priv);
0093 return -EINVAL;
0094 }
0095
0096 ath9k_htc_ps_restore(priv);
0097
0098 len += scnprintf(buf + len, sizeof(buf) - len,
0099 "%20s : %10u\n", "Xretries",
0100 be32_to_cpu(cmd_rsp.xretries));
0101
0102 len += scnprintf(buf + len, sizeof(buf) - len,
0103 "%20s : %10u\n", "FifoErr",
0104 be32_to_cpu(cmd_rsp.fifoerr));
0105
0106 len += scnprintf(buf + len, sizeof(buf) - len,
0107 "%20s : %10u\n", "Filtered",
0108 be32_to_cpu(cmd_rsp.filtered));
0109
0110 len += scnprintf(buf + len, sizeof(buf) - len,
0111 "%20s : %10u\n", "TimerExp",
0112 be32_to_cpu(cmd_rsp.timer_exp));
0113
0114 len += scnprintf(buf + len, sizeof(buf) - len,
0115 "%20s : %10u\n", "ShortRetries",
0116 be32_to_cpu(cmd_rsp.shortretries));
0117
0118 len += scnprintf(buf + len, sizeof(buf) - len,
0119 "%20s : %10u\n", "LongRetries",
0120 be32_to_cpu(cmd_rsp.longretries));
0121
0122 len += scnprintf(buf + len, sizeof(buf) - len,
0123 "%20s : %10u\n", "QueueNull",
0124 be32_to_cpu(cmd_rsp.qnull));
0125
0126 len += scnprintf(buf + len, sizeof(buf) - len,
0127 "%20s : %10u\n", "EncapFail",
0128 be32_to_cpu(cmd_rsp.encap_fail));
0129
0130 len += scnprintf(buf + len, sizeof(buf) - len,
0131 "%20s : %10u\n", "NoBuf",
0132 be32_to_cpu(cmd_rsp.nobuf));
0133
0134 if (len > sizeof(buf))
0135 len = sizeof(buf);
0136
0137 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0138 }
0139
0140 static const struct file_operations fops_tgt_tx_stats = {
0141 .read = read_file_tgt_tx_stats,
0142 .open = simple_open,
0143 .owner = THIS_MODULE,
0144 .llseek = default_llseek,
0145 };
0146
0147 static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
0148 size_t count, loff_t *ppos)
0149 {
0150 struct ath9k_htc_priv *priv = file->private_data;
0151 struct ath9k_htc_target_rx_stats cmd_rsp;
0152 char buf[512];
0153 unsigned int len = 0;
0154 int ret = 0;
0155
0156 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
0157
0158 ath9k_htc_ps_wakeup(priv);
0159
0160 WMI_CMD(WMI_RX_STATS_CMDID);
0161 if (ret) {
0162 ath9k_htc_ps_restore(priv);
0163 return -EINVAL;
0164 }
0165
0166 ath9k_htc_ps_restore(priv);
0167
0168 len += scnprintf(buf + len, sizeof(buf) - len,
0169 "%20s : %10u\n", "NoBuf",
0170 be32_to_cpu(cmd_rsp.nobuf));
0171
0172 len += scnprintf(buf + len, sizeof(buf) - len,
0173 "%20s : %10u\n", "HostSend",
0174 be32_to_cpu(cmd_rsp.host_send));
0175
0176 len += scnprintf(buf + len, sizeof(buf) - len,
0177 "%20s : %10u\n", "HostDone",
0178 be32_to_cpu(cmd_rsp.host_done));
0179
0180 if (len > sizeof(buf))
0181 len = sizeof(buf);
0182
0183 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0184 }
0185
0186 static const struct file_operations fops_tgt_rx_stats = {
0187 .read = read_file_tgt_rx_stats,
0188 .open = simple_open,
0189 .owner = THIS_MODULE,
0190 .llseek = default_llseek,
0191 };
0192
0193 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
0194 size_t count, loff_t *ppos)
0195 {
0196 struct ath9k_htc_priv *priv = file->private_data;
0197 char buf[512];
0198 unsigned int len = 0;
0199
0200 len += scnprintf(buf + len, sizeof(buf) - len,
0201 "%20s : %10u\n", "Buffers queued",
0202 priv->debug.tx_stats.buf_queued);
0203 len += scnprintf(buf + len, sizeof(buf) - len,
0204 "%20s : %10u\n", "Buffers completed",
0205 priv->debug.tx_stats.buf_completed);
0206 len += scnprintf(buf + len, sizeof(buf) - len,
0207 "%20s : %10u\n", "SKBs queued",
0208 priv->debug.tx_stats.skb_queued);
0209 len += scnprintf(buf + len, sizeof(buf) - len,
0210 "%20s : %10u\n", "SKBs success",
0211 priv->debug.tx_stats.skb_success);
0212 len += scnprintf(buf + len, sizeof(buf) - len,
0213 "%20s : %10u\n", "SKBs failed",
0214 priv->debug.tx_stats.skb_failed);
0215 len += scnprintf(buf + len, sizeof(buf) - len,
0216 "%20s : %10u\n", "CAB queued",
0217 priv->debug.tx_stats.cab_queued);
0218
0219 len += scnprintf(buf + len, sizeof(buf) - len,
0220 "%20s : %10u\n", "BE queued",
0221 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]);
0222 len += scnprintf(buf + len, sizeof(buf) - len,
0223 "%20s : %10u\n", "BK queued",
0224 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]);
0225 len += scnprintf(buf + len, sizeof(buf) - len,
0226 "%20s : %10u\n", "VI queued",
0227 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]);
0228 len += scnprintf(buf + len, sizeof(buf) - len,
0229 "%20s : %10u\n", "VO queued",
0230 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]);
0231
0232 if (len > sizeof(buf))
0233 len = sizeof(buf);
0234
0235 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0236 }
0237
0238 static const struct file_operations fops_xmit = {
0239 .read = read_file_xmit,
0240 .open = simple_open,
0241 .owner = THIS_MODULE,
0242 .llseek = default_llseek,
0243 };
0244
0245 void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
0246 struct ath_rx_status *rs)
0247 {
0248 ath9k_cmn_debug_stat_rx(&priv->debug.rx_stats, rs);
0249 }
0250
0251 static ssize_t read_file_skb_rx(struct file *file, char __user *user_buf,
0252 size_t count, loff_t *ppos)
0253 {
0254 struct ath9k_htc_priv *priv = file->private_data;
0255 char *buf;
0256 unsigned int len = 0, size = 1500;
0257 ssize_t retval = 0;
0258
0259 buf = kzalloc(size, GFP_KERNEL);
0260 if (buf == NULL)
0261 return -ENOMEM;
0262
0263 len += scnprintf(buf + len, size - len,
0264 "%20s : %10u\n", "SKBs allocated",
0265 priv->debug.skbrx_stats.skb_allocated);
0266 len += scnprintf(buf + len, size - len,
0267 "%20s : %10u\n", "SKBs completed",
0268 priv->debug.skbrx_stats.skb_completed);
0269 len += scnprintf(buf + len, size - len,
0270 "%20s : %10u\n", "SKBs Dropped",
0271 priv->debug.skbrx_stats.skb_dropped);
0272
0273 if (len > size)
0274 len = size;
0275
0276 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
0277 kfree(buf);
0278
0279 return retval;
0280 }
0281
0282 static const struct file_operations fops_skb_rx = {
0283 .read = read_file_skb_rx,
0284 .open = simple_open,
0285 .owner = THIS_MODULE,
0286 .llseek = default_llseek,
0287 };
0288
0289 static ssize_t read_file_slot(struct file *file, char __user *user_buf,
0290 size_t count, loff_t *ppos)
0291 {
0292 struct ath9k_htc_priv *priv = file->private_data;
0293 char buf[512];
0294 unsigned int len;
0295
0296 spin_lock_bh(&priv->tx.tx_lock);
0297 len = scnprintf(buf, sizeof(buf),
0298 "TX slot bitmap : %*pb\n"
0299 "Used slots : %d\n",
0300 MAX_TX_BUF_NUM, priv->tx.tx_slot,
0301 bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
0302 spin_unlock_bh(&priv->tx.tx_lock);
0303 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0304 }
0305
0306 static const struct file_operations fops_slot = {
0307 .read = read_file_slot,
0308 .open = simple_open,
0309 .owner = THIS_MODULE,
0310 .llseek = default_llseek,
0311 };
0312
0313 static ssize_t read_file_queue(struct file *file, char __user *user_buf,
0314 size_t count, loff_t *ppos)
0315 {
0316 struct ath9k_htc_priv *priv = file->private_data;
0317 char buf[512];
0318 unsigned int len = 0;
0319
0320 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0321 "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
0322
0323 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0324 "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
0325
0326 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0327 "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
0328
0329 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0330 "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
0331
0332 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0333 "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
0334
0335 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0336 "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
0337
0338 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0339 "Failed queue", skb_queue_len(&priv->tx.tx_failed));
0340
0341 spin_lock_bh(&priv->tx.tx_lock);
0342 len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
0343 "Queued count", priv->tx.queued_cnt);
0344 spin_unlock_bh(&priv->tx.tx_lock);
0345
0346 if (len > sizeof(buf))
0347 len = sizeof(buf);
0348
0349 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0350
0351 }
0352
0353 static const struct file_operations fops_queue = {
0354 .read = read_file_queue,
0355 .open = simple_open,
0356 .owner = THIS_MODULE,
0357 .llseek = default_llseek,
0358 };
0359
0360 static ssize_t read_file_debug(struct file *file, char __user *user_buf,
0361 size_t count, loff_t *ppos)
0362 {
0363 struct ath9k_htc_priv *priv = file->private_data;
0364 struct ath_common *common = ath9k_hw_common(priv->ah);
0365 char buf[32];
0366 unsigned int len;
0367
0368 len = sprintf(buf, "0x%08x\n", common->debug_mask);
0369 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
0370 }
0371
0372 static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
0373 size_t count, loff_t *ppos)
0374 {
0375 struct ath9k_htc_priv *priv = file->private_data;
0376 struct ath_common *common = ath9k_hw_common(priv->ah);
0377 unsigned long mask;
0378 char buf[32];
0379 ssize_t len;
0380
0381 len = min(count, sizeof(buf) - 1);
0382 if (copy_from_user(buf, user_buf, len))
0383 return -EFAULT;
0384
0385 buf[len] = '\0';
0386 if (kstrtoul(buf, 0, &mask))
0387 return -EINVAL;
0388
0389 common->debug_mask = mask;
0390 return count;
0391 }
0392
0393 static const struct file_operations fops_debug = {
0394 .read = read_file_debug,
0395 .write = write_file_debug,
0396 .open = simple_open,
0397 .owner = THIS_MODULE,
0398 .llseek = default_llseek,
0399 };
0400
0401
0402 #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
0403 static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
0404 "tx_pkts_nic",
0405 "tx_bytes_nic",
0406 "rx_pkts_nic",
0407 "rx_bytes_nic",
0408
0409 AMKSTR(d_tx_pkts),
0410
0411 "d_rx_crc_err",
0412 "d_rx_decrypt_crc_err",
0413 "d_rx_phy_err",
0414 "d_rx_mic_err",
0415 "d_rx_pre_delim_crc_err",
0416 "d_rx_post_delim_crc_err",
0417 "d_rx_decrypt_busy_err",
0418
0419 "d_rx_phyerr_radar",
0420 "d_rx_phyerr_ofdm_timing",
0421 "d_rx_phyerr_cck_timing",
0422
0423 };
0424 #define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)
0425
0426 void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
0427 struct ieee80211_vif *vif,
0428 u32 sset, u8 *data)
0429 {
0430 if (sset == ETH_SS_STATS)
0431 memcpy(data, *ath9k_htc_gstrings_stats,
0432 sizeof(ath9k_htc_gstrings_stats));
0433 }
0434
0435 int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
0436 struct ieee80211_vif *vif, int sset)
0437 {
0438 if (sset == ETH_SS_STATS)
0439 return ATH9K_HTC_SSTATS_LEN;
0440 return 0;
0441 }
0442
0443 #define STXBASE priv->debug.tx_stats
0444 #define SRXBASE priv->debug.rx_stats
0445 #define SKBTXBASE priv->debug.tx_stats
0446 #define SKBRXBASE priv->debug.skbrx_stats
0447 #define ASTXQ(a) \
0448 data[i++] = STXBASE.a[IEEE80211_AC_BE]; \
0449 data[i++] = STXBASE.a[IEEE80211_AC_BK]; \
0450 data[i++] = STXBASE.a[IEEE80211_AC_VI]; \
0451 data[i++] = STXBASE.a[IEEE80211_AC_VO]
0452
0453 void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
0454 struct ieee80211_vif *vif,
0455 struct ethtool_stats *stats, u64 *data)
0456 {
0457 struct ath9k_htc_priv *priv = hw->priv;
0458 int i = 0;
0459
0460 data[i++] = SKBTXBASE.skb_success;
0461 data[i++] = SKBTXBASE.skb_success_bytes;
0462 data[i++] = SKBRXBASE.skb_completed;
0463 data[i++] = SKBRXBASE.skb_completed_bytes;
0464
0465 ASTXQ(queue_stats);
0466
0467 data[i++] = SRXBASE.crc_err;
0468 data[i++] = SRXBASE.decrypt_crc_err;
0469 data[i++] = SRXBASE.phy_err;
0470 data[i++] = SRXBASE.mic_err;
0471 data[i++] = SRXBASE.pre_delim_crc_err;
0472 data[i++] = SRXBASE.post_delim_crc_err;
0473 data[i++] = SRXBASE.decrypt_busy_err;
0474
0475 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_RADAR];
0476 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_OFDM_TIMING];
0477 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_CCK_TIMING];
0478
0479 WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
0480 }
0481
0482 void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv)
0483 {
0484 ath9k_cmn_spectral_deinit_debug(&priv->spec_priv);
0485 }
0486
0487 int ath9k_htc_init_debug(struct ath_hw *ah)
0488 {
0489 struct ath_common *common = ath9k_hw_common(ah);
0490 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
0491
0492 priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
0493 priv->hw->wiphy->debugfsdir);
0494 if (!priv->debug.debugfs_phy)
0495 return -ENOMEM;
0496
0497 ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
0498
0499 debugfs_create_file("tgt_int_stats", 0400, priv->debug.debugfs_phy,
0500 priv, &fops_tgt_int_stats);
0501 debugfs_create_file("tgt_tx_stats", 0400, priv->debug.debugfs_phy,
0502 priv, &fops_tgt_tx_stats);
0503 debugfs_create_file("tgt_rx_stats", 0400, priv->debug.debugfs_phy,
0504 priv, &fops_tgt_rx_stats);
0505 debugfs_create_file("xmit", 0400, priv->debug.debugfs_phy,
0506 priv, &fops_xmit);
0507 debugfs_create_file("skb_rx", 0400, priv->debug.debugfs_phy,
0508 priv, &fops_skb_rx);
0509
0510 ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
0511 ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
0512
0513 debugfs_create_file("slot", 0400, priv->debug.debugfs_phy,
0514 priv, &fops_slot);
0515 debugfs_create_file("queue", 0400, priv->debug.debugfs_phy,
0516 priv, &fops_queue);
0517 debugfs_create_file("debug", 0600, priv->debug.debugfs_phy,
0518 priv, &fops_debug);
0519
0520 ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
0521 ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);
0522
0523 return 0;
0524 }