@@ -2294,8 +2294,11 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
22942294 struct cfg80211_bss_ies * ies ;
22952295 struct ieee80211_channel * channel ;
22962296 bool signal_valid ;
2297- size_t ielen = len - offsetof(struct ieee80211_mgmt ,
2298- u .probe_resp .variable );
2297+ struct ieee80211_ext * ext = NULL ;
2298+ u8 * bssid , * variable ;
2299+ u16 capability , beacon_int ;
2300+ size_t ielen , min_hdr_len = offsetof(struct ieee80211_mgmt ,
2301+ u .probe_resp .variable );
22992302 int bss_type ;
23002303
23012304 BUILD_BUG_ON (offsetof (struct ieee80211_mgmt , u .probe_resp .variable ) !=
@@ -2313,34 +2316,70 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
23132316 (data -> signal < 0 || data -> signal > 100 )))
23142317 return NULL ;
23152318
2316- if (WARN_ON (len < offsetof(struct ieee80211_mgmt , u .probe_resp .variable )))
2319+ if (ieee80211_is_s1g_beacon (mgmt -> frame_control )) {
2320+ ext = (void * ) mgmt ;
2321+ min_hdr_len = offsetof(struct ieee80211_ext , u .s1g_beacon );
2322+ if (ieee80211_is_s1g_short_beacon (mgmt -> frame_control ))
2323+ min_hdr_len = offsetof(struct ieee80211_ext ,
2324+ u .s1g_short_beacon .variable );
2325+ }
2326+
2327+ if (WARN_ON (len < min_hdr_len ))
23172328 return NULL ;
23182329
2319- channel = cfg80211_get_bss_channel (wiphy , mgmt -> u .beacon .variable ,
2330+ ielen = len - min_hdr_len ;
2331+ variable = mgmt -> u .probe_resp .variable ;
2332+ if (ext ) {
2333+ if (ieee80211_is_s1g_short_beacon (mgmt -> frame_control ))
2334+ variable = ext -> u .s1g_short_beacon .variable ;
2335+ else
2336+ variable = ext -> u .s1g_beacon .variable ;
2337+ }
2338+
2339+ channel = cfg80211_get_bss_channel (wiphy , variable ,
23202340 ielen , data -> chan , data -> scan_width );
23212341 if (!channel )
23222342 return NULL ;
23232343
2344+ if (ext ) {
2345+ struct ieee80211_s1g_bcn_compat_ie * compat ;
2346+ u8 * ie ;
2347+
2348+ ie = (void * )cfg80211_find_ie (WLAN_EID_S1G_BCN_COMPAT ,
2349+ variable , ielen );
2350+ if (!ie )
2351+ return NULL ;
2352+ compat = (void * )(ie + 2 );
2353+ bssid = ext -> u .s1g_beacon .sa ;
2354+ capability = le16_to_cpu (compat -> compat_info );
2355+ beacon_int = le16_to_cpu (compat -> beacon_int );
2356+ } else {
2357+ bssid = mgmt -> bssid ;
2358+ beacon_int = le16_to_cpu (mgmt -> u .probe_resp .beacon_int );
2359+ capability = le16_to_cpu (mgmt -> u .probe_resp .capab_info );
2360+ }
2361+
23242362 ies = kzalloc (sizeof (* ies ) + ielen , gfp );
23252363 if (!ies )
23262364 return NULL ;
23272365 ies -> len = ielen ;
23282366 ies -> tsf = le64_to_cpu (mgmt -> u .probe_resp .timestamp );
2329- ies -> from_beacon = ieee80211_is_beacon (mgmt -> frame_control );
2330- memcpy (ies -> data , mgmt -> u .probe_resp .variable , ielen );
2367+ ies -> from_beacon = ieee80211_is_beacon (mgmt -> frame_control ) ||
2368+ ieee80211_is_s1g_beacon (mgmt -> frame_control );
2369+ memcpy (ies -> data , variable , ielen );
23312370
23322371 if (ieee80211_is_probe_resp (mgmt -> frame_control ))
23332372 rcu_assign_pointer (tmp .pub .proberesp_ies , ies );
23342373 else
23352374 rcu_assign_pointer (tmp .pub .beacon_ies , ies );
23362375 rcu_assign_pointer (tmp .pub .ies , ies );
23372376
2338- memcpy (tmp .pub .bssid , mgmt -> bssid , ETH_ALEN );
2377+ memcpy (tmp .pub .bssid , bssid , ETH_ALEN );
2378+ tmp .pub .beacon_interval = beacon_int ;
2379+ tmp .pub .capability = capability ;
23392380 tmp .pub .channel = channel ;
23402381 tmp .pub .scan_width = data -> scan_width ;
23412382 tmp .pub .signal = data -> signal ;
2342- tmp .pub .beacon_interval = le16_to_cpu (mgmt -> u .probe_resp .beacon_int );
2343- tmp .pub .capability = le16_to_cpu (mgmt -> u .probe_resp .capab_info );
23442383 tmp .ts_boottime = data -> boottime_ns ;
23452384 tmp .parent_tsf = data -> parent_tsf ;
23462385 tmp .pub .chains = data -> chains ;
0 commit comments