int ath6kl_wmi_get_customer_stats_cmd(struct ath6kl_vif *vif, athcfg_wcmd_stats_t *val) { //struct sk_buff *skb; //athcfg_wcmd_sta_t *cmd; int ret; int left; set_bit(STATS_UPDATE_PEND, &vif->flag); ret = ath6kl_wmi_get_stats_cmd(vif); if (ret != 0) { up(&vif->ar->sem); return -EIO; } left = wait_event_interruptible_timeout(vif->event_wq, !test_bit(STATS_UPDATE_PEND, &vif->flag), WMI_TIMEOUT); if (left == 0) return -ETIMEDOUT; else if (left < 0) return left; val->txPackets = vif->ar->target_stats.tx_pkt; val->txRetry = vif->ar->target_stats.tx_fail_cnt;//retry count,not include first tx val->txAggrRetry = 0; val->txAggrSubRetry = 0; val->txAggrExcessiveRetry = 0; val->txSubRetry = 0; return ret; }
static int ap_keepalive_preload_txrx_time(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; int ret = 0; /* Get AP stats only at least one station associated. */ if (vif->sta_list_index) ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx); return ret; }
static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { struct ath6kl *ar = ath6kl_priv(dev); long left; bool sgi; s32 rate; int ret; u8 mcs; if (memcmp(mac, ar->bssid, ETH_ALEN) != 0) return -ENOENT; if (down_interruptible(&ar->sem)) return -EBUSY; set_bit(STATS_UPDATE_PEND, &ar->flag); ret = ath6kl_wmi_get_stats_cmd(ar->wmi); if (ret != 0) { up(&ar->sem); return -EIO; } left = wait_event_interruptible_timeout(ar->event_wq, !test_bit(STATS_UPDATE_PEND, &ar->flag), WMI_TIMEOUT); up(&ar->sem); if (left == 0) return -ETIMEDOUT; else if (left < 0) return left; if (ar->target_stats.rx_byte) { sinfo->rx_bytes = ar->target_stats.rx_byte; sinfo->filled |= STATION_INFO_RX_BYTES; sinfo->rx_packets = ar->target_stats.rx_pkt; sinfo->filled |= STATION_INFO_RX_PACKETS; } if (ar->target_stats.tx_byte) { sinfo->tx_bytes = ar->target_stats.tx_byte; sinfo->filled |= STATION_INFO_TX_BYTES; sinfo->tx_packets = ar->target_stats.tx_pkt; sinfo->filled |= STATION_INFO_TX_PACKETS; } sinfo->signal = ar->target_stats.cs_rssi; sinfo->filled |= STATION_INFO_SIGNAL; rate = ar->target_stats.tx_ucast_rate; if (is_rate_legacy(rate)) { sinfo->txrate.legacy = rate / 100; } else if (is_rate_ht20(rate, &mcs, &sgi)) { if (sgi) { sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; sinfo->txrate.mcs = mcs - 1; } else { sinfo->txrate.mcs = mcs; } sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; } else if (is_rate_ht40(rate, &mcs, &sgi)) { if (sgi) { sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; sinfo->txrate.mcs = mcs - 1; } else { sinfo->txrate.mcs = mcs; } sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; } else { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "invalid rate from stats: %d\n", rate); ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE); return 0; } sinfo->filled |= STATION_INFO_TX_BITRATE; if (test_bit(CONNECTED, &ar->flag) && test_bit(DTIM_PERIOD_AVAIL, &ar->flag) && ar->nw_type == INFRA_NETWORK) { sinfo->filled |= STATION_INFO_BSS_PARAM; sinfo->bss_param.flags = 0; sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period; sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int; } return 0; }