@@ -2294,8 +2294,11 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
2294
2294
struct cfg80211_bss_ies * ies ;
2295
2295
struct ieee80211_channel * channel ;
2296
2296
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 );
2299
2302
int bss_type ;
2300
2303
2301
2304
BUILD_BUG_ON (offsetof (struct ieee80211_mgmt , u .probe_resp .variable ) !=
@@ -2313,34 +2316,70 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
2313
2316
(data -> signal < 0 || data -> signal > 100 )))
2314
2317
return NULL ;
2315
2318
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 ))
2317
2328
return NULL ;
2318
2329
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 ,
2320
2340
ielen , data -> chan , data -> scan_width );
2321
2341
if (!channel )
2322
2342
return NULL ;
2323
2343
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
+
2324
2362
ies = kzalloc (sizeof (* ies ) + ielen , gfp );
2325
2363
if (!ies )
2326
2364
return NULL ;
2327
2365
ies -> len = ielen ;
2328
2366
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 );
2331
2370
2332
2371
if (ieee80211_is_probe_resp (mgmt -> frame_control ))
2333
2372
rcu_assign_pointer (tmp .pub .proberesp_ies , ies );
2334
2373
else
2335
2374
rcu_assign_pointer (tmp .pub .beacon_ies , ies );
2336
2375
rcu_assign_pointer (tmp .pub .ies , ies );
2337
2376
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 ;
2339
2380
tmp .pub .channel = channel ;
2340
2381
tmp .pub .scan_width = data -> scan_width ;
2341
2382
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 );
2344
2383
tmp .ts_boottime = data -> boottime_ns ;
2345
2384
tmp .parent_tsf = data -> parent_tsf ;
2346
2385
tmp .pub .chains = data -> chains ;
0 commit comments