X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fath%2Fath10k%2Fdebug.c;h=145c066b50870c84374430d7549a9239f78f6678;hb=844fa57227124c353049df02de809b3d6c9505e8;hp=f316efdbd6c3471ab60e44c9762a6db915662edc;hpb=295426669cd68efc84657e6ee426499cfb54346e;p=linux-beck.git diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index f316efdbd6c3..145c066b5087 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -125,19 +125,25 @@ EXPORT_SYMBOL(ath10k_info); void ath10k_print_driver_info(struct ath10k *ar) { char fw_features[128] = {}; + char boardinfo[100]; ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features)); - ath10k_info(ar, "%s (0x%08x, 0x%08x%s%s%s) fw %s api %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n", + if (ar->id.bmi_ids_valid) + scnprintf(boardinfo, sizeof(boardinfo), "bmi %d:%d", + ar->id.bmi_chip_id, ar->id.bmi_board_id); + else + scnprintf(boardinfo, sizeof(boardinfo), "sub %04x:%04x", + ar->id.subsystem_vendor, ar->id.subsystem_device); + + ath10k_info(ar, "%s (0x%08x, 0x%08x %s) fw %s fwapi %d bdapi %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n", ar->hw_params.name, ar->target_version, ar->chip_id, - (strlen(ar->spec_board_id) > 0 ? ", " : ""), - ar->spec_board_id, - (strlen(ar->spec_board_id) > 0 && !ar->spec_board_loaded - ? " fallback" : ""), + boardinfo, ar->hw->wiphy->fw_version, ar->fw_api, + ar->bd_api, ar->htt.target_version_major, ar->htt.target_version_minor, ar->wmi.op_version, @@ -285,28 +291,6 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar) spin_unlock_bh(&ar->data_lock); } -static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head) -{ - struct ath10k_fw_stats_peer *i; - size_t num = 0; - - list_for_each_entry(i, head, list) - ++num; - - return num; -} - -static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head) -{ - struct ath10k_fw_stats_vdev *i; - size_t num = 0; - - list_for_each_entry(i, head, list) - ++num; - - return num; -} - void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) { struct ath10k_fw_stats stats = {}; @@ -343,8 +327,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) goto free; } - num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); - num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs); + num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers); + num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs); is_start = (list_empty(&ar->debug.fw_stats.pdevs) && !list_empty(&stats.pdevs)); is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && @@ -429,240 +413,6 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar) return 0; } -/* FIXME: How to calculate the buffer size sanely? */ -#define ATH10K_FW_STATS_BUF_SIZE (1024*1024) - -static void ath10k_fw_stats_fill(struct ath10k *ar, - struct ath10k_fw_stats *fw_stats, - char *buf) -{ - unsigned int len = 0; - unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; - const struct ath10k_fw_stats_pdev *pdev; - const struct ath10k_fw_stats_vdev *vdev; - const struct ath10k_fw_stats_peer *peer; - size_t num_peers; - size_t num_vdevs; - int i; - - spin_lock_bh(&ar->data_lock); - - pdev = list_first_entry_or_null(&fw_stats->pdevs, - struct ath10k_fw_stats_pdev, list); - if (!pdev) { - ath10k_warn(ar, "failed to get pdev stats\n"); - goto unlock; - } - - num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); - num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs); - - len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s\n", - "ath10k PDEV stats"); - len += scnprintf(buf + len, buf_len - len, "%30s\n\n", - "================="); - - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Channel noise floor", pdev->ch_noise_floor); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "Channel TX power", pdev->chan_tx_power); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "TX frame count", pdev->tx_frame_count); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RX frame count", pdev->rx_frame_count); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RX clear count", pdev->rx_clear_count); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "Cycle count", pdev->cycle_count); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "PHY error count", pdev->phy_err_count); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RTS bad count", pdev->rts_bad); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "RTS good count", pdev->rts_good); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "FCS bad count", pdev->fcs_bad); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "No beacon count", pdev->no_beacons); - len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", - "MIB int count", pdev->mib_int_count); - - len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s\n", - "ath10k PDEV TX stats"); - len += scnprintf(buf + len, buf_len - len, "%30s\n\n", - "================="); - - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HTT cookies queued", pdev->comp_queued); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HTT cookies disp.", pdev->comp_delivered); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDU queued", pdev->msdu_enqued); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU queued", pdev->mpdu_enqued); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs dropped", pdev->wmm_drop); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Local enqued", pdev->local_enqued); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Local freed", pdev->local_freed); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HW queued", pdev->hw_queued); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PPDUs reaped", pdev->hw_reaped); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Num underruns", pdev->underrun); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PPDUs cleaned", pdev->tx_abort); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs requed", pdev->mpdus_requed); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Excessive retries", pdev->tx_ko); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "HW rate", pdev->data_rc); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Sched self tiggers", pdev->self_triggers); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Dropped due to SW retries", - pdev->sw_retry_failure); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Illegal rate phy errors", - pdev->illgl_rate_phy_err); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Pdev continous xretry", pdev->pdev_cont_xretry); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "TX timeout", pdev->pdev_tx_timeout); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PDEV resets", pdev->pdev_resets); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY underrun", pdev->phy_underrun); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU is more than txop limit", pdev->txop_ovf); - - len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s\n", - "ath10k PDEV RX stats"); - len += scnprintf(buf + len, buf_len - len, "%30s\n\n", - "================="); - - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Mid PPDU route change", - pdev->mid_ppdu_route_change); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Tot. number of statuses", pdev->status_rcvd); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 0", pdev->r0_frags); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 1", pdev->r1_frags); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 2", pdev->r2_frags); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Extra frags on rings 3", pdev->r3_frags); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs delivered to HTT", pdev->htt_msdus); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs delivered to HTT", pdev->htt_mpdus); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MSDUs delivered to stack", pdev->loc_msdus); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDUs delivered to stack", pdev->loc_mpdus); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "Oversized AMSUs", pdev->oversize_amsdu); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY errors", pdev->phy_errs); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "PHY errors drops", pdev->phy_err_drop); - len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", - "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); - - len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", - "ath10k VDEV stats", num_vdevs); - len += scnprintf(buf + len, buf_len - len, "%30s\n\n", - "================="); - - list_for_each_entry(vdev, &fw_stats->vdevs, list) { - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "vdev id", vdev->vdev_id); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "beacon snr", vdev->beacon_snr); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "data snr", vdev->data_snr); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num rx frames", vdev->num_rx_frames); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num rts fail", vdev->num_rts_fail); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num rts success", vdev->num_rts_success); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num rx err", vdev->num_rx_err); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num rx discard", vdev->num_rx_discard); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "num tx not acked", vdev->num_tx_not_acked); - - for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++) - len += scnprintf(buf + len, buf_len - len, - "%25s [%02d] %u\n", - "num tx frames", i, - vdev->num_tx_frames[i]); - - for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++) - len += scnprintf(buf + len, buf_len - len, - "%25s [%02d] %u\n", - "num tx frames retries", i, - vdev->num_tx_frames_retries[i]); - - for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++) - len += scnprintf(buf + len, buf_len - len, - "%25s [%02d] %u\n", - "num tx frames failures", i, - vdev->num_tx_frames_failures[i]); - - for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++) - len += scnprintf(buf + len, buf_len - len, - "%25s [%02d] 0x%08x\n", - "tx rate history", i, - vdev->tx_rate_history[i]); - - for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++) - len += scnprintf(buf + len, buf_len - len, - "%25s [%02d] %u\n", - "beacon rssi history", i, - vdev->beacon_rssi_history[i]); - - len += scnprintf(buf + len, buf_len - len, "\n"); - } - - len += scnprintf(buf + len, buf_len - len, "\n"); - len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", - "ath10k PEER stats", num_peers); - len += scnprintf(buf + len, buf_len - len, "%30s\n\n", - "================="); - - list_for_each_entry(peer, &fw_stats->peers, list) { - len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", - "Peer MAC address", peer->peer_macaddr); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer RSSI", peer->peer_rssi); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer TX rate", peer->peer_tx_rate); - len += scnprintf(buf + len, buf_len - len, "%30s %u\n", - "Peer RX rate", peer->peer_rx_rate); - len += scnprintf(buf + len, buf_len - len, "\n"); - } - -unlock: - spin_unlock_bh(&ar->data_lock); - - if (len >= buf_len) - buf[len - 1] = 0; - else - buf[len] = 0; -} - static int ath10k_fw_stats_open(struct inode *inode, struct file *file) { struct ath10k *ar = inode->i_private; @@ -688,7 +438,12 @@ static int ath10k_fw_stats_open(struct inode *inode, struct file *file) goto err_free; } - ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf); + ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf); + if (ret) { + ath10k_warn(ar, "failed to fill fw stats: %d\n", ret); + goto err_free; + } + file->private_data = buf; mutex_unlock(&ar->conf_mutex); @@ -2319,6 +2074,68 @@ static const struct file_operations fops_quiet_period = { .open = simple_open }; +static ssize_t ath10k_write_btcoex(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char buf[32]; + size_t buf_size; + bool val; + + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, ubuf, buf_size)) + return -EFAULT; + + buf[buf_size] = '\0'; + + if (strtobool(buf, &val) != 0) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + + if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) + goto exit; + + if (val) + set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags); + else + clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags); + + if (ar->state != ATH10K_STATE_ON) + goto exit; + + ath10k_info(ar, "restarting firmware due to btcoex change"); + + queue_work(ar->workqueue, &ar->restart_work); + +exit: + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char buf[32]; + struct ath10k *ar = file->private_data; + int len = 0; + + mutex_lock(&ar->conf_mutex); + len = scnprintf(buf, sizeof(buf) - len, "%d\n", + test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags)); + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(ubuf, count, ppos, buf, len); +} + +static const struct file_operations fops_btcoex = { + .read = ath10k_read_btcoex, + .write = ath10k_write_btcoex, + .open = simple_open +}; + int ath10k_debug_create(struct ath10k *ar) { ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); @@ -2428,6 +2245,10 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("tpc_stats", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_tpc_stats); + if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) + debugfs_create_file("btcoex", S_IRUGO | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_btcoex); + return 0; }