|
@@ -180,6 +180,8 @@ static int rssi_mcs_tbl[][12] = {
|
|
|
{-76, -73, -71, -68, -64, -60, -59, -58, -53, -51, -46, -42} /* 80 */
|
|
|
};
|
|
|
|
|
|
+static bool get_station_fw_request_needed = true;
|
|
|
+
|
|
|
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
|
|
|
|
|
|
/**
|
|
@@ -1567,6 +1569,271 @@ static void wlan_hdd_dealloc_ll_stats(void *priv)
|
|
|
qdf_list_destroy(&ll_stats_priv->ll_stats_q);
|
|
|
}
|
|
|
|
|
|
+#ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
|
|
|
+static void
|
|
|
+hdd_update_station_stats_cached_timestamp(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ adapter->hdd_stats.sta_stats_cached_timestamp =
|
|
|
+ qdf_system_ticks_to_msecs(qdf_system_ticks());
|
|
|
+}
|
|
|
+#else
|
|
|
+static void
|
|
|
+hdd_update_station_stats_cached_timestamp(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
|
|
|
+
|
|
|
+/*
|
|
|
+ * copy_station_stats_to_adapter() - Copy station stats to adapter
|
|
|
+ * @adapter: Pointer to the adapter
|
|
|
+ * @stats: Pointer to the station stats event
|
|
|
+ *
|
|
|
+ * Return: 0 if success, non-zero for failure
|
|
|
+ */
|
|
|
+static int copy_station_stats_to_adapter(struct hdd_adapter *adapter,
|
|
|
+ struct stats_event *stats)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ struct wlan_mlme_nss_chains *dynamic_cfg;
|
|
|
+ uint32_t tx_nss, rx_nss;
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+
|
|
|
+ vdev = hdd_objmgr_get_vdev(adapter);
|
|
|
+ if (!vdev)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* save summary stats to legacy location */
|
|
|
+ qdf_mem_copy(adapter->hdd_stats.summary_stat.retry_cnt,
|
|
|
+ stats->vdev_summary_stats[0].stats.retry_cnt,
|
|
|
+ sizeof(adapter->hdd_stats.summary_stat.retry_cnt));
|
|
|
+ qdf_mem_copy(
|
|
|
+ adapter->hdd_stats.summary_stat.multiple_retry_cnt,
|
|
|
+ stats->vdev_summary_stats[0].stats.multiple_retry_cnt,
|
|
|
+ sizeof(adapter->hdd_stats.summary_stat.multiple_retry_cnt));
|
|
|
+ qdf_mem_copy(adapter->hdd_stats.summary_stat.tx_frm_cnt,
|
|
|
+ stats->vdev_summary_stats[0].stats.tx_frm_cnt,
|
|
|
+ sizeof(adapter->hdd_stats.summary_stat.tx_frm_cnt));
|
|
|
+ qdf_mem_copy(adapter->hdd_stats.summary_stat.fail_cnt,
|
|
|
+ stats->vdev_summary_stats[0].stats.fail_cnt,
|
|
|
+ sizeof(adapter->hdd_stats.summary_stat.fail_cnt));
|
|
|
+ adapter->hdd_stats.summary_stat.snr =
|
|
|
+ stats->vdev_summary_stats[0].stats.snr;
|
|
|
+ adapter->hdd_stats.summary_stat.rssi =
|
|
|
+ stats->vdev_summary_stats[0].stats.rssi;
|
|
|
+ adapter->hdd_stats.summary_stat.rx_frm_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.rx_frm_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.frm_dup_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.frm_dup_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.rts_fail_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.rts_fail_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.ack_fail_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.ack_fail_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.rts_succ_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.rts_succ_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.rx_discard_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.rx_discard_cnt;
|
|
|
+ adapter->hdd_stats.summary_stat.rx_error_cnt =
|
|
|
+ stats->vdev_summary_stats[0].stats.rx_error_cnt;
|
|
|
+ adapter->hdd_stats.peer_stats.rx_count =
|
|
|
+ stats->peer_adv_stats->rx_count;
|
|
|
+ adapter->hdd_stats.peer_stats.rx_bytes =
|
|
|
+ stats->peer_adv_stats->rx_bytes;
|
|
|
+ adapter->hdd_stats.peer_stats.fcs_count =
|
|
|
+ stats->peer_adv_stats->fcs_count;
|
|
|
+
|
|
|
+ dynamic_cfg = mlme_get_dynamic_vdev_config(vdev);
|
|
|
+ if (!dynamic_cfg) {
|
|
|
+ hdd_err("nss chain dynamic config NULL");
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (hdd_conn_get_connected_band(&adapter->session.station)) {
|
|
|
+ case BAND_2G:
|
|
|
+ tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ];
|
|
|
+ rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ];
|
|
|
+ break;
|
|
|
+ case BAND_5G:
|
|
|
+ tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ];
|
|
|
+ rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ tx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
+ rx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Intersection of self and AP's NSS capability */
|
|
|
+ if (tx_nss > wlan_vdev_mlme_get_nss(vdev))
|
|
|
+ tx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
+
|
|
|
+ if (rx_nss > wlan_vdev_mlme_get_nss(vdev))
|
|
|
+ rx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
+
|
|
|
+ /* save class a stats to legacy location */
|
|
|
+ adapter->hdd_stats.class_a_stat.tx_nss = tx_nss;
|
|
|
+ adapter->hdd_stats.class_a_stat.rx_nss = rx_nss;
|
|
|
+ adapter->hdd_stats.class_a_stat.tx_rate = stats->tx_rate;
|
|
|
+ adapter->hdd_stats.class_a_stat.rx_rate = stats->rx_rate;
|
|
|
+ adapter->hdd_stats.class_a_stat.tx_rx_rate_flags = stats->tx_rate_flags;
|
|
|
+ adapter->hdd_stats.class_a_stat.tx_mcs_index =
|
|
|
+ sme_get_mcs_idx(stats->tx_rate, stats->tx_rate_flags,
|
|
|
+ &adapter->hdd_stats.class_a_stat.tx_nss,
|
|
|
+ &adapter->hdd_stats.class_a_stat.tx_dcm,
|
|
|
+ &adapter->hdd_stats.class_a_stat.tx_gi,
|
|
|
+ &adapter->hdd_stats.class_a_stat.
|
|
|
+ tx_mcs_rate_flags);
|
|
|
+
|
|
|
+ adapter->hdd_stats.class_a_stat.rx_mcs_index =
|
|
|
+ sme_get_mcs_idx(stats->rx_rate, stats->tx_rate_flags,
|
|
|
+ &adapter->hdd_stats.class_a_stat.rx_nss,
|
|
|
+ &adapter->hdd_stats.class_a_stat.rx_dcm,
|
|
|
+ &adapter->hdd_stats.class_a_stat.rx_gi,
|
|
|
+ &adapter->hdd_stats.class_a_stat.
|
|
|
+ rx_mcs_rate_flags);
|
|
|
+
|
|
|
+ /* save per chain rssi to legacy location */
|
|
|
+ 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;
|
|
|
+out:
|
|
|
+ hdd_objmgr_put_vdev(vdev);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
|
|
|
+/**
|
|
|
+ * cache_station_stats_cb() - cache_station_stats_cb callback function
|
|
|
+ * @ev: station stats buffer
|
|
|
+ * @cookie: cookie that contains the address of the adapter corresponding to
|
|
|
+ * the request
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+static void cache_station_stats_cb(struct stats_event *ev, void *cookie)
|
|
|
+{
|
|
|
+ struct hdd_adapter *adapter = cookie;
|
|
|
+ struct hdd_context *hdd_ctx = adapter->hdd_ctx;
|
|
|
+ uint8_t vdev_id = adapter->vdev_id;
|
|
|
+
|
|
|
+ hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
|
|
|
+ if (adapter->vdev_id != vdev_id) {
|
|
|
+ dev_put(adapter->dev);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ copy_station_stats_to_adapter(adapter, ev);
|
|
|
+ /* dev_put has to be done here */
|
|
|
+ dev_put(adapter->dev);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+wlan_hdd_set_station_stats_request_pending(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_peer *peer;
|
|
|
+ struct request_info info = {0};
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+
|
|
|
+ if (!adapter->hdd_ctx->is_get_station_clubbed_in_ll_stats_req)
|
|
|
+ return;
|
|
|
+
|
|
|
+ vdev = hdd_objmgr_get_vdev(adapter);
|
|
|
+ if (!vdev)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (adapter->hdd_stats.is_ll_stats_req_in_progress) {
|
|
|
+ hdd_err("Previous ll_stats request is in progress");
|
|
|
+ goto get_station_stats_fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ adapter->hdd_stats.is_ll_stats_req_in_progress = true;
|
|
|
+
|
|
|
+ info.cookie = adapter;
|
|
|
+ info.u.get_station_stats_cb = cache_station_stats_cb;
|
|
|
+ info.vdev_id = adapter->vdev_id;
|
|
|
+ info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
|
|
|
+ peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_OSIF_ID);
|
|
|
+ if (!peer) {
|
|
|
+ osif_err("peer is null");
|
|
|
+ goto get_station_stats_fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(info.peer_mac_addr, peer->macaddr, QDF_MAC_ADDR_SIZE);
|
|
|
+
|
|
|
+ wlan_objmgr_peer_release_ref(peer, WLAN_OSIF_ID);
|
|
|
+
|
|
|
+ ucfg_mc_cp_stats_set_pending_req(wlan_vdev_get_psoc(vdev),
|
|
|
+ TYPE_STATION_STATS, &info);
|
|
|
+
|
|
|
+get_station_stats_fail:
|
|
|
+ hdd_objmgr_put_vdev(vdev);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+wlan_hdd_reset_station_stats_request_pending(struct wlan_objmgr_psoc *psoc,
|
|
|
+ struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ QDF_STATUS status;
|
|
|
+ struct request_info last_req = {0};
|
|
|
+ bool pending = false;
|
|
|
+
|
|
|
+ if (!adapter->hdd_ctx->is_get_station_clubbed_in_ll_stats_req)
|
|
|
+ return;
|
|
|
+
|
|
|
+ adapter->hdd_stats.is_ll_stats_req_in_progress = false;
|
|
|
+
|
|
|
+ status = ucfg_mc_cp_stats_get_pending_req(psoc, TYPE_STATION_STATS,
|
|
|
+ &last_req);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ hdd_err("ucfg_mc_cp_stats_get_pending_req failed");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ ucfg_mc_cp_stats_reset_pending_req(psoc, TYPE_STATION_STATS,
|
|
|
+ &last_req, &pending);
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS wlan_hdd_stats_request_needed(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ if (adapter->device_mode != QDF_STA_MODE)
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ if (!adapter->hdd_ctx->config) {
|
|
|
+ hdd_err("Invalid hdd config");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+ if (adapter->hdd_ctx->is_get_station_clubbed_in_ll_stats_req) {
|
|
|
+ uint32_t stats_cached_duration;
|
|
|
+
|
|
|
+ stats_cached_duration =
|
|
|
+ qdf_system_ticks_to_msecs(qdf_system_ticks()) -
|
|
|
+ adapter->hdd_stats.sta_stats_cached_timestamp;
|
|
|
+ if (stats_cached_duration <=
|
|
|
+ adapter->hdd_ctx->config->sta_stats_cache_expiry_time)
|
|
|
+ return QDF_STATUS_E_ALREADY;
|
|
|
+ }
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+static void
|
|
|
+wlan_hdd_set_station_stats_request_pending(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+wlan_hdd_reset_station_stats_request_pending(struct wlan_objmgr_psoc *psoc,
|
|
|
+ struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS wlan_hdd_stats_request_needed(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+#endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
|
|
|
+
|
|
|
static int wlan_hdd_send_ll_stats_req(struct hdd_adapter *adapter,
|
|
|
tSirLLStatsGetReq *req)
|
|
|
{
|
|
@@ -1584,11 +1851,15 @@ static int wlan_hdd_send_ll_stats_req(struct hdd_adapter *adapter,
|
|
|
.dealloc = wlan_hdd_dealloc_ll_stats,
|
|
|
};
|
|
|
|
|
|
- hdd_enter();
|
|
|
+ hdd_enter_dev(adapter->dev);
|
|
|
+
|
|
|
+ wlan_hdd_set_station_stats_request_pending(adapter);
|
|
|
|
|
|
request = osif_request_alloc(¶ms);
|
|
|
if (!request) {
|
|
|
hdd_err("Request Allocation Failure");
|
|
|
+ wlan_hdd_reset_station_stats_request_pending(hdd_ctx->psoc,
|
|
|
+ adapter);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
@@ -1601,11 +1872,12 @@ static int wlan_hdd_send_ll_stats_req(struct hdd_adapter *adapter,
|
|
|
qdf_spinlock_create(&priv->ll_stats_lock);
|
|
|
qdf_list_create(&priv->ll_stats_q, HDD_LINK_STATS_MAX);
|
|
|
|
|
|
- if (QDF_STATUS_SUCCESS !=
|
|
|
- sme_ll_stats_get_req(hdd_ctx->mac_handle, req,
|
|
|
- cookie)) {
|
|
|
+ status = sme_ll_stats_get_req(hdd_ctx->mac_handle, req, cookie);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
hdd_err("sme_ll_stats_get_req Failed");
|
|
|
- ret = -EINVAL;
|
|
|
+ ret = qdf_status_to_os_return(status);
|
|
|
+ wlan_hdd_reset_station_stats_request_pending(hdd_ctx->psoc,
|
|
|
+ adapter);
|
|
|
goto exit;
|
|
|
}
|
|
|
ret = osif_request_wait_for_response(request);
|
|
@@ -1616,6 +1888,10 @@ static int wlan_hdd_send_ll_stats_req(struct hdd_adapter *adapter,
|
|
|
priv->request_bitmap = 0;
|
|
|
qdf_spin_unlock(&priv->ll_stats_lock);
|
|
|
ret = -ETIMEDOUT;
|
|
|
+ wlan_hdd_reset_station_stats_request_pending(hdd_ctx->psoc,
|
|
|
+ adapter);
|
|
|
+ } else {
|
|
|
+ hdd_update_station_stats_cached_timestamp(adapter);
|
|
|
}
|
|
|
qdf_spin_lock(&priv->ll_stats_lock);
|
|
|
status = qdf_list_remove_front(&priv->ll_stats_q, &ll_node);
|
|
@@ -1643,9 +1919,10 @@ int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id,
|
|
|
{
|
|
|
int errno;
|
|
|
tSirLLStatsGetReq get_req;
|
|
|
- struct hdd_station_ctx *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
|
|
+ struct hdd_station_ctx *hddstactx =
|
|
|
+ WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
|
|
|
|
|
- hdd_enter();
|
|
|
+ hdd_enter_dev(adapter->dev);
|
|
|
|
|
|
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
|
|
hdd_warn("Command not allowed in FTM mode");
|
|
@@ -3239,6 +3516,12 @@ int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy,
|
|
|
|
|
|
return errno;
|
|
|
}
|
|
|
+
|
|
|
+#else
|
|
|
+static QDF_STATUS wlan_hdd_stats_request_needed(struct hdd_adapter *adapter)
|
|
|
+{
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
|
|
|
|
|
|
#ifdef WLAN_FEATURE_STATS_EXT
|
|
@@ -5256,8 +5539,10 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
|
|
|
struct station_info *sinfo)
|
|
|
{
|
|
|
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
|
|
+ struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
|
|
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
|
|
int errno;
|
|
|
+ QDF_STATUS status;
|
|
|
|
|
|
errno = wlan_hdd_validate_context(hdd_ctx);
|
|
|
if (errno)
|
|
@@ -5266,13 +5551,26 @@ static int _wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
|
|
|
if (!qdf_ctx)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev);
|
|
|
- if (errno)
|
|
|
- return errno;
|
|
|
+ status = wlan_hdd_stats_request_needed(adapter);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
+ if (status == QDF_STATUS_E_ALREADY)
|
|
|
+ get_station_fw_request_needed = false;
|
|
|
+ else
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (get_station_fw_request_needed) {
|
|
|
+ errno = wlan_hdd_qmi_get_sync_resume(hdd_ctx, qdf_ctx->dev);
|
|
|
+ if (errno)
|
|
|
+ return errno;
|
|
|
+ }
|
|
|
|
|
|
errno = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
|
|
|
|
|
|
- wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev);
|
|
|
+ if (get_station_fw_request_needed)
|
|
|
+ wlan_hdd_qmi_put_suspend(hdd_ctx, qdf_ctx->dev);
|
|
|
+
|
|
|
+ get_station_fw_request_needed = true;
|
|
|
|
|
|
return errno;
|
|
|
}
|
|
@@ -6133,10 +6431,11 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
struct stats_event *stats;
|
|
|
- struct wlan_mlme_nss_chains *dynamic_cfg;
|
|
|
- uint32_t tx_nss, rx_nss;
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
|
|
|
+ if (!get_station_fw_request_needed)
|
|
|
+ return 0;
|
|
|
+
|
|
|
vdev = hdd_objmgr_get_vdev(adapter);
|
|
|
if (!vdev)
|
|
|
return -EINVAL;
|
|
@@ -6147,99 +6446,7 @@ int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /* save summary stats to legacy location */
|
|
|
- qdf_mem_copy(adapter->hdd_stats.summary_stat.retry_cnt,
|
|
|
- stats->vdev_summary_stats[0].stats.retry_cnt,
|
|
|
- sizeof(adapter->hdd_stats.summary_stat.retry_cnt));
|
|
|
- qdf_mem_copy(adapter->hdd_stats.summary_stat.multiple_retry_cnt,
|
|
|
- stats->vdev_summary_stats[0].stats.multiple_retry_cnt,
|
|
|
- sizeof(adapter->hdd_stats.summary_stat.multiple_retry_cnt));
|
|
|
- qdf_mem_copy(adapter->hdd_stats.summary_stat.tx_frm_cnt,
|
|
|
- stats->vdev_summary_stats[0].stats.tx_frm_cnt,
|
|
|
- sizeof(adapter->hdd_stats.summary_stat.tx_frm_cnt));
|
|
|
- qdf_mem_copy(adapter->hdd_stats.summary_stat.fail_cnt,
|
|
|
- stats->vdev_summary_stats[0].stats.fail_cnt,
|
|
|
- sizeof(adapter->hdd_stats.summary_stat.fail_cnt));
|
|
|
- adapter->hdd_stats.summary_stat.snr =
|
|
|
- stats->vdev_summary_stats[0].stats.snr;
|
|
|
- adapter->hdd_stats.summary_stat.rssi =
|
|
|
- stats->vdev_summary_stats[0].stats.rssi;
|
|
|
- adapter->hdd_stats.summary_stat.rx_frm_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.rx_frm_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.frm_dup_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.frm_dup_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.rts_fail_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.rts_fail_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.ack_fail_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.ack_fail_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.rts_succ_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.rts_succ_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.rx_discard_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.rx_discard_cnt;
|
|
|
- adapter->hdd_stats.summary_stat.rx_error_cnt =
|
|
|
- stats->vdev_summary_stats[0].stats.rx_error_cnt;
|
|
|
- adapter->hdd_stats.peer_stats.rx_count =
|
|
|
- stats->peer_adv_stats->rx_count;
|
|
|
- adapter->hdd_stats.peer_stats.rx_bytes =
|
|
|
- stats->peer_adv_stats->rx_bytes;
|
|
|
- adapter->hdd_stats.peer_stats.fcs_count =
|
|
|
- stats->peer_adv_stats->fcs_count;
|
|
|
-
|
|
|
- dynamic_cfg = mlme_get_dynamic_vdev_config(vdev);
|
|
|
- if (!dynamic_cfg) {
|
|
|
- hdd_err("nss chain dynamic config NULL");
|
|
|
- wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
|
|
- ret = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- switch (hdd_conn_get_connected_band(&adapter->session.station)) {
|
|
|
- case BAND_2G:
|
|
|
- tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ];
|
|
|
- rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ];
|
|
|
- break;
|
|
|
- case BAND_5G:
|
|
|
- tx_nss = dynamic_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ];
|
|
|
- rx_nss = dynamic_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ];
|
|
|
- break;
|
|
|
- default:
|
|
|
- tx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
- rx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
- }
|
|
|
- /* Intersection of self and AP's NSS capability */
|
|
|
- if (tx_nss > wlan_vdev_mlme_get_nss(vdev))
|
|
|
- tx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
-
|
|
|
- if (rx_nss > wlan_vdev_mlme_get_nss(vdev))
|
|
|
- rx_nss = wlan_vdev_mlme_get_nss(vdev);
|
|
|
-
|
|
|
- /* save class a stats to legacy location */
|
|
|
- adapter->hdd_stats.class_a_stat.tx_nss = tx_nss;
|
|
|
- adapter->hdd_stats.class_a_stat.rx_nss = rx_nss;
|
|
|
- adapter->hdd_stats.class_a_stat.tx_rate = stats->tx_rate;
|
|
|
- adapter->hdd_stats.class_a_stat.rx_rate = stats->rx_rate;
|
|
|
- adapter->hdd_stats.class_a_stat.tx_rx_rate_flags = stats->tx_rate_flags;
|
|
|
- adapter->hdd_stats.class_a_stat.tx_mcs_index =
|
|
|
- sme_get_mcs_idx(stats->tx_rate, stats->tx_rate_flags,
|
|
|
- &adapter->hdd_stats.class_a_stat.tx_nss,
|
|
|
- &adapter->hdd_stats.class_a_stat.tx_dcm,
|
|
|
- &adapter->hdd_stats.class_a_stat.tx_gi,
|
|
|
- &adapter->hdd_stats.class_a_stat.
|
|
|
- tx_mcs_rate_flags);
|
|
|
-
|
|
|
- adapter->hdd_stats.class_a_stat.rx_mcs_index =
|
|
|
- sme_get_mcs_idx(stats->rx_rate, stats->tx_rate_flags,
|
|
|
- &adapter->hdd_stats.class_a_stat.rx_nss,
|
|
|
- &adapter->hdd_stats.class_a_stat.rx_dcm,
|
|
|
- &adapter->hdd_stats.class_a_stat.rx_gi,
|
|
|
- &adapter->hdd_stats.class_a_stat.
|
|
|
- rx_mcs_rate_flags);
|
|
|
-
|
|
|
- /* save per chain rssi to legacy location */
|
|
|
- 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;
|
|
|
+ copy_station_stats_to_adapter(adapter, stats);
|
|
|
wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
|
|
|
|
|
|
out:
|