Merge "qcacld-3.0: Add support to get per chain rssi stats" into wlan-cld3.driver.lnx.1.1-dev

This commit is contained in:
Service qcabuildsw 2016-09-19 12:40:49 -07:00 • committed by Gerrit - the friendly Code Review server
commit ca47d22857
12 changed files with 275 additions and 8 deletions

View file

@ -401,6 +401,7 @@ typedef struct hdd_stats_s {
tCsrGlobalClassCStatsInfo ClassC_stat;
tCsrGlobalClassDStatsInfo ClassD_stat;
tCsrPerStaStatsInfo perStaStats;
struct csr_per_chain_rssi_stats_info per_chain_rssi_stats;
hdd_tx_rx_stats_t hddTxRxStats;
#ifdef WLAN_FEATURE_11W
hdd_pmf_stats_t hddPmfStats;

View file

@ -14031,6 +14031,7 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
.mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
.set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
.set_txq_params = wlan_hdd_set_txq_params,
.dump_station = wlan_hdd_cfg80211_dump_station,
.get_station = wlan_hdd_cfg80211_get_station,
.set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
.del_station = wlan_hdd_cfg80211_del_station,

View file

@ -1650,6 +1650,9 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
int status, mode = 0, maxHtIdx;
struct index_vht_data_rate_type *supported_vht_mcs_rate;
struct index_data_rate_type *supported_mcs_rate;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
bool rssi_stats_valid = false;
#endif
uint32_t vht_mcs_map;
enum eDataRate11ACMaxMcs vhtMaxMcs;
@ -2128,6 +2131,35 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
sinfo->txrate.mcs, sinfo->txrate.flags,
sinfo->tx_packets, sinfo->rx_packets);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
sinfo->signal_avg = WLAN_HDD_TGT_NOISE_FLOOR_DBM;
for (i = 0; i < NUM_CHAINS_MAX; i++) {
sinfo->chain_signal_avg[i] =
pAdapter->hdd_stats.per_chain_rssi_stats.rssi[i];
sinfo->chains |= 1 << i;
if (sinfo->chain_signal_avg[i] > sinfo->signal_avg &&
sinfo->chain_signal_avg[i] != 0)
sinfo->signal_avg = sinfo->chain_signal_avg[i];
hdd_info("RSSI for chain %d, vdev_id %d is %d",
i, pAdapter->sessionId, sinfo->chain_signal_avg[i]);
if (!rssi_stats_valid && sinfo->chain_signal_avg[i])
rssi_stats_valid = true;
}
if (rssi_stats_valid) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
sinfo->filled |= STATION_INFO_CHAIN_SIGNAL_AVG;
sinfo->filled |= STATION_INFO_SIGNAL_AVG;
#else
sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL_AVG);
#endif
}
#endif
MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
TRACE_CODE_HDD_CFG80211_GET_STA,
pAdapter->sessionId, maxRate));
@ -2163,6 +2195,54 @@ int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
return ret;
}
/**
* __wlan_hdd_cfg80211_dump_station() - dump station statistics
* @wiphy: Pointer to wiphy
* @dev: Pointer to network device
* @idx: variable to determine whether to get stats or not
* @mac: Pointer to mac
* @sinfo: Pointer to station info
*
* Return: 0 for success, non-zero for failure
*/
static int __wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
struct net_device *dev,
int idx, u8 *mac,
struct station_info *sinfo)
{
hdd_context_t *hdd_ctx = (hdd_context_t *) wiphy_priv(wiphy);
hdd_debug("%s: idx %d", __func__, idx);
if (idx != 0)
return -ENOENT;
qdf_mem_copy(mac, hdd_ctx->config->intfMacAddr[0].bytes,
QDF_MAC_ADDR_SIZE);
return __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
}
/**
* wlan_hdd_cfg80211_dump_station() - dump station statistics
* @wiphy: Pointer to wiphy
* @dev: Pointer to network device
* @idx: variable to determine whether to get stats or not
* @mac: Pointer to mac
* @sinfo: Pointer to station info
*
* Return: 0 for success, non-zero for failure
*/
int wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
struct net_device *dev,
int idx, u8 *mac,
struct station_info *sinfo)
{
int ret;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_dump_station(wiphy, dev, idx, mac, sinfo);
cds_ssr_unprotect(__func__);
return ret;
}
/**
* hdd_get_stats() - Function to retrieve interface statistics
* @dev: pointer to network device

View file

@ -40,6 +40,8 @@
/* LL stats get request time out value */
#define WLAN_WAIT_TIME_LL_STATS 800
#define WLAN_HDD_TGT_NOISE_FLOOR_DBM (-96)
/**
* struct index_vht_data_rate_type - vht data rate type
* @beacon_rate_index: Beacon rate index
@ -190,6 +192,21 @@ int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
struct station_info *sinfo);
#endif
/**
* wlan_hdd_cfg80211_dump_station() - dump station statistics
* @wiphy: Pointer to wiphy
* @dev: Pointer to network device
* @idx: variable to determine whether to get stats or not
* @mac: Pointer to mac
* @sinfo: Pointer to station info
*
* Return: 0 for success, non-zero for failure
*/
int wlan_hdd_cfg80211_dump_station(struct wiphy *wiphy,
struct net_device *dev,
int idx, u8 *mac,
struct station_info *sinfo);
struct net_device_stats *hdd_get_stats(struct net_device *dev);
int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,

View file

@ -3717,6 +3717,7 @@ static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
struct statsContext *pStatsContext;
tCsrSummaryStatsInfo *pSummaryStats;
tCsrGlobalClassAStatsInfo *pClassAStats;
struct csr_per_chain_rssi_stats_info *per_chain_rssi_stats;
hdd_adapter_t *pAdapter;
if (ioctl_debug) {
@ -3739,6 +3740,8 @@ static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
per_chain_rssi_stats = (struct csr_per_chain_rssi_stats_info *)
(pClassAStats + 1);
pStatsContext = pContext;
pAdapter = pStatsContext->pAdapter;
if ((NULL == pAdapter) ||
@ -3764,6 +3767,7 @@ static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
/* copy over the stats. do so as a struct copy */
pAdapter->hdd_stats.summary_stat = *pSummaryStats;
pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
pAdapter->hdd_stats.per_chain_rssi_stats = *per_chain_rssi_stats;
/* notify the caller */
complete(&pStatsContext->completion);
@ -3799,7 +3803,8 @@ QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
eCSR_HDD,
SME_SUMMARY_STATS |
SME_GLOBAL_CLASSA_STATS,
SME_GLOBAL_CLASSA_STATS |
SME_PER_CHAIN_RSSI_STATS,
hdd_get_station_statistics_cb,
0, /* not periodic */
false, /* non-cached results */

View file

@ -109,6 +109,8 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN];
#define MAX_POWER_DBG_ARGS_SUPPORTED 8
#define NUM_CHAINS_MAX 2
/**
* enum sir_conn_update_reason: Reason for conc connection update
* @SIR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel

View file

@ -1522,6 +1522,16 @@ typedef struct tagCsrPerStaStatsInfo {
uint32_t tx_mpdu_in_ampdu_cnt;
} tCsrPerStaStatsInfo;
/**
* struct csr_per_chain_rssi_stats_info - stores chain rssi
* @rssi: array containing rssi for all chains
* @peer_mac_addr: peer mac address
*/
struct csr_per_chain_rssi_stats_info {
int8_t rssi[NUM_CHAINS_MAX];
tSirMacAddr peer_mac_addr;
};
typedef struct tagCsrRoamSetKey {
eCsrEncryptionType encType;
tAniKeyDirection keyDirection; /* Tx, Rx or Tx-and-Rx */

View file

@ -240,6 +240,7 @@ typedef enum {
eCsrGlobalClassCStats,
eCsrGlobalClassDStats,
eCsrPerStaStats,
csr_per_chain_rssi_stats,
eCsrMaxStats
} eCsrRoamStatsClassTypes;
@ -1023,6 +1024,7 @@ typedef struct tagCsrRoamStruct {
tCsrGlobalClassCStatsInfo classCStatsInfo;
tCsrGlobalClassDStatsInfo classDStatsInfo;
tCsrPerStaStatsInfo perStaStatsInfo[CSR_MAX_STA];
struct csr_per_chain_rssi_stats_info per_chain_rssi_stats;
tDblLinkList statsClientReqList;
tDblLinkList peStatsReqList;
tCsrTlStatsReqInfo tlStatsReqInfo;

View file

@ -60,6 +60,7 @@
#define SME_GLOBAL_CLASSC_STATS 8
#define SME_GLOBAL_CLASSD_STATS 16
#define SME_PER_STA_STATS 32
#define SME_PER_CHAIN_RSSI_STATS 64
#define SME_SESSION_ID_ANY 50

View file

@ -15986,6 +15986,14 @@ csr_update_stats(tpAniSirGlobal mac, uint8_t stats_type,
*stats += sizeof(tCsrPerStaStatsInfo);
*length -= sizeof(tCsrPerStaStatsInfo);
break;
case csr_per_chain_rssi_stats:
sms_log(mac, LOG2,
FL("csrRoamStatsRspProcessor:Per Chain RSSI stats"));
qdf_mem_copy((uint8_t *)&mac->roam.per_chain_rssi_stats,
*stats, sizeof(struct csr_per_chain_rssi_stats_info));
*stats += sizeof(struct csr_per_chain_rssi_stats_info);
*length -= sizeof(struct csr_per_chain_rssi_stats_info);
break;
default:
sms_log(mac, LOGW, FL("unknown stats type"));
break;
@ -17754,6 +17762,14 @@ void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
sizeof(tCsrPerStaStatsInfo));
pStats += sizeof(tCsrPerStaStatsInfo);
break;
case csr_per_chain_rssi_stats:
sms_log(pMac, LOG2, FL("Per Chain RSSI stats"));
qdf_mem_copy(pStats,
(uint8_t *)&pMac->roam.per_chain_rssi_stats,
sizeof(struct csr_per_chain_rssi_stats_info));
pStats += sizeof(
struct csr_per_chain_rssi_stats_info);
break;
default:
sms_log(pMac, LOGE,
FL("Unknown stats type and counter %d"),

View file

@ -55,12 +55,14 @@
#define FW_PDEV_STATS_SET 0x1
#define FW_VDEV_STATS_SET 0x2
#define FW_PEER_STATS_SET 0x4
#define FW_STATS_SET 0x7
#define FW_RSSI_PER_CHAIN_STATS_SET 0x8
#define FW_STATS_SET 0xf
/*AR9888/AR6320 noise floor approx value
* similar to the mentioned the WMA
*/
#define WMA_TGT_NOISE_FLOOR_DBM (-96)
#define WMA_TGT_RSSI_INVALID 96
/*
* Make sure that link monitor and keep alive

View file

@ -1298,11 +1298,6 @@ static void wma_update_peer_stats(tp_wma_handle wma,
node->rate_flags, node->nss,
classa_stats->max_pwr);
}
if (node->fw_stats_set & FW_STATS_SET) {
WMA_LOGD("<--STATS RSP VDEV_ID:%d", vdev_id);
wma_post_stats(wma, node);
}
}
}
@ -1331,6 +1326,107 @@ void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus,
}
}
/**
* wma_update_per_chain_rssi_stats() - to store per chain rssi stats
* @wma: wma handle
* @rssi_stats: rssi stats
* @rssi_per_chain_stats: buffer where rssi stats to be stored
*
* This function stores per chain rssi stats received from fw for all vdevs for
* which the stats were requested into a csr stats structure.
*
* Return: void
*/
static void wma_update_per_chain_rssi_stats(tp_wma_handle wma,
wmi_rssi_stats *rssi_stats,
struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats)
{
int i;
int8_t bcn_snr, dat_snr;
for (i = 0; i < NUM_CHAINS_MAX; i++) {
bcn_snr = rssi_stats->rssi_avg_beacon[i];
dat_snr = rssi_stats->rssi_avg_data[i];
WMA_LOGD("chain %d beacon snr %d data snr %d",
i, bcn_snr, dat_snr);
if (dat_snr != WMA_TGT_INVALID_SNR)
rssi_per_chain_stats->rssi[i] = dat_snr;
else if (bcn_snr != WMA_TGT_INVALID_SNR)
rssi_per_chain_stats->rssi[i] = bcn_snr;
else
/*
* Firmware sends invalid snr till it sees
* Beacon/Data after connection since after
* vdev up fw resets the snr to invalid.
* In this duartion Host will return an invalid rssi
* value.
*/
rssi_per_chain_stats->rssi[i] = WMA_TGT_RSSI_INVALID;
/*
* Get the absolute rssi value from the current rssi value the
* sinr value is hardcoded into 0 in the qcacld-new/CORE stack
*/
rssi_per_chain_stats->rssi[i] += WMA_TGT_NOISE_FLOOR_DBM;
WMI_MAC_ADDR_TO_CHAR_ARRAY(&(rssi_stats->peer_macaddr),
rssi_per_chain_stats->peer_mac_addr);
}
}
/**
* wma_update_rssi_stats() - to update rssi stats for all vdevs
* for which the stats were requested.
* @wma: wma handle
* @rssi_stats: rssi stats
*
* This function updates the rssi stats for all vdevs for which
* the stats were requested.
*
* Return: void
*/
static void wma_update_rssi_stats(tp_wma_handle wma,
wmi_rssi_stats *rssi_stats)
{
tAniGetPEStatsRsp *stats_rsp_params;
struct csr_per_chain_rssi_stats_info *rssi_per_chain_stats = NULL;
struct wma_txrx_node *node;
uint8_t *stats_buf;
uint32_t temp_mask;
uint8_t vdev_id;
vdev_id = rssi_stats->vdev_id;
node = &wma->interfaces[vdev_id];
if (node->stats_rsp) {
node->fw_stats_set |= FW_RSSI_PER_CHAIN_STATS_SET;
WMA_LOGD("<-- FW RSSI PER CHAIN STATS received for vdevId:%d",
vdev_id);
stats_rsp_params = (tAniGetPEStatsRsp *) node->stats_rsp;
stats_buf = (uint8_t *) (stats_rsp_params + 1);
temp_mask = stats_rsp_params->statsMask;
if (temp_mask & (1 << eCsrSummaryStats))
stats_buf += sizeof(tCsrSummaryStatsInfo);
if (temp_mask & (1 << eCsrGlobalClassAStats))
stats_buf += sizeof(tCsrGlobalClassAStatsInfo);
if (temp_mask & (1 << eCsrGlobalClassBStats))
stats_buf += sizeof(tCsrGlobalClassBStatsInfo);
if (temp_mask & (1 << eCsrGlobalClassCStats))
stats_buf += sizeof(tCsrGlobalClassCStatsInfo);
if (temp_mask & (1 << eCsrGlobalClassDStats))
stats_buf += sizeof(tCsrGlobalClassDStatsInfo);
if (temp_mask & (1 << eCsrPerStaStats))
stats_buf += sizeof(tCsrPerStaStatsInfo);
if (temp_mask & (1 << csr_per_chain_rssi_stats)) {
rssi_per_chain_stats =
(struct csr_per_chain_rssi_stats_info *)stats_buf;
wma_update_per_chain_rssi_stats(wma, rssi_stats,
rssi_per_chain_stats);
}
}
}
/**
* wma_link_status_event_handler() - link status event handler
* @handle: wma handle
@ -1412,9 +1508,11 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
wmi_pdev_stats *pdev_stats;
wmi_vdev_stats *vdev_stats;
wmi_peer_stats *peer_stats;
wmi_rssi_stats *rssi_stats;
wmi_per_chain_rssi_stats *rssi_event;
struct wma_txrx_node *node;
uint8_t i, *temp;
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
WMA_LOGA("%s: Invalid stats event", __func__);
@ -1450,6 +1548,34 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
}
}
rssi_event = (wmi_per_chain_rssi_stats *) param_buf->chain_stats;
if (rssi_event) {
if ((rssi_event->tlv_header & 0xFFFF0000) >> 16 ==
WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats) {
WMA_LOGD("%s: num_rssi_stats %u", __func__,
rssi_event->num_per_chain_rssi_stats);
if (rssi_event->num_per_chain_rssi_stats > 0) {
temp = (uint8_t *) rssi_event;
temp += sizeof(*rssi_event);
for (i = 0;
i < rssi_event->num_per_chain_rssi_stats;
i++) {
rssi_stats = (wmi_rssi_stats *)temp;
wma_update_rssi_stats(wma, rssi_stats);
temp += sizeof(wmi_rssi_stats);
}
}
}
}
for (i = 0; i < wma->max_bssid; i++) {
node = &wma->interfaces[i];
if (node->fw_stats_set & FW_PEER_STATS_SET) {
WMA_LOGD("<--STATS RSP VDEV_ID:%d", i);
wma_post_stats(wma, node);
}
}
WMA_LOGI("%s: Exit", __func__);
return 0;
}
@ -1880,6 +2006,10 @@ static tAniGetPEStatsRsp *wma_get_stats_rsp_buf
case eCsrPerStaStats:
len += sizeof(tCsrPerStaStatsInfo);
break;
case csr_per_chain_rssi_stats:
len +=
sizeof(struct csr_per_chain_rssi_stats_info);
break;
}
}