qcacld-3.0: Add support to get pmf bcn protect stats
Host sets WMI_REQUEST_PMF_BCN_PROTECT_STAT bit in stats_id param of WMI_REQUEST_STATS_CMDID command. Firmware supporting pmf beacon protection stats responds host with stats in wmi_update_stats_id event. Host extracts PMF beacon protection stats from wmi_update_stats_id event. Host adds PMF beacon protection stats in the response of vendor command QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO for STA mode. Change-Id: Ib3cb06e03dbccdb9fa1782d414ed734bd97aa309 CRs-Fixed: 2705236
This commit is contained in:
parent
7f2bf137e9
commit
8c579f5a5b
@ -270,18 +270,36 @@ struct summary_stats {
|
||||
uint32_t rx_error_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pmf_bcn_protect_stats - pmf bcn protect stats param
|
||||
* @pmf_bcn_stats_valid: bcn protect stats received from fw are valid or not
|
||||
* @igtk_mic_fail_cnt: MIC failure count of management packets using IGTK
|
||||
* @igtk_replay_cnt: Replay detection count of management packets using IGTK
|
||||
* @bcn_mic_fail_cnt: MIC failure count of beacon packets using BIGTK
|
||||
* @bcn_replay_cnt: Replay detection count of beacon packets using BIGTK
|
||||
*/
|
||||
struct pmf_bcn_protect_stats {
|
||||
bool pmf_bcn_stats_valid;
|
||||
uint32_t igtk_mic_fail_cnt;
|
||||
uint32_t igtk_replay_cnt;
|
||||
uint32_t bcn_mic_fail_cnt;
|
||||
uint32_t bcn_replay_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vdev_mc_cp_stats - vdev specific stats
|
||||
* @cca: cca stats
|
||||
* @tx_rate_flags: tx rate flags (enum tx_rate_info)
|
||||
* @chain_rssi: chain rssi
|
||||
* @vdev_summary_stats: vdev's summary stats
|
||||
* @pmf_bcn_stats: pmf beacon protect stats
|
||||
*/
|
||||
struct vdev_mc_cp_stats {
|
||||
struct cca_stats cca;
|
||||
uint32_t tx_rate_flags;
|
||||
int8_t chain_rssi[MAX_NUM_CHAINS];
|
||||
struct summary_stats vdev_summary_stats;
|
||||
struct pmf_bcn_protect_stats pmf_bcn_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -560,6 +578,7 @@ struct peer_stats_info_ext_event {
|
||||
* MSB indicates if this feature is supported by FW or not.
|
||||
* @num_peer_stats_info_ext: number of peer extended stats info
|
||||
* @peer_stats_info_ext: peer extended stats info
|
||||
* @pmf_bcn_protect_stats: pmf bcn protect stats
|
||||
*/
|
||||
struct stats_event {
|
||||
uint32_t num_pdev_stats;
|
||||
@ -585,6 +604,7 @@ struct stats_event {
|
||||
uint32_t last_event;
|
||||
uint32_t num_peer_stats_info_ext;
|
||||
struct peer_stats_info_ext_event *peer_stats_info_ext;
|
||||
struct pmf_bcn_protect_stats bcn_protect_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -648,6 +648,48 @@ end:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
}
|
||||
|
||||
static void
|
||||
tgt_mc_cp_stats_extract_pmf_bcn_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct request_info last_req = {0};
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct vdev_mc_cp_stats *vdev_mc_stats;
|
||||
struct vdev_cp_stats *vdev_cp_stats_priv;
|
||||
|
||||
status = ucfg_mc_cp_stats_get_pending_req(psoc,
|
||||
TYPE_STATION_STATS,
|
||||
&last_req);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
|
||||
return;
|
||||
}
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, last_req.vdev_id,
|
||||
WLAN_CP_STATS_ID);
|
||||
if (!vdev) {
|
||||
cp_stats_err("vdev is null");
|
||||
return;
|
||||
}
|
||||
|
||||
vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
|
||||
if (!vdev_cp_stats_priv) {
|
||||
cp_stats_err("vdev cp stats object is null");
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
|
||||
vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
|
||||
|
||||
if (ev->bcn_protect_stats.pmf_bcn_stats_valid)
|
||||
vdev_mc_stats->pmf_bcn_stats = ev->bcn_protect_stats;
|
||||
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
|
||||
}
|
||||
|
||||
static void tgt_mc_cp_stats_extract_vdev_summary_stats(
|
||||
struct wlan_objmgr_psoc *psoc,
|
||||
struct stats_event *ev)
|
||||
@ -701,6 +743,7 @@ static void tgt_mc_cp_stats_extract_vdev_summary_stats(
|
||||
qdf_mem_copy(&vdev_mc_stats->vdev_summary_stats,
|
||||
&ev->vdev_summary_stats[i].stats,
|
||||
sizeof(vdev_mc_stats->vdev_summary_stats));
|
||||
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
|
||||
peer = wlan_objmgr_get_peer(psoc, last_req.pdev_id,
|
||||
@ -851,6 +894,8 @@ tgt_mc_cp_stats_prepare_n_send_raw_station_stats(struct wlan_objmgr_psoc *psoc,
|
||||
vdev_mc_stats->chain_rssi,
|
||||
sizeof(vdev_mc_stats->chain_rssi));
|
||||
info.tx_rate_flags = vdev_mc_stats->tx_rate_flags;
|
||||
|
||||
info.bcn_protect_stats = vdev_mc_stats->pmf_bcn_stats;
|
||||
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
|
||||
|
||||
info.peer_adv_stats = qdf_mem_malloc(sizeof(*info.peer_adv_stats));
|
||||
@ -907,6 +952,7 @@ static void tgt_mc_cp_stats_extract_station_stats(
|
||||
tgt_mc_cp_stats_extract_peer_stats(psoc, ev, true);
|
||||
tgt_mc_cp_stats_extract_vdev_summary_stats(psoc, ev);
|
||||
tgt_mc_cp_stats_extract_vdev_chain_rssi_stats(psoc, ev);
|
||||
tgt_mc_cp_stats_extract_pmf_bcn_stats(psoc, ev);
|
||||
|
||||
/*
|
||||
* PEER stats are the last stats sent for get_station statistics.
|
||||
|
@ -375,6 +375,38 @@ static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_cp_stats_extract_pmf_bcn_protect_stats(
|
||||
struct wmi_unified *wmi_hdl,
|
||||
wmi_host_stats_event *stats_param,
|
||||
struct stats_event *ev, uint8_t *data)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
wmi_host_pmf_bcn_protect_stats pmf_bcn_stats = {0};
|
||||
|
||||
if (!(stats_param->stats_id & WMI_HOST_REQUEST_PMF_BCN_PROTECT_STAT))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
qdf_mem_zero(&ev->bcn_protect_stats, sizeof(ev->bcn_protect_stats));
|
||||
status = wmi_extract_pmf_bcn_protect_stats(wmi_hdl, data,
|
||||
&pmf_bcn_stats);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cp_stats_err("wmi_extract_pmf_bcn_protect_stats failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
ev->bcn_protect_stats.pmf_bcn_stats_valid = true;
|
||||
ev->bcn_protect_stats.igtk_mic_fail_cnt =
|
||||
pmf_bcn_stats.igtk_mic_fail_cnt;
|
||||
ev->bcn_protect_stats.igtk_replay_cnt =
|
||||
pmf_bcn_stats.igtk_replay_cnt;
|
||||
ev->bcn_protect_stats.bcn_mic_fail_cnt =
|
||||
pmf_bcn_stats.bcn_mic_fail_cnt;
|
||||
ev->bcn_protect_stats.bcn_replay_cnt =
|
||||
pmf_bcn_stats.bcn_replay_cnt;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void target_if_cp_stats_extract_peer_extd_stats(
|
||||
struct wmi_unified *wmi_hdl,
|
||||
wmi_host_stats_event *stats_param,
|
||||
@ -709,7 +741,7 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
cp_stats_nofl_debug("num: pdev: %d, pdev_extd: %d, vdev: %d, peer: %d,"
|
||||
"peer_extd: %d rssi: %d, mib %d, mib_extd %d, "
|
||||
"bcnflt: %d, channel: %d, bcn: %d, peer_extd2: %d,"
|
||||
"last_event: %x",
|
||||
"last_event: %x, stats id: %d",
|
||||
stats_param.num_pdev_stats,
|
||||
stats_param.num_pdev_ext_stats,
|
||||
stats_param.num_vdev_stats,
|
||||
@ -721,7 +753,9 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
stats_param.num_bcnflt_stats,
|
||||
stats_param.num_chan_stats,
|
||||
stats_param.num_bcn_stats,
|
||||
stats_param.num_peer_adv_stats, stats_param.last_event);
|
||||
stats_param.num_peer_adv_stats,
|
||||
stats_param.last_event,
|
||||
stats_param.stats_id);
|
||||
|
||||
ev->last_event = stats_param.last_event;
|
||||
status = target_if_cp_stats_extract_pdev_stats(wmi_hdl, &stats_param,
|
||||
@ -757,7 +791,11 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
status = target_if_cp_stats_extract_pmf_bcn_protect_stats(wmi_hdl,
|
||||
&stats_param,
|
||||
ev, data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1090,7 +1128,8 @@ static uint32_t get_stats_id(enum stats_req_type type)
|
||||
WMI_REQUEST_VDEV_STAT |
|
||||
WMI_REQUEST_PDEV_STAT |
|
||||
WMI_REQUEST_PEER_EXTD2_STAT |
|
||||
WMI_REQUEST_RSSI_PER_CHAIN_STAT);
|
||||
WMI_REQUEST_RSSI_PER_CHAIN_STAT |
|
||||
WMI_REQUEST_PMF_BCN_PROTECT_STAT);
|
||||
case TYPE_MIB_STATS:
|
||||
return (WMI_REQUEST_MIB_STAT | WMI_REQUEST_MIB_EXTD_STAT);
|
||||
}
|
||||
|
@ -700,6 +700,7 @@ struct hdd_stats {
|
||||
#endif
|
||||
struct hdd_eapol_stats_s hdd_eapol_stats;
|
||||
struct hdd_dhcp_stats_s hdd_dhcp_stats;
|
||||
struct pmf_bcn_protect_stats bcn_protect_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -58,6 +58,19 @@
|
||||
#define STATION_MAX \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
|
||||
|
||||
#define STA_INFO_INVALID \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID
|
||||
#define STA_INFO_BIP_MIC_ERROR_COUNT \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT
|
||||
#define STA_INFO_BIP_REPLAY_COUNT \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT
|
||||
#define STA_INFO_BEACON_MIC_ERROR_COUNT \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT
|
||||
#define STA_INFO_BEACON_REPLAY_COUNT \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT
|
||||
#define STA_INFO_MAX \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX
|
||||
|
||||
/* define short names for get station info attributes */
|
||||
#define LINK_INFO_STANDARD_NL80211_ATTR \
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
|
||||
@ -127,7 +140,6 @@
|
||||
*/
|
||||
#define HDD_STATION_INFO_RX_MC_BC_COUNT (1 << 31)
|
||||
|
||||
|
||||
const struct nla_policy
|
||||
hdd_get_station_policy[STATION_MAX + 1] = {
|
||||
[STATION_INFO] = {.type = NLA_FLAG},
|
||||
@ -1593,6 +1605,55 @@ hdd_add_peer_stats_get_len(struct hdd_station_info *stainfo)
|
||||
nla_attr_size(sizeof(stainfo->tx_retry_exhaust_fw)));
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_pmf_bcn_protect_stats_len() - get pmf bcn protect counters len
|
||||
* @adapter: adapter holding valid bcn protect counters
|
||||
*
|
||||
* This function calculates the data length for valid pmf bcn counters.
|
||||
*
|
||||
* Return: total data length used in hdd_add_peer_stats()
|
||||
*/
|
||||
static uint32_t
|
||||
hdd_get_pmf_bcn_protect_stats_len(struct hdd_adapter *adapter)
|
||||
{
|
||||
if (!adapter->hdd_stats.bcn_protect_stats.pmf_bcn_stats_valid)
|
||||
return 0;
|
||||
|
||||
/* 4 pmf becon protect counters each of 32 bit */
|
||||
return nla_attr_size(sizeof(uint32_t) * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_pmf_bcn_protect_stats() - add pmf bcn protect counters in resp
|
||||
* @skb: pointer to response skb buffer
|
||||
* @adapter: adapter holding valid bcn protect counters
|
||||
*
|
||||
* This function adds the pmf bcn stats in response.
|
||||
*
|
||||
* Return: 0 on success
|
||||
*/
|
||||
static int hdd_add_pmf_bcn_protect_stats(struct sk_buff *skb,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
if (!adapter->hdd_stats.bcn_protect_stats.pmf_bcn_stats_valid)
|
||||
return 0;
|
||||
|
||||
adapter->hdd_stats.bcn_protect_stats.pmf_bcn_stats_valid = 0;
|
||||
if (nla_put_u32(skb, STA_INFO_BIP_MIC_ERROR_COUNT,
|
||||
adapter->hdd_stats.bcn_protect_stats.igtk_mic_fail_cnt) ||
|
||||
nla_put_u32(skb, STA_INFO_BIP_REPLAY_COUNT,
|
||||
adapter->hdd_stats.bcn_protect_stats.igtk_replay_cnt) ||
|
||||
nla_put_u32(skb, STA_INFO_BEACON_MIC_ERROR_COUNT,
|
||||
adapter->hdd_stats.bcn_protect_stats.bcn_mic_fail_cnt) ||
|
||||
nla_put_u32(skb, STA_INFO_BEACON_REPLAY_COUNT,
|
||||
adapter->hdd_stats.bcn_protect_stats.bcn_replay_cnt)) {
|
||||
hdd_err("put fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_peer_stats - add peer statistics information
|
||||
* @skb: pointer to response skb buffer
|
||||
@ -1807,6 +1868,49 @@ static int hdd_get_station_remote_ex(struct hdd_context *hdd_ctx,
|
||||
return hdd_get_connected_station_info_ex(hdd_ctx, adapter, stainfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_station_info_ex() - send STA info to userspace, for STA mode only
|
||||
* @hdd_ctx: pointer to hdd context
|
||||
* @adapter: pointer to adapter
|
||||
*
|
||||
* Return: 0 if success else error status
|
||||
*/
|
||||
static int hdd_get_station_info_ex(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
uint32_t nl_buf_len;
|
||||
struct hdd_station_ctx *hdd_sta_ctx;
|
||||
|
||||
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
|
||||
if (wlan_hdd_get_station_stats(adapter)) {
|
||||
hdd_err_rl("wlan_hdd_get_station_stats fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nl_buf_len = hdd_get_pmf_bcn_protect_stats_len(adapter);
|
||||
if (!nl_buf_len) {
|
||||
hdd_err_rl("Failed to get bcn pmf stats");
|
||||
return -EINVAL;
|
||||
}
|
||||
nl_buf_len += NLMSG_HDRLEN;
|
||||
|
||||
skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
|
||||
if (!skb) {
|
||||
hdd_err_rl("cfg80211_vendor_cmd_alloc_reply_skb failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (hdd_add_pmf_bcn_protect_stats(skb, adapter)) {
|
||||
hdd_err_rl("hdd_add_pmf_bcn_protect_stats fail");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cfg80211_vendor_cmd_reply(skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd
|
||||
* @wiphy: pointer to wireless phy
|
||||
@ -1857,6 +1961,7 @@ __hdd_cfg80211_get_sta_info_cmd(struct wiphy *wiphy,
|
||||
switch (adapter->device_mode) {
|
||||
case QDF_STA_MODE:
|
||||
case QDF_P2P_CLIENT_MODE:
|
||||
status = hdd_get_station_info_ex(hdd_ctx, adapter);
|
||||
break;
|
||||
case QDF_SAP_MODE:
|
||||
case QDF_P2P_GO_MODE:
|
||||
|
@ -30,7 +30,7 @@ extern const struct nla_policy hdd_get_station_policy[
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
|
||||
* hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
|
||||
* @wiphy: corestack handler
|
||||
* @wdev: wireless device
|
||||
* @data: data
|
||||
@ -50,14 +50,14 @@ extern const struct nla_policy hdd_get_sta_policy[
|
||||
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd
|
||||
* hdd_cfg80211_get_sta_info_cmd() - Handle get sta info vendor cmd
|
||||
* @wiphy: corestack handler
|
||||
* @wdev: wireless device
|
||||
* @data: data
|
||||
* @data_len: data length
|
||||
*
|
||||
* Handles QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO.
|
||||
* Validate cmd attributes and send the station info to upper layers.
|
||||
* Validate cmd attributes and send the sta info to upper layers.
|
||||
*
|
||||
* Return: Success(0) or reason code for failure
|
||||
*/
|
||||
|
@ -4866,15 +4866,12 @@ void hdd_wlan_fill_per_chain_rssi_stats(struct station_info *sinfo,
|
||||
sinfo->filled |= HDD_INFO_SIGNAL_AVG;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline
|
||||
void hdd_wlan_fill_per_chain_rssi_stats(struct station_info *sinfo,
|
||||
struct hdd_adapter *adapter)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CFG80211_RX_FCS_ERROR_REPORTING_SUPPORT)
|
||||
@ -6229,6 +6226,7 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
|
||||
qdf_mem_copy(adapter->hdd_stats.per_chain_rssi_stats.rssi,
|
||||
stats->vdev_chain_rssi[0].chain_rssi,
|
||||
sizeof(stats->vdev_chain_rssi[0].chain_rssi));
|
||||
adapter->hdd_stats.bcn_protect_stats = stats->bcn_protect_stats;
|
||||
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
||||
|
||||
out:
|
||||
|
@ -495,6 +495,7 @@ static void get_station_stats_cb(struct stats_event *ev, void *cookie)
|
||||
qdf_mem_copy(priv->vdev_chain_rssi, ev->vdev_chain_rssi, rssi_size);
|
||||
qdf_mem_copy(priv->vdev_summary_stats, ev->vdev_summary_stats,
|
||||
summary_size);
|
||||
priv->bcn_protect_stats = ev->bcn_protect_stats;
|
||||
|
||||
station_stats_cb_fail:
|
||||
osif_request_complete(request);
|
||||
@ -585,6 +586,7 @@ wlan_cfg80211_mc_cp_stats_get_station_stats(struct wlan_objmgr_vdev *vdev,
|
||||
if (priv->peer_adv_stats)
|
||||
out->peer_adv_stats = priv->peer_adv_stats;
|
||||
priv->peer_adv_stats = NULL;
|
||||
out->bcn_protect_stats = priv->bcn_protect_stats;
|
||||
osif_request_put(request);
|
||||
|
||||
osif_debug("Exit");
|
||||
|
Loading…
Reference in New Issue
Block a user