@@ -319,28 +319,38 @@ static const struct ieee80211_supported_band rtw89_sband_6ghz = {
319319 .n_bitrates = ARRAY_SIZE (rtw89_bitrates ) - 4 ,
320320};
321321
322+ static void __rtw89_traffic_stats_accu (struct rtw89_traffic_stats * stats ,
323+ struct sk_buff * skb , bool tx )
324+ {
325+ if (tx ) {
326+ stats -> tx_cnt ++ ;
327+ stats -> tx_unicast += skb -> len ;
328+ } else {
329+ stats -> rx_cnt ++ ;
330+ stats -> rx_unicast += skb -> len ;
331+ }
332+ }
333+
322334static void rtw89_traffic_stats_accu (struct rtw89_dev * rtwdev ,
323- struct rtw89_traffic_stats * stats ,
324- struct sk_buff * skb , bool tx )
335+ struct rtw89_vif * rtwvif ,
336+ struct sk_buff * skb ,
337+ bool accu_dev , bool tx )
325338{
326339 struct ieee80211_hdr * hdr = (struct ieee80211_hdr * )skb -> data ;
327340
328- if (tx && ieee80211_is_assoc_req (hdr -> frame_control ))
329- rtw89_wow_parse_akm (rtwdev , skb );
330-
331341 if (!ieee80211_is_data (hdr -> frame_control ))
332342 return ;
333343
334344 if (is_broadcast_ether_addr (hdr -> addr1 ) ||
335345 is_multicast_ether_addr (hdr -> addr1 ))
336346 return ;
337347
338- if (tx ) {
339- stats -> tx_cnt ++ ;
340- stats -> tx_unicast += skb -> len ;
341- } else {
342- stats -> rx_cnt ++ ;
343- stats -> rx_unicast += skb -> len ;
348+ if (accu_dev )
349+ __rtw89_traffic_stats_accu ( & rtwdev -> stats , skb , tx ) ;
350+
351+ if ( rtwvif ) {
352+ __rtw89_traffic_stats_accu ( & rtwvif -> stats , skb , tx ) ;
353+ __rtw89_traffic_stats_accu ( & rtwvif -> stats_ps , skb , tx ) ;
344354 }
345355}
346356
@@ -1150,8 +1160,8 @@ static int rtw89_core_tx_write_link(struct rtw89_dev *rtwdev,
11501160 tx_req .rtwsta_link = rtwsta_link ;
11511161 tx_req .desc_info .sw_mld = sw_mld ;
11521162
1153- rtw89_traffic_stats_accu (rtwdev , & rtwdev -> stats , skb , true);
1154- rtw89_traffic_stats_accu (rtwdev , & rtwvif -> stats , skb , true );
1163+ rtw89_traffic_stats_accu (rtwdev , rtwvif , skb , true , true);
1164+ rtw89_wow_parse_akm (rtwdev , skb );
11551165 rtw89_core_tx_update_desc_info (rtwdev , & tx_req );
11561166 rtw89_core_tx_wake (rtwdev , & tx_req );
11571167
@@ -2267,7 +2277,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
22672277 if (desc_info -> data_rate < RTW89_HW_RATE_NR )
22682278 pkt_stat -> rx_rate_cnt [desc_info -> data_rate ]++ ;
22692279
2270- rtw89_traffic_stats_accu (rtwdev , & rtwvif -> stats , skb , false);
2280+ rtw89_traffic_stats_accu (rtwdev , rtwvif , skb , false , false);
22712281
22722282out :
22732283 rcu_read_unlock ();
@@ -2280,7 +2290,7 @@ static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
22802290{
22812291 struct rtw89_vif_rx_stats_iter_data iter_data ;
22822292
2283- rtw89_traffic_stats_accu (rtwdev , & rtwdev -> stats , skb , false);
2293+ rtw89_traffic_stats_accu (rtwdev , NULL , skb , true , false);
22842294
22852295 iter_data .rtwdev = rtwdev ;
22862296 iter_data .phy_ppdu = phy_ppdu ;
@@ -3570,9 +3580,22 @@ void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
35703580}
35713581
35723582static enum rtw89_tfc_lv rtw89_get_traffic_level (struct rtw89_dev * rtwdev ,
3573- u32 throughput , u64 cnt )
3583+ u32 throughput , u64 cnt ,
3584+ enum rtw89_tfc_interval interval )
35743585{
3575- if (cnt < 100 )
3586+ u64 cnt_level ;
3587+
3588+ switch (interval ) {
3589+ default :
3590+ case RTW89_TFC_INTERVAL_100MS :
3591+ cnt_level = 5 ;
3592+ break ;
3593+ case RTW89_TFC_INTERVAL_2SEC :
3594+ cnt_level = 100 ;
3595+ break ;
3596+ }
3597+
3598+ if (cnt < cnt_level )
35763599 return RTW89_TFC_IDLE ;
35773600 if (throughput > 50 )
35783601 return RTW89_TFC_HIGH ;
@@ -3584,23 +3607,24 @@ static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev,
35843607}
35853608
35863609static bool rtw89_traffic_stats_calc (struct rtw89_dev * rtwdev ,
3587- struct rtw89_traffic_stats * stats )
3610+ struct rtw89_traffic_stats * stats ,
3611+ enum rtw89_tfc_interval interval )
35883612{
35893613 enum rtw89_tfc_lv tx_tfc_lv = stats -> tx_tfc_lv ;
35903614 enum rtw89_tfc_lv rx_tfc_lv = stats -> rx_tfc_lv ;
35913615
3592- stats -> tx_throughput_raw = ( u32 )( stats -> tx_unicast >> RTW89_TP_SHIFT );
3593- stats -> rx_throughput_raw = ( u32 )( stats -> rx_unicast >> RTW89_TP_SHIFT );
3616+ stats -> tx_throughput_raw = rtw89_bytes_to_mbps ( stats -> tx_unicast , interval );
3617+ stats -> rx_throughput_raw = rtw89_bytes_to_mbps ( stats -> rx_unicast , interval );
35943618
35953619 ewma_tp_add (& stats -> tx_ewma_tp , stats -> tx_throughput_raw );
35963620 ewma_tp_add (& stats -> rx_ewma_tp , stats -> rx_throughput_raw );
35973621
35983622 stats -> tx_throughput = ewma_tp_read (& stats -> tx_ewma_tp );
35993623 stats -> rx_throughput = ewma_tp_read (& stats -> rx_ewma_tp );
36003624 stats -> tx_tfc_lv = rtw89_get_traffic_level (rtwdev , stats -> tx_throughput ,
3601- stats -> tx_cnt );
3625+ stats -> tx_cnt , interval );
36023626 stats -> rx_tfc_lv = rtw89_get_traffic_level (rtwdev , stats -> rx_throughput ,
3603- stats -> rx_cnt );
3627+ stats -> rx_cnt , interval );
36043628 stats -> tx_avg_len = stats -> tx_cnt ?
36053629 DIV_ROUND_DOWN_ULL (stats -> tx_unicast , stats -> tx_cnt ) : 0 ;
36063630 stats -> rx_avg_len = stats -> rx_cnt ?
@@ -3626,10 +3650,12 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev)
36263650 unsigned int link_id ;
36273651 bool tfc_changed ;
36283652
3629- tfc_changed = rtw89_traffic_stats_calc (rtwdev , & rtwdev -> stats );
3653+ tfc_changed = rtw89_traffic_stats_calc (rtwdev , & rtwdev -> stats ,
3654+ RTW89_TFC_INTERVAL_2SEC );
36303655
36313656 rtw89_for_each_rtwvif (rtwdev , rtwvif ) {
3632- rtw89_traffic_stats_calc (rtwdev , & rtwvif -> stats );
3657+ rtw89_traffic_stats_calc (rtwdev , & rtwvif -> stats ,
3658+ RTW89_TFC_INTERVAL_2SEC );
36333659
36343660 rtw89_vif_for_each_link (rtwvif , rtwvif_link , link_id )
36353661 rtw89_fw_h2c_tp_offload (rtwdev , rtwvif_link );
@@ -3649,8 +3675,8 @@ static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
36493675 if (rtwvif -> offchan )
36503676 continue ;
36513677
3652- if (rtwvif -> stats .tx_tfc_lv != RTW89_TFC_IDLE ||
3653- rtwvif -> stats .rx_tfc_lv != RTW89_TFC_IDLE )
3678+ if (rtwvif -> stats_ps .tx_tfc_lv >= RTW89_TFC_MID ||
3679+ rtwvif -> stats_ps .rx_tfc_lv >= RTW89_TFC_MID )
36543680 continue ;
36553681
36563682 vif = rtwvif_to_vif (rtwvif );
@@ -3789,6 +3815,34 @@ static void rtw89_core_mlo_track(struct rtw89_dev *rtwdev)
37893815 }
37903816}
37913817
3818+ static void rtw89_track_ps_work (struct wiphy * wiphy , struct wiphy_work * work )
3819+ {
3820+ struct rtw89_dev * rtwdev = container_of (work , struct rtw89_dev ,
3821+ track_ps_work .work );
3822+ struct rtw89_vif * rtwvif ;
3823+
3824+ lockdep_assert_wiphy (wiphy );
3825+
3826+ if (test_bit (RTW89_FLAG_FORBIDDEN_TRACK_WORK , rtwdev -> flags ))
3827+ return ;
3828+
3829+ if (!test_bit (RTW89_FLAG_RUNNING , rtwdev -> flags ))
3830+ return ;
3831+
3832+ wiphy_delayed_work_queue (wiphy , & rtwdev -> track_ps_work ,
3833+ RTW89_TRACK_PS_WORK_PERIOD );
3834+
3835+ rtw89_for_each_rtwvif (rtwdev , rtwvif )
3836+ rtw89_traffic_stats_calc (rtwdev , & rtwvif -> stats_ps ,
3837+ RTW89_TFC_INTERVAL_100MS );
3838+
3839+ if (rtwdev -> scanning )
3840+ return ;
3841+
3842+ if (rtwdev -> lps_enabled && !rtwdev -> btc .lps )
3843+ rtw89_enter_lps_track (rtwdev );
3844+ }
3845+
37923846static void rtw89_track_work (struct wiphy * wiphy , struct wiphy_work * work )
37933847{
37943848 struct rtw89_dev * rtwdev = container_of (work , struct rtw89_dev ,
@@ -4875,6 +4929,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
48754929
48764930 wiphy_delayed_work_queue (rtwdev -> hw -> wiphy , & rtwdev -> track_work ,
48774931 RTW89_TRACK_WORK_PERIOD );
4932+ wiphy_delayed_work_queue (rtwdev -> hw -> wiphy , & rtwdev -> track_ps_work ,
4933+ RTW89_TRACK_PS_WORK_PERIOD );
48784934
48794935 set_bit (RTW89_FLAG_RUNNING , rtwdev -> flags );
48804936
@@ -4909,6 +4965,7 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
49094965 wiphy_work_cancel (wiphy , & btc -> icmp_notify_work );
49104966 cancel_delayed_work_sync (& rtwdev -> txq_reinvoke_work );
49114967 wiphy_delayed_work_cancel (wiphy , & rtwdev -> track_work );
4968+ wiphy_delayed_work_cancel (wiphy , & rtwdev -> track_ps_work );
49124969 wiphy_delayed_work_cancel (wiphy , & rtwdev -> chanctx_work );
49134970 wiphy_delayed_work_cancel (wiphy , & rtwdev -> coex_act1_work );
49144971 wiphy_delayed_work_cancel (wiphy , & rtwdev -> coex_bt_devinfo_work );
@@ -5136,6 +5193,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
51365193 INIT_WORK (& rtwdev -> txq_work , rtw89_core_txq_work );
51375194 INIT_DELAYED_WORK (& rtwdev -> txq_reinvoke_work , rtw89_core_txq_reinvoke_work );
51385195 wiphy_delayed_work_init (& rtwdev -> track_work , rtw89_track_work );
5196+ wiphy_delayed_work_init (& rtwdev -> track_ps_work , rtw89_track_ps_work );
51395197 wiphy_delayed_work_init (& rtwdev -> chanctx_work , rtw89_chanctx_work );
51405198 wiphy_delayed_work_init (& rtwdev -> coex_act1_work , rtw89_coex_act1_work );
51415199 wiphy_delayed_work_init (& rtwdev -> coex_bt_devinfo_work , rtw89_coex_bt_devinfo_work );
0 commit comments