1b032f27cSSam Leffler /*- 2b032f27cSSam Leffler * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting 3b032f27cSSam Leffler * All rights reserved. 4b032f27cSSam Leffler * 5b032f27cSSam Leffler * Redistribution and use in source and binary forms, with or without 6b032f27cSSam Leffler * modification, are permitted provided that the following conditions 7b032f27cSSam Leffler * are met: 8b032f27cSSam Leffler * 1. Redistributions of source code must retain the above copyright 9b032f27cSSam Leffler * notice, this list of conditions and the following disclaimer. 10b032f27cSSam Leffler * 2. Redistributions in binary form must reproduce the above copyright 11b032f27cSSam Leffler * notice, this list of conditions and the following disclaimer in the 12b032f27cSSam Leffler * documentation and/or other materials provided with the distribution. 13b032f27cSSam Leffler * 14b032f27cSSam Leffler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15b032f27cSSam Leffler * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16b032f27cSSam Leffler * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17b032f27cSSam Leffler * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18b032f27cSSam Leffler * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19b032f27cSSam Leffler * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20b032f27cSSam Leffler * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21b032f27cSSam Leffler * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22b032f27cSSam Leffler * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23b032f27cSSam Leffler * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24b032f27cSSam Leffler */ 25b032f27cSSam Leffler 26b032f27cSSam Leffler #include <sys/cdefs.h> 27b032f27cSSam Leffler __FBSDID("$FreeBSD$"); 28b032f27cSSam Leffler 29b032f27cSSam Leffler /* 30b032f27cSSam Leffler * IEEE 802.11 PHY-related support. 31b032f27cSSam Leffler */ 32b032f27cSSam Leffler 33b032f27cSSam Leffler #include "opt_inet.h" 34b032f27cSSam Leffler 35b032f27cSSam Leffler #include <sys/param.h> 36b032f27cSSam Leffler #include <sys/kernel.h> 37b032f27cSSam Leffler #include <sys/systm.h> 38b032f27cSSam Leffler 39b032f27cSSam Leffler #include <sys/socket.h> 40b032f27cSSam Leffler 41b032f27cSSam Leffler #include <net/if.h> 42b032f27cSSam Leffler #include <net/if_media.h> 43b032f27cSSam Leffler 44b032f27cSSam Leffler #include <net80211/ieee80211_var.h> 45b032f27cSSam Leffler #include <net80211/ieee80211_phy.h> 46b032f27cSSam Leffler 47b032f27cSSam Leffler #ifdef notyet 48b032f27cSSam Leffler struct ieee80211_ds_plcp_hdr { 49b032f27cSSam Leffler uint8_t i_signal; 50b032f27cSSam Leffler uint8_t i_service; 51b032f27cSSam Leffler uint16_t i_length; 52b032f27cSSam Leffler uint16_t i_crc; 53b032f27cSSam Leffler } __packed; 54b032f27cSSam Leffler 55b032f27cSSam Leffler #endif /* notyet */ 56b032f27cSSam Leffler 57b032f27cSSam Leffler /* shorthands to compact tables for readability */ 58b032f27cSSam Leffler #define OFDM IEEE80211_T_OFDM 59b032f27cSSam Leffler #define CCK IEEE80211_T_CCK 60b032f27cSSam Leffler #define TURBO IEEE80211_T_TURBO 6124a07b5bSSam Leffler #define HALF IEEE80211_T_OFDM_HALF 6224a07b5bSSam Leffler #define QUART IEEE80211_T_OFDM_QUARTER 63*f8bf74f2SAdrian Chadd #define HT IEEE80211_T_HT 64*f8bf74f2SAdrian Chadd /* XXX the 11n and the basic rate flag are unfortunately overlapping. Grr. */ 65*f8bf74f2SAdrian Chadd #define N(r) (IEEE80211_RATE_MCS | r) 6624a07b5bSSam Leffler #define PBCC (IEEE80211_T_OFDM_QUARTER+1) /* XXX */ 67*f8bf74f2SAdrian Chadd #define B(r) (IEEE80211_RATE_BASIC | r) 68c9f78f45SSam Leffler #define Mb(x) (x*1000) 69b032f27cSSam Leffler 70b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_11b_table = { 71c9f78f45SSam Leffler .rateCount = 4, /* XXX no PBCC */ 72c9f78f45SSam Leffler .info = { 73b032f27cSSam Leffler /* short ctrl */ 74b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 75c9f78f45SSam Leffler [0] = { .phy = CCK, 1000, 0x00, B(2), 0 },/* 1 Mb */ 76c9f78f45SSam Leffler [1] = { .phy = CCK, 2000, 0x04, B(4), 1 },/* 2 Mb */ 77c9f78f45SSam Leffler [2] = { .phy = CCK, 5500, 0x04, B(11), 1 },/* 5.5 Mb */ 78c9f78f45SSam Leffler [3] = { .phy = CCK, 11000, 0x04, B(22), 1 },/* 11 Mb */ 79c9f78f45SSam Leffler [4] = { .phy = PBCC, 22000, 0x04, 44, 3 } /* 22 Mb */ 80b032f27cSSam Leffler }, 81b032f27cSSam Leffler }; 82b032f27cSSam Leffler 83b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_11g_table = { 84c9f78f45SSam Leffler .rateCount = 12, 85c9f78f45SSam Leffler .info = { 86b032f27cSSam Leffler /* short ctrl */ 87b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 88c9f78f45SSam Leffler [0] = { .phy = CCK, 1000, 0x00, B(2), 0 }, 89c9f78f45SSam Leffler [1] = { .phy = CCK, 2000, 0x04, B(4), 1 }, 90c9f78f45SSam Leffler [2] = { .phy = CCK, 5500, 0x04, B(11), 2 }, 91c9f78f45SSam Leffler [3] = { .phy = CCK, 11000, 0x04, B(22), 3 }, 92c9f78f45SSam Leffler [4] = { .phy = OFDM, 6000, 0x00, 12, 4 }, 93c9f78f45SSam Leffler [5] = { .phy = OFDM, 9000, 0x00, 18, 4 }, 94c9f78f45SSam Leffler [6] = { .phy = OFDM, 12000, 0x00, 24, 6 }, 95c9f78f45SSam Leffler [7] = { .phy = OFDM, 18000, 0x00, 36, 6 }, 96c9f78f45SSam Leffler [8] = { .phy = OFDM, 24000, 0x00, 48, 8 }, 97c9f78f45SSam Leffler [9] = { .phy = OFDM, 36000, 0x00, 72, 8 }, 98c9f78f45SSam Leffler [10] = { .phy = OFDM, 48000, 0x00, 96, 8 }, 99c9f78f45SSam Leffler [11] = { .phy = OFDM, 54000, 0x00, 108, 8 } 100b032f27cSSam Leffler }, 101b032f27cSSam Leffler }; 102b032f27cSSam Leffler 103b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_11a_table = { 104c9f78f45SSam Leffler .rateCount = 8, 105c9f78f45SSam Leffler .info = { 106b032f27cSSam Leffler /* short ctrl */ 107b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 108c9f78f45SSam Leffler [0] = { .phy = OFDM, 6000, 0x00, B(12), 0 }, 109c9f78f45SSam Leffler [1] = { .phy = OFDM, 9000, 0x00, 18, 0 }, 110c9f78f45SSam Leffler [2] = { .phy = OFDM, 12000, 0x00, B(24), 2 }, 111c9f78f45SSam Leffler [3] = { .phy = OFDM, 18000, 0x00, 36, 2 }, 112c9f78f45SSam Leffler [4] = { .phy = OFDM, 24000, 0x00, B(48), 4 }, 113c9f78f45SSam Leffler [5] = { .phy = OFDM, 36000, 0x00, 72, 4 }, 114c9f78f45SSam Leffler [6] = { .phy = OFDM, 48000, 0x00, 96, 4 }, 115c9f78f45SSam Leffler [7] = { .phy = OFDM, 54000, 0x00, 108, 4 } 116b032f27cSSam Leffler }, 117b032f27cSSam Leffler }; 118b032f27cSSam Leffler 119b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_half_table = { 120c9f78f45SSam Leffler .rateCount = 8, 121c9f78f45SSam Leffler .info = { 122b032f27cSSam Leffler /* short ctrl */ 123b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 12424a07b5bSSam Leffler [0] = { .phy = HALF, 3000, 0x00, B(6), 0 }, 12524a07b5bSSam Leffler [1] = { .phy = HALF, 4500, 0x00, 9, 0 }, 12624a07b5bSSam Leffler [2] = { .phy = HALF, 6000, 0x00, B(12), 2 }, 12724a07b5bSSam Leffler [3] = { .phy = HALF, 9000, 0x00, 18, 2 }, 12824a07b5bSSam Leffler [4] = { .phy = HALF, 12000, 0x00, B(24), 4 }, 12924a07b5bSSam Leffler [5] = { .phy = HALF, 18000, 0x00, 36, 4 }, 13024a07b5bSSam Leffler [6] = { .phy = HALF, 24000, 0x00, 48, 4 }, 13124a07b5bSSam Leffler [7] = { .phy = HALF, 27000, 0x00, 54, 4 } 132b032f27cSSam Leffler }, 133b032f27cSSam Leffler }; 134b032f27cSSam Leffler 135b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_quarter_table = { 136c9f78f45SSam Leffler .rateCount = 8, 137c9f78f45SSam Leffler .info = { 138b032f27cSSam Leffler /* short ctrl */ 139b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 14024a07b5bSSam Leffler [0] = { .phy = QUART, 1500, 0x00, B(3), 0 }, 14124a07b5bSSam Leffler [1] = { .phy = QUART, 2250, 0x00, 4, 0 }, 14224a07b5bSSam Leffler [2] = { .phy = QUART, 3000, 0x00, B(9), 2 }, 14324a07b5bSSam Leffler [3] = { .phy = QUART, 4500, 0x00, 9, 2 }, 14424a07b5bSSam Leffler [4] = { .phy = QUART, 6000, 0x00, B(12), 4 }, 14524a07b5bSSam Leffler [5] = { .phy = QUART, 9000, 0x00, 18, 4 }, 14624a07b5bSSam Leffler [6] = { .phy = QUART, 12000, 0x00, 24, 4 }, 14724a07b5bSSam Leffler [7] = { .phy = QUART, 13500, 0x00, 27, 4 } 148b032f27cSSam Leffler }, 149b032f27cSSam Leffler }; 150b032f27cSSam Leffler 151b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_turbog_table = { 152c9f78f45SSam Leffler .rateCount = 7, 153c9f78f45SSam Leffler .info = { 154b032f27cSSam Leffler /* short ctrl */ 155b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 156c9f78f45SSam Leffler [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 }, 157c9f78f45SSam Leffler [1] = { .phy = TURBO, 24000, 0x00, B(24), 1 }, 158c9f78f45SSam Leffler [2] = { .phy = TURBO, 36000, 0x00, 36, 1 }, 159c9f78f45SSam Leffler [3] = { .phy = TURBO, 48000, 0x00, B(48), 3 }, 160c9f78f45SSam Leffler [4] = { .phy = TURBO, 72000, 0x00, 72, 3 }, 161c9f78f45SSam Leffler [5] = { .phy = TURBO, 96000, 0x00, 96, 3 }, 162c9f78f45SSam Leffler [6] = { .phy = TURBO, 108000, 0x00, 108, 3 } 163b032f27cSSam Leffler }, 164b032f27cSSam Leffler }; 165b032f27cSSam Leffler 166b032f27cSSam Leffler static struct ieee80211_rate_table ieee80211_turboa_table = { 167c9f78f45SSam Leffler .rateCount = 8, 168c9f78f45SSam Leffler .info = { 169b032f27cSSam Leffler /* short ctrl */ 170b032f27cSSam Leffler /* Preamble dot11Rate Rate */ 171c9f78f45SSam Leffler [0] = { .phy = TURBO, 12000, 0x00, B(12), 0 }, 172c9f78f45SSam Leffler [1] = { .phy = TURBO, 18000, 0x00, 18, 0 }, 173c9f78f45SSam Leffler [2] = { .phy = TURBO, 24000, 0x00, B(24), 2 }, 174c9f78f45SSam Leffler [3] = { .phy = TURBO, 36000, 0x00, 36, 2 }, 175c9f78f45SSam Leffler [4] = { .phy = TURBO, 48000, 0x00, B(48), 4 }, 176c9f78f45SSam Leffler [5] = { .phy = TURBO, 72000, 0x00, 72, 4 }, 177c9f78f45SSam Leffler [6] = { .phy = TURBO, 96000, 0x00, 96, 4 }, 178c9f78f45SSam Leffler [7] = { .phy = TURBO, 108000, 0x00, 108, 4 } 179b032f27cSSam Leffler }, 180b032f27cSSam Leffler }; 181b032f27cSSam Leffler 182*f8bf74f2SAdrian Chadd static struct ieee80211_rate_table ieee80211_11ng_table = { 183*f8bf74f2SAdrian Chadd .rateCount = 36, 184*f8bf74f2SAdrian Chadd .info = { 185*f8bf74f2SAdrian Chadd /* short ctrl */ 186*f8bf74f2SAdrian Chadd /* Preamble dot11Rate Rate */ 187*f8bf74f2SAdrian Chadd [0] = { .phy = CCK, 1000, 0x00, B(2), 0 }, 188*f8bf74f2SAdrian Chadd [1] = { .phy = CCK, 2000, 0x04, B(4), 1 }, 189*f8bf74f2SAdrian Chadd [2] = { .phy = CCK, 5500, 0x04, B(11), 2 }, 190*f8bf74f2SAdrian Chadd [3] = { .phy = CCK, 11000, 0x04, B(22), 3 }, 191*f8bf74f2SAdrian Chadd [4] = { .phy = OFDM, 6000, 0x00, 12, 4 }, 192*f8bf74f2SAdrian Chadd [5] = { .phy = OFDM, 9000, 0x00, 18, 4 }, 193*f8bf74f2SAdrian Chadd [6] = { .phy = OFDM, 12000, 0x00, 24, 6 }, 194*f8bf74f2SAdrian Chadd [7] = { .phy = OFDM, 18000, 0x00, 36, 6 }, 195*f8bf74f2SAdrian Chadd [8] = { .phy = OFDM, 24000, 0x00, 48, 8 }, 196*f8bf74f2SAdrian Chadd [9] = { .phy = OFDM, 36000, 0x00, 72, 8 }, 197*f8bf74f2SAdrian Chadd [10] = { .phy = OFDM, 48000, 0x00, 96, 8 }, 198*f8bf74f2SAdrian Chadd [11] = { .phy = OFDM, 54000, 0x00, 108, 8 }, 199*f8bf74f2SAdrian Chadd 200*f8bf74f2SAdrian Chadd [12] = { .phy = HT, 6500, 0x00, N(0), 4 }, 201*f8bf74f2SAdrian Chadd [13] = { .phy = HT, 13000, 0x00, N(1), 6 }, 202*f8bf74f2SAdrian Chadd [14] = { .phy = HT, 19500, 0x00, N(2), 6 }, 203*f8bf74f2SAdrian Chadd [15] = { .phy = HT, 26000, 0x00, N(3), 8 }, 204*f8bf74f2SAdrian Chadd [16] = { .phy = HT, 39000, 0x00, N(4), 8 }, 205*f8bf74f2SAdrian Chadd [17] = { .phy = HT, 52000, 0x00, N(5), 8 }, 206*f8bf74f2SAdrian Chadd [18] = { .phy = HT, 58500, 0x00, N(6), 8 }, 207*f8bf74f2SAdrian Chadd [19] = { .phy = HT, 65000, 0x00, N(7), 8 }, 208*f8bf74f2SAdrian Chadd 209*f8bf74f2SAdrian Chadd [20] = { .phy = HT, 13000, 0x00, N(8), 4 }, 210*f8bf74f2SAdrian Chadd [21] = { .phy = HT, 26000, 0x00, N(9), 6 }, 211*f8bf74f2SAdrian Chadd [22] = { .phy = HT, 39000, 0x00, N(10), 6 }, 212*f8bf74f2SAdrian Chadd [23] = { .phy = HT, 52000, 0x00, N(11), 8 }, 213*f8bf74f2SAdrian Chadd [24] = { .phy = HT, 78000, 0x00, N(12), 8 }, 214*f8bf74f2SAdrian Chadd [25] = { .phy = HT, 104000, 0x00, N(13), 8 }, 215*f8bf74f2SAdrian Chadd [26] = { .phy = HT, 117000, 0x00, N(14), 8 }, 216*f8bf74f2SAdrian Chadd [27] = { .phy = HT, 130000, 0x00, N(15), 8 }, 217*f8bf74f2SAdrian Chadd 218*f8bf74f2SAdrian Chadd [28] = { .phy = HT, 19500, 0x00, N(16), 4 }, 219*f8bf74f2SAdrian Chadd [29] = { .phy = HT, 39000, 0x00, N(17), 6 }, 220*f8bf74f2SAdrian Chadd [30] = { .phy = HT, 58500, 0x00, N(18), 6 }, 221*f8bf74f2SAdrian Chadd [31] = { .phy = HT, 78000, 0x00, N(19), 8 }, 222*f8bf74f2SAdrian Chadd [32] = { .phy = HT, 117000, 0x00, N(20), 8 }, 223*f8bf74f2SAdrian Chadd [33] = { .phy = HT, 156000, 0x00, N(21), 8 }, 224*f8bf74f2SAdrian Chadd [34] = { .phy = HT, 175500, 0x00, N(22), 8 }, 225*f8bf74f2SAdrian Chadd [35] = { .phy = HT, 195000, 0x00, N(23), 8 }, 226*f8bf74f2SAdrian Chadd 227*f8bf74f2SAdrian Chadd }, 228*f8bf74f2SAdrian Chadd }; 229*f8bf74f2SAdrian Chadd 230*f8bf74f2SAdrian Chadd static struct ieee80211_rate_table ieee80211_11na_table = { 231*f8bf74f2SAdrian Chadd .rateCount = 32, 232*f8bf74f2SAdrian Chadd .info = { 233*f8bf74f2SAdrian Chadd /* short ctrl */ 234*f8bf74f2SAdrian Chadd /* Preamble dot11Rate Rate */ 235*f8bf74f2SAdrian Chadd [0] = { .phy = OFDM, 6000, 0x00, B(12), 0 }, 236*f8bf74f2SAdrian Chadd [1] = { .phy = OFDM, 9000, 0x00, 18, 0 }, 237*f8bf74f2SAdrian Chadd [2] = { .phy = OFDM, 12000, 0x00, B(24), 2 }, 238*f8bf74f2SAdrian Chadd [3] = { .phy = OFDM, 18000, 0x00, 36, 2 }, 239*f8bf74f2SAdrian Chadd [4] = { .phy = OFDM, 24000, 0x00, B(48), 4 }, 240*f8bf74f2SAdrian Chadd [5] = { .phy = OFDM, 36000, 0x00, 72, 4 }, 241*f8bf74f2SAdrian Chadd [6] = { .phy = OFDM, 48000, 0x00, 96, 4 }, 242*f8bf74f2SAdrian Chadd [7] = { .phy = OFDM, 54000, 0x00, 108, 4 }, 243*f8bf74f2SAdrian Chadd 244*f8bf74f2SAdrian Chadd [8] = { .phy = HT, 6500, 0x00, N(0), 0 }, 245*f8bf74f2SAdrian Chadd [9] = { .phy = HT, 13000, 0x00, N(1), 2 }, 246*f8bf74f2SAdrian Chadd [10] = { .phy = HT, 19500, 0x00, N(2), 2 }, 247*f8bf74f2SAdrian Chadd [11] = { .phy = HT, 26000, 0x00, N(3), 4 }, 248*f8bf74f2SAdrian Chadd [12] = { .phy = HT, 39000, 0x00, N(4), 4 }, 249*f8bf74f2SAdrian Chadd [13] = { .phy = HT, 52000, 0x00, N(5), 4 }, 250*f8bf74f2SAdrian Chadd [14] = { .phy = HT, 58500, 0x00, N(6), 4 }, 251*f8bf74f2SAdrian Chadd [15] = { .phy = HT, 65000, 0x00, N(7), 4 }, 252*f8bf74f2SAdrian Chadd 253*f8bf74f2SAdrian Chadd [16] = { .phy = HT, 13000, 0x00, N(8), 0 }, 254*f8bf74f2SAdrian Chadd [17] = { .phy = HT, 26000, 0x00, N(9), 2 }, 255*f8bf74f2SAdrian Chadd [18] = { .phy = HT, 39000, 0x00, N(10), 2 }, 256*f8bf74f2SAdrian Chadd [19] = { .phy = HT, 52000, 0x00, N(11), 4 }, 257*f8bf74f2SAdrian Chadd [20] = { .phy = HT, 78000, 0x00, N(12), 4 }, 258*f8bf74f2SAdrian Chadd [21] = { .phy = HT, 104000, 0x00, N(13), 4 }, 259*f8bf74f2SAdrian Chadd [22] = { .phy = HT, 117000, 0x00, N(14), 4 }, 260*f8bf74f2SAdrian Chadd [23] = { .phy = HT, 130000, 0x00, N(15), 4 }, 261*f8bf74f2SAdrian Chadd 262*f8bf74f2SAdrian Chadd [24] = { .phy = HT, 19500, 0x00, N(16), 0 }, 263*f8bf74f2SAdrian Chadd [25] = { .phy = HT, 39000, 0x00, N(17), 2 }, 264*f8bf74f2SAdrian Chadd [26] = { .phy = HT, 58500, 0x00, N(18), 2 }, 265*f8bf74f2SAdrian Chadd [27] = { .phy = HT, 78000, 0x00, N(19), 4 }, 266*f8bf74f2SAdrian Chadd [28] = { .phy = HT, 117000, 0x00, N(20), 4 }, 267*f8bf74f2SAdrian Chadd [29] = { .phy = HT, 156000, 0x00, N(21), 4 }, 268*f8bf74f2SAdrian Chadd [30] = { .phy = HT, 175500, 0x00, N(22), 4 }, 269*f8bf74f2SAdrian Chadd [31] = { .phy = HT, 195000, 0x00, N(23), 4 }, 270*f8bf74f2SAdrian Chadd 271*f8bf74f2SAdrian Chadd }, 272*f8bf74f2SAdrian Chadd }; 273*f8bf74f2SAdrian Chadd 274c9f78f45SSam Leffler #undef Mb 275c9f78f45SSam Leffler #undef B 276b032f27cSSam Leffler #undef OFDM 27724a07b5bSSam Leffler #undef HALF 27824a07b5bSSam Leffler #undef QUART 279b032f27cSSam Leffler #undef CCK 280b032f27cSSam Leffler #undef TURBO 281b032f27cSSam Leffler #undef XR 282*f8bf74f2SAdrian Chadd #undef HT 283*f8bf74f2SAdrian Chadd #undef N 284b032f27cSSam Leffler 285b032f27cSSam Leffler /* 286b032f27cSSam Leffler * Setup a rate table's reverse lookup table and fill in 287b032f27cSSam Leffler * ack durations. The reverse lookup tables are assumed 288b032f27cSSam Leffler * to be initialized to zero (or at least the first entry). 289b032f27cSSam Leffler * We use this as a key that indicates whether or not 290b032f27cSSam Leffler * we've previously setup the reverse lookup table. 291b032f27cSSam Leffler * 292b032f27cSSam Leffler * XXX not reentrant, but shouldn't matter 293b032f27cSSam Leffler */ 294b032f27cSSam Leffler static void 295b032f27cSSam Leffler ieee80211_setup_ratetable(struct ieee80211_rate_table *rt) 296b032f27cSSam Leffler { 297b032f27cSSam Leffler #define N(a) (sizeof(a)/sizeof(a[0])) 298b032f27cSSam Leffler #define WLAN_CTRL_FRAME_SIZE \ 299b032f27cSSam Leffler (sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN) 300b032f27cSSam Leffler 301b032f27cSSam Leffler int i; 302b032f27cSSam Leffler 303b032f27cSSam Leffler for (i = 0; i < N(rt->rateCodeToIndex); i++) 304b032f27cSSam Leffler rt->rateCodeToIndex[i] = (uint8_t) -1; 305b032f27cSSam Leffler for (i = 0; i < rt->rateCount; i++) { 306b032f27cSSam Leffler uint8_t code = rt->info[i].dot11Rate; 307b032f27cSSam Leffler uint8_t cix = rt->info[i].ctlRateIndex; 308b032f27cSSam Leffler uint8_t ctl_rate = rt->info[cix].dot11Rate; 309b032f27cSSam Leffler 310b032f27cSSam Leffler /* 311*f8bf74f2SAdrian Chadd * Map without the basic rate bit. 312*f8bf74f2SAdrian Chadd * 313*f8bf74f2SAdrian Chadd * It's up to the caller to ensure that the basic 314*f8bf74f2SAdrian Chadd * rate bit is stripped here. 315*f8bf74f2SAdrian Chadd * 316*f8bf74f2SAdrian Chadd * For HT, use the MCS rate bit. 317b032f27cSSam Leffler */ 318b032f27cSSam Leffler code &= IEEE80211_RATE_VAL; 319*f8bf74f2SAdrian Chadd if (rt->info[i].phy == IEEE80211_T_HT) { 320*f8bf74f2SAdrian Chadd code |= IEEE80211_RATE_MCS; 321b032f27cSSam Leffler } 322b032f27cSSam Leffler 323*f8bf74f2SAdrian Chadd /* XXX assume the control rate is non-MCS? */ 324*f8bf74f2SAdrian Chadd ctl_rate &= IEEE80211_RATE_VAL; 325*f8bf74f2SAdrian Chadd rt->rateCodeToIndex[code] = i; 326*f8bf74f2SAdrian Chadd 327b032f27cSSam Leffler /* 328b032f27cSSam Leffler * XXX for 11g the control rate to use for 5.5 and 11 Mb/s 329b032f27cSSam Leffler * depends on whether they are marked as basic rates; 330b032f27cSSam Leffler * the static tables are setup with an 11b-compatible 331b032f27cSSam Leffler * 2Mb/s rate which will work but is suboptimal 332b032f27cSSam Leffler * 333b032f27cSSam Leffler * NB: Control rate is always less than or equal to the 334b032f27cSSam Leffler * current rate, so control rate's reverse lookup entry 335b032f27cSSam Leffler * has been installed and following call is safe. 336b032f27cSSam Leffler */ 337b032f27cSSam Leffler rt->info[i].lpAckDuration = ieee80211_compute_duration(rt, 338b032f27cSSam Leffler WLAN_CTRL_FRAME_SIZE, ctl_rate, 0); 339b032f27cSSam Leffler rt->info[i].spAckDuration = ieee80211_compute_duration(rt, 340b032f27cSSam Leffler WLAN_CTRL_FRAME_SIZE, ctl_rate, IEEE80211_F_SHPREAMBLE); 341b032f27cSSam Leffler } 342b032f27cSSam Leffler 343b032f27cSSam Leffler #undef WLAN_CTRL_FRAME_SIZE 344b032f27cSSam Leffler #undef N 345b032f27cSSam Leffler } 346b032f27cSSam Leffler 347b032f27cSSam Leffler /* Setup all rate tables */ 348b032f27cSSam Leffler static void 349b032f27cSSam Leffler ieee80211_phy_init(void) 350b032f27cSSam Leffler { 351b032f27cSSam Leffler #define N(arr) (int)(sizeof(arr) / sizeof(arr[0])) 352b032f27cSSam Leffler static struct ieee80211_rate_table * const ratetables[] = { 353b032f27cSSam Leffler &ieee80211_half_table, 354b032f27cSSam Leffler &ieee80211_quarter_table, 355*f8bf74f2SAdrian Chadd &ieee80211_11na_table, 356*f8bf74f2SAdrian Chadd &ieee80211_11ng_table, 357b032f27cSSam Leffler &ieee80211_turbog_table, 358b032f27cSSam Leffler &ieee80211_turboa_table, 359b032f27cSSam Leffler &ieee80211_11a_table, 360b032f27cSSam Leffler &ieee80211_11g_table, 361b032f27cSSam Leffler &ieee80211_11b_table 362b032f27cSSam Leffler }; 363b032f27cSSam Leffler int i; 364b032f27cSSam Leffler 365b032f27cSSam Leffler for (i = 0; i < N(ratetables); ++i) 366b032f27cSSam Leffler ieee80211_setup_ratetable(ratetables[i]); 367b032f27cSSam Leffler 368b032f27cSSam Leffler #undef N 369b032f27cSSam Leffler } 370b032f27cSSam Leffler SYSINIT(wlan_phy, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_phy_init, NULL); 371b032f27cSSam Leffler 372b032f27cSSam Leffler const struct ieee80211_rate_table * 373b032f27cSSam Leffler ieee80211_get_ratetable(struct ieee80211_channel *c) 374b032f27cSSam Leffler { 375b032f27cSSam Leffler const struct ieee80211_rate_table *rt; 376b032f27cSSam Leffler 377b032f27cSSam Leffler /* XXX HT */ 378b032f27cSSam Leffler if (IEEE80211_IS_CHAN_HALF(c)) 379b032f27cSSam Leffler rt = &ieee80211_half_table; 380b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_QUARTER(c)) 381b032f27cSSam Leffler rt = &ieee80211_quarter_table; 382b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_HTA(c)) 383*f8bf74f2SAdrian Chadd rt = &ieee80211_11na_table; 384b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_HTG(c)) 385*f8bf74f2SAdrian Chadd rt = &ieee80211_11ng_table; 386b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_108G(c)) 387b032f27cSSam Leffler rt = &ieee80211_turbog_table; 388b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_ST(c)) 389b032f27cSSam Leffler rt = &ieee80211_turboa_table; 390b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_TURBO(c)) 391b032f27cSSam Leffler rt = &ieee80211_turboa_table; 392b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_A(c)) 393b032f27cSSam Leffler rt = &ieee80211_11a_table; 394b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_ANYG(c)) 395b032f27cSSam Leffler rt = &ieee80211_11g_table; 396b032f27cSSam Leffler else if (IEEE80211_IS_CHAN_B(c)) 397b032f27cSSam Leffler rt = &ieee80211_11b_table; 398b032f27cSSam Leffler else { 399b032f27cSSam Leffler /* NB: should not get here */ 400b032f27cSSam Leffler panic("%s: no rate table for channel; freq %u flags 0x%x\n", 401b032f27cSSam Leffler __func__, c->ic_freq, c->ic_flags); 402b032f27cSSam Leffler } 403b032f27cSSam Leffler return rt; 404b032f27cSSam Leffler } 405b032f27cSSam Leffler 406b032f27cSSam Leffler /* 407b032f27cSSam Leffler * Convert PLCP signal/rate field to 802.11 rate (.5Mbits/s) 408b032f27cSSam Leffler * 409b032f27cSSam Leffler * Note we do no parameter checking; this routine is mainly 410b032f27cSSam Leffler * used to derive an 802.11 rate for constructing radiotap 411b032f27cSSam Leffler * header data for rx frames. 412b032f27cSSam Leffler * 413b032f27cSSam Leffler * XXX might be a candidate for inline 414b032f27cSSam Leffler */ 415b032f27cSSam Leffler uint8_t 4168215d906SSam Leffler ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phytype type) 417b032f27cSSam Leffler { 4188215d906SSam Leffler if (type == IEEE80211_T_OFDM) { 419b032f27cSSam Leffler static const uint8_t ofdm_plcp2rate[16] = { 420b032f27cSSam Leffler [0xb] = 12, 421b032f27cSSam Leffler [0xf] = 18, 422b032f27cSSam Leffler [0xa] = 24, 423b032f27cSSam Leffler [0xe] = 36, 424b032f27cSSam Leffler [0x9] = 48, 425b032f27cSSam Leffler [0xd] = 72, 426b032f27cSSam Leffler [0x8] = 96, 427b032f27cSSam Leffler [0xc] = 108 428b032f27cSSam Leffler }; 429b032f27cSSam Leffler return ofdm_plcp2rate[plcp & 0xf]; 4308215d906SSam Leffler } 4318215d906SSam Leffler if (type == IEEE80211_T_CCK) { 432b032f27cSSam Leffler static const uint8_t cck_plcp2rate[16] = { 433b032f27cSSam Leffler [0xa] = 2, /* 0x0a */ 434b032f27cSSam Leffler [0x4] = 4, /* 0x14 */ 435b032f27cSSam Leffler [0x7] = 11, /* 0x37 */ 436b032f27cSSam Leffler [0xe] = 22, /* 0x6e */ 437b032f27cSSam Leffler [0xc] = 44, /* 0xdc , actually PBCC */ 438b032f27cSSam Leffler }; 439b032f27cSSam Leffler return cck_plcp2rate[plcp & 0xf]; 440b032f27cSSam Leffler } 4418215d906SSam Leffler return 0; 442b032f27cSSam Leffler } 443b032f27cSSam Leffler 444b032f27cSSam Leffler /* 445b032f27cSSam Leffler * Covert 802.11 rate to PLCP signal. 446b032f27cSSam Leffler */ 447b032f27cSSam Leffler uint8_t 4488215d906SSam Leffler ieee80211_rate2plcp(int rate, enum ieee80211_phytype type) 449b032f27cSSam Leffler { 4508215d906SSam Leffler /* XXX ignore type for now since rates are unique */ 451b032f27cSSam Leffler switch (rate) { 452b032f27cSSam Leffler /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ 453b032f27cSSam Leffler case 12: return 0xb; 454b032f27cSSam Leffler case 18: return 0xf; 455b032f27cSSam Leffler case 24: return 0xa; 456b032f27cSSam Leffler case 36: return 0xe; 457b032f27cSSam Leffler case 48: return 0x9; 458b032f27cSSam Leffler case 72: return 0xd; 459b032f27cSSam Leffler case 96: return 0x8; 460b032f27cSSam Leffler case 108: return 0xc; 4618215d906SSam Leffler /* CCK rates (IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3) */ 4628215d906SSam Leffler case 2: return 10; 4638215d906SSam Leffler case 4: return 20; 4648215d906SSam Leffler case 11: return 55; 4658215d906SSam Leffler case 22: return 110; 4668215d906SSam Leffler /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ 4678215d906SSam Leffler case 44: return 220; 468b032f27cSSam Leffler } 4698215d906SSam Leffler return 0; /* XXX unsupported/unknown rate */ 470b032f27cSSam Leffler } 4718215d906SSam Leffler 47224a07b5bSSam Leffler #define CCK_SIFS_TIME 10 47324a07b5bSSam Leffler #define CCK_PREAMBLE_BITS 144 47424a07b5bSSam Leffler #define CCK_PLCP_BITS 48 47524a07b5bSSam Leffler 47624a07b5bSSam Leffler #define OFDM_SIFS_TIME 16 47724a07b5bSSam Leffler #define OFDM_PREAMBLE_TIME 20 47824a07b5bSSam Leffler #define OFDM_PLCP_BITS 22 47924a07b5bSSam Leffler #define OFDM_SYMBOL_TIME 4 48024a07b5bSSam Leffler 48124a07b5bSSam Leffler #define OFDM_HALF_SIFS_TIME 32 48224a07b5bSSam Leffler #define OFDM_HALF_PREAMBLE_TIME 40 48324a07b5bSSam Leffler #define OFDM_HALF_PLCP_BITS 22 48424a07b5bSSam Leffler #define OFDM_HALF_SYMBOL_TIME 8 48524a07b5bSSam Leffler 48624a07b5bSSam Leffler #define OFDM_QUARTER_SIFS_TIME 64 48724a07b5bSSam Leffler #define OFDM_QUARTER_PREAMBLE_TIME 80 48824a07b5bSSam Leffler #define OFDM_QUARTER_PLCP_BITS 22 48924a07b5bSSam Leffler #define OFDM_QUARTER_SYMBOL_TIME 16 49024a07b5bSSam Leffler 49124a07b5bSSam Leffler #define TURBO_SIFS_TIME 8 49224a07b5bSSam Leffler #define TURBO_PREAMBLE_TIME 14 49324a07b5bSSam Leffler #define TURBO_PLCP_BITS 22 49424a07b5bSSam Leffler #define TURBO_SYMBOL_TIME 4 49524a07b5bSSam Leffler 496b032f27cSSam Leffler /* 497b032f27cSSam Leffler * Compute the time to transmit a frame of length frameLen bytes 498b032f27cSSam Leffler * using the specified rate, phy, and short preamble setting. 499b032f27cSSam Leffler * SIFS is included. 500b032f27cSSam Leffler */ 501b032f27cSSam Leffler uint16_t 502b032f27cSSam Leffler ieee80211_compute_duration(const struct ieee80211_rate_table *rt, 503b032f27cSSam Leffler uint32_t frameLen, uint16_t rate, int isShortPreamble) 504b032f27cSSam Leffler { 505b032f27cSSam Leffler uint8_t rix = rt->rateCodeToIndex[rate]; 506b032f27cSSam Leffler uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 507b032f27cSSam Leffler uint32_t kbps; 508b032f27cSSam Leffler 509b032f27cSSam Leffler KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate)); 510b032f27cSSam Leffler kbps = rt->info[rix].rateKbps; 511b032f27cSSam Leffler if (kbps == 0) /* XXX bandaid for channel changes */ 512b032f27cSSam Leffler return 0; 513b032f27cSSam Leffler 514b032f27cSSam Leffler switch (rt->info[rix].phy) { 515b032f27cSSam Leffler case IEEE80211_T_CCK: 516b032f27cSSam Leffler phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 517b032f27cSSam Leffler if (isShortPreamble && rt->info[rix].shortPreamble) 518b032f27cSSam Leffler phyTime >>= 1; 519b032f27cSSam Leffler numBits = frameLen << 3; 520b032f27cSSam Leffler txTime = CCK_SIFS_TIME + phyTime 521b032f27cSSam Leffler + ((numBits * 1000)/kbps); 522b032f27cSSam Leffler break; 523b032f27cSSam Leffler case IEEE80211_T_OFDM: 524b032f27cSSam Leffler bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 525b032f27cSSam Leffler KASSERT(bitsPerSymbol != 0, ("full rate bps")); 526b032f27cSSam Leffler 527b032f27cSSam Leffler numBits = OFDM_PLCP_BITS + (frameLen << 3); 528b032f27cSSam Leffler numSymbols = howmany(numBits, bitsPerSymbol); 529b032f27cSSam Leffler txTime = OFDM_SIFS_TIME 530b032f27cSSam Leffler + OFDM_PREAMBLE_TIME 531b032f27cSSam Leffler + (numSymbols * OFDM_SYMBOL_TIME); 532b032f27cSSam Leffler break; 53324a07b5bSSam Leffler case IEEE80211_T_OFDM_HALF: 53424a07b5bSSam Leffler bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000; 53524a07b5bSSam Leffler KASSERT(bitsPerSymbol != 0, ("1/4 rate bps")); 536b032f27cSSam Leffler 53724a07b5bSSam Leffler numBits = OFDM_PLCP_BITS + (frameLen << 3); 53824a07b5bSSam Leffler numSymbols = howmany(numBits, bitsPerSymbol); 53924a07b5bSSam Leffler txTime = OFDM_HALF_SIFS_TIME 54024a07b5bSSam Leffler + OFDM_HALF_PREAMBLE_TIME 54124a07b5bSSam Leffler + (numSymbols * OFDM_HALF_SYMBOL_TIME); 54224a07b5bSSam Leffler break; 54324a07b5bSSam Leffler case IEEE80211_T_OFDM_QUARTER: 54424a07b5bSSam Leffler bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000; 54524a07b5bSSam Leffler KASSERT(bitsPerSymbol != 0, ("1/2 rate bps")); 546b032f27cSSam Leffler 54724a07b5bSSam Leffler numBits = OFDM_PLCP_BITS + (frameLen << 3); 54824a07b5bSSam Leffler numSymbols = howmany(numBits, bitsPerSymbol); 54924a07b5bSSam Leffler txTime = OFDM_QUARTER_SIFS_TIME 55024a07b5bSSam Leffler + OFDM_QUARTER_PREAMBLE_TIME 55124a07b5bSSam Leffler + (numSymbols * OFDM_QUARTER_SYMBOL_TIME); 55224a07b5bSSam Leffler break; 553b032f27cSSam Leffler case IEEE80211_T_TURBO: 554b032f27cSSam Leffler /* we still save OFDM rates in kbps - so double them */ 555b032f27cSSam Leffler bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000; 556b032f27cSSam Leffler KASSERT(bitsPerSymbol != 0, ("turbo bps")); 557b032f27cSSam Leffler 558b032f27cSSam Leffler numBits = TURBO_PLCP_BITS + (frameLen << 3); 559b032f27cSSam Leffler numSymbols = howmany(numBits, bitsPerSymbol); 560b032f27cSSam Leffler txTime = TURBO_SIFS_TIME + TURBO_PREAMBLE_TIME 561b032f27cSSam Leffler + (numSymbols * TURBO_SYMBOL_TIME); 562b032f27cSSam Leffler break; 563b032f27cSSam Leffler default: 564b032f27cSSam Leffler panic("%s: unknown phy %u (rate %u)\n", __func__, 565b032f27cSSam Leffler rt->info[rix].phy, rate); 566b032f27cSSam Leffler break; 567b032f27cSSam Leffler } 568b032f27cSSam Leffler return txTime; 569b032f27cSSam Leffler } 570*f8bf74f2SAdrian Chadd 571*f8bf74f2SAdrian Chadd static const uint16_t ht20_bps[32] = { 572*f8bf74f2SAdrian Chadd 26, 52, 78, 104, 156, 208, 234, 260, 573*f8bf74f2SAdrian Chadd 52, 104, 156, 208, 312, 416, 468, 520, 574*f8bf74f2SAdrian Chadd 78, 156, 234, 312, 468, 624, 702, 780, 575*f8bf74f2SAdrian Chadd 104, 208, 312, 416, 624, 832, 936, 1040 576*f8bf74f2SAdrian Chadd }; 577*f8bf74f2SAdrian Chadd static const uint16_t ht40_bps[32] = { 578*f8bf74f2SAdrian Chadd 54, 108, 162, 216, 324, 432, 486, 540, 579*f8bf74f2SAdrian Chadd 108, 216, 324, 432, 648, 864, 972, 1080, 580*f8bf74f2SAdrian Chadd 162, 324, 486, 648, 972, 1296, 1458, 1620, 581*f8bf74f2SAdrian Chadd 216, 432, 648, 864, 1296, 1728, 1944, 2160 582*f8bf74f2SAdrian Chadd }; 583*f8bf74f2SAdrian Chadd 584*f8bf74f2SAdrian Chadd 585*f8bf74f2SAdrian Chadd #define OFDM_PLCP_BITS 22 586*f8bf74f2SAdrian Chadd #define HT_L_STF 8 587*f8bf74f2SAdrian Chadd #define HT_L_LTF 8 588*f8bf74f2SAdrian Chadd #define HT_L_SIG 4 589*f8bf74f2SAdrian Chadd #define HT_SIG 8 590*f8bf74f2SAdrian Chadd #define HT_STF 4 591*f8bf74f2SAdrian Chadd #define HT_LTF(n) ((n) * 4) 592*f8bf74f2SAdrian Chadd 593*f8bf74f2SAdrian Chadd #define HT_RC_2_MCS(_rc) ((_rc) & 0xf) 594*f8bf74f2SAdrian Chadd #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 595*f8bf74f2SAdrian Chadd #define IS_HT_RATE(_rc) ( (_rc) & IEEE80211_RATE_MCS) 596*f8bf74f2SAdrian Chadd 597*f8bf74f2SAdrian Chadd /* 598*f8bf74f2SAdrian Chadd * Calculate the transmit duration of an 11n frame. 599*f8bf74f2SAdrian Chadd */ 600*f8bf74f2SAdrian Chadd uint32_t 601*f8bf74f2SAdrian Chadd ieee80211_compute_duration_ht(uint32_t frameLen, uint16_t rate, 602*f8bf74f2SAdrian Chadd int streams, int isht40, int isShortGI) 603*f8bf74f2SAdrian Chadd { 604*f8bf74f2SAdrian Chadd uint32_t bitsPerSymbol, numBits, numSymbols, txTime; 605*f8bf74f2SAdrian Chadd 606*f8bf74f2SAdrian Chadd KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate)); 607*f8bf74f2SAdrian Chadd KASSERT((rate &~ IEEE80211_RATE_MCS) < 31, ("bad mcs 0x%x", rate)); 608*f8bf74f2SAdrian Chadd 609*f8bf74f2SAdrian Chadd if (isht40) 610*f8bf74f2SAdrian Chadd bitsPerSymbol = ht40_bps[rate & 0x1f]; 611*f8bf74f2SAdrian Chadd else 612*f8bf74f2SAdrian Chadd bitsPerSymbol = ht20_bps[rate & 0x1f]; 613*f8bf74f2SAdrian Chadd numBits = OFDM_PLCP_BITS + (frameLen << 3); 614*f8bf74f2SAdrian Chadd numSymbols = howmany(numBits, bitsPerSymbol); 615*f8bf74f2SAdrian Chadd if (isShortGI) 616*f8bf74f2SAdrian Chadd txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */ 617*f8bf74f2SAdrian Chadd else 618*f8bf74f2SAdrian Chadd txTime = numSymbols * 4; /* 4us */ 619*f8bf74f2SAdrian Chadd return txTime + HT_L_STF + HT_L_LTF + 620*f8bf74f2SAdrian Chadd HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams); 621*f8bf74f2SAdrian Chadd } 622*f8bf74f2SAdrian Chadd 623*f8bf74f2SAdrian Chadd #undef IS_HT_RATE 624*f8bf74f2SAdrian Chadd #undef HT_RC_2_STREAMS 625*f8bf74f2SAdrian Chadd #undef HT_RC_2_MCS 626*f8bf74f2SAdrian Chadd #undef HT_LTF 627*f8bf74f2SAdrian Chadd #undef HT_STF 628*f8bf74f2SAdrian Chadd #undef HT_SIG 629*f8bf74f2SAdrian Chadd #undef HT_L_SIG 630*f8bf74f2SAdrian Chadd #undef HT_L_LTF 631*f8bf74f2SAdrian Chadd #undef HT_L_STF 632*f8bf74f2SAdrian Chadd #undef OFDM_PLCP_BITS 633