1*71bfe67cSkevlo /* $OpenBSD: ieee80211_node.h,v 1.95 2024/11/14 07:49:24 kevlo Exp $ */ 291b2158bSmillert /* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */ 391b2158bSmillert 491b2158bSmillert /*- 591b2158bSmillert * Copyright (c) 2001 Atsushi Onoe 691b2158bSmillert * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 791b2158bSmillert * All rights reserved. 891b2158bSmillert * 991b2158bSmillert * Redistribution and use in source and binary forms, with or without 1091b2158bSmillert * modification, are permitted provided that the following conditions 1191b2158bSmillert * are met: 1291b2158bSmillert * 1. Redistributions of source code must retain the above copyright 1391b2158bSmillert * notice, this list of conditions and the following disclaimer. 1491b2158bSmillert * 2. Redistributions in binary form must reproduce the above copyright 1591b2158bSmillert * notice, this list of conditions and the following disclaimer in the 1691b2158bSmillert * documentation and/or other materials provided with the distribution. 1791b2158bSmillert * 3. The name of the author may not be used to endorse or promote products 1891b2158bSmillert * derived from this software without specific prior written permission. 1991b2158bSmillert * 2091b2158bSmillert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2191b2158bSmillert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2291b2158bSmillert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2391b2158bSmillert * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2491b2158bSmillert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2591b2158bSmillert * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2691b2158bSmillert * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2791b2158bSmillert * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2891b2158bSmillert * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2991b2158bSmillert * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3091b2158bSmillert * 3191b2158bSmillert * $FreeBSD: src/sys/net80211/ieee80211_node.h,v 1.10 2004/04/05 22:10:26 sam Exp $ 3291b2158bSmillert */ 3391b2158bSmillert #ifndef _NET80211_IEEE80211_NODE_H_ 3491b2158bSmillert #define _NET80211_IEEE80211_NODE_H_ 3591b2158bSmillert 369532dee0Smpi #include <sys/tree.h> 379532dee0Smpi 3891b2158bSmillert #define IEEE80211_PSCAN_WAIT 5 /* passive scan wait */ 3991b2158bSmillert #define IEEE80211_TRANS_WAIT 5 /* transition wait */ 4091b2158bSmillert #define IEEE80211_INACT_WAIT 5 /* inactivity timer interval */ 4191b2158bSmillert #define IEEE80211_INACT_MAX (300/IEEE80211_INACT_WAIT) 4224464ca2Sstsp #define IEEE80211_CACHE_SIZE 512 43cfaefb40Sstsp #define IEEE80211_CACHE_WAIT 30 446a173c79Sstsp #define IEEE80211_INACT_SCAN 10 /* for station mode */ 4591b2158bSmillert 4691b2158bSmillert struct ieee80211_rateset { 4791b2158bSmillert u_int8_t rs_nrates; 4891b2158bSmillert u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE]; 4991b2158bSmillert }; 5091b2158bSmillert 51f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11a; 52f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11b; 53f22d9adcSdamien extern const struct ieee80211_rateset ieee80211_std_rateset_11g; 54f2cd5b67Sderaadt 55*71bfe67cSkevlo /* Index into ieee80211_std_ratesets_11n[] array. */ 56b812c027Sstsp #define IEEE80211_HT_RATESET_SISO 0 57b812c027Sstsp #define IEEE80211_HT_RATESET_SISO_SGI 1 58b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO2 2 59b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO2_SGI 3 60b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO3 4 61b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO3_SGI 5 62b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO4 6 63b812c027Sstsp #define IEEE80211_HT_RATESET_MIMO4_SGI 7 64ca785ca0Sstsp #define IEEE80211_HT_RATESET_SISO_40 8 65ca785ca0Sstsp #define IEEE80211_HT_RATESET_SISO_SGI40 9 66ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO2_40 10 67ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO2_SGI40 11 68ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO3_40 12 69ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO3_SGI40 13 70ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO4_40 14 71ca785ca0Sstsp #define IEEE80211_HT_RATESET_MIMO4_SGI40 15 72ca785ca0Sstsp #define IEEE80211_HT_NUM_RATESETS 16 73b812c027Sstsp 74b812c027Sstsp /* Maximum number of rates in a HT rateset. */ 75b812c027Sstsp #define IEEE80211_HT_RATESET_MAX_NRATES 8 76b812c027Sstsp 77b812c027Sstsp /* Number of MCS indices represented by struct ieee80211_ht_rateset. */ 78b812c027Sstsp #define IEEE80211_HT_RATESET_NUM_MCS 32 79b812c027Sstsp 80b812c027Sstsp struct ieee80211_ht_rateset { 81b812c027Sstsp uint32_t nrates; 82b812c027Sstsp uint32_t rates[IEEE80211_HT_RATESET_MAX_NRATES]; /* 500 kbit/s units */ 83b812c027Sstsp 84b812c027Sstsp /* 85b812c027Sstsp * This bitmask can only express MCS 0 - MCS 31. 86b812c027Sstsp * IEEE 802.11 defined 77 HT MCS in total but common hardware 87b812c027Sstsp * implementations tend to support MCS index 0 through 31 only. 88b812c027Sstsp */ 89b812c027Sstsp uint32_t mcs_mask; 90b812c027Sstsp 91b812c027Sstsp /* Range of MCS indices represented in this rateset. */ 92b812c027Sstsp int min_mcs; 93b812c027Sstsp int max_mcs; 94b812c027Sstsp 95ca785ca0Sstsp int chan40; 96b812c027Sstsp int sgi; 97b812c027Sstsp }; 98b812c027Sstsp 99b812c027Sstsp extern const struct ieee80211_ht_rateset ieee80211_std_ratesets_11n[]; 100b812c027Sstsp 101*71bfe67cSkevlo /* Index into ieee80211_std_ratesets_11ac[] array. */ 10250d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO 0 10350d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_SGI 1 10450d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2 2 10550d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_SGI 3 10650d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_40 4 10750d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_40_SGI 5 10850d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_40 6 10950d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_40_SGI 7 11050d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_80 8 11150d1a4aeSstsp #define IEEE80211_VHT_RATESET_SISO_80_SGI 9 11250d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_80 10 11350d1a4aeSstsp #define IEEE80211_VHT_RATESET_MIMO2_80_SGI 11 11450d1a4aeSstsp #define IEEE80211_VHT_NUM_RATESETS 12 11550d1a4aeSstsp 1168a82c5beSstsp /* Maximum number of rates in a VHT rateset. */ 11750d1a4aeSstsp #define IEEE80211_VHT_RATESET_MAX_NRATES 10 11850d1a4aeSstsp 11950d1a4aeSstsp struct ieee80211_vht_rateset { 120*71bfe67cSkevlo int idx; /* This rateset's index in ieee80211_std_ratesets_11ac[]. */ 1218a82c5beSstsp 12250d1a4aeSstsp uint32_t nrates; 12350d1a4aeSstsp uint32_t rates[IEEE80211_VHT_RATESET_MAX_NRATES]; /* 500 kbit/s units */ 12450d1a4aeSstsp 12550d1a4aeSstsp /* Number of spatial streams used by rates in this rateset. */ 12650d1a4aeSstsp int num_ss; 12750d1a4aeSstsp 1288a82c5beSstsp int chan40; 1298a82c5beSstsp int chan80; 13050d1a4aeSstsp int sgi; 13150d1a4aeSstsp }; 13250d1a4aeSstsp 13350d1a4aeSstsp extern const struct ieee80211_vht_rateset ieee80211_std_ratesets_11ac[]; 13450d1a4aeSstsp 1357ad39289Sreyk enum ieee80211_node_state { 1367ad39289Sreyk IEEE80211_STA_CACHE, /* cached node */ 1377ad39289Sreyk IEEE80211_STA_BSS, /* ic->ic_bss, the network we joined */ 1387ad39289Sreyk IEEE80211_STA_AUTH, /* successfully authenticated */ 1397ad39289Sreyk IEEE80211_STA_ASSOC, /* successfully associated */ 1407ad39289Sreyk IEEE80211_STA_COLLECT /* This node remains in the cache while 1417ad39289Sreyk * the driver sends a de-auth message; 1427ad39289Sreyk * afterward it should be freed to make room 1437ad39289Sreyk * for a new node. 1447ad39289Sreyk */ 1457ad39289Sreyk }; 1467ad39289Sreyk 1477ad39289Sreyk #define ieee80211_node_newstate(__ni, __state) \ 1487ad39289Sreyk do { \ 1497ad39289Sreyk (__ni)->ni_state = (__state); \ 1507ad39289Sreyk } while (0) 1517ad39289Sreyk 152361aed72Sdamien enum ieee80211_node_psstate { 153361aed72Sdamien IEEE80211_PS_AWAKE, 154361aed72Sdamien IEEE80211_PS_DOZE 155361aed72Sdamien }; 156361aed72Sdamien 157361aed72Sdamien #define IEEE80211_PS_MAX_QUEUE 50 /* maximum saved packets */ 158361aed72Sdamien 159e03e709cSdamien /* Authenticator state machine: 4-Way Handshake (see 8.5.6.1.1) */ 160aa17e3d5Sdamien enum { 161e03e709cSdamien RSNA_INITIALIZE, 162aa17e3d5Sdamien RSNA_AUTHENTICATION, 163aa17e3d5Sdamien RSNA_AUTHENTICATION_2, 164aa17e3d5Sdamien RSNA_INITPMK, 165aa17e3d5Sdamien RSNA_INITPSK, 166aa17e3d5Sdamien RSNA_PTKSTART, 167aa17e3d5Sdamien RSNA_PTKCALCNEGOTIATING, 168aa17e3d5Sdamien RSNA_PTKCALCNEGOTIATING_2, 169aa17e3d5Sdamien RSNA_PTKINITNEGOTIATING, 170aa17e3d5Sdamien RSNA_PTKINITDONE, 171aa17e3d5Sdamien RSNA_DISCONNECT, 172e03e709cSdamien RSNA_DISCONNECTED 173e03e709cSdamien }; 174e03e709cSdamien 175e03e709cSdamien /* Authenticator state machine: Group Key Handshake (see 8.5.6.1.2) */ 176e03e709cSdamien enum { 177aa17e3d5Sdamien RSNA_IDLE, 178aa17e3d5Sdamien RSNA_REKEYNEGOTIATING, 179aa17e3d5Sdamien RSNA_REKEYESTABLISHED, 180e03e709cSdamien RSNA_KEYERROR 181aa17e3d5Sdamien }; 182aa17e3d5Sdamien 18398998980Sstsp /* Supplicant state machine: 4-Way Handshake (not documented in standard) */ 18498998980Sstsp enum { 18598998980Sstsp RSNA_SUPP_INITIALIZE, /* not expecting any messages */ 18698998980Sstsp RSNA_SUPP_PTKSTART, /* awaiting handshake message 1 */ 18798998980Sstsp RSNA_SUPP_PTKNEGOTIATING, /* got message 1 and derived PTK */ 188fbf3f982Sstsp RSNA_SUPP_PTKDONE /* got message 3 and authenticated AP */ 18998998980Sstsp }; 19098998980Sstsp 19145eec175Sdamien struct ieee80211_rxinfo { 19245eec175Sdamien u_int32_t rxi_flags; 19345eec175Sdamien u_int32_t rxi_tstamp; 19445eec175Sdamien int rxi_rssi; 1957307575aSstsp uint8_t rxi_chan; 19645eec175Sdamien }; 19745eec175Sdamien #define IEEE80211_RXI_HWDEC 0x00000001 19845eec175Sdamien #define IEEE80211_RXI_AMPDU_DONE 0x00000002 199ccc2d1c4Sstsp #define IEEE80211_RXI_HWDEC_SAME_PN 0x00000004 200ccc2d1c4Sstsp #define IEEE80211_RXI_SAME_SEQ 0x00000008 20145eec175Sdamien 20245eec175Sdamien /* Block Acknowledgement Record */ 203ec69e05aSdamien struct ieee80211_tx_ba { 20445eec175Sdamien struct ieee80211_node *ba_ni; /* backpointer for callbacks */ 20545eec175Sdamien struct timeout ba_to; 20645eec175Sdamien int ba_timeout_val; 20745eec175Sdamien int ba_state; 20845eec175Sdamien #define IEEE80211_BA_INIT 0 20945eec175Sdamien #define IEEE80211_BA_REQUESTED 1 21045eec175Sdamien #define IEEE80211_BA_AGREED 2 21145eec175Sdamien 2123367136cSstsp /* ADDBA parameter set field for this BA agreement. */ 2133367136cSstsp u_int16_t ba_params; 2143367136cSstsp 21520fce2ddSstsp /* These values are IEEE802.11 frame sequence numbers (0x0-0xfff) */ 21645eec175Sdamien u_int16_t ba_winstart; 21745eec175Sdamien u_int16_t ba_winend; 21820fce2ddSstsp 21920fce2ddSstsp /* Number of A-MPDU subframes in reorder buffer. */ 22045eec175Sdamien u_int16_t ba_winsize; 22120fce2ddSstsp #define IEEE80211_BA_MAX_WINSZ 64 /* corresponds to maximum ADDBA BUFSZ */ 22245eec175Sdamien 22345eec175Sdamien u_int8_t ba_token; 224aefc44daSstsp 225aefc44daSstsp /* Bitmap for ACK'd frames in the current BA window. */ 226aefc44daSstsp uint64_t ba_bitmap; 22745eec175Sdamien }; 22845eec175Sdamien 229ec69e05aSdamien struct ieee80211_rx_ba { 230ec69e05aSdamien struct ieee80211_node *ba_ni; /* backpointer for callbacks */ 231ec69e05aSdamien struct { 232ec69e05aSdamien struct mbuf *m; 233ec69e05aSdamien struct ieee80211_rxinfo rxi; 234ec69e05aSdamien } *ba_buf; 235ec69e05aSdamien struct timeout ba_to; 236ec69e05aSdamien int ba_timeout_val; 237ec69e05aSdamien int ba_state; 2383367136cSstsp u_int16_t ba_params; 239ec69e05aSdamien u_int16_t ba_winstart; 240ec69e05aSdamien u_int16_t ba_winend; 241ec69e05aSdamien u_int16_t ba_winsize; 242ec69e05aSdamien u_int16_t ba_head; 24320fce2ddSstsp struct timeout ba_gap_to; 244580511faSstsp #define IEEE80211_BA_GAP_TIMEOUT 300 /* msec */ 24520599cf9Sstsp 24620599cf9Sstsp /* 24720599cf9Sstsp * Counter for frames forced to wait in the reordering buffer 24820599cf9Sstsp * due to a leading gap caused by one or more missing frames. 24920599cf9Sstsp */ 25020599cf9Sstsp int ba_gapwait; 25120599cf9Sstsp 2520b126c70Sstsp /* Counter for consecutive frames which missed the BA window. */ 2530b126c70Sstsp int ba_winmiss; 2540b126c70Sstsp /* Sequence number of previous frame which missed the BA window. */ 2550b126c70Sstsp uint16_t ba_missedsn; 2560b126c70Sstsp /* Window moves forward after this many frames have missed it. */ 2570b126c70Sstsp #define IEEE80211_BA_MAX_WINMISS 8 25871c11c14Sstsp 25971c11c14Sstsp uint8_t ba_token; 260ec69e05aSdamien }; 261ec69e05aSdamien 26291b2158bSmillert /* 26391b2158bSmillert * Node specific information. Note that drivers are expected 26491b2158bSmillert * to derive from this structure to add device-specific per-node 26591b2158bSmillert * state. This is done by overriding the ic_node_* methods in 26691b2158bSmillert * the ieee80211com structure. 26791b2158bSmillert */ 26891b2158bSmillert struct ieee80211_node { 2698529d8f0Sdlg RBT_ENTRY(ieee80211_node) ni_node; 2703ce67372Sreyk 271e03e709cSdamien struct ieee80211com *ni_ic; /* back-pointer */ 272e03e709cSdamien 27391b2158bSmillert u_int ni_refcnt; 27491b2158bSmillert u_int ni_scangen; /* gen# for timeout scan */ 27591b2158bSmillert 27691b2158bSmillert /* hardware */ 27791b2158bSmillert u_int32_t ni_rstamp; /* recv timestamp */ 27891b2158bSmillert u_int8_t ni_rssi; /* recv ssi */ 27991b2158bSmillert 2809a4d53fcSdamien /* header */ 2819a4d53fcSdamien u_int8_t ni_macaddr[IEEE80211_ADDR_LEN]; 2829a4d53fcSdamien u_int8_t ni_bssid[IEEE80211_ADDR_LEN]; 2839a4d53fcSdamien 28491b2158bSmillert /* beacon, probe response */ 28591b2158bSmillert u_int8_t ni_tstamp[8]; /* from last rcv'd beacon */ 28691b2158bSmillert u_int16_t ni_intval; /* beacon interval */ 28791b2158bSmillert u_int16_t ni_capinfo; /* capabilities */ 28891b2158bSmillert u_int8_t ni_esslen; 28991b2158bSmillert u_int8_t ni_essid[IEEE80211_NWID_LEN]; 29091b2158bSmillert struct ieee80211_rateset ni_rates; /* negotiated rate set */ 29191b2158bSmillert u_int8_t *ni_country; /* country information XXX */ 29291b2158bSmillert struct ieee80211_channel *ni_chan; 29391b2158bSmillert u_int8_t ni_erp; /* 11g only */ 29491b2158bSmillert 29591b2158bSmillert /* DTIM and contention free period (CFP) */ 296bacd9707Sstsp u_int8_t ni_dtimcount; 29791b2158bSmillert u_int8_t ni_dtimperiod; 298bacd9707Sstsp #ifdef notyet 29991b2158bSmillert u_int8_t ni_cfpperiod; /* # of DTIMs between CFPs */ 30091b2158bSmillert u_int16_t ni_cfpduremain; /* remaining cfp duration */ 30191b2158bSmillert u_int16_t ni_cfpmaxduration;/* max CFP duration in TU */ 30291b2158bSmillert u_int16_t ni_nextdtim; /* time to next DTIM */ 30391b2158bSmillert u_int16_t ni_timoffset; 30491b2158bSmillert #endif 30591b2158bSmillert 30691b2158bSmillert /* power saving mode */ 30791b2158bSmillert u_int8_t ni_pwrsave; 308351e1934Sdlg struct mbuf_queue ni_savedq; /* packets queued for pspoll */ 30991b2158bSmillert 31005534718Sdamien /* RSN */ 31145eec175Sdamien struct timeout ni_eapol_to; 312aa17e3d5Sdamien u_int ni_rsn_state; 31398998980Sstsp u_int ni_rsn_supp_state; 314e03e709cSdamien u_int ni_rsn_gstate; 315e03e709cSdamien u_int ni_rsn_retries; 316b2709672Sstsp u_int ni_supported_rsnprotos; 317e03e709cSdamien u_int ni_rsnprotos; 318b2709672Sstsp u_int ni_supported_rsnakms; 319e03e709cSdamien u_int ni_rsnakms; 320e03e709cSdamien u_int ni_rsnciphers; 321e03e709cSdamien enum ieee80211_cipher ni_rsngroupcipher; 3223dc5ecc7Sdamien enum ieee80211_cipher ni_rsngroupmgmtcipher; 32305534718Sdamien u_int16_t ni_rsncaps; 324e03e709cSdamien enum ieee80211_cipher ni_rsncipher; 325991765deSdamien u_int8_t ni_nonce[EAPOL_KEY_NONCE_LEN]; 326f91ff320Sdamien u_int8_t ni_pmk[IEEE80211_PMK_LEN]; 327f91ff320Sdamien u_int8_t ni_pmkid[IEEE80211_PMKID_LEN]; 328991765deSdamien u_int64_t ni_replaycnt; 329692af90cSdamien u_int8_t ni_replaycnt_ok; 330e03e709cSdamien u_int64_t ni_reqreplaycnt; 331e03e709cSdamien u_int8_t ni_reqreplaycnt_ok; 332991765deSdamien u_int8_t *ni_rsnie; 3335e0cdda0Sdamien struct ieee80211_key ni_pairwise_key; 334991765deSdamien struct ieee80211_ptk ni_ptk; 335991765deSdamien u_int8_t ni_key_count; 336e03e709cSdamien int ni_port_valid; 33705534718Sdamien 33845eec175Sdamien /* SA Query */ 339199d5af3Sdamien u_int16_t ni_sa_query_trid; 34045eec175Sdamien struct timeout ni_sa_query_to; 34145eec175Sdamien int ni_sa_query_count; 34245eec175Sdamien 343fe8f5243Sstsp /* HT capabilities */ 344fe8f5243Sstsp uint16_t ni_htcaps; 345fe8f5243Sstsp uint8_t ni_ampdu_param; 346fe8f5243Sstsp uint8_t ni_rxmcs[howmany(80,NBBY)]; 347fe8f5243Sstsp uint16_t ni_max_rxrate; /* in Mb/s, 0 <= rate <= 1023 */ 348fe8f5243Sstsp uint8_t ni_tx_mcs_set; 349fe8f5243Sstsp uint16_t ni_htxcaps; 350fe8f5243Sstsp uint32_t ni_txbfcaps; 351fe8f5243Sstsp uint8_t ni_aselcaps; 352fe8f5243Sstsp 353fe8f5243Sstsp /* HT operation */ 354fe8f5243Sstsp uint8_t ni_primary_chan; /* XXX corresponds to ni_chan */ 355fe8f5243Sstsp uint8_t ni_htop0; 356fe8f5243Sstsp uint16_t ni_htop1; 357fe8f5243Sstsp uint16_t ni_htop2; 358fe8f5243Sstsp uint8_t ni_basic_mcs[howmany(128,NBBY)]; 359fe8f5243Sstsp 36050e8fe1cSstsp /* VHT capabilities */ 36150e8fe1cSstsp uint32_t ni_vhtcaps; 36250e8fe1cSstsp uint16_t ni_vht_rxmcs; 36350e8fe1cSstsp uint16_t ni_vht_rx_max_lgi_mbit_s; 36450e8fe1cSstsp uint16_t ni_vht_txmcs; 36550e8fe1cSstsp uint16_t ni_vht_tx_max_lgi_mbit_s; 36650e8fe1cSstsp 36750e8fe1cSstsp /* VHT operation */ 36850e8fe1cSstsp uint8_t ni_vht_chan_width; 36950e8fe1cSstsp uint8_t ni_vht_chan_center_freq_idx0; 37050e8fe1cSstsp uint8_t ni_vht_chan_center_freq_idx1; 37150e8fe1cSstsp uint16_t ni_vht_basic_mcs; 37250e8fe1cSstsp 373aefc44daSstsp /* Timeout handlers which trigger Tx Block Ack negotiation. */ 374aefc44daSstsp struct timeout ni_addba_req_to[IEEE80211_NUM_TID]; 375aefc44daSstsp int ni_addba_req_intval[IEEE80211_NUM_TID]; 376aefc44daSstsp #define IEEE80211_ADDBA_REQ_INTVAL_MAX 30 /* in seconds */ 377aefc44daSstsp 378ec69e05aSdamien /* Block Ack records */ 379ec69e05aSdamien struct ieee80211_tx_ba ni_tx_ba[IEEE80211_NUM_TID]; 380ec69e05aSdamien struct ieee80211_rx_ba ni_rx_ba[IEEE80211_NUM_TID]; 3814c97d237Sstsp 3824c97d237Sstsp int ni_txmcs; /* current MCS used for TX */ 38350d1a4aeSstsp int ni_vht_ss; /* VHT # spatial streams */ 38445eec175Sdamien 38591b2158bSmillert /* others */ 38691b2158bSmillert u_int16_t ni_associd; /* assoc response */ 38791b2158bSmillert u_int16_t ni_txseq; /* seq to be transmitted */ 38891b2158bSmillert u_int16_t ni_rxseq; /* seq previous received */ 38932e88c03Sdamien u_int16_t ni_qos_txseqs[IEEE80211_NUM_TID]; 39032e88c03Sdamien u_int16_t ni_qos_rxseqs[IEEE80211_NUM_TID]; 39191b2158bSmillert int ni_fails; /* failure count to associate */ 392799b58a5Sstsp uint32_t ni_assoc_fail; /* assoc failure reasons */ 393799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_CHAN 0x01 394799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_IBSS 0x02 395799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_PRIVACY 0x04 396799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_BASIC_RATE 0x08 397799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_ESSID 0x10 398799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_BSSID 0x20 399799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_WPA_PROTO 0x40 400799b58a5Sstsp #define IEEE80211_NODE_ASSOCFAIL_WPA_KEY 0x80 401799b58a5Sstsp 40291b2158bSmillert int ni_inact; /* inactivity mark count */ 40391b2158bSmillert int ni_txrate; /* index to ni_rates[] */ 4047ad39289Sreyk int ni_state; 40505534718Sdamien 40650d1a4aeSstsp u_int32_t ni_flags; /* special-purpose state */ 407f91ff320Sdamien #define IEEE80211_NODE_ERP 0x0001 408f91ff320Sdamien #define IEEE80211_NODE_QOS 0x0002 409f91ff320Sdamien #define IEEE80211_NODE_REKEY 0x0004 /* GTK rekeying in progress */ 410f91ff320Sdamien #define IEEE80211_NODE_RXPROT 0x0008 /* RX protection ON */ 411f91ff320Sdamien #define IEEE80211_NODE_TXPROT 0x0010 /* TX protection ON */ 41201ad6d9fSdamien #define IEEE80211_NODE_TXRXPROT \ 41301ad6d9fSdamien (IEEE80211_NODE_TXPROT | IEEE80211_NODE_RXPROT) 414f91ff320Sdamien #define IEEE80211_NODE_RXMGMTPROT 0x0020 /* RX MMPDU protection ON */ 415f91ff320Sdamien #define IEEE80211_NODE_TXMGMTPROT 0x0040 /* TX MMPDU protection ON */ 416f91ff320Sdamien #define IEEE80211_NODE_MFP 0x0080 /* MFP negotiated */ 417f91ff320Sdamien #define IEEE80211_NODE_PMK 0x0100 /* ni_pmk set */ 418f91ff320Sdamien #define IEEE80211_NODE_PMKID 0x0200 /* ni_pmkid set */ 41945eec175Sdamien #define IEEE80211_NODE_HT 0x0400 /* HT negotiated */ 42045eec175Sdamien #define IEEE80211_NODE_SA_QUERY 0x0800 /* SA Query in progress */ 42145eec175Sdamien #define IEEE80211_NODE_SA_QUERY_FAILED 0x1000 /* last SA Query failed */ 4222e40dd69Sstsp #define IEEE80211_NODE_RSN_NEW_PTK 0x2000 /* expecting a new PTK */ 423b812c027Sstsp #define IEEE80211_NODE_HT_SGI20 0x4000 /* SGI on 20 MHz negotiated */ 424b812c027Sstsp #define IEEE80211_NODE_HT_SGI40 0x8000 /* SGI on 40 MHz negotiated */ 42550d1a4aeSstsp #define IEEE80211_NODE_VHT 0x10000 /* VHT negotiated */ 4261c062f30Sstsp #define IEEE80211_NODE_HTCAP 0x20000 /* claims to support HT */ 42750e8fe1cSstsp #define IEEE80211_NODE_VHTCAP 0x40000 /* claims to support VHT */ 42850e8fe1cSstsp #define IEEE80211_NODE_VHT_SGI80 0x80000 /* SGI on 80 MHz negotiated */ 42950e8fe1cSstsp #define IEEE80211_NODE_VHT_SGI160 0x100000 /* SGI on 160 MHz negotiated */ 43006e069b5Sstsp 43106e069b5Sstsp /* If not NULL, this function gets called when ni_refcnt hits zero. */ 43206e069b5Sstsp void (*ni_unref_cb)(struct ieee80211com *, 43306e069b5Sstsp struct ieee80211_node *); 43406e069b5Sstsp void * ni_unref_arg; 43506e069b5Sstsp size_t ni_unref_arg_size; 43691b2158bSmillert }; 43791b2158bSmillert 4388529d8f0Sdlg RBT_HEAD(ieee80211_tree, ieee80211_node); 4393ce67372Sreyk 440020402a2Sphessler struct ieee80211_ess_rbt { 441020402a2Sphessler RBT_ENTRY(ieee80211_ess_rbt) ess_rbt; 442020402a2Sphessler u_int8_t esslen; 443020402a2Sphessler u_int8_t essid[IEEE80211_NWID_LEN]; 444020402a2Sphessler struct ieee80211_node *ni2; 445020402a2Sphessler struct ieee80211_node *ni5; 446020402a2Sphessler struct ieee80211_node *ni; 447020402a2Sphessler }; 448020402a2Sphessler 449020402a2Sphessler RBT_HEAD(ieee80211_ess_tree, ieee80211_ess_rbt); 450020402a2Sphessler 4512edbedcfSphessler static inline void 45226b1026eSstsp ieee80211_node_incref(struct ieee80211_node *ni) 45326b1026eSstsp { 45426b1026eSstsp int s; 45591b2158bSmillert 45626b1026eSstsp s = splnet(); 45726b1026eSstsp ni->ni_refcnt++; 45826b1026eSstsp splx(s); 45926b1026eSstsp } 46026b1026eSstsp 4612edbedcfSphessler static inline u_int 46291b2158bSmillert ieee80211_node_decref(struct ieee80211_node *ni) 46391b2158bSmillert { 46426b1026eSstsp u_int refcnt; 46526b1026eSstsp int s; 46626b1026eSstsp 46791b2158bSmillert s = splnet(); 46891b2158bSmillert refcnt = --ni->ni_refcnt; 46991b2158bSmillert splx(s); 47091b2158bSmillert return refcnt; 47191b2158bSmillert } 47291b2158bSmillert 4732edbedcfSphessler static inline struct ieee80211_node * 47491b2158bSmillert ieee80211_ref_node(struct ieee80211_node *ni) 47591b2158bSmillert { 47691b2158bSmillert ieee80211_node_incref(ni); 47791b2158bSmillert return ni; 47891b2158bSmillert } 47991b2158bSmillert 4802edbedcfSphessler static inline void 48191b2158bSmillert ieee80211_unref_node(struct ieee80211_node **ni) 48291b2158bSmillert { 48391b2158bSmillert ieee80211_node_decref(*ni); 48491b2158bSmillert *ni = NULL; /* guard against use */ 48591b2158bSmillert } 48691b2158bSmillert 48708e4cc2bSphessler /* 48808e4cc2bSphessler * Check if the peer supports HT. 4891c062f30Sstsp * Require a HT capabilities IE and at least one of the mandatory MCS. 49008e4cc2bSphessler * MCS 0-7 are mandatory but some APs have particular MCS disabled. 49108e4cc2bSphessler */ 49208e4cc2bSphessler static inline int 49308e4cc2bSphessler ieee80211_node_supports_ht(struct ieee80211_node *ni) 49408e4cc2bSphessler { 4951c062f30Sstsp return ((ni->ni_flags & IEEE80211_NODE_HTCAP) && 4961c062f30Sstsp ni->ni_rxmcs[0] & 0xff); 49708e4cc2bSphessler } 49808e4cc2bSphessler 499b812c027Sstsp /* Check if the peer supports HT short guard interval (SGI) on 20 MHz. */ 500b812c027Sstsp static inline int 501b812c027Sstsp ieee80211_node_supports_ht_sgi20(struct ieee80211_node *ni) 502b812c027Sstsp { 503b812c027Sstsp return ieee80211_node_supports_ht(ni) && 504b812c027Sstsp (ni->ni_htcaps & IEEE80211_HTCAP_SGI20); 505b812c027Sstsp } 506b812c027Sstsp 507b812c027Sstsp /* Check if the peer supports HT short guard interval (SGI) on 40 MHz. */ 508b812c027Sstsp static inline int 509b812c027Sstsp ieee80211_node_supports_ht_sgi40(struct ieee80211_node *ni) 510b812c027Sstsp { 511b812c027Sstsp return ieee80211_node_supports_ht(ni) && 512b812c027Sstsp (ni->ni_htcaps & IEEE80211_HTCAP_SGI40); 513b812c027Sstsp } 514b812c027Sstsp 515ca785ca0Sstsp /* Check if the peer can receive frames sent on a 40 MHz channel. */ 516ca785ca0Sstsp static inline int 517ca785ca0Sstsp ieee80211_node_supports_ht_chan40(struct ieee80211_node *ni) 518ca785ca0Sstsp { 519ca785ca0Sstsp return (ieee80211_node_supports_ht(ni) && 520ca785ca0Sstsp (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) && 521ca785ca0Sstsp (ni->ni_htop0 & IEEE80211_HTOP0_CHW)); 522ca785ca0Sstsp } 523ca785ca0Sstsp 52450e8fe1cSstsp /* 52550e8fe1cSstsp * Check if the peer supports VHT. 52650e8fe1cSstsp * Require a VHT capabilities IE and support for VHT MCS with a single 52750e8fe1cSstsp * spatial stream. 52850e8fe1cSstsp */ 52950e8fe1cSstsp static inline int 53050e8fe1cSstsp ieee80211_node_supports_vht(struct ieee80211_node *ni) 53150e8fe1cSstsp { 53250e8fe1cSstsp uint16_t rx_mcs; 53350e8fe1cSstsp 53450e8fe1cSstsp rx_mcs = (ni->ni_vht_rxmcs & IEEE80211_VHT_MCS_FOR_SS_MASK(1)) >> 53550e8fe1cSstsp IEEE80211_VHT_MCS_FOR_SS_SHIFT(1); 53650e8fe1cSstsp 53750e8fe1cSstsp return ((ni->ni_flags & IEEE80211_NODE_VHTCAP) && 53850e8fe1cSstsp rx_mcs != IEEE80211_VHT_MCS_SS_NOT_SUPP); 53950e8fe1cSstsp } 54050e8fe1cSstsp 54150e8fe1cSstsp /* Check if the peer supports VHT short guard interval (SGI) on 80 MHz. */ 54250e8fe1cSstsp static inline int 54350e8fe1cSstsp ieee80211_node_supports_vht_sgi80(struct ieee80211_node *ni) 54450e8fe1cSstsp { 54550e8fe1cSstsp return ieee80211_node_supports_vht(ni) && 54650e8fe1cSstsp (ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI80); 54750e8fe1cSstsp } 54850e8fe1cSstsp 54950e8fe1cSstsp /* Check if the peer supports VHT short guard interval (SGI) on 160 MHz. */ 55050e8fe1cSstsp static inline int 55150e8fe1cSstsp ieee80211_node_supports_vht_sgi160(struct ieee80211_node *ni) 55250e8fe1cSstsp { 55350e8fe1cSstsp return ieee80211_node_supports_vht(ni) && 55450e8fe1cSstsp (ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI160); 55550e8fe1cSstsp } 55650e8fe1cSstsp 55750e8fe1cSstsp /* Check if the peer can receive frames sent on an 80 MHz channel. */ 55850e8fe1cSstsp static inline int 55950e8fe1cSstsp ieee80211_node_supports_vht_chan80(struct ieee80211_node *ni) 56050e8fe1cSstsp { 56150e8fe1cSstsp uint8_t cap_chan_width, op_chan_width; 56250e8fe1cSstsp 56350e8fe1cSstsp if (!ieee80211_node_supports_vht(ni)) 56450e8fe1cSstsp return 0; 56550e8fe1cSstsp 56650e8fe1cSstsp cap_chan_width = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >> 56750e8fe1cSstsp IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT; 56850e8fe1cSstsp if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_80 && 56950e8fe1cSstsp cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160 && 57050e8fe1cSstsp cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160_8080) 57150e8fe1cSstsp return 0; 57250e8fe1cSstsp 57350e8fe1cSstsp op_chan_width = (ni->ni_vht_chan_width & 57450e8fe1cSstsp IEEE80211_VHTOP0_CHAN_WIDTH_MASK) >> 57550e8fe1cSstsp IEEE80211_VHTOP0_CHAN_WIDTH_SHIFT; 57650e8fe1cSstsp 57750e8fe1cSstsp return (op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_80 || 57850e8fe1cSstsp op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_160 || 57950e8fe1cSstsp op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_8080); 58050e8fe1cSstsp } 58150e8fe1cSstsp 5828a82c5beSstsp /* Check if the peer can receive frames sent on a 160 MHz channel. */ 5838a82c5beSstsp static inline int 5848a82c5beSstsp ieee80211_node_supports_vht_chan160(struct ieee80211_node *ni) 5858a82c5beSstsp { 5868a82c5beSstsp uint8_t cap_chan_width, op_chan_width; 5878a82c5beSstsp 5888a82c5beSstsp if (!ieee80211_node_supports_vht(ni)) 5898a82c5beSstsp return 0; 5908a82c5beSstsp 5918a82c5beSstsp cap_chan_width = (ni->ni_vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) >> 5928a82c5beSstsp IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT; 5938a82c5beSstsp if (cap_chan_width != IEEE80211_VHTCAP_CHAN_WIDTH_160) 5948a82c5beSstsp return 0; 5958a82c5beSstsp 5968a82c5beSstsp op_chan_width = (ni->ni_vht_chan_width & 5978a82c5beSstsp IEEE80211_VHTOP0_CHAN_WIDTH_MASK) >> 5988a82c5beSstsp IEEE80211_VHTOP0_CHAN_WIDTH_SHIFT; 5998a82c5beSstsp 6008a82c5beSstsp return (op_chan_width == IEEE80211_VHTOP0_CHAN_WIDTH_160); 6018a82c5beSstsp } 6028a82c5beSstsp 60391b2158bSmillert struct ieee80211com; 60491b2158bSmillert 60571ca7184Sphessler typedef void ieee80211_iter_func(void *, struct ieee80211_node *); 60691b2158bSmillert 60771ca7184Sphessler void ieee80211_node_attach(struct ifnet *); 60871ca7184Sphessler void ieee80211_node_lateattach(struct ifnet *); 60971ca7184Sphessler void ieee80211_node_detach(struct ifnet *); 61091b2158bSmillert 61171ca7184Sphessler void ieee80211_begin_scan(struct ifnet *); 61271ca7184Sphessler void ieee80211_next_scan(struct ifnet *); 61371ca7184Sphessler void ieee80211_end_scan(struct ifnet *); 61471ca7184Sphessler void ieee80211_reset_scan(struct ifnet *); 61571ca7184Sphessler struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *, 616f22d9adcSdamien const u_int8_t *); 61771ca7184Sphessler struct ieee80211_node *ieee80211_dup_bss(struct ieee80211com *, 618f22d9adcSdamien const u_int8_t *); 61971ca7184Sphessler struct ieee80211_node *ieee80211_find_node(struct ieee80211com *, 620f22d9adcSdamien const u_int8_t *); 621de9c1173Sstsp void ieee80211_node_tx_ba_clear(struct ieee80211_node *, int); 622aefc44daSstsp void ieee80211_ba_del(struct ieee80211_node *); 62371ca7184Sphessler struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *, 624f22d9adcSdamien const struct ieee80211_frame *); 62571ca7184Sphessler struct ieee80211_node *ieee80211_find_txnode(struct ieee80211com *, 626f22d9adcSdamien const u_int8_t *); 62771ca7184Sphessler void ieee80211_release_node(struct ieee80211com *, 62891b2158bSmillert struct ieee80211_node *); 6296a173c79Sstsp void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node *); 630d466420eSstsp void ieee80211_free_allnodes(struct ieee80211com *, int); 63171ca7184Sphessler void ieee80211_iterate_nodes(struct ieee80211com *, 63291b2158bSmillert ieee80211_iter_func *, void *); 63371ca7184Sphessler void ieee80211_clean_cached(struct ieee80211com *); 63471ca7184Sphessler void ieee80211_clean_nodes(struct ieee80211com *, int); 635fe8f5243Sstsp void ieee80211_setup_htcaps(struct ieee80211_node *, const uint8_t *, 636fe8f5243Sstsp uint8_t); 6372040b0e1Sstsp void ieee80211_clear_htcaps(struct ieee80211_node *); 6387a831903Sstsp int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *, 639f9214ef6Sstsp uint8_t, int); 64050e8fe1cSstsp void ieee80211_setup_vhtcaps(struct ieee80211_node *, const uint8_t *, 64150e8fe1cSstsp uint8_t); 64250e8fe1cSstsp void ieee80211_clear_vhtcaps(struct ieee80211_node *); 64350e8fe1cSstsp int ieee80211_setup_vhtop(struct ieee80211_node *, const uint8_t *, 64450e8fe1cSstsp uint8_t, int); 64571ca7184Sphessler int ieee80211_setup_rates(struct ieee80211com *, 6466de17962Sdamien struct ieee80211_node *, const u_int8_t *, const u_int8_t *, int); 647aefc44daSstsp void ieee80211_node_trigger_addba_req(struct ieee80211_node *, int); 64871ca7184Sphessler int ieee80211_iserp_sta(const struct ieee80211_node *); 64971ca7184Sphessler void ieee80211_count_longslotsta(void *, struct ieee80211_node *); 65071ca7184Sphessler void ieee80211_count_nonerpsta(void *, struct ieee80211_node *); 65171ca7184Sphessler void ieee80211_count_pssta(void *, struct ieee80211_node *); 65271ca7184Sphessler void ieee80211_count_rekeysta(void *, struct ieee80211_node *); 65371ca7184Sphessler void ieee80211_node_join(struct ieee80211com *, 6540fd4e251Sreyk struct ieee80211_node *, int); 65571ca7184Sphessler void ieee80211_node_leave(struct ieee80211com *, 6560fd4e251Sreyk struct ieee80211_node *); 657799b58a5Sstsp int ieee80211_match_bss(struct ieee80211com *, struct ieee80211_node *, int); 658de9c1173Sstsp void ieee80211_node_tx_stopped(struct ieee80211com *, struct ieee80211_node *); 65940dc231eSstsp struct ieee80211_node *ieee80211_node_choose_bss(struct ieee80211com *, int, 66040dc231eSstsp struct ieee80211_node **); 66140dc231eSstsp void ieee80211_node_join_bss(struct ieee80211com *, struct ieee80211_node *); 66271ca7184Sphessler void ieee80211_create_ibss(struct ieee80211com* , 66391b2158bSmillert struct ieee80211_channel *); 66471ca7184Sphessler void ieee80211_notify_dtim(struct ieee80211com *); 66571ca7184Sphessler void ieee80211_set_tim(struct ieee80211com *, int, int); 66626bb14d9Sphessler void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *); 6673ce67372Sreyk 66871ca7184Sphessler int ieee80211_node_cmp(const struct ieee80211_node *, 669f22d9adcSdamien const struct ieee80211_node *); 670020402a2Sphessler int ieee80211_ess_cmp(const struct ieee80211_ess_rbt *, 671020402a2Sphessler const struct ieee80211_ess_rbt *); 6728529d8f0Sdlg RBT_PROTOTYPE(ieee80211_tree, ieee80211_node, ni_node, ieee80211_node_cmp); 673020402a2Sphessler RBT_PROTOTYPE(ieee80211_ess_tree, ieee80211_ess_rbt, ess_rbt, ieee80211_ess_cmp); 6743ce67372Sreyk 67591b2158bSmillert #endif /* _NET80211_IEEE80211_NODE_H_ */ 676