Currently, link station statistics for MLO are filled by mac80211. But there are some statistics that kept by mac80211 might not be accurate, so let the driver pre-fill the link statistics. The driver can fill the values (indicating which field is filled, by setting the filled bitmapin in link_station structure). Statistics that driver don't fill are filled by mac80211. Hence, add link_sta_statistics callback to fill link station statistics for MLO in sta_set_link_sinfo() by drivers.
Unified · Split
| @@ -4133,6 +4133,15 @@ struct ieee80211_prep_tx_info { · 4132 unmodified lines | |||
| 4133 | * Statistics that the driver doesn't fill will be filled by mac80211. | 4133 | * Statistics that the driver doesn't fill will be filled by mac80211. |
| 4134 | * The callback can sleep. | 4134 | * The callback can sleep. |
| 4135 | * | 4135 | * |
| 4136 | * @link_sta_statistics: Get link statistics for this station. For example with | ||
| 4137 | * beacon filtering, the statistics kept by mac80211 might not be | ||
| 4138 | * accurate, so let the driver pre-fill the statistics. The driver can | ||
| 4139 | * fill most of the values (indicating which by setting the filled | ||
| 4140 | * bitmap), but not all of them make sense - see the source for which | ||
| 4141 | * ones are possible. | ||
| 4142 | * Statistics that the driver doesn't fill will be filled by mac80211. | ||
| 4143 | * The callback can sleep. | ||
| 4144 | * | ||
| 4136 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), | 4145 | * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), |
| 4137 | * bursting) for a hardware TX queue. | 4146 | * bursting) for a hardware TX queue. |
| 4138 | * Returns a negative error code on failure. | 4147 | * Returns a negative error code on failure. |
| @@ -4627,6 +4636,10 @@ struct ieee80211_ops { · 488 unmodified lines | |||
| 4627 | s64 offset); | 4636 | s64 offset); |
| 4628 | void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | 4637 | void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); |
| 4629 | int (*tx_last_beacon)(struct ieee80211_hw *hw); | 4638 | int (*tx_last_beacon)(struct ieee80211_hw *hw); |
| 4639 | void (*link_sta_statistics)(struct ieee80211_hw *hw, | ||
| 4640 | struct ieee80211_vif *vif, | ||
| 4641 | struct ieee80211_link_sta *link_sta, | ||
| 4642 | struct link_station_info *link_sinfo); | ||
| 4630 | 4643 | ||
| 4631 | /** | 4644 | /** |
| 4632 | * @ampdu_action: | 4645 | * @ampdu_action: |
| @@ -631,6 +631,25 @@ static inline void drv_sta_statistics(struct ieee80211_local *local, · 630 unmodified lines | |||
| 631 | trace_drv_return_void(local); | 631 | trace_drv_return_void(local); |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | static inline void drv_link_sta_statistics(struct ieee80211_local *local, | ||
| 635 | struct ieee80211_sub_if_data *sdata, | ||
| 636 | struct ieee80211_link_sta *link_sta, | ||
| 637 | struct link_station_info *link_sinfo) | ||
| 638 | { | ||
| 639 | might_sleep(); | ||
| 640 | lockdep_assert_wiphy(local->hw.wiphy); | ||
| 641 | |||
| 642 | sdata = get_bss_sdata(sdata); | ||
| 643 | if (!check_sdata_in_driver(sdata)) | ||
| 644 | return; | ||
| 645 | |||
| 646 | trace_drv_link_sta_statistics(local, sdata, link_sta); | ||
| 647 | if (local->ops->link_sta_statistics) | ||
| 648 | local->ops->link_sta_statistics(&local->hw, &sdata->vif, | ||
| 649 | link_sta, link_sinfo); | ||
| 650 | trace_drv_return_void(local); | ||
| 651 | } | ||
| 652 | |||
| 634 | int drv_conf_tx(struct ieee80211_local *local, | 653 | int drv_conf_tx(struct ieee80211_local *local, |
| 635 | struct ieee80211_link_data *link, u16 ac, | 654 | struct ieee80211_link_data *link, u16 ac, |
| 636 | const struct ieee80211_tx_queue_params *params); | 655 | const struct ieee80211_tx_queue_params *params); |
| @@ -2744,9 +2744,9 @@ static void sta_set_link_sinfo(struct sta_info *sta, · 2743 unmodified lines | |||
| 2744 | 2744 | ||
| 2745 | ether_addr_copy(link_sinfo->addr, link_sta_info->addr); | 2745 | ether_addr_copy(link_sinfo->addr, link_sta_info->addr); |
| 2746 | 2746 | ||
| 2747 | /* TODO: add drv_link_sta_statistics() ops to fill link_station | 2747 | drv_link_sta_statistics(sta->local, sdata, |
| 2748 | * statistics of station. | 2748 | link_sta_info->pub, |
| 2749 | */ | 2749 | link_sinfo); |
| 2750 | 2750 | ||
| 2751 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | | 2751 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | |
| 2752 | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | | 2752 | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | |
| @@ -1002,6 +1002,33 @@ DEFINE_EVENT(sta_event, drv_sta_statistics, · 1001 unmodified lines | |||
| 1002 | TP_ARGS(local, sdata, sta) | 1002 | TP_ARGS(local, sdata, sta) |
| 1003 | ); | 1003 | ); |
| 1004 | 1004 | ||
| 1005 | TRACE_EVENT(drv_link_sta_statistics, | ||
| 1006 | TP_PROTO(struct ieee80211_local *local, | ||
| 1007 | struct ieee80211_sub_if_data *sdata, | ||
| 1008 | struct ieee80211_link_sta *link_sta), | ||
| 1009 | |||
| 1010 | TP_ARGS(local, sdata, link_sta), | ||
| 1011 | |||
| 1012 | TP_STRUCT__entry( | ||
| 1013 | LOCAL_ENTRY | ||
| 1014 | VIF_ENTRY | ||
| 1015 | STA_ENTRY | ||
| 1016 | __field(u32, link_id) | ||
| 1017 | ), | ||
| 1018 | |||
| 1019 | TP_fast_assign( | ||
| 1020 | LOCAL_ASSIGN; | ||
| 1021 | VIF_ASSIGN; | ||
| 1022 | STA_NAMED_ASSIGN(link_sta->sta); | ||
| 1023 | __entry->link_id = link_sta->link_id; | ||
| 1024 | ), | ||
| 1025 | |||
| 1026 | TP_printk( | ||
| 1027 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " (link %d)", | ||
| 1028 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->link_id | ||
| 1029 | ) | ||
| 1030 | ); | ||
| 1031 | |||
| 1005 | DEFINE_EVENT(sta_event, drv_sta_add, | 1032 | DEFINE_EVENT(sta_event, drv_sta_add, |
| 1006 | TP_PROTO(struct ieee80211_local *local, | 1033 | TP_PROTO(struct ieee80211_local *local, |
| 1007 | struct ieee80211_sub_if_data *sdata, | 1034 | struct ieee80211_sub_if_data *sdata, |