Skip to content

Commit b6e3d1b

Browse files
panjaneyjmberg-intel
authored andcommitted
wifi: iwlwifi: mvm: implement new firmware API for statistics
The new firmware API uses a new command and notification, the command configures in which statistics types driver is interested and the notification is sent periodically. An additional change in the API is that most of the statistics data is accumulated and reported by the firmware per MLO link. Implement new command and notification handlers and adjust to per-link statistics. Signed-off-by: Anjaneyulu <[email protected]> Signed-off-by: Gregory Greenman <[email protected]> Link: https://lore.kernel.org/r/20231022173519.8cc7df0ebff2.If1dcb57145841c5b3c68ed112bbfcd0201f7acc3@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent ea02a20 commit b6e3d1b

File tree

8 files changed

+451
-38
lines changed

8 files changed

+451
-38
lines changed

drivers/net/wireless/intel/iwlwifi/fw/api/commands.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
* @REGULATORY_AND_NVM_GROUP: regulatory/NVM group, uses command IDs from
3131
* &enum iwl_regulatory_and_nvm_subcmd_ids
3232
* @DEBUG_GROUP: Debug group, uses command IDs from &enum iwl_debug_cmds
33+
* @STATISTICS_GROUP: Statistics group, uses command IDs from
34+
* &enum iwl_statistics_subcmd_ids
3335
*/
3436
enum iwl_mvm_command_groups {
3537
LEGACY_GROUP = 0x0,
@@ -44,6 +46,7 @@ enum iwl_mvm_command_groups {
4446
PROT_OFFLOAD_GROUP = 0xb,
4547
REGULATORY_AND_NVM_GROUP = 0xc,
4648
DEBUG_GROUP = 0xf,
49+
STATISTICS_GROUP = 0x10,
4750
};
4851

4952
/**
@@ -616,10 +619,37 @@ enum iwl_system_subcmd_ids {
616619
*/
617620
SYSTEM_FEATURES_CONTROL_CMD = 0xd,
618621

622+
/**
623+
* @SYSTEM_STATISTICS_CMD: &struct iwl_system_statistics_cmd
624+
*/
625+
SYSTEM_STATISTICS_CMD = 0xf,
626+
627+
/**
628+
* @SYSTEM_STATISTICS_END_NOTIF: &struct iwl_system_statistics_end_notif
629+
*/
630+
SYSTEM_STATISTICS_END_NOTIF = 0xfd,
631+
619632
/**
620633
* @RFI_DEACTIVATE_NOTIF: &struct iwl_rfi_deactivate_notif
621634
*/
622635
RFI_DEACTIVATE_NOTIF = 0xff,
623636
};
624637

638+
/**
639+
* enum iwl_statistics_subcmd_ids - Statistics group command IDs
640+
*/
641+
enum iwl_statistics_subcmd_ids {
642+
/**
643+
* @STATISTICS_OPER_NOTIF: Notification about operational
644+
* statistics &struct iwl_system_statistics_notif_oper
645+
*/
646+
STATISTICS_OPER_NOTIF = 0x0,
647+
648+
/**
649+
* @STATISTICS_OPER_PART1_NOTIF: Notification about operational part1
650+
* statistics &struct iwl_system_statistics_part1_notif_oper
651+
*/
652+
STATISTICS_OPER_PART1_NOTIF = 0x1,
653+
};
654+
625655
#endif /* __iwl_fw_api_commands_h__ */

drivers/net/wireless/intel/iwlwifi/fw/api/stats.h

Lines changed: 139 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
22
/*
3-
* Copyright (C) 2012-2014, 2018, 2020 - 2021 Intel Corporation
3+
* Copyright (C) 2012-2014, 2018, 2020 - 2021, 2023 Intel Corporation
44
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
55
* Copyright (C) 2016-2017 Intel Deutschland GmbH
66
*/
77
#ifndef __iwl_fw_api_stats_h__
88
#define __iwl_fw_api_stats_h__
99
#include "mac.h"
10+
#include "mac-cfg.h"
1011

1112
struct mvm_statistics_dbg {
1213
__le32 burst_check;
@@ -411,6 +412,49 @@ struct iwl_statistics_cmd {
411412

412413
#define MAX_BCAST_FILTER_NUM 8
413414

415+
/**
416+
* enum iwl_statistics_notify_type_id - type_id used in system statistics
417+
* command
418+
* @IWL_STATS_NTFY_TYPE_ID_OPER: request legacy statistics
419+
* @IWL_STATS_NTFY_TYPE_ID_OPER_PART1: request operational part1 statistics
420+
* @IWL_STATS_NTFY_TYPE_ID_OPER_PART2: request operational part2 statistics
421+
* @IWL_STATS_NTFY_TYPE_ID_OPER_PART3: request operational part3 statistics
422+
* @IWL_STATS_NTFY_TYPE_ID_OPER_PART4: request operational part4 statistics
423+
*/
424+
enum iwl_statistics_notify_type_id {
425+
IWL_STATS_NTFY_TYPE_ID_OPER = BIT(0),
426+
IWL_STATS_NTFY_TYPE_ID_OPER_PART1 = BIT(1),
427+
IWL_STATS_NTFY_TYPE_ID_OPER_PART2 = BIT(2),
428+
IWL_STATS_NTFY_TYPE_ID_OPER_PART3 = BIT(3),
429+
IWL_STATS_NTFY_TYPE_ID_OPER_PART4 = BIT(4),
430+
};
431+
432+
/**
433+
* enum iwl_statistics_cfg_flags - cfg_mask used in system statistics command
434+
* @IWL_STATS_CFG_FLG_DISABLE_NTFY_MSK: 0 for enable, 1 for disable
435+
* @IWL_STATS_CFG_FLG_ON_DEMAND_NTFY_MSK: 0 for periodic, 1 for on-demand
436+
* @IWL_STATS_CFG_FLG_RESET_MSK: 0 for reset statistics after
437+
* sending the notification, 1 for do not reset statistics after sending
438+
* the notification
439+
*/
440+
enum iwl_statistics_cfg_flags {
441+
IWL_STATS_CFG_FLG_DISABLE_NTFY_MSK = BIT(0),
442+
IWL_STATS_CFG_FLG_ON_DEMAND_NTFY_MSK = BIT(1),
443+
IWL_STATS_CFG_FLG_RESET_MSK = BIT(2),
444+
};
445+
446+
/**
447+
* struct iwl_system_statistics_cmd - system statistics command
448+
* @cfg_mask: configuration mask, &enum iwl_statistics_cfg_flags
449+
* @config_time_sec: time in sec for periodic notification
450+
* @type_id_mask: type_id masks, &enum iwl_statistics_notify_type_id
451+
*/
452+
struct iwl_system_statistics_cmd {
453+
__le32 cfg_mask;
454+
__le32 config_time_sec;
455+
__le32 type_id_mask;
456+
} __packed; /* STATISTICS_FW_CMD_API_S_VER_1 */
457+
414458
/**
415459
* enum iwl_fw_statistics_type
416460
*
@@ -447,7 +491,49 @@ struct iwl_statistics_ntfy_hdr {
447491
}; /* STATISTICS_NTFY_HDR_API_S_VER_1 */
448492

449493
/**
450-
* struct iwl_statistics_ntfy_per_mac
494+
* struct iwl_stats_ntfy_per_link
495+
*
496+
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
497+
* antennas.
498+
* @air_time: air time
499+
* @beacon_counter: all beacons (both filtered and not filtered)
500+
* @beacon_average_energy: Average energy [-dBm] of all beacons
501+
* (both filtered and not filtered)
502+
* @beacon_rssi_a: beacon RSSI on antenna A
503+
* @beacon_rssi_b: beacon RSSI on antenna B
504+
* @rx_bytes: RX byte count
505+
*/
506+
struct iwl_stats_ntfy_per_link {
507+
__le32 beacon_filter_average_energy;
508+
__le32 air_time;
509+
__le32 beacon_counter;
510+
__le32 beacon_average_energy;
511+
__le32 beacon_rssi_a;
512+
__le32 beacon_rssi_b;
513+
__le32 rx_bytes;
514+
} __packed; /* STATISTICS_NTFY_PER_LINK_API_S_VER_1 */
515+
516+
/**
517+
* struct iwl_stats_ntfy_part1_per_link
518+
*
519+
* @rx_time: rx time
520+
* @tx_time: tx time
521+
* @rx_action: action frames handled by FW
522+
* @tx_action: action frames generated and transmitted by FW
523+
* @cca_defers: cca defer count
524+
* @beacon_filtered: filtered out beacons
525+
*/
526+
struct iwl_stats_ntfy_part1_per_link {
527+
__le64 rx_time;
528+
__le64 tx_time;
529+
__le32 rx_action;
530+
__le32 tx_action;
531+
__le32 cca_defers;
532+
__le32 beacon_filtered;
533+
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_PER_LINK_API_S_VER_1 */
534+
535+
/**
536+
* struct iwl_stats_ntfy_per_mac
451537
*
452538
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
453539
* antennas.
@@ -459,7 +545,7 @@ struct iwl_statistics_ntfy_hdr {
459545
* @beacon_rssi_b: beacon RSSI on antenna B
460546
* @rx_bytes: RX byte count
461547
*/
462-
struct iwl_statistics_ntfy_per_mac {
548+
struct iwl_stats_ntfy_per_mac {
463549
__le32 beacon_filter_average_energy;
464550
__le32 air_time;
465551
__le32 beacon_counter;
@@ -470,7 +556,7 @@ struct iwl_statistics_ntfy_per_mac {
470556
} __packed; /* STATISTICS_NTFY_PER_MAC_API_S_VER_1 */
471557

472558
#define IWL_STATS_MAX_BW_INDEX 5
473-
/** struct iwl_statistics_ntfy_per_phy
559+
/** struct iwl_stats_ntfy_per_phy
474560
* @channel_load: channel load
475561
* @channel_load_by_us: device contribution to MCLM
476562
* @channel_load_not_by_us: other devices' contribution to MCLM
@@ -485,7 +571,7 @@ struct iwl_statistics_ntfy_per_mac {
485571
* per channel BW. note BACK counted as 1
486572
* @last_tx_ch_width_indx: last txed frame channel width index
487573
*/
488-
struct iwl_statistics_ntfy_per_phy {
574+
struct iwl_stats_ntfy_per_phy {
489575
__le32 channel_load;
490576
__le32 channel_load_by_us;
491577
__le32 channel_load_not_by_us;
@@ -499,23 +585,62 @@ struct iwl_statistics_ntfy_per_phy {
499585
} __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_1 */
500586

501587
/**
502-
* struct iwl_statistics_ntfy_per_sta
588+
* struct iwl_stats_ntfy_per_sta
503589
*
504590
* @average_energy: in fact it is minus the energy..
505591
*/
506-
struct iwl_statistics_ntfy_per_sta {
592+
struct iwl_stats_ntfy_per_sta {
507593
__le32 average_energy;
508594
} __packed; /* STATISTICS_NTFY_PER_STA_API_S_VER_1 */
509595

510-
#define IWL_STATS_MAX_PHY_OPERTINAL 3
596+
#define IWL_STATS_MAX_PHY_OPERATIONAL 3
597+
#define IWL_STATS_MAX_FW_LINKS (IWL_MVM_FW_MAX_LINK_ID + 1)
598+
599+
/**
600+
* struct iwl_system_statistics_notif_oper
601+
*
602+
* @time_stamp: time when the notification is sent from firmware
603+
* @per_link: per link statistics, &struct iwl_stats_ntfy_per_link
604+
* @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy
605+
* @per_sta: per sta statistics, &struct iwl_stats_ntfy_per_sta
606+
*/
607+
struct iwl_system_statistics_notif_oper {
608+
__le32 time_stamp;
609+
struct iwl_stats_ntfy_per_link per_link[IWL_STATS_MAX_FW_LINKS];
610+
struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
611+
struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX];
612+
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */
613+
614+
/**
615+
* struct iwl_system_statistics_part1_notif_oper
616+
*
617+
* @time_stamp: time when the notification is sent from firmware
618+
* @per_link: per link statistics &struct iwl_stats_ntfy_part1_per_link
619+
* @per_phy_crc_error_stats: per phy crc error statistics
620+
*/
621+
struct iwl_system_statistics_part1_notif_oper {
622+
__le32 time_stamp;
623+
struct iwl_stats_ntfy_part1_per_link per_link[IWL_STATS_MAX_FW_LINKS];
624+
__le32 per_phy_crc_error_stats[IWL_STATS_MAX_PHY_OPERATIONAL];
625+
} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_PART1_API_S_VER_4 */
626+
627+
/**
628+
* struct iwl_system_statistics_end_notif
629+
*
630+
* @time_stamp: time when the notification is sent from firmware
631+
*/
632+
struct iwl_system_statistics_end_notif {
633+
__le32 time_stamp;
634+
} __packed; /* STATISTICS_FW_NTFY_END_API_S_VER_1 */
635+
511636
/**
512637
* struct iwl_statistics_operational_ntfy
513638
*
514639
* @hdr: general statistics header
515640
* @flags: bitmap of possible notification structures
516-
* @per_mac_stats: per mac statistics, &struct iwl_statistics_ntfy_per_mac
517-
* @per_phy_stats: per phy statistics, &struct iwl_statistics_ntfy_per_phy
518-
* @per_sta_stats: per sta statistics, &struct iwl_statistics_ntfy_per_sta
641+
* @per_mac: per mac statistics, &struct iwl_stats_ntfy_per_mac
642+
* @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy
643+
* @per_sta: per sta statistics, &struct iwl_stats_ntfy_per_sta
519644
* @rx_time: rx time
520645
* @tx_time: usec the radio is transmitting.
521646
* @on_time_rf: The total time in usec the RF is awake.
@@ -524,9 +649,9 @@ struct iwl_statistics_ntfy_per_sta {
524649
struct iwl_statistics_operational_ntfy {
525650
struct iwl_statistics_ntfy_hdr hdr;
526651
__le32 flags;
527-
struct iwl_statistics_ntfy_per_mac per_mac_stats[MAC_INDEX_AUX];
528-
struct iwl_statistics_ntfy_per_phy per_phy_stats[IWL_STATS_MAX_PHY_OPERTINAL];
529-
struct iwl_statistics_ntfy_per_sta per_sta_stats[IWL_MVM_STATION_COUNT_MAX];
652+
struct iwl_stats_ntfy_per_mac per_mac[MAC_INDEX_AUX];
653+
struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
654+
struct iwl_stats_ntfy_per_sta per_sta[IWL_MVM_STATION_COUNT_MAX];
530655
__le64 rx_time;
531656
__le64 tx_time;
532657
__le64 on_time_rf;

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
15391539
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
15401540
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
15411541
int ret;
1542+
int i;
15421543

15431544
mutex_lock(&mvm->mutex);
15441545

@@ -1555,8 +1556,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
15551556

15561557
/* make sure that beacon statistics don't go backwards with FW reset */
15571558
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1558-
mvmvif->deflink.beacon_stats.accu_num_beacons +=
1559-
mvmvif->deflink.beacon_stats.num_beacons;
1559+
for_each_mvm_vif_valid_link(mvmvif, i)
1560+
mvmvif->link[i]->beacon_stats.accu_num_beacons +=
1561+
mvmvif->link[i]->beacon_stats.num_beacons;
15601562

15611563
/* Allocate resources for the MAC context, and add it to the fw */
15621564
ret = iwl_mvm_mac_ctxt_init(mvm, vif);
@@ -2581,6 +2583,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
25812583
{
25822584
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
25832585
int ret;
2586+
int i;
25842587

25852588
/*
25862589
* Re-calculate the tsf id, as the leader-follower relations depend
@@ -2627,8 +2630,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
26272630
if (vif->cfg.assoc) {
26282631
/* clear statistics to get clean beacon counter */
26292632
iwl_mvm_request_statistics(mvm, true);
2630-
memset(&mvmvif->deflink.beacon_stats, 0,
2631-
sizeof(mvmvif->deflink.beacon_stats));
2633+
for_each_mvm_vif_valid_link(mvmvif, i)
2634+
memset(&mvmvif->link[i]->beacon_stats, 0,
2635+
sizeof(mvmvif->link[i]->beacon_stats));
26322636

26332637
/* add quota for this interface */
26342638
ret = iwl_mvm_update_quotas(mvm, true, NULL);
@@ -5726,7 +5730,11 @@ int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
57265730
struct survey_info *survey)
57275731
{
57285732
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5729-
int ret;
5733+
int ret = 0;
5734+
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
5735+
WIDE_ID(SYSTEM_GROUP,
5736+
SYSTEM_STATISTICS_CMD),
5737+
IWL_FW_CMD_VER_UNKNOWN);
57305738

57315739
memset(survey, 0, sizeof(*survey));
57325740

@@ -5746,13 +5754,8 @@ int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
57465754
goto out;
57475755
}
57485756

5749-
survey->filled = SURVEY_INFO_TIME |
5750-
SURVEY_INFO_TIME_RX |
5751-
SURVEY_INFO_TIME_TX |
5752-
SURVEY_INFO_TIME_SCAN;
5753-
survey->time = mvm->accu_radio_stats.on_time_rf +
5754-
mvm->radio_stats.on_time_rf;
5755-
do_div(survey->time, USEC_PER_MSEC);
5757+
survey->filled = SURVEY_INFO_TIME_RX |
5758+
SURVEY_INFO_TIME_TX;
57565759

57575760
survey->time_rx = mvm->accu_radio_stats.rx_time +
57585761
mvm->radio_stats.rx_time;
@@ -5762,11 +5765,20 @@ int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
57625765
mvm->radio_stats.tx_time;
57635766
do_div(survey->time_tx, USEC_PER_MSEC);
57645767

5768+
/* the new fw api doesn't support the following fields */
5769+
if (cmd_ver != IWL_FW_CMD_VER_UNKNOWN)
5770+
goto out;
5771+
5772+
survey->filled |= SURVEY_INFO_TIME |
5773+
SURVEY_INFO_TIME_SCAN;
5774+
survey->time = mvm->accu_radio_stats.on_time_rf +
5775+
mvm->radio_stats.on_time_rf;
5776+
do_div(survey->time, USEC_PER_MSEC);
5777+
57655778
survey->time_scan = mvm->accu_radio_stats.on_time_scan +
57665779
mvm->radio_stats.on_time_scan;
57675780
do_div(survey->time_scan, USEC_PER_MSEC);
57685781

5769-
ret = 0;
57705782
out:
57715783
mutex_unlock(&mvm->mutex);
57725784
return ret;
@@ -5915,6 +5927,7 @@ void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
59155927
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
59165928
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
59175929
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
5930+
int i;
59185931

59195932
if (mvmsta->deflink.avg_energy) {
59205933
sinfo->signal_avg = -(s8)mvmsta->deflink.avg_energy;
@@ -5943,8 +5956,11 @@ void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
59435956
if (iwl_mvm_request_statistics(mvm, false))
59445957
goto unlock;
59455958

5946-
sinfo->rx_beacon = mvmvif->deflink.beacon_stats.num_beacons +
5947-
mvmvif->deflink.beacon_stats.accu_num_beacons;
5959+
sinfo->rx_beacon = 0;
5960+
for_each_mvm_vif_valid_link(mvmvif, i)
5961+
sinfo->rx_beacon += mvmvif->link[i]->beacon_stats.num_beacons +
5962+
mvmvif->link[i]->beacon_stats.accu_num_beacons;
5963+
59485964
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX);
59495965
if (mvmvif->deflink.beacon_stats.avg_signal) {
59505966
/* firmware only reports a value after RXing a few beacons */

0 commit comments

Comments
 (0)