@@ -2702,9 +2702,29 @@ static void rtw89_release_pkt_list(struct rtw89_dev *rtwdev)
2702
2702
}
2703
2703
}
2704
2704
2705
+ static bool rtw89_is_6ghz_wildcard_probe_req (struct rtw89_dev * rtwdev ,
2706
+ struct rtw89_vif * rtwvif ,
2707
+ struct rtw89_pktofld_info * info ,
2708
+ enum nl80211_band band , u8 ssid_idx )
2709
+ {
2710
+ struct cfg80211_scan_request * req = rtwvif -> scan_req ;
2711
+
2712
+ if (band != NL80211_BAND_6GHZ )
2713
+ return false;
2714
+
2715
+ if (req -> ssids [ssid_idx ].ssid_len ) {
2716
+ memcpy (info -> ssid , req -> ssids [ssid_idx ].ssid ,
2717
+ req -> ssids [ssid_idx ].ssid_len );
2718
+ info -> ssid_len = req -> ssids [ssid_idx ].ssid_len ;
2719
+ return false;
2720
+ } else {
2721
+ return true;
2722
+ }
2723
+ }
2724
+
2705
2725
static int rtw89_append_probe_req_ie (struct rtw89_dev * rtwdev ,
2706
2726
struct rtw89_vif * rtwvif ,
2707
- struct sk_buff * skb )
2727
+ struct sk_buff * skb , u8 ssid_idx )
2708
2728
{
2709
2729
struct rtw89_hw_scan_info * scan_info = & rtwdev -> scan_info ;
2710
2730
struct ieee80211_scan_ies * ies = rtwvif -> scan_ies ;
@@ -2732,6 +2752,13 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev,
2732
2752
goto out ;
2733
2753
}
2734
2754
2755
+ if (rtw89_is_6ghz_wildcard_probe_req (rtwdev , rtwvif , info , band ,
2756
+ ssid_idx )) {
2757
+ kfree_skb (new );
2758
+ kfree (info );
2759
+ goto out ;
2760
+ }
2761
+
2735
2762
ret = rtw89_fw_h2c_add_pkt_offload (rtwdev , & info -> id , new );
2736
2763
if (ret ) {
2737
2764
kfree_skb (new );
@@ -2762,7 +2789,7 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
2762
2789
if (!skb )
2763
2790
return - ENOMEM ;
2764
2791
2765
- ret = rtw89_append_probe_req_ie (rtwdev , rtwvif , skb );
2792
+ ret = rtw89_append_probe_req_ie (rtwdev , rtwvif , skb , i );
2766
2793
kfree_skb (skb );
2767
2794
2768
2795
if (ret )
@@ -2772,6 +2799,77 @@ static int rtw89_hw_scan_update_probe_req(struct rtw89_dev *rtwdev,
2772
2799
return 0 ;
2773
2800
}
2774
2801
2802
+ static int rtw89_update_6ghz_rnr_chan (struct rtw89_dev * rtwdev ,
2803
+ struct cfg80211_scan_request * req ,
2804
+ struct rtw89_mac_chinfo * ch_info )
2805
+ {
2806
+ struct ieee80211_vif * vif = rtwdev -> scan_info .scanning_vif ;
2807
+ struct list_head * pkt_list = rtwdev -> scan_info .pkt_list ;
2808
+ struct rtw89_vif * rtwvif = vif_to_rtwvif_safe (vif );
2809
+ struct ieee80211_scan_ies * ies = rtwvif -> scan_ies ;
2810
+ struct cfg80211_scan_6ghz_params * params ;
2811
+ struct rtw89_pktofld_info * info , * tmp ;
2812
+ struct ieee80211_hdr * hdr ;
2813
+ struct sk_buff * skb ;
2814
+ bool found ;
2815
+ int ret = 0 ;
2816
+ u8 i ;
2817
+
2818
+ if (!req -> n_6ghz_params )
2819
+ return 0 ;
2820
+
2821
+ for (i = 0 ; i < req -> n_6ghz_params ; i ++ ) {
2822
+ params = & req -> scan_6ghz_params [i ];
2823
+
2824
+ if (req -> channels [params -> channel_idx ]-> hw_value !=
2825
+ ch_info -> pri_ch )
2826
+ continue ;
2827
+
2828
+ found = false;
2829
+ list_for_each_entry (tmp , & pkt_list [NL80211_BAND_6GHZ ], list ) {
2830
+ if (ether_addr_equal (tmp -> bssid , params -> bssid )) {
2831
+ found = true;
2832
+ break ;
2833
+ }
2834
+ }
2835
+ if (found )
2836
+ continue ;
2837
+
2838
+ skb = ieee80211_probereq_get (rtwdev -> hw , rtwvif -> mac_addr ,
2839
+ NULL , 0 , req -> ie_len );
2840
+ skb_put_data (skb , ies -> ies [NL80211_BAND_6GHZ ], ies -> len [NL80211_BAND_6GHZ ]);
2841
+ skb_put_data (skb , ies -> common_ies , ies -> common_ie_len );
2842
+ hdr = (struct ieee80211_hdr * )skb -> data ;
2843
+ ether_addr_copy (hdr -> addr3 , params -> bssid );
2844
+
2845
+ info = kzalloc (sizeof (* info ), GFP_KERNEL );
2846
+ if (!info ) {
2847
+ ret = - ENOMEM ;
2848
+ kfree_skb (skb );
2849
+ goto out ;
2850
+ }
2851
+
2852
+ ret = rtw89_fw_h2c_add_pkt_offload (rtwdev , & info -> id , skb );
2853
+ if (ret ) {
2854
+ kfree_skb (skb );
2855
+ kfree (info );
2856
+ goto out ;
2857
+ }
2858
+
2859
+ ether_addr_copy (info -> bssid , params -> bssid );
2860
+ info -> channel_6ghz = req -> channels [params -> channel_idx ]-> hw_value ;
2861
+ list_add_tail (& info -> list , & rtwdev -> scan_info .pkt_list [NL80211_BAND_6GHZ ]);
2862
+
2863
+ ch_info -> tx_pkt = true;
2864
+ ch_info -> period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G ;
2865
+
2866
+ kfree_skb (skb );
2867
+ }
2868
+
2869
+ out :
2870
+ return ret ;
2871
+ }
2872
+
2775
2873
static void rtw89_hw_scan_add_chan (struct rtw89_dev * rtwdev , int chan_type ,
2776
2874
int ssid_num ,
2777
2875
struct rtw89_mac_chinfo * ch_info )
@@ -2782,6 +2880,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
2782
2880
struct cfg80211_scan_request * req = rtwvif -> scan_req ;
2783
2881
struct rtw89_pktofld_info * info ;
2784
2882
u8 band , probe_count = 0 ;
2883
+ int ret ;
2785
2884
2786
2885
ch_info -> notify_action = RTW89_SCANOFLD_DEBUG_MASK ;
2787
2886
ch_info -> dfs_ch = chan_type == RTW89_CHAN_DFS ;
@@ -2793,25 +2892,31 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type,
2793
2892
ch_info -> pause_data = false;
2794
2893
ch_info -> probe_id = RTW89_SCANOFLD_PKT_NONE ;
2795
2894
2895
+ if (ch_info -> ch_band == RTW89_BAND_6G ) {
2896
+ if ((ssid_num == 1 && req -> ssids [0 ].ssid_len == 0 ) ||
2897
+ !ch_info -> is_psc ) {
2898
+ ch_info -> tx_pkt = false;
2899
+ if (!req -> duration_mandatory )
2900
+ ch_info -> period -= RTW89_DWELL_TIME_6G ;
2901
+ }
2902
+ }
2903
+
2904
+ ret = rtw89_update_6ghz_rnr_chan (rtwdev , req , ch_info );
2905
+ if (ret )
2906
+ rtw89_warn (rtwdev , "RNR fails: %d\n" , ret );
2907
+
2796
2908
if (ssid_num ) {
2797
- ch_info -> num_pkt = ssid_num ;
2798
2909
band = rtw89_hw_to_nl80211_band (ch_info -> ch_band );
2799
2910
2800
2911
list_for_each_entry (info , & scan_info -> pkt_list [band ], list ) {
2801
- ch_info -> pkt_id [probe_count ] = info -> id ;
2802
- if (++ probe_count >= ssid_num )
2912
+ if (info -> channel_6ghz &&
2913
+ ch_info -> pri_ch != info -> channel_6ghz )
2914
+ continue ;
2915
+ ch_info -> pkt_id [probe_count ++ ] = info -> id ;
2916
+ if (probe_count >= RTW89_SCANOFLD_MAX_SSID )
2803
2917
break ;
2804
2918
}
2805
- if (probe_count != ssid_num )
2806
- rtw89_err (rtwdev , "SSID num differs from list len\n" );
2807
- }
2808
-
2809
- if (ch_info -> ch_band == RTW89_BAND_6G ) {
2810
- if (ssid_num == 1 && req -> ssids [0 ].ssid_len == 0 ) {
2811
- ch_info -> tx_pkt = false;
2812
- if (!req -> duration_mandatory )
2813
- ch_info -> period -= RTW89_DWELL_TIME_6G ;
2814
- }
2919
+ ch_info -> num_pkt = probe_count ;
2815
2920
}
2816
2921
2817
2922
switch (chan_type ) {
@@ -2872,6 +2977,7 @@ static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev,
2872
2977
ch_info -> central_ch = channel -> hw_value ;
2873
2978
ch_info -> pri_ch = channel -> hw_value ;
2874
2979
ch_info -> rand_seq_num = random_seq ;
2980
+ ch_info -> is_psc = cfg80211_channel_is_psc (channel );
2875
2981
2876
2982
if (channel -> flags &
2877
2983
(IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR ))
0 commit comments