|
@@ -776,50 +776,85 @@ static void hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hdd_link_layer_process_radio_stats() - This function is called after
|
|
|
- * @pAdapter: Pointer to device adapter
|
|
|
- * @more_data: More data
|
|
|
- * @pData: Pointer to stats data
|
|
|
- * @num_radios: Number of radios
|
|
|
- *
|
|
|
- * Receiving Link Layer Radio statistics from FW.This function converts
|
|
|
- * the firmware data to the NL data and sends the same to the kernel/upper
|
|
|
- * layers.
|
|
|
+ * hdd_llstats_radio_fill_channels() - radio stats fill channels
|
|
|
+ * @adapter: Pointer to device adapter
|
|
|
+ * @radiostat: Pointer to stats data
|
|
|
+ * @vendor_event: vendor event
|
|
|
*
|
|
|
- * Return: None
|
|
|
+ * Return: 0 on success; errno on failure
|
|
|
*/
|
|
|
-static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
|
|
|
- u32 more_data,
|
|
|
- tpSirWifiRadioStat pData,
|
|
|
- u32 num_radio)
|
|
|
+static int hdd_llstats_radio_fill_channels(hdd_adapter_t *adapter,
|
|
|
+ tSirWifiRadioStat *radiostat,
|
|
|
+ struct sk_buff *vendor_event)
|
|
|
{
|
|
|
- int status, i;
|
|
|
- tpSirWifiRadioStat pWifiRadioStat;
|
|
|
- tpSirWifiChannelStats pWifiChannelStats;
|
|
|
- struct sk_buff *vendor_event;
|
|
|
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
|
|
|
+ tSirWifiChannelStats *channel_stats;
|
|
|
+ struct nlattr *chlist;
|
|
|
+ struct nlattr *chinfo;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ chlist = nla_nest_start(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
|
|
|
+ if (chlist == NULL) {
|
|
|
+ hdd_err("nla_nest_start failed");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- ENTER();
|
|
|
+ for (i = 0; i < radiostat->numChannels; i++) {
|
|
|
+ channel_stats = (tSirWifiChannelStats *) ((uint8_t *)
|
|
|
+ radiostat->channels +
|
|
|
+ (i * sizeof(tSirWifiChannelStats)));
|
|
|
|
|
|
- pWifiRadioStat = pData;
|
|
|
- status = wlan_hdd_validate_context(pHddCtx);
|
|
|
- if (0 != status)
|
|
|
- return;
|
|
|
+ chinfo = nla_nest_start(vendor_event, i);
|
|
|
+ if (chinfo == NULL) {
|
|
|
+ hdd_err("nla_nest_start failed");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
|
|
|
+ channel_stats->channel.width) ||
|
|
|
+ nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
|
|
|
+ channel_stats->channel.centerFreq) ||
|
|
|
+ nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
|
|
|
+ channel_stats->channel.centerFreq0) ||
|
|
|
+ nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
|
|
|
+ channel_stats->channel.centerFreq1) ||
|
|
|
+ nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
|
|
|
+ channel_stats->onTime) ||
|
|
|
+ nla_put_u32(vendor_event,
|
|
|
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
|
|
|
+ channel_stats->ccaBusyTime)) {
|
|
|
+ hdd_err("nla_put failed");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ nla_nest_end(vendor_event, chinfo);
|
|
|
+ }
|
|
|
+ nla_nest_end(vendor_event, chlist);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- hdd_notice("LL_STATS_RADIO"
|
|
|
- " number of radios: %u radio: %d onTime: %u"
|
|
|
- " txTime: %u rxTime: %u onTimeScan: %u onTimeNbd: %u"
|
|
|
- " onTimeGscan: %u onTimeRoamScan: %u"
|
|
|
- " onTimePnoScan: %u onTimeHs20: %u"
|
|
|
- " numChannels: %u total_num_tx_power_levels: %u",
|
|
|
- num_radio, pWifiRadioStat->radio,
|
|
|
- pWifiRadioStat->onTime, pWifiRadioStat->txTime,
|
|
|
- pWifiRadioStat->rxTime, pWifiRadioStat->onTimeScan,
|
|
|
- pWifiRadioStat->onTimeNbd, pWifiRadioStat->onTimeGscan,
|
|
|
- pWifiRadioStat->onTimeRoamScan,
|
|
|
- pWifiRadioStat->onTimePnoScan,
|
|
|
- pWifiRadioStat->onTimeHs20, pWifiRadioStat->numChannels,
|
|
|
- pWifiRadioStat->total_num_tx_power_levels);
|
|
|
+/**
|
|
|
+ * hdd_llstats_post_radio_stats() - post radio stats
|
|
|
+ * @adapter: Pointer to device adapter
|
|
|
+ * @more_data: More data
|
|
|
+ * @radiostat: Pointer to stats data
|
|
|
+ * @num_radio: Number of radios
|
|
|
+ *
|
|
|
+ * Return: 0 on success; errno on failure
|
|
|
+ */
|
|
|
+static int hdd_llstats_post_radio_stats(hdd_adapter_t *adapter,
|
|
|
+ u32 more_data,
|
|
|
+ tSirWifiRadioStat *radiostat,
|
|
|
+ u32 num_radio)
|
|
|
+{
|
|
|
+ struct sk_buff *vendor_event;
|
|
|
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
|
|
+ int ret;
|
|
|
|
|
|
/*
|
|
|
* Allocate a size of 4096 for the Radio stats comprising
|
|
@@ -830,12 +865,13 @@ static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
|
|
|
* sizeof (tSirWifiChannelStats) being 24 bytes.
|
|
|
*/
|
|
|
|
|
|
- vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
|
|
|
- LL_STATS_EVENT_BUF_SIZE);
|
|
|
+ vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(
|
|
|
+ hdd_ctx->wiphy,
|
|
|
+ LL_STATS_EVENT_BUF_SIZE);
|
|
|
|
|
|
if (!vendor_event) {
|
|
|
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
|
|
|
- return;
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
if (nla_put_u32(vendor_event,
|
|
@@ -849,114 +885,127 @@ static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
|
|
|
num_radio) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
|
|
|
- pWifiRadioStat->radio) ||
|
|
|
+ radiostat->radio) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
|
|
|
- pWifiRadioStat->onTime) ||
|
|
|
+ radiostat->onTime) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
|
|
|
- pWifiRadioStat->txTime) ||
|
|
|
+ radiostat->txTime) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
|
|
|
- pWifiRadioStat->rxTime) ||
|
|
|
+ radiostat->rxTime) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
|
|
|
- pWifiRadioStat->onTimeScan) ||
|
|
|
+ radiostat->onTimeScan) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
|
|
|
- pWifiRadioStat->onTimeNbd) ||
|
|
|
+ radiostat->onTimeNbd) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN,
|
|
|
- pWifiRadioStat->onTimeGscan) ||
|
|
|
+ radiostat->onTimeGscan) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
|
|
|
- pWifiRadioStat->onTimeRoamScan) ||
|
|
|
+ radiostat->onTimeRoamScan) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
|
|
|
- pWifiRadioStat->onTimePnoScan) ||
|
|
|
+ radiostat->onTimePnoScan) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
|
|
|
- pWifiRadioStat->onTimeHs20) ||
|
|
|
+ radiostat->onTimeHs20) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS,
|
|
|
- pWifiRadioStat->total_num_tx_power_levels) ||
|
|
|
+ radiostat->total_num_tx_power_levels) ||
|
|
|
nla_put_u32(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
|
|
|
- pWifiRadioStat->numChannels)) {
|
|
|
+ radiostat->numChannels)) {
|
|
|
hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
|
|
|
-
|
|
|
- kfree_skb(vendor_event);
|
|
|
- return;
|
|
|
+ goto failure;
|
|
|
}
|
|
|
|
|
|
- if (pWifiRadioStat->total_num_tx_power_levels) {
|
|
|
+ if (radiostat->total_num_tx_power_levels) {
|
|
|
if (nla_put(vendor_event,
|
|
|
QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL,
|
|
|
sizeof(u32) *
|
|
|
- pWifiRadioStat->total_num_tx_power_levels,
|
|
|
- pWifiRadioStat->tx_time_per_power_level)) {
|
|
|
+ radiostat->total_num_tx_power_levels,
|
|
|
+ radiostat->tx_time_per_power_level)) {
|
|
|
hdd_err("nla_put fail");
|
|
|
- kfree_skb(vendor_event);
|
|
|
- return;
|
|
|
+ goto failure;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (pWifiRadioStat->numChannels) {
|
|
|
- struct nlattr *chList;
|
|
|
- struct nlattr *chInfo;
|
|
|
+ if (radiostat->numChannels) {
|
|
|
+ ret = hdd_llstats_radio_fill_channels(adapter, radiostat,
|
|
|
+ vendor_event);
|
|
|
+ if (ret)
|
|
|
+ goto failure;
|
|
|
+ }
|
|
|
|
|
|
- chList = nla_nest_start(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
|
|
|
- if (chList == NULL) {
|
|
|
- hdd_err("nla_nest_start failed");
|
|
|
- kfree_skb(vendor_event);
|
|
|
- return;
|
|
|
- }
|
|
|
+ cfg80211_vendor_cmd_reply(vendor_event);
|
|
|
+ return 0;
|
|
|
|
|
|
- for (i = 0; i < pWifiRadioStat->numChannels; i++) {
|
|
|
- pWifiChannelStats = (tpSirWifiChannelStats) ((uint8_t *)
|
|
|
- pWifiRadioStat->
|
|
|
- channels +
|
|
|
- (i *
|
|
|
- sizeof
|
|
|
- (tSirWifiChannelStats)));
|
|
|
+failure:
|
|
|
+ kfree_skb(vendor_event);
|
|
|
+ return -EINVAL;
|
|
|
+}
|
|
|
|
|
|
- chInfo = nla_nest_start(vendor_event, i);
|
|
|
- if (chInfo == NULL) {
|
|
|
- hdd_err("nla_nest_start failed");
|
|
|
- kfree_skb(vendor_event);
|
|
|
- return;
|
|
|
- }
|
|
|
+/**
|
|
|
+ * hdd_link_layer_process_radio_stats() - This function is called after
|
|
|
+ * @pAdapter: Pointer to device adapter
|
|
|
+ * @more_data: More data
|
|
|
+ * @pData: Pointer to stats data
|
|
|
+ * @num_radios: Number of radios
|
|
|
+ *
|
|
|
+ * Receiving Link Layer Radio statistics from FW.This function converts
|
|
|
+ * the firmware data to the NL data and sends the same to the kernel/upper
|
|
|
+ * layers.
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
|
|
|
+ u32 more_data,
|
|
|
+ tpSirWifiRadioStat pData,
|
|
|
+ u32 num_radio)
|
|
|
+{
|
|
|
+ int status, i, nr, ret;
|
|
|
+ tSirWifiRadioStat *pWifiRadioStat = pData;
|
|
|
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
|
|
|
|
|
|
- if (nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
|
|
|
- pWifiChannelStats->channel.width) ||
|
|
|
- nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
|
|
|
- pWifiChannelStats->channel.centerFreq) ||
|
|
|
- nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
|
|
|
- pWifiChannelStats->channel.
|
|
|
- centerFreq0) ||
|
|
|
- nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
|
|
|
- pWifiChannelStats->channel.
|
|
|
- centerFreq1) ||
|
|
|
- nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
|
|
|
- pWifiChannelStats->onTime) ||
|
|
|
- nla_put_u32(vendor_event,
|
|
|
- QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
|
|
|
- pWifiChannelStats->ccaBusyTime)) {
|
|
|
- hdd_err("nla_put failed");
|
|
|
- kfree_skb(vendor_event);
|
|
|
- return;
|
|
|
- }
|
|
|
- nla_nest_end(vendor_event, chInfo);
|
|
|
- }
|
|
|
- nla_nest_end(vendor_event, chList);
|
|
|
+ ENTER();
|
|
|
+
|
|
|
+ status = wlan_hdd_validate_context(pHddCtx);
|
|
|
+ if (0 != status)
|
|
|
+ return;
|
|
|
+
|
|
|
+ hdd_notice("LL_STATS_RADIO: number of radios: %u", num_radio);
|
|
|
+
|
|
|
+ for (i = 0; i < num_radio; i++) {
|
|
|
+ hdd_notice("LL_STATS_RADIO"
|
|
|
+ " radio: %u onTime: %u txTime: %u rxTime: %u"
|
|
|
+ " onTimeScan: %u onTimeNbd: %u"
|
|
|
+ " onTimeGscan: %u onTimeRoamScan: %u"
|
|
|
+ " onTimePnoScan: %u onTimeHs20: %u"
|
|
|
+ " numChannels: %u total_num_tx_pwr_levels: %u",
|
|
|
+ pWifiRadioStat->radio, pWifiRadioStat->onTime,
|
|
|
+ pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
|
|
|
+ pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
|
|
|
+ pWifiRadioStat->onTimeGscan,
|
|
|
+ pWifiRadioStat->onTimeRoamScan,
|
|
|
+ pWifiRadioStat->onTimePnoScan,
|
|
|
+ pWifiRadioStat->onTimeHs20, pWifiRadioStat->numChannels,
|
|
|
+ pWifiRadioStat->total_num_tx_power_levels);
|
|
|
+ pWifiRadioStat++;
|
|
|
+ }
|
|
|
+
|
|
|
+ pWifiRadioStat = pData;
|
|
|
+ for (nr = 0; nr < num_radio; nr++) {
|
|
|
+ ret = hdd_llstats_post_radio_stats(pAdapter, more_data,
|
|
|
+ pWifiRadioStat, num_radio);
|
|
|
+ if (ret)
|
|
|
+ return;
|
|
|
+
|
|
|
+ pWifiRadioStat++;
|
|
|
}
|
|
|
- cfg80211_vendor_cmd_reply(vendor_event);
|
|
|
EXIT();
|
|
|
return;
|
|
|
}
|