at v6.19 575 lines 17 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * IEEE 802.11 S1G definitions 4 * 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 6 * <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 8 * Copyright (c) 2005, Devicescape Software, Inc. 9 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 10 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH 11 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH 12 * Copyright (c) 2018 - 2025 Intel Corporation 13 */ 14 15#ifndef LINUX_IEEE80211_S1G_H 16#define LINUX_IEEE80211_S1G_H 17 18#include <linux/types.h> 19#include <linux/if_ether.h> 20 21/* bits unique to S1G beacon frame control */ 22#define IEEE80211_S1G_BCN_NEXT_TBTT 0x100 23#define IEEE80211_S1G_BCN_CSSID 0x200 24#define IEEE80211_S1G_BCN_ANO 0x400 25 26/* see 802.11ah-2016 9.9 NDP CMAC frames */ 27#define IEEE80211_S1G_1MHZ_NDP_BITS 25 28#define IEEE80211_S1G_1MHZ_NDP_BYTES 4 29#define IEEE80211_S1G_2MHZ_NDP_BITS 37 30#define IEEE80211_S1G_2MHZ_NDP_BYTES 5 31 32/** 33 * ieee80211_is_s1g_beacon - check if IEEE80211_FTYPE_EXT && 34 * IEEE80211_STYPE_S1G_BEACON 35 * @fc: frame control bytes in little-endian byteorder 36 * Return: whether or not the frame is an S1G beacon 37 */ 38static inline bool ieee80211_is_s1g_beacon(__le16 fc) 39{ 40 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 41 IEEE80211_FCTL_STYPE)) == 42 cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON); 43} 44 45/** 46 * ieee80211_s1g_has_next_tbtt - check if IEEE80211_S1G_BCN_NEXT_TBTT 47 * @fc: frame control bytes in little-endian byteorder 48 * Return: whether or not the frame contains the variable-length 49 * next TBTT field 50 */ 51static inline bool ieee80211_s1g_has_next_tbtt(__le16 fc) 52{ 53 return ieee80211_is_s1g_beacon(fc) && 54 (fc & cpu_to_le16(IEEE80211_S1G_BCN_NEXT_TBTT)); 55} 56 57/** 58 * ieee80211_s1g_has_ano - check if IEEE80211_S1G_BCN_ANO 59 * @fc: frame control bytes in little-endian byteorder 60 * Return: whether or not the frame contains the variable-length 61 * ANO field 62 */ 63static inline bool ieee80211_s1g_has_ano(__le16 fc) 64{ 65 return ieee80211_is_s1g_beacon(fc) && 66 (fc & cpu_to_le16(IEEE80211_S1G_BCN_ANO)); 67} 68 69/** 70 * ieee80211_s1g_has_cssid - check if IEEE80211_S1G_BCN_CSSID 71 * @fc: frame control bytes in little-endian byteorder 72 * Return: whether or not the frame contains the variable-length 73 * compressed SSID field 74 */ 75static inline bool ieee80211_s1g_has_cssid(__le16 fc) 76{ 77 return ieee80211_is_s1g_beacon(fc) && 78 (fc & cpu_to_le16(IEEE80211_S1G_BCN_CSSID)); 79} 80 81/** 82 * enum ieee80211_s1g_chanwidth - S1G channel widths 83 * These are defined in IEEE802.11-2016ah Table 10-20 84 * as BSS Channel Width 85 * 86 * @IEEE80211_S1G_CHANWIDTH_1MHZ: 1MHz operating channel 87 * @IEEE80211_S1G_CHANWIDTH_2MHZ: 2MHz operating channel 88 * @IEEE80211_S1G_CHANWIDTH_4MHZ: 4MHz operating channel 89 * @IEEE80211_S1G_CHANWIDTH_8MHZ: 8MHz operating channel 90 * @IEEE80211_S1G_CHANWIDTH_16MHZ: 16MHz operating channel 91 */ 92enum ieee80211_s1g_chanwidth { 93 IEEE80211_S1G_CHANWIDTH_1MHZ = 0, 94 IEEE80211_S1G_CHANWIDTH_2MHZ = 1, 95 IEEE80211_S1G_CHANWIDTH_4MHZ = 3, 96 IEEE80211_S1G_CHANWIDTH_8MHZ = 7, 97 IEEE80211_S1G_CHANWIDTH_16MHZ = 15, 98}; 99 100/** 101 * enum ieee80211_s1g_pri_chanwidth - S1G primary channel widths 102 * described in IEEE80211-2024 Table 10-39. 103 * 104 * @IEEE80211_S1G_PRI_CHANWIDTH_2MHZ: 2MHz primary channel 105 * @IEEE80211_S1G_PRI_CHANWIDTH_1MHZ: 1MHz primary channel 106 */ 107enum ieee80211_s1g_pri_chanwidth { 108 IEEE80211_S1G_PRI_CHANWIDTH_2MHZ = 0, 109 IEEE80211_S1G_PRI_CHANWIDTH_1MHZ = 1, 110}; 111 112/** 113 * struct ieee80211_s1g_bcn_compat_ie - S1G Beacon Compatibility element 114 * @compat_info: Compatibility Information 115 * @beacon_int: Beacon Interval 116 * @tsf_completion: TSF Completion 117 * 118 * This structure represents the payload of the "S1G Beacon 119 * Compatibility element" as described in IEEE Std 802.11-2020 section 120 * 9.4.2.196. 121 */ 122struct ieee80211_s1g_bcn_compat_ie { 123 __le16 compat_info; 124 __le16 beacon_int; 125 __le32 tsf_completion; 126} __packed; 127 128/** 129 * struct ieee80211_s1g_oper_ie - S1G Operation element 130 * @ch_width: S1G Operation Information Channel Width 131 * @oper_class: S1G Operation Information Operating Class 132 * @primary_ch: S1G Operation Information Primary Channel Number 133 * @oper_ch: S1G Operation Information Channel Center Frequency 134 * @basic_mcs_nss: Basic S1G-MCS and NSS Set 135 * 136 * This structure represents the payload of the "S1G Operation 137 * element" as described in IEEE Std 802.11-2020 section 9.4.2.212. 138 */ 139struct ieee80211_s1g_oper_ie { 140 u8 ch_width; 141 u8 oper_class; 142 u8 primary_ch; 143 u8 oper_ch; 144 __le16 basic_mcs_nss; 145} __packed; 146 147/** 148 * struct ieee80211_aid_response_ie - AID Response element 149 * @aid: AID/Group AID 150 * @switch_count: AID Switch Count 151 * @response_int: AID Response Interval 152 * 153 * This structure represents the payload of the "AID Response element" 154 * as described in IEEE Std 802.11-2020 section 9.4.2.194. 155 */ 156struct ieee80211_aid_response_ie { 157 __le16 aid; 158 u8 switch_count; 159 __le16 response_int; 160} __packed; 161 162struct ieee80211_s1g_cap { 163 u8 capab_info[10]; 164 u8 supp_mcs_nss[5]; 165} __packed; 166 167/** 168 * ieee80211_s1g_optional_len - determine length of optional S1G beacon fields 169 * @fc: frame control bytes in little-endian byteorder 170 * Return: total length in bytes of the optional fixed-length fields 171 * 172 * S1G beacons may contain up to three optional fixed-length fields that 173 * precede the variable-length elements. Whether these fields are present 174 * is indicated by flags in the frame control field. 175 * 176 * From IEEE 802.11-2024 section 9.3.4.3: 177 * - Next TBTT field may be 0 or 3 bytes 178 * - Short SSID field may be 0 or 4 bytes 179 * - Access Network Options (ANO) field may be 0 or 1 byte 180 */ 181static inline size_t 182ieee80211_s1g_optional_len(__le16 fc) 183{ 184 size_t len = 0; 185 186 if (ieee80211_s1g_has_next_tbtt(fc)) 187 len += 3; 188 189 if (ieee80211_s1g_has_cssid(fc)) 190 len += 4; 191 192 if (ieee80211_s1g_has_ano(fc)) 193 len += 1; 194 195 return len; 196} 197 198/* S1G Capabilities Information field */ 199#define IEEE80211_S1G_CAPABILITY_LEN 15 200 201#define S1G_CAP0_S1G_LONG BIT(0) 202#define S1G_CAP0_SGI_1MHZ BIT(1) 203#define S1G_CAP0_SGI_2MHZ BIT(2) 204#define S1G_CAP0_SGI_4MHZ BIT(3) 205#define S1G_CAP0_SGI_8MHZ BIT(4) 206#define S1G_CAP0_SGI_16MHZ BIT(5) 207#define S1G_CAP0_SUPP_CH_WIDTH GENMASK(7, 6) 208 209#define S1G_SUPP_CH_WIDTH_2 0 210#define S1G_SUPP_CH_WIDTH_4 1 211#define S1G_SUPP_CH_WIDTH_8 2 212#define S1G_SUPP_CH_WIDTH_16 3 213#define S1G_SUPP_CH_WIDTH_MAX(cap) ((1 << FIELD_GET(S1G_CAP0_SUPP_CH_WIDTH, \ 214 cap[0])) << 1) 215 216#define S1G_CAP1_RX_LDPC BIT(0) 217#define S1G_CAP1_TX_STBC BIT(1) 218#define S1G_CAP1_RX_STBC BIT(2) 219#define S1G_CAP1_SU_BFER BIT(3) 220#define S1G_CAP1_SU_BFEE BIT(4) 221#define S1G_CAP1_BFEE_STS GENMASK(7, 5) 222 223#define S1G_CAP2_SOUNDING_DIMENSIONS GENMASK(2, 0) 224#define S1G_CAP2_MU_BFER BIT(3) 225#define S1G_CAP2_MU_BFEE BIT(4) 226#define S1G_CAP2_PLUS_HTC_VHT BIT(5) 227#define S1G_CAP2_TRAVELING_PILOT GENMASK(7, 6) 228 229#define S1G_CAP3_RD_RESPONDER BIT(0) 230#define S1G_CAP3_HT_DELAYED_BA BIT(1) 231#define S1G_CAP3_MAX_MPDU_LEN BIT(2) 232#define S1G_CAP3_MAX_AMPDU_LEN_EXP GENMASK(4, 3) 233#define S1G_CAP3_MIN_MPDU_START GENMASK(7, 5) 234 235#define S1G_CAP4_UPLINK_SYNC BIT(0) 236#define S1G_CAP4_DYNAMIC_AID BIT(1) 237#define S1G_CAP4_BAT BIT(2) 238#define S1G_CAP4_TIME_ADE BIT(3) 239#define S1G_CAP4_NON_TIM BIT(4) 240#define S1G_CAP4_GROUP_AID BIT(5) 241#define S1G_CAP4_STA_TYPE GENMASK(7, 6) 242 243#define S1G_CAP5_CENT_AUTH_CONTROL BIT(0) 244#define S1G_CAP5_DIST_AUTH_CONTROL BIT(1) 245#define S1G_CAP5_AMSDU BIT(2) 246#define S1G_CAP5_AMPDU BIT(3) 247#define S1G_CAP5_ASYMMETRIC_BA BIT(4) 248#define S1G_CAP5_FLOW_CONTROL BIT(5) 249#define S1G_CAP5_SECTORIZED_BEAM GENMASK(7, 6) 250 251#define S1G_CAP6_OBSS_MITIGATION BIT(0) 252#define S1G_CAP6_FRAGMENT_BA BIT(1) 253#define S1G_CAP6_NDP_PS_POLL BIT(2) 254#define S1G_CAP6_RAW_OPERATION BIT(3) 255#define S1G_CAP6_PAGE_SLICING BIT(4) 256#define S1G_CAP6_TXOP_SHARING_IMP_ACK BIT(5) 257#define S1G_CAP6_VHT_LINK_ADAPT GENMASK(7, 6) 258 259#define S1G_CAP7_TACK_AS_PS_POLL BIT(0) 260#define S1G_CAP7_DUP_1MHZ BIT(1) 261#define S1G_CAP7_MCS_NEGOTIATION BIT(2) 262#define S1G_CAP7_1MHZ_CTL_RESPONSE_PREAMBLE BIT(3) 263#define S1G_CAP7_NDP_BFING_REPORT_POLL BIT(4) 264#define S1G_CAP7_UNSOLICITED_DYN_AID BIT(5) 265#define S1G_CAP7_SECTOR_TRAINING_OPERATION BIT(6) 266#define S1G_CAP7_TEMP_PS_MODE_SWITCH BIT(7) 267 268#define S1G_CAP8_TWT_GROUPING BIT(0) 269#define S1G_CAP8_BDT BIT(1) 270#define S1G_CAP8_COLOR GENMASK(4, 2) 271#define S1G_CAP8_TWT_REQUEST BIT(5) 272#define S1G_CAP8_TWT_RESPOND BIT(6) 273#define S1G_CAP8_PV1_FRAME BIT(7) 274 275#define S1G_CAP9_LINK_ADAPT_PER_CONTROL_RESPONSE BIT(0) 276 277#define S1G_OPER_CH_WIDTH_PRIMARY BIT(0) 278#define S1G_OPER_CH_WIDTH_OPER GENMASK(4, 1) 279#define S1G_OPER_CH_PRIMARY_LOCATION BIT(5) 280 281#define S1G_2M_PRIMARY_LOCATION_LOWER 0 282#define S1G_2M_PRIMARY_LOCATION_UPPER 1 283 284#define LISTEN_INT_USF GENMASK(15, 14) 285#define LISTEN_INT_UI GENMASK(13, 0) 286 287#define IEEE80211_MAX_USF FIELD_MAX(LISTEN_INT_USF) 288#define IEEE80211_MAX_UI FIELD_MAX(LISTEN_INT_UI) 289 290/* S1G encoding types */ 291#define IEEE80211_S1G_TIM_ENC_MODE_BLOCK 0 292#define IEEE80211_S1G_TIM_ENC_MODE_SINGLE 1 293#define IEEE80211_S1G_TIM_ENC_MODE_OLB 2 294 295enum ieee80211_s1g_actioncode { 296 WLAN_S1G_AID_SWITCH_REQUEST, 297 WLAN_S1G_AID_SWITCH_RESPONSE, 298 WLAN_S1G_SYNC_CONTROL, 299 WLAN_S1G_STA_INFO_ANNOUNCE, 300 WLAN_S1G_EDCA_PARAM_SET, 301 WLAN_S1G_EL_OPERATION, 302 WLAN_S1G_TWT_SETUP, 303 WLAN_S1G_TWT_TEARDOWN, 304 WLAN_S1G_SECT_GROUP_ID_LIST, 305 WLAN_S1G_SECT_ID_FEEDBACK, 306 WLAN_S1G_TWT_INFORMATION = 11, 307}; 308 309/** 310 * ieee80211_is_s1g_short_beacon - check if frame is an S1G short beacon 311 * @fc: frame control bytes in little-endian byteorder 312 * @variable: pointer to the beacon frame elements 313 * @variable_len: length of the frame elements 314 * Return: whether or not the frame is an S1G short beacon. As per 315 * IEEE80211-2024 11.1.3.10.1, The S1G beacon compatibility element shall 316 * always be present as the first element in beacon frames generated at a 317 * TBTT (Target Beacon Transmission Time), so any frame not containing 318 * this element must have been generated at a TSBTT (Target Short Beacon 319 * Transmission Time) that is not a TBTT. Additionally, short beacons are 320 * prohibited from containing the S1G beacon compatibility element as per 321 * IEEE80211-2024 9.3.4.3 Table 9-76, so if we have an S1G beacon with 322 * either no elements or the first element is not the beacon compatibility 323 * element, we have a short beacon. 324 */ 325static inline bool ieee80211_is_s1g_short_beacon(__le16 fc, const u8 *variable, 326 size_t variable_len) 327{ 328 if (!ieee80211_is_s1g_beacon(fc)) 329 return false; 330 331 /* 332 * If the frame does not contain at least 1 element (this is perfectly 333 * valid in a short beacon) and is an S1G beacon, we have a short 334 * beacon. 335 */ 336 if (variable_len < 2) 337 return true; 338 339 return variable[0] != WLAN_EID_S1G_BCN_COMPAT; 340} 341 342struct s1g_tim_aid { 343 u16 aid; 344 u8 target_blk; /* Target block index */ 345 u8 target_subblk; /* Target subblock index */ 346 u8 target_subblk_bit; /* Target subblock bit */ 347}; 348 349struct s1g_tim_enc_block { 350 u8 enc_mode; 351 bool inverse; 352 const u8 *ptr; 353 u8 len; 354 355 /* 356 * For an OLB encoded block that spans multiple blocks, this 357 * is the offset into the span described by that encoded block. 358 */ 359 u8 olb_blk_offset; 360}; 361 362/* 363 * Helper routines to quickly extract the length of an encoded block. Validation 364 * is also performed to ensure the length extracted lies within the TIM. 365 */ 366 367static inline int ieee80211_s1g_len_bitmap(const u8 *ptr, const u8 *end) 368{ 369 u8 blkmap; 370 u8 n_subblks; 371 372 if (ptr >= end) 373 return -EINVAL; 374 375 blkmap = *ptr; 376 n_subblks = hweight8(blkmap); 377 378 if (ptr + 1 + n_subblks > end) 379 return -EINVAL; 380 381 return 1 + n_subblks; 382} 383 384static inline int ieee80211_s1g_len_single(const u8 *ptr, const u8 *end) 385{ 386 return (ptr + 1 > end) ? -EINVAL : 1; 387} 388 389static inline int ieee80211_s1g_len_olb(const u8 *ptr, const u8 *end) 390{ 391 if (ptr >= end) 392 return -EINVAL; 393 394 return (ptr + 1 + *ptr > end) ? -EINVAL : 1 + *ptr; 395} 396 397/* 398 * Enumerate all encoded blocks until we find the encoded block that describes 399 * our target AID. OLB is a special case as a single encoded block can describe 400 * multiple blocks as a single encoded block. 401 */ 402static inline int ieee80211_s1g_find_target_block(struct s1g_tim_enc_block *enc, 403 const struct s1g_tim_aid *aid, 404 const u8 *ptr, const u8 *end) 405{ 406 /* need at least block-control octet */ 407 while (ptr + 1 <= end) { 408 u8 ctrl = *ptr++; 409 u8 mode = ctrl & 0x03; 410 bool contains, inverse = ctrl & BIT(2); 411 u8 span, blk_off = ctrl >> 3; 412 int len; 413 414 switch (mode) { 415 case IEEE80211_S1G_TIM_ENC_MODE_BLOCK: 416 len = ieee80211_s1g_len_bitmap(ptr, end); 417 contains = blk_off == aid->target_blk; 418 break; 419 case IEEE80211_S1G_TIM_ENC_MODE_SINGLE: 420 len = ieee80211_s1g_len_single(ptr, end); 421 contains = blk_off == aid->target_blk; 422 break; 423 case IEEE80211_S1G_TIM_ENC_MODE_OLB: 424 len = ieee80211_s1g_len_olb(ptr, end); 425 /* 426 * An OLB encoded block can describe more then one 427 * block, meaning an encoded OLB block can span more 428 * then a single block. 429 */ 430 if (len > 0) { 431 /* Minus one for the length octet */ 432 span = DIV_ROUND_UP(len - 1, 8); 433 /* 434 * Check if our target block lies within the 435 * block span described by this encoded block. 436 */ 437 contains = (aid->target_blk >= blk_off) && 438 (aid->target_blk < blk_off + span); 439 } 440 break; 441 default: 442 return -EOPNOTSUPP; 443 } 444 445 if (len < 0) 446 return len; 447 448 if (contains) { 449 enc->enc_mode = mode; 450 enc->inverse = inverse; 451 enc->ptr = ptr; 452 enc->len = (u8)len; 453 enc->olb_blk_offset = blk_off; 454 return 0; 455 } 456 457 ptr += len; 458 } 459 460 return -ENOENT; 461} 462 463static inline bool ieee80211_s1g_parse_bitmap(struct s1g_tim_enc_block *enc, 464 struct s1g_tim_aid *aid) 465{ 466 const u8 *ptr = enc->ptr; 467 u8 blkmap = *ptr++; 468 469 /* 470 * If our block bitmap does not contain a set bit that corresponds 471 * to our AID, it could mean a variety of things depending on if 472 * the encoding mode is inverted or not. 473 * 474 * 1. If inverted, it means the entire subblock is present and hence 475 * our AID has been set. 476 * 2. If not inverted, it means our subblock is not present and hence 477 * it is all zero meaning our AID is not set. 478 */ 479 if (!(blkmap & BIT(aid->target_subblk))) 480 return enc->inverse; 481 482 /* 483 * Increment ptr by the number of set subblocks that appear before our 484 * target subblock. If our target subblock is 0, do nothing as ptr 485 * already points to our target subblock. 486 */ 487 if (aid->target_subblk) 488 ptr += hweight8(blkmap & GENMASK(aid->target_subblk - 1, 0)); 489 490 return !!(*ptr & BIT(aid->target_subblk_bit)) ^ enc->inverse; 491} 492 493static inline bool ieee80211_s1g_parse_single(struct s1g_tim_enc_block *enc, 494 struct s1g_tim_aid *aid) 495{ 496 /* 497 * Single AID mode describes, as the name suggests, a single AID 498 * within the block described by the encoded block. The octet 499 * contains the 6 LSBs of the AID described in the block. The other 500 * 2 bits are reserved. When inversed, every single AID described 501 * by the current block have buffered traffic except for the AID 502 * described in the single AID octet. 503 */ 504 return ((*enc->ptr & 0x3f) == (aid->aid & 0x3f)) ^ enc->inverse; 505} 506 507static inline bool ieee80211_s1g_parse_olb(struct s1g_tim_enc_block *enc, 508 struct s1g_tim_aid *aid) 509{ 510 const u8 *ptr = enc->ptr; 511 u8 blk_len = *ptr++; 512 /* 513 * Given an OLB encoded block that describes multiple blocks, 514 * calculate the offset into the span. Then calculate the 515 * subblock location normally. 516 */ 517 u16 span_offset = aid->target_blk - enc->olb_blk_offset; 518 u16 subblk_idx = span_offset * 8 + aid->target_subblk; 519 520 if (subblk_idx >= blk_len) 521 return enc->inverse; 522 523 return !!(ptr[subblk_idx] & BIT(aid->target_subblk_bit)) ^ enc->inverse; 524} 525 526/* 527 * An S1G PVB has 3 non optional encoding types, each that can be inverted. 528 * An S1G PVB is constructed with zero or more encoded block subfields. Each 529 * encoded block represents a single "block" of AIDs (64), and each encoded 530 * block can contain one of the 3 encoding types alongside a single bit for 531 * whether the bits should be inverted. 532 * 533 * As the standard makes no guarantee about the ordering of encoded blocks, 534 * we must parse every encoded block in the worst case scenario given an 535 * AID that lies within the last block. 536 */ 537static inline bool ieee80211_s1g_check_tim(const struct ieee80211_tim_ie *tim, 538 u8 tim_len, u16 aid) 539{ 540 int err; 541 struct s1g_tim_aid target_aid; 542 struct s1g_tim_enc_block enc_blk; 543 544 if (tim_len < 3) 545 return false; 546 547 target_aid.aid = aid; 548 target_aid.target_blk = (aid >> 6) & 0x1f; 549 target_aid.target_subblk = (aid >> 3) & 0x7; 550 target_aid.target_subblk_bit = aid & 0x7; 551 552 /* 553 * Find our AIDs target encoded block and fill &enc_blk with the 554 * encoded blocks information. If no entry is found or an error 555 * occurs return false. 556 */ 557 err = ieee80211_s1g_find_target_block(&enc_blk, &target_aid, 558 tim->virtual_map, 559 (const u8 *)tim + tim_len + 2); 560 if (err) 561 return false; 562 563 switch (enc_blk.enc_mode) { 564 case IEEE80211_S1G_TIM_ENC_MODE_BLOCK: 565 return ieee80211_s1g_parse_bitmap(&enc_blk, &target_aid); 566 case IEEE80211_S1G_TIM_ENC_MODE_SINGLE: 567 return ieee80211_s1g_parse_single(&enc_blk, &target_aid); 568 case IEEE80211_S1G_TIM_ENC_MODE_OLB: 569 return ieee80211_s1g_parse_olb(&enc_blk, &target_aid); 570 default: 571 return false; 572 } 573} 574 575#endif /* LINUX_IEEE80211_H */