Prechádzať zdrojové kódy

qcacld-3.0: Add aggregate stats support for SAP

The cfg80211 get_station callback is not intended for use with
non-station device types. However, it is useful to expose aggregate
statistics for non-station type devices. Add support for returning
aggregate statistics when get_station is used with a soft access point
device.

Change-Id: I8ae32c307f241525a7d74467328d9d40dc805053
CRs-Fixed: 2077011
Dustin Brown 7 rokov pred
rodič
commit
0e4479e27e

+ 73 - 32
core/hdd/src/wlan_hdd_stats.c

@@ -3020,6 +3020,69 @@ static inline void wlan_hdd_fill_station_info_signal(struct station_info
 #define linkspeed_dbg(format, args...)
 #endif /* LINKSPEED_DEBUG_ENABLED */
 
+/**
+ * wlan_hdd_fill_summary_stats() - populate station_info summary stats
+ * @stats: summary stats to use as a source
+ * @info: kernel station_info struct to use as a destination
+ *
+ * Return: None
+ */
+static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
+					struct station_info *info)
+{
+	int i;
+
+	info->rx_packets = stats->rx_frm_cnt;
+	info->tx_packets = 0;
+	info->tx_retries = 0;
+	info->tx_failed = 0;
+
+	for (i = 0; i < WIFI_MAX_AC; ++i) {
+		info->tx_packets += stats->tx_frm_cnt[i];
+		info->tx_retries += stats->multiple_retry_cnt[i];
+		info->tx_failed += stats->fail_cnt[i];
+	}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
+	info->filled |= STATION_INFO_TX_PACKETS |
+			STATION_INFO_TX_RETRIES |
+			STATION_INFO_TX_FAILED |
+			STATION_INFO_RX_PACKETS;
+#else
+	info->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
+			BIT(NL80211_STA_INFO_TX_PACKETS) |
+			BIT(NL80211_STA_INFO_TX_RETRIES) |
+			BIT(NL80211_STA_INFO_TX_FAILED);
+#endif
+}
+
+/**
+ * wlan_hdd_get_sap_stats() - get aggregate SAP stats
+ * @adapter: sap adapter to get stats for
+ * @info: kernel station_info struct to populate
+ *
+ * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
+ * support "station dump" and "station get" for SAP vdevs, even though they
+ * aren't technically stations.
+ *
+ * Return: errno
+ */
+static int
+wlan_hdd_get_sap_stats(hdd_adapter_t *adapter, struct station_info *info)
+{
+	QDF_STATUS status;
+
+	status = wlan_hdd_get_station_stats(adapter);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_err("Failed to get SAP stats; status:%d", status);
+		return qdf_status_to_os_return(status);
+	}
+
+	wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
+
+	return 0;
+}
+
 /**
  * __wlan_hdd_cfg80211_get_station() - get station statistics
  * @wiphy: Pointer to wiphy
@@ -3075,11 +3138,18 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 
+	status = wlan_hdd_validate_context(pHddCtx);
+	if (status)
+		return status;
+
 	if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
 		hdd_err("invalid session id: %d", pAdapter->sessionId);
 		return -EINVAL;
 	}
 
+	if (pAdapter->device_mode == QDF_SAP_MODE)
+		return wlan_hdd_get_sap_stats(pAdapter, sinfo);
+
 	if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
 	    (0 == ssidlen)) {
 		hdd_debug("Not associated or Invalid ssidlen, %d",
@@ -3100,11 +3170,6 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 		return 0;
 	}
 
-	status = wlan_hdd_validate_context(pHddCtx);
-
-	if (0 != status)
-		return status;
-
 	wlan_hdd_get_station_stats(pAdapter);
 
 	if (pAdapter->hdd_stats.summary_stat.rssi)
@@ -3472,26 +3537,8 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 		}
 	}
 
+	wlan_hdd_fill_summary_stats(&pAdapter->hdd_stats.summary_stat, sinfo);
 	sinfo->tx_bytes = pAdapter->stats.tx_bytes;
-
-	sinfo->tx_packets =
-		pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
-		pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
-		pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
-		pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
-
-	sinfo->tx_retries =
-		pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[0] +
-		pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[1] +
-		pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[2] +
-		pAdapter->hdd_stats.summary_stat.multiple_retry_cnt[3];
-
-	sinfo->tx_failed =
-		pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
-		pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
-		pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
-		pAdapter->hdd_stats.summary_stat.fail_cnt[3];
-
 	sinfo->rx_bytes = pAdapter->stats.rx_bytes;
 	sinfo->rx_packets = pAdapter->stats.rx_packets;
 
@@ -3501,17 +3548,11 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
 	sinfo->filled |= STATION_INFO_TX_BITRATE |
 			 STATION_INFO_TX_BYTES   |
-			 STATION_INFO_TX_PACKETS |
-			 STATION_INFO_TX_RETRIES |
-			 STATION_INFO_TX_FAILED  |
 			 STATION_INFO_RX_BYTES   |
 			 STATION_INFO_RX_PACKETS;
 #else
-	sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES)   |
-			 BIT(NL80211_STA_INFO_TX_BITRATE) |
-			 BIT(NL80211_STA_INFO_TX_PACKETS) |
-			 BIT(NL80211_STA_INFO_TX_RETRIES) |
-			 BIT(NL80211_STA_INFO_TX_FAILED)  |
+	sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE) |
+			 BIT(NL80211_STA_INFO_TX_BYTES)   |
 			 BIT(NL80211_STA_INFO_RX_BYTES)   |
 			 BIT(NL80211_STA_INFO_RX_PACKETS);
 #endif

+ 7 - 0
core/sme/src/csr/csr_cmd_process.c

@@ -76,6 +76,13 @@ QDF_STATUS csr_msg_processor(tpAniSirGlobal mac_ctx, void *msg_buf)
 			break;
 
 		default:
+			if (sme_rsp->messageType ==
+			    eWNI_SME_GET_STATISTICS_RSP) {
+				csr_roam_joined_state_msg_processor(mac_ctx,
+								    msg_buf);
+				break;
+			}
+
 			/*
 			 * For all other messages, we ignore it
 			 * To work-around an issue where checking for set/remove