Merge "qcacmn: Add support to cache peer capability info"

This commit is contained in:
Linux Build Service Account 2019-04-08 12:06:01 -07:00 • committed by Gerrit - the friendly Code Review server
commit b8a649b3a0
10 changed files with 301 additions and 13 deletions

View file

@ -770,9 +770,10 @@ enum qca_wlan_vendor_attr_get_station_info {
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC,
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH,
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD,
#endif
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT,
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT,
/* keep last */
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX =

View file

@ -43,6 +43,8 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
ev->peer_stats = NULL;
qdf_mem_free(ev->peer_adv_stats);
ev->peer_adv_stats = NULL;
qdf_mem_free(ev->peer_extended_stats);
ev->peer_extended_stats = NULL;
qdf_mem_free(ev->cca_stats);
ev->cca_stats = NULL;
qdf_mem_free(ev->vdev_summary_stats);
@ -86,6 +88,43 @@ static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
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,
struct stats_event *ev,
uint8_t *data)
{
QDF_STATUS status;
uint32_t i;
wmi_host_peer_extd_stats peer_extd_stats;
if (!stats_param->num_peer_extd_stats)
return;
ev->peer_extended_stats =
qdf_mem_malloc(sizeof(*ev->peer_extended_stats) *
stats_param->num_peer_extd_stats);
if (!ev->peer_extended_stats)
return;
ev->num_peer_extd_stats = stats_param->num_peer_extd_stats;
for (i = 0; i < ev->num_peer_extd_stats; i++) {
status = wmi_extract_peer_extd_stats(wmi_hdl, data, i,
&peer_extd_stats);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("wmi_extract_peer_extd_stats failed");
continue;
}
WMI_MAC_ADDR_TO_CHAR_ARRAY(
&peer_extd_stats.peer_macaddr,
ev->peer_extended_stats[i].peer_macaddr);
ev->peer_extended_stats[i].rx_mc_bc_cnt =
peer_extd_stats.rx_mc_bc_cnt;
}
}
static QDF_STATUS target_if_cp_stats_extract_peer_stats(
struct wmi_unified *wmi_hdl,
wmi_host_stats_event *stats_param,
@ -99,14 +138,14 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats(
struct wmi_host_peer_adv_stats *peer_adv_stats;
/* Extract peer_stats */
ev->num_peer_stats = stats_param->num_peer_stats;
if (!ev->num_peer_stats)
if (!stats_param->num_peer_stats)
return QDF_STATUS_SUCCESS;
ev->peer_stats = qdf_mem_malloc(sizeof(*ev->peer_stats) *
ev->num_peer_stats);
stats_param->num_peer_stats);
if (!ev->peer_stats)
return QDF_STATUS_E_NOMEM;
ev->num_peer_stats = stats_param->num_peer_stats;
db2dbm_enabled = wmi_service_enabled(wmi_hdl,
wmi_service_hw_db2dbm_support);
@ -127,6 +166,9 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats(
TGT_NOISE_FLOOR_DBM;
}
target_if_cp_stats_extract_peer_extd_stats(wmi_hdl, stats_param, ev,
data);
/* Extract peer_adv_stats */
ev->num_peer_adv_stats = stats_param->num_peer_adv_stats;
if (!ev->num_peer_adv_stats)
@ -540,7 +582,7 @@ static uint32_t get_stats_id(enum stats_req_type type)
case TYPE_CONNECTION_TX_POWER:
return WMI_REQUEST_PDEV_STAT;
case TYPE_PEER_STATS:
return WMI_REQUEST_PEER_STAT;
return WMI_REQUEST_PEER_STAT | WMI_REQUEST_PEER_EXTD_STAT;
case TYPE_STATION_STATS:
return (WMI_REQUEST_AP_STAT |
WMI_REQUEST_PEER_STAT |

View file

@ -222,6 +222,16 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
*/
bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev);
/**
* wlan_crypto_vdev_is_pmf_required - called to check is pmf required in vdev
* @vdev: vdev
*
* This function gets called to check is pmf required or not in vdev.
*
* Return: true or false
*/
bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev);
/**
* wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
* @vdev: vdev

View file

@ -394,8 +394,11 @@ QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev,
QDF_STATUS status = QDF_STATUS_E_INVAL;
struct wlan_crypto_comp_priv *crypto_priv;
struct wlan_crypto_params *crypto_params;
enum QDF_OPMODE op_mode;
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
op_mode = wlan_vdev_mlme_get_opmode(vdev);
if (op_mode != QDF_STA_MODE && op_mode != QDF_SAP_MODE)
return QDF_STATUS_E_NOSUPPORT;
if (!pmksa && set) {
@ -1642,6 +1645,36 @@ bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev)
return false;
}
/**
* wlan_crypto_vdev_is_pmf_required - called to check is pmf required in vdev
* @vdev: vdev
*
* This function gets called to check is pmf required or not in vdev.
*
* Return: true or false
*/
bool wlan_crypto_vdev_is_pmf_required(struct wlan_objmgr_vdev *vdev)
{
struct wlan_crypto_comp_priv *crypto_priv;
struct wlan_crypto_params *vdev_crypto_params;
if (!vdev)
return false;
vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
&crypto_priv);
if (!crypto_priv) {
crypto_err("crypto_priv NULL");
return QDF_STATUS_E_INVAL;
}
if (vdev_crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)
return true;
return false;
}
/**
* wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
* @vdev: vdev
@ -2805,7 +2838,7 @@ bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
crypto_debug("Key mgmt match failed");
return false;
}
if (wlan_crypto_vdev_is_pmf_enabled(vdev) &&
if (wlan_crypto_vdev_is_pmf_required(vdev) &&
!(crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) {
crypto_debug("Peer is not PMF capable");
return false;

View file

@ -88,6 +88,7 @@ struct vdev_cp_stats {
* @peer_obj: pointer to peer
* @peer_stats: pointer to ic/mc specific stats
* @peer_adv_stats: pointer to peer adv stats
* @peer_extd_stats: Pointer to peer extended stats
* @peer_comp_priv_obj[]: component's private object pointers
* @peer_cp_stats_lock: lock to protect object
*/
@ -95,6 +96,7 @@ struct peer_cp_stats {
struct wlan_objmgr_peer *peer_obj;
void *peer_stats;
void *peer_adv_stats;
void *peer_extd_stats;
void *peer_comp_priv_obj[WLAN_CP_STATS_MAX_COMPONENTS];
qdf_spinlock_t peer_cp_stats_lock;
};

View file

@ -237,6 +237,28 @@ struct vdev_mc_cp_stats {
struct summary_stats vdev_summary_stats;
};
/**
* struct peer_extd_stats - Peer extension statistics
* @peer_macaddr: peer MAC address
* @rx_duration: lower 32 bits of rx duration in microseconds
* @peer_tx_bytes: Total TX bytes (including dot11 header) sent to peer
* @peer_rx_bytes: Total RX bytes (including dot11 header) received from peer
* @last_tx_rate_code: last TX ratecode
* @last_tx_power: TX power used by peer - units are 0.5 dBm
* @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames
* corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a
* valid data
*/
struct peer_extd_stats {
uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
uint32_t rx_duration;
uint32_t peer_tx_bytes;
uint32_t peer_rx_bytes;
uint32_t last_tx_rate_code;
int32_t last_tx_power;
uint32_t rx_mc_bc_cnt;
};
/**
* struct peer_mc_cp_stats - peer specific stats
* @tx_rate: tx rate
@ -303,6 +325,8 @@ struct chain_rssi_event {
* @peer_stats: if populated array indicating peer stats
* @peer_adv_stats: if populated, indicates peer adv (extd2) stats
* @num_peer_adv_stats: number of peer adv (extd2) stats
* @num_peer_extd_stats: Num peer extended stats
* @peer_extended_stats: Peer extended stats
* @cca_stats: if populated indicates congestion stats
* @num_summary_stats: number of summary stats
* @vdev_summary_stats: if populated indicates array of summary stats per vdev
@ -320,6 +344,8 @@ struct stats_event {
struct peer_mc_cp_stats *peer_stats;
uint32_t num_peer_adv_stats;
struct peer_adv_mc_cp_stats *peer_adv_stats;
uint32_t num_peer_extd_stats;
struct peer_extd_stats *peer_extended_stats;
struct congestion_stats_event *cca_stats;
uint32_t num_summary_stats;
struct summary_stats_event *vdev_summary_stats;

View file

@ -115,6 +115,7 @@ static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev,
struct stats_event *ev;
struct peer_mc_cp_stats *peer_mc_stats;
struct peer_cp_stats *peer_cp_stats_priv;
struct peer_extd_stats *peer_extd_mc_stats;
if (WLAN_PEER_SELF == wlan_peer_get_peer_type(peer)) {
cp_stats_err("ignore self peer: %pM",
@ -133,6 +134,10 @@ static void peer_rssi_iterator(struct wlan_objmgr_pdev *pdev,
ev = arg;
ev->peer_stats[ev->num_peer_stats] = *peer_mc_stats;
ev->num_peer_stats++;
peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats;
ev->peer_extended_stats[ev->num_peer_extd_stats] = *peer_extd_mc_stats;
ev->num_peer_extd_stats++;
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
}
@ -147,6 +152,7 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_peer *peer = NULL;
struct peer_mc_cp_stats *peer_mc_stats;
struct peer_extd_stats *peer_mc_extd_stats;
struct peer_cp_stats *peer_cp_stats_priv;
void (*get_peer_rssi_cb)(struct stats_event *ev, void *cookie);
@ -172,6 +178,12 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc,
if (!ev.peer_stats)
goto end;
ev.peer_extended_stats =
qdf_mem_malloc(sizeof(*ev.peer_extended_stats) *
peer_count);
if (!ev.peer_extended_stats)
goto end;
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP,
peer_rssi_iterator, &ev,
true, WLAN_CP_STATS_ID);
@ -194,9 +206,20 @@ tgt_mc_cp_stats_prepare_raw_peer_rssi(struct wlan_objmgr_psoc *psoc,
goto end;
ev.num_peer_stats = 1;
ev.peer_extended_stats =
qdf_mem_malloc(sizeof(*ev.peer_extended_stats));
if (!ev.peer_extended_stats)
goto end;
ev.num_peer_extd_stats = 1;
wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
peer_mc_stats = peer_cp_stats_priv->peer_stats;
*ev.peer_stats = *peer_mc_stats;
peer_mc_extd_stats = peer_cp_stats_priv->peer_extd_stats;
*ev.peer_extended_stats = *peer_mc_extd_stats;
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
}
@ -299,8 +322,7 @@ tgt_mc_cp_stats_update_peer_stats(struct wlan_objmgr_psoc *psoc,
peer_mc_stats->rx_rate = peer_stats->rx_rate;
if (peer_stats->peer_rssi)
peer_mc_stats->peer_rssi = peer_stats->peer_rssi;
cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%u",
cp_stats_debug("peer_mac=%pM, tx_rate=%u, rx_rate=%u, peer_rssi=%d",
peer_mc_stats->peer_macaddr, peer_mc_stats->tx_rate,
peer_mc_stats->rx_rate, peer_mc_stats->peer_rssi);
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
@ -312,6 +334,103 @@ end:
return status;
}
static QDF_STATUS
tgt_mc_cp_stats_update_peer_extd_stats(
struct wlan_objmgr_psoc *psoc,
struct peer_extd_stats *peer_extended_stats)
{
uint8_t *peer_mac_addr;
struct wlan_objmgr_peer *peer;
struct peer_extd_stats *peer_extd_mc_stats;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct peer_cp_stats *peer_cp_stats_priv;
if (!peer_extended_stats)
return QDF_STATUS_E_INVAL;
peer_mac_addr = peer_extended_stats->peer_macaddr;
peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_addr,
WLAN_CP_STATS_ID);
if (!peer) {
cp_stats_err("peer is null");
return QDF_STATUS_E_EXISTS;
}
peer_cp_stats_priv = wlan_cp_stats_get_peer_stats_obj(peer);
if (!peer_cp_stats_priv) {
cp_stats_err("peer_cp_stats_priv is null");
status = QDF_STATUS_E_EXISTS;
goto end;
}
wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
peer_extd_mc_stats = peer_cp_stats_priv->peer_extd_stats;
if (!peer_extd_mc_stats) {
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
cp_stats_err("No peer_extd_mc_stats");
status = QDF_STATUS_E_INVAL;
goto end;
}
qdf_mem_copy(peer_extd_mc_stats->peer_macaddr,
peer_extended_stats->peer_macaddr,
QDF_MAC_ADDR_SIZE);
if (peer_extended_stats->rx_mc_bc_cnt)
peer_extd_mc_stats->rx_mc_bc_cnt =
peer_extended_stats->rx_mc_bc_cnt;
wlan_cp_stats_peer_obj_unlock(peer_cp_stats_priv);
cp_stats_debug("peer_mac=%pM, rx_mc_bc_cnt=%u",
peer_extended_stats->peer_macaddr,
peer_extended_stats->rx_mc_bc_cnt);
end:
wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID);
return status;
}
static void tgt_mc_cp_stats_extract_peer_extd_stats(
struct wlan_objmgr_psoc *psoc,
struct stats_event *ev)
{
uint32_t i, selected;
QDF_STATUS status;
struct request_info last_req = {0};
status = ucfg_mc_cp_stats_get_pending_req(psoc,
TYPE_PEER_STATS,
&last_req);
if (QDF_IS_STATUS_ERROR(status)) {
cp_stats_err("ucfg_mc_cp_stats_get_pending_req failed");
return;
}
selected = ev->num_peer_extd_stats;
for (i = 0; i < ev->num_peer_extd_stats; i++) {
status = tgt_mc_cp_stats_update_peer_extd_stats(
psoc,
&ev->peer_extended_stats[i]);
if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
!qdf_mem_cmp(ev->peer_stats[i].peer_macaddr,
last_req.peer_mac_addr,
QDF_MAC_ADDR_SIZE)) {
/* mac is specified, but failed to update the peer */
if (QDF_IS_STATUS_ERROR(status))
return;
selected = i;
}
}
/* no matched peer */
if (!QDF_IS_ADDR_BROADCAST(last_req.peer_mac_addr) &&
selected == ev->num_peer_extd_stats) {
cp_stats_err("peer not found stats");
return;
}
}
static void tgt_mc_cp_stats_extract_peer_stats(struct wlan_objmgr_psoc *psoc,
struct stats_event *ev,
bool is_station_stats)
@ -397,6 +516,7 @@ complete:
if (is_station_stats)
return;
tgt_mc_cp_stats_extract_peer_extd_stats(psoc, ev);
tgt_mc_cp_stats_prepare_raw_peer_rssi(psoc, &last_req);
ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_PEER_STATS);
}

View file

@ -88,10 +88,19 @@ QDF_STATUS wlan_cp_stats_peer_cs_init(struct peer_cp_stats *peer_cs)
peer_cs->peer_adv_stats = qdf_mem_malloc(sizeof
(struct peer_adv_mc_cp_stats));
if (!peer_cs->peer_adv_stats) {
cp_stats_err("malloc failed");
qdf_mem_free(peer_cs->peer_stats);
return QDF_STATUS_E_NOMEM;
}
peer_cs->peer_extd_stats =
qdf_mem_malloc(sizeof(struct peer_extd_stats));
if (!peer_cs->peer_extd_stats) {
qdf_mem_free(peer_cs->peer_stats);
peer_cs->peer_stats = NULL;
qdf_mem_free(peer_cs->peer_adv_stats);
peer_cs->peer_adv_stats = NULL;
return QDF_STATUS_E_NOMEM;
}
return QDF_STATUS_SUCCESS;
}
@ -99,8 +108,11 @@ QDF_STATUS wlan_cp_stats_peer_cs_deinit(struct peer_cp_stats *peer_cs)
{
qdf_mem_free(peer_cs->peer_adv_stats);
peer_cs->peer_adv_stats = NULL;
qdf_mem_free(peer_cs->peer_extd_stats);
peer_cs->peer_extd_stats = NULL;
qdf_mem_free(peer_cs->peer_stats);
peer_cs->peer_stats = NULL;
return QDF_STATUS_SUCCESS;
}
@ -568,6 +580,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
qdf_mem_free(ev->cca_stats);
qdf_mem_free(ev->vdev_summary_stats);
qdf_mem_free(ev->vdev_chain_rssi);
qdf_mem_free(ev->peer_extended_stats);
qdf_mem_zero(ev, sizeof(*ev));
}

View file

@ -4083,6 +4083,8 @@ struct rx_reorder_queue_remove_params {
* @num_pdev_ext_stats: number of pdev ext stats event structures
* @num_vdev_stats: number of vdev stats
* @num_peer_stats: number of peer stats event structures 0 or max peers
* @num_peer_extd_stats: number of peer extended stats event structures 0
* or max peers
* @num_bcnflt_stats: number of beacon filter stats
* @num_chan_stats: number of channel stats
* @pdev_id: device id for the radio
@ -4097,6 +4099,7 @@ typedef struct {
uint32_t num_pdev_ext_stats;
uint32_t num_vdev_stats;
uint32_t num_peer_stats;
uint32_t num_peer_extd_stats;
uint32_t num_bcnflt_stats;
uint32_t num_chan_stats;
uint32_t pdev_id;
@ -4119,7 +4122,10 @@ typedef struct {
* @atf_tokens_utilized: atf tokens utilized
* @num_mu_tx_blacklisted: Blacklisted MU Tx count
* @sgi_count: sgi count of the peer
* @reserved: for future use
* @rx_mc_bc_cnt: Total number of received multicast & broadcast data frames
* corresponding to this peer, 1 in the MSB of rx_mc_bc_cnt represents a
* valid data
* @rx_retry_cnt: Number of rx retries received from current station
*/
typedef struct {
wmi_host_mac_addr peer_macaddr;
@ -4133,7 +4139,8 @@ typedef struct {
uint32_t atf_tokens_utilized;
uint32_t num_mu_tx_blacklisted;
uint32_t sgi_count;
uint32_t reserved[2];
uint32_t rx_mc_bc_cnt;
uint32_t rx_retry_cnt;
} wmi_host_peer_extd_stats;
/**

View file

@ -8341,6 +8341,9 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
case WMI_REQUEST_BCN_STAT:
stats_param->stats_id |= WMI_HOST_REQUEST_BCN_STAT;
break;
case WMI_REQUEST_PEER_EXTD_STAT:
stats_param->stats_id |= WMI_REQUEST_PEER_EXTD_STAT;
break;
case WMI_REQUEST_PEER_EXTD2_STAT:
stats_param->stats_id |= WMI_HOST_REQUEST_PEER_ADV_STATS;
@ -8377,6 +8380,7 @@ static QDF_STATUS extract_all_stats_counts_tlv(wmi_unified_t wmi_handle,
stats_param->num_pdev_ext_stats = 0;
stats_param->num_vdev_stats = ev->num_vdev_stats;
stats_param->num_peer_stats = ev->num_peer_stats;
stats_param->num_peer_extd_stats = ev->num_peer_extd_stats;
stats_param->num_bcnflt_stats = ev->num_bcnflt_stats;
stats_param->num_chan_stats = ev->num_chan_stats;
stats_param->num_bcn_stats = ev->num_bcn_stats;
@ -8821,7 +8825,37 @@ static QDF_STATUS extract_peer_extd_stats_tlv(wmi_unified_t wmi_handle,
void *evt_buf, uint32_t index,
wmi_host_peer_extd_stats *peer_extd_stats)
{
WMI_UPDATE_STATS_EVENTID_param_tlvs *param_buf;
wmi_stats_event_fixed_param *ev_param;
uint8_t *data;
param_buf = (WMI_UPDATE_STATS_EVENTID_param_tlvs *)evt_buf;
ev_param = (wmi_stats_event_fixed_param *)param_buf->fixed_param;
data = (uint8_t *)param_buf->data;
if (!data)
return QDF_STATUS_E_FAILURE;
if (index < ev_param->num_peer_extd_stats) {
wmi_peer_extd_stats *ev = (wmi_peer_extd_stats *) (data +
(ev_param->num_pdev_stats * sizeof(wmi_pdev_stats)) +
(ev_param->num_vdev_stats * sizeof(wmi_vdev_stats)) +
(ev_param->num_peer_stats * sizeof(wmi_peer_stats)) +
(ev_param->num_bcnflt_stats *
sizeof(wmi_bcnfilter_stats_t)) +
(ev_param->num_chan_stats * sizeof(wmi_chan_stats)) +
(ev_param->num_mib_stats * sizeof(wmi_mib_stats)) +
(ev_param->num_bcn_stats * sizeof(wmi_bcn_stats)) +
(index * sizeof(wmi_peer_extd_stats)));
qdf_mem_zero(peer_extd_stats, sizeof(wmi_host_peer_extd_stats));
qdf_mem_copy(&peer_extd_stats->peer_macaddr, &ev->peer_macaddr,
sizeof(wmi_mac_addr));
peer_extd_stats->rx_mc_bc_cnt = ev->rx_mc_bc_cnt;
}
return QDF_STATUS_SUCCESS;
}
/**