To allow scanning and working with 5 MHz and 10 MHz BSS, extend the inform bss commands and add wrappers to take 5 and 10 MHz bss into account.
Unified · Split
| @@ -1285,6 +1285,7 @@ struct cfg80211_ssid { · 1284 unmodified lines | ||
| 1285 | 1285 | * @n_ssids: number of SSIDs |
| 1286 | 1286 | * @channels: channels to scan on. |
| 1287 | 1287 | * @n_channels: total number of channels to scan |
| 1288 | + * @scan_width: channel width for scanning | |
| 1288 | 1289 | * @ie: optional information element(s) to add into Probe Request or %NULL |
| 1289 | 1290 | * @ie_len: length of ie in octets |
| 1290 | 1291 | * @flags: bit field of flags controlling operation |
| @@ -1300,6 +1301,7 @@ struct cfg80211_scan_request { · 9 unmodified lines | ||
| 1300 | 1301 | struct cfg80211_ssid *ssids; |
| 1301 | 1302 | int n_ssids; |
| 1302 | 1303 | u32 n_channels; |
| 1304 | + enum nl80211_bss_scan_width scan_width; | |
| 1303 | 1305 | const u8 *ie; |
| 1304 | 1306 | size_t ie_len; |
| 1305 | 1307 | u32 flags; |
| @@ -1333,6 +1335,7 @@ struct cfg80211_match_set { · 27 unmodified lines | ||
| 1333 | 1335 | * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) |
| 1334 | 1336 | * @n_ssids: number of SSIDs |
| 1335 | 1337 | * @n_channels: total number of channels to scan |
| 1338 | + * @scan_width: channel width for scanning | |
| 1336 | 1339 | * @interval: interval between each scheduled scan cycle |
| 1337 | 1340 | * @ie: optional information element(s) to add into Probe Request or %NULL |
| 1338 | 1341 | * @ie_len: length of ie in octets |
| @@ -1352,6 +1355,7 @@ struct cfg80211_sched_scan_request { · 13 unmodified lines | ||
| 1352 | 1355 | struct cfg80211_ssid *ssids; |
| 1353 | 1356 | int n_ssids; |
| 1354 | 1357 | u32 n_channels; |
| 1358 | + enum nl80211_bss_scan_width scan_width; | |
| 1355 | 1359 | u32 interval; |
| 1356 | 1360 | const u8 *ie; |
| 1357 | 1361 | size_t ie_len; |
| @@ -1403,6 +1407,7 @@ struct cfg80211_bss_ies { · 45 unmodified lines | ||
| 1403 | 1407 | * for use in scan results and similar. |
| 1404 | 1408 | * |
| 1405 | 1409 | * @channel: channel this BSS is on |
| 1410 | + * @scan_width: width of the control channel | |
| 1406 | 1411 | * @bssid: BSSID of the BSS |
| 1407 | 1412 | * @beacon_interval: the beacon interval as from the frame |
| 1408 | 1413 | * @capability: the capability field in host byte order |
| @@ -1424,6 +1429,7 @@ struct cfg80211_bss_ies { · 15 unmodified lines | ||
| 1424 | 1429 | */ |
| 1425 | 1430 | struct cfg80211_bss { |
| 1426 | 1431 | struct ieee80211_channel *channel; |
| 1432 | + enum nl80211_bss_scan_width scan_width; | |
| 1427 | 1433 | |
| 1428 | 1434 | const struct cfg80211_bss_ies __rcu *ies; |
| 1429 | 1435 | const struct cfg80211_bss_ies __rcu *beacon_ies; |
| @@ -3438,10 +3444,11 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy); · 2008 unmodified lines | ||
| 3438 | 3444 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy); |
| 3439 | 3445 | |
| 3440 | 3446 | /** |
| 3441 | − * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame | |
| 3447 | + * cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame | |
| 3442 | 3448 | * |
| 3443 | 3449 | * @wiphy: the wiphy reporting the BSS |
| 3444 | 3450 | * @channel: The channel the frame was received on |
| 3451 | + * @scan_width: width of the control channel | |
| 3445 | 3452 | * @mgmt: the management frame (probe response or beacon) |
| 3446 | 3453 | * @len: length of the management frame |
| 3447 | 3454 | * @signal: the signal strength, type depends on the wiphy's signal_type |
| @@ -3454,16 +3461,29 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy); · 6 unmodified lines | ||
| 3454 | 3461 | * Or %NULL on error. |
| 3455 | 3462 | */ |
| 3456 | 3463 | struct cfg80211_bss * __must_check |
| 3464 | +cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |
| 3465 | + struct ieee80211_channel *channel, | |
| 3466 | + enum nl80211_bss_scan_width scan_width, | |
| 3467 | + struct ieee80211_mgmt *mgmt, size_t len, | |
| 3468 | + s32 signal, gfp_t gfp); | |
| 3469 | + | |
| 3470 | +static inline struct cfg80211_bss * __must_check | |
| 3457 | 3471 | cfg80211_inform_bss_frame(struct wiphy *wiphy, |
| 3458 | 3472 | struct ieee80211_channel *channel, |
| 3459 | 3473 | struct ieee80211_mgmt *mgmt, size_t len, |
| 3460 | − s32 signal, gfp_t gfp); | |
| 3474 | + s32 signal, gfp_t gfp) | |
| 3475 | +{ | |
| 3476 | + return cfg80211_inform_bss_width_frame(wiphy, channel, | |
| 3477 | + NL80211_BSS_CHAN_WIDTH_20, | |
| 3478 | + mgmt, len, signal, gfp); | |
| 3479 | +} | |
| 3461 | 3480 | |
| 3462 | 3481 | /** |
| 3463 | 3482 | * cfg80211_inform_bss - inform cfg80211 of a new BSS |
| 3464 | 3483 | * |
| 3465 | 3484 | * @wiphy: the wiphy reporting the BSS |
| 3466 | 3485 | * @channel: The channel the frame was received on |
| 3486 | + * @scan_width: width of the control channel | |
| 3467 | 3487 | * @bssid: the BSSID of the BSS |
| 3468 | 3488 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) |
| 3469 | 3489 | * @capability: the capability field sent by the peer |
| @@ -3480,11 +3500,26 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 10 unmodified lines | ||
| 3480 | 3500 | * Or %NULL on error. |
| 3481 | 3501 | */ |
| 3482 | 3502 | struct cfg80211_bss * __must_check |
| 3503 | +cfg80211_inform_bss_width(struct wiphy *wiphy, | |
| 3504 | + struct ieee80211_channel *channel, | |
| 3505 | + enum nl80211_bss_scan_width scan_width, | |
| 3506 | + const u8 *bssid, u64 tsf, u16 capability, | |
| 3507 | + u16 beacon_interval, const u8 *ie, size_t ielen, | |
| 3508 | + s32 signal, gfp_t gfp); | |
| 3509 | + | |
| 3510 | +static inline struct cfg80211_bss * __must_check | |
| 3483 | 3511 | cfg80211_inform_bss(struct wiphy *wiphy, |
| 3484 | 3512 | struct ieee80211_channel *channel, |
| 3485 | 3513 | const u8 *bssid, u64 tsf, u16 capability, |
| 3486 | 3514 | u16 beacon_interval, const u8 *ie, size_t ielen, |
| 3487 | − s32 signal, gfp_t gfp); | |
| 3515 | + s32 signal, gfp_t gfp) | |
| 3516 | +{ | |
| 3517 | + return cfg80211_inform_bss_width(wiphy, channel, | |
| 3518 | + NL80211_BSS_CHAN_WIDTH_20, | |
| 3519 | + bssid, tsf, capability, | |
| 3520 | + beacon_interval, ie, ielen, signal, | |
| 3521 | + gfp); | |
| 3522 | +} | |
| 3488 | 3523 | |
| 3489 | 3524 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
| 3490 | 3525 | struct ieee80211_channel *channel, |
| @@ -3530,6 +3565,19 @@ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); · 39 unmodified lines | ||
| 3530 | 3565 | */ |
| 3531 | 3566 | void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); |
| 3532 | 3567 | |
| 3568 | +static inline enum nl80211_bss_scan_width | |
| 3569 | +cfg80211_chandef_to_scan_width(const struct cfg80211_chan_def *chandef) | |
| 3570 | +{ | |
| 3571 | + switch (chandef->width) { | |
| 3572 | + case NL80211_CHAN_WIDTH_5: | |
| 3573 | + return NL80211_BSS_CHAN_WIDTH_5; | |
| 3574 | + case NL80211_CHAN_WIDTH_10: | |
| 3575 | + return NL80211_BSS_CHAN_WIDTH_10; | |
| 3576 | + default: | |
| 3577 | + return NL80211_BSS_CHAN_WIDTH_20; | |
| 3578 | + } | |
| 3579 | +} | |
| 3580 | + | |
| 3533 | 3581 | /** |
| 3534 | 3582 | * cfg80211_rx_mlme_mgmt - notification of processed MLME management frame |
| 3535 | 3583 | * @dev: network device |
| @@ -2807,6 +2807,21 @@ enum nl80211_chan_width { · 2806 unmodified lines | ||
| 2807 | 2807 | NL80211_CHAN_WIDTH_10, |
| 2808 | 2808 | }; |
| 2809 | 2809 | |
| 2810 | +/** | |
| 2811 | + * enum nl80211_bss_scan_width - control channel width for a BSS | |
| 2812 | + * | |
| 2813 | + * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute. | |
| 2814 | + * | |
| 2815 | + * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible | |
| 2816 | + * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide | |
| 2817 | + * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide | |
| 2818 | + */ | |
| 2819 | +enum nl80211_bss_scan_width { | |
| 2820 | + NL80211_BSS_CHAN_WIDTH_20, | |
| 2821 | + NL80211_BSS_CHAN_WIDTH_10, | |
| 2822 | + NL80211_BSS_CHAN_WIDTH_5, | |
| 2823 | +}; | |
| 2824 | + | |
| 2810 | 2825 | /** |
| 2811 | 2826 | * enum nl80211_bss - netlink attributes for a BSS |
| 2812 | 2827 | * |
| @@ -2831,6 +2846,8 @@ enum nl80211_chan_width { · 18 unmodified lines | ||
| 2831 | 2846 | * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information |
| 2832 | 2847 | * elements from a Beacon frame (bin); not present if no Beacon frame has |
| 2833 | 2848 | * yet been received |
| 2849 | + * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel | |
| 2850 | + * (u32, enum nl80211_bss_scan_width) | |
| 2834 | 2851 | * @__NL80211_BSS_AFTER_LAST: internal |
| 2835 | 2852 | * @NL80211_BSS_MAX: highest BSS attribute |
| 2836 | 2853 | */ |
| @@ -2847,6 +2864,7 @@ enum nl80211_bss { · 10 unmodified lines | ||
| 2847 | 2864 | NL80211_BSS_STATUS, |
| 2848 | 2865 | NL80211_BSS_SEEN_MS_AGO, |
| 2849 | 2866 | NL80211_BSS_BEACON_IES, |
| 2867 | + NL80211_BSS_CHAN_WIDTH, | |
| 2850 | 2868 | |
| 2851 | 2869 | /* keep last */ |
| 2852 | 2870 | __NL80211_BSS_AFTER_LAST, |
| @@ -5674,6 +5674,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, · 5673 unmodified lines | ||
| 5674 | 5674 | goto nla_put_failure; |
| 5675 | 5675 | if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) || |
| 5676 | 5676 | nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) || |
| 5677 | + nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) || | |
| 5677 | 5678 | nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, |
| 5678 | 5679 | jiffies_to_msecs(jiffies - intbss->ts))) |
| 5679 | 5680 | goto nla_put_failure; |
| @@ -651,6 +651,8 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, · 650 unmodified lines | ||
| 651 | 651 | continue; |
| 652 | 652 | if (bss->pub.channel != new->pub.channel) |
| 653 | 653 | continue; |
| 654 | + if (bss->pub.scan_width != new->pub.scan_width) | |
| 655 | + continue; | |
| 654 | 656 | if (rcu_access_pointer(bss->pub.beacon_ies)) |
| 655 | 657 | continue; |
| 656 | 658 | ies = rcu_access_pointer(bss->pub.ies); |
| @@ -870,11 +872,12 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, · 213 unmodified lines | ||
| 870 | 872 | |
| 871 | 873 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
| 872 | 874 | struct cfg80211_bss* |
| 873 | −cfg80211_inform_bss(struct wiphy *wiphy, | |
| 874 | − struct ieee80211_channel *channel, | |
| 875 | − const u8 *bssid, u64 tsf, u16 capability, | |
| 876 | − u16 beacon_interval, const u8 *ie, size_t ielen, | |
| 877 | − s32 signal, gfp_t gfp) | |
| 875 | +cfg80211_inform_bss_width(struct wiphy *wiphy, | |
| 876 | + struct ieee80211_channel *channel, | |
| 877 | + enum nl80211_bss_scan_width scan_width, | |
| 878 | + const u8 *bssid, u64 tsf, u16 capability, | |
| 879 | + u16 beacon_interval, const u8 *ie, size_t ielen, | |
| 880 | + s32 signal, gfp_t gfp) | |
| 878 | 881 | { |
| 879 | 882 | struct cfg80211_bss_ies *ies; |
| 880 | 883 | struct cfg80211_internal_bss tmp = {}, *res; |
| @@ -892,6 +895,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, · 11 unmodified lines | ||
| 892 | 895 | |
| 893 | 896 | memcpy(tmp.pub.bssid, bssid, ETH_ALEN); |
| 894 | 897 | tmp.pub.channel = channel; |
| 898 | + tmp.pub.scan_width = scan_width; | |
| 895 | 899 | tmp.pub.signal = signal; |
| 896 | 900 | tmp.pub.beacon_interval = beacon_interval; |
| 897 | 901 | tmp.pub.capability = capability; |
| @@ -924,14 +928,15 @@ cfg80211_inform_bss(struct wiphy *wiphy, · 26 unmodified lines | ||
| 924 | 928 | /* cfg80211_bss_update gives us a referenced result */ |
| 925 | 929 | return &res->pub; |
| 926 | 930 | } |
| 927 | −EXPORT_SYMBOL(cfg80211_inform_bss); | |
| 931 | +EXPORT_SYMBOL(cfg80211_inform_bss_width); | |
| 928 | 932 | |
| 929 | 933 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
| 930 | 934 | struct cfg80211_bss * |
| 931 | −cfg80211_inform_bss_frame(struct wiphy *wiphy, | |
| 932 | − struct ieee80211_channel *channel, | |
| 933 | − struct ieee80211_mgmt *mgmt, size_t len, | |
| 934 | − s32 signal, gfp_t gfp) | |
| 935 | +cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |
| 936 | + struct ieee80211_channel *channel, | |
| 937 | + enum nl80211_bss_scan_width scan_width, | |
| 938 | + struct ieee80211_mgmt *mgmt, size_t len, | |
| 939 | + s32 signal, gfp_t gfp) | |
| 935 | 940 | { |
| 936 | 941 | struct cfg80211_internal_bss tmp = {}, *res; |
| 937 | 942 | struct cfg80211_bss_ies *ies; |
| @@ -941,7 +946,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 3 unmodified lines | ||
| 941 | 946 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != |
| 942 | 947 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); |
| 943 | 948 | |
| 944 | − trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); | |
| 949 | + trace_cfg80211_inform_bss_width_frame(wiphy, channel, scan_width, mgmt, | |
| 950 | + len, signal); | |
| 945 | 951 | |
| 946 | 952 | if (WARN_ON(!mgmt)) |
| 947 | 953 | return NULL; |
| @@ -976,6 +982,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 28 unmodified lines | ||
| 976 | 982 | |
| 977 | 983 | memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); |
| 978 | 984 | tmp.pub.channel = channel; |
| 985 | + tmp.pub.scan_width = scan_width; | |
| 979 | 986 | tmp.pub.signal = signal; |
| 980 | 987 | tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); |
| 981 | 988 | tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); |
| @@ -991,7 +998,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 9 unmodified lines | ||
| 991 | 998 | /* cfg80211_bss_update gives us a referenced result */ |
| 992 | 999 | return &res->pub; |
| 993 | 1000 | } |
| 994 | −EXPORT_SYMBOL(cfg80211_inform_bss_frame); | |
| 1001 | +EXPORT_SYMBOL(cfg80211_inform_bss_width_frame); | |
| 995 | 1002 | |
| 996 | 1003 | void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) |
| 997 | 1004 | { |
| @@ -2391,26 +2391,30 @@ TRACE_EVENT(cfg80211_get_bss, · 2390 unmodified lines | ||
| 2391 | 2391 | __entry->capa_mask, __entry->capa_val) |
| 2392 | 2392 | ); |
| 2393 | 2393 | |
| 2394 | −TRACE_EVENT(cfg80211_inform_bss_frame, | |
| 2394 | +TRACE_EVENT(cfg80211_inform_bss_width_frame, | |
| 2395 | 2395 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, |
| 2396 | + enum nl80211_bss_scan_width scan_width, | |
| 2396 | 2397 | struct ieee80211_mgmt *mgmt, size_t len, |
| 2397 | 2398 | s32 signal), |
| 2398 | − TP_ARGS(wiphy, channel, mgmt, len, signal), | |
| 2399 | + TP_ARGS(wiphy, channel, scan_width, mgmt, len, signal), | |
| 2399 | 2400 | TP_STRUCT__entry( |
| 2400 | 2401 | WIPHY_ENTRY |
| 2401 | 2402 | CHAN_ENTRY |
| 2403 | + __field(enum nl80211_bss_scan_width, scan_width) | |
| 2402 | 2404 | __dynamic_array(u8, mgmt, len) |
| 2403 | 2405 | __field(s32, signal) |
| 2404 | 2406 | ), |
| 2405 | 2407 | TP_fast_assign( |
| 2406 | 2408 | WIPHY_ASSIGN; |
| 2407 | 2409 | CHAN_ASSIGN(channel); |
| 2410 | + __entry->scan_width = scan_width; | |
| 2408 | 2411 | if (mgmt) |
| 2409 | 2412 | memcpy(__get_dynamic_array(mgmt), mgmt, len); |
| 2410 | 2413 | __entry->signal = signal; |
| 2411 | 2414 | ), |
| 2412 | − TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "signal: %d", | |
| 2413 | − WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) | |
| 2415 | + TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT "(scan_width: %d) signal: %d", | |
| 2416 | + WIPHY_PR_ARG, CHAN_PR_ARG, __entry->scan_width, | |
| 2417 | + __entry->signal) | |
| 2414 | 2418 | ); |
| 2415 | 2419 | |
| 2416 | 2420 | DECLARE_EVENT_CLASS(cfg80211_bss_evt, |