rate.h (7171B)
1/* 2 * Copyright (c) 2010 Broadcom Corporation 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#ifndef _BRCM_RATE_H_ 18#define _BRCM_RATE_H_ 19 20#include "types.h" 21#include "d11.h" 22#include "phy_hal.h" 23 24extern const u8 rate_info[]; 25extern const struct brcms_c_rateset cck_ofdm_mimo_rates; 26extern const struct brcms_c_rateset ofdm_mimo_rates; 27extern const struct brcms_c_rateset cck_ofdm_rates; 28extern const struct brcms_c_rateset ofdm_rates; 29extern const struct brcms_c_rateset cck_rates; 30extern const struct brcms_c_rateset gphy_legacy_rates; 31extern const struct brcms_c_rateset rate_limit_1_2; 32 33struct brcms_mcs_info { 34 /* phy rate in kbps [20Mhz] */ 35 u32 phy_rate_20; 36 /* phy rate in kbps [40Mhz] */ 37 u32 phy_rate_40; 38 /* phy rate in kbps [20Mhz] with SGI */ 39 u32 phy_rate_20_sgi; 40 /* phy rate in kbps [40Mhz] with SGI */ 41 u32 phy_rate_40_sgi; 42 /* phy ctl byte 3, code rate, modulation type, # of streams */ 43 u8 tx_phy_ctl3; 44 /* matching legacy ofdm rate in 500bkps */ 45 u8 leg_ofdm; 46}; 47 48#define BRCMS_MAXMCS 32 /* max valid mcs index */ 49#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ 50extern const struct brcms_mcs_info mcs_table[]; 51 52#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ 53#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ 54 55/* returns num tx streams - 1 */ 56static inline u8 mcs_2_txstreams(u8 mcs) 57{ 58 return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT; 59} 60 61static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi) 62{ 63 if (sgi) { 64 if (is40) 65 return mcs_table[mcs].phy_rate_40_sgi; 66 return mcs_table[mcs].phy_rate_20_sgi; 67 } 68 if (is40) 69 return mcs_table[mcs].phy_rate_40; 70 71 return mcs_table[mcs].phy_rate_20; 72} 73 74/* Macro to use the rate_info table */ 75#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ 76 77/* 78 * rate spec : holds rate and mode specific information required to generate a 79 * tx frame. Legacy CCK and OFDM information is held in the same manner as was 80 * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO 81 * specific information 82 */ 83 84/* rate spec bit fields */ 85 86/* Either 500Kbps units or MIMO MCS idx */ 87#define RSPEC_RATE_MASK 0x0000007F 88/* mimo MCS is stored in RSPEC_RATE_MASK */ 89#define RSPEC_MIMORATE 0x08000000 90/* mimo bw mask */ 91#define RSPEC_BW_MASK 0x00000700 92/* mimo bw shift */ 93#define RSPEC_BW_SHIFT 8 94/* mimo Space/Time/Frequency mode mask */ 95#define RSPEC_STF_MASK 0x00003800 96/* mimo Space/Time/Frequency mode shift */ 97#define RSPEC_STF_SHIFT 11 98/* mimo coding type mask */ 99#define RSPEC_CT_MASK 0x0000C000 100/* mimo coding type shift */ 101#define RSPEC_CT_SHIFT 14 102/* mimo num STC streams per PLCP defn. */ 103#define RSPEC_STC_MASK 0x00300000 104/* mimo num STC streams per PLCP defn. */ 105#define RSPEC_STC_SHIFT 20 106/* mimo bit indicates adv coding in use */ 107#define RSPEC_LDPC_CODING 0x00400000 108/* mimo bit indicates short GI in use */ 109#define RSPEC_SHORT_GI 0x00800000 110/* bit indicates override both rate & mode */ 111#define RSPEC_OVERRIDE 0x80000000 112/* bit indicates override rate only */ 113#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 114 115static inline bool rspec_active(u32 rspec) 116{ 117 return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE); 118} 119 120static inline u8 rspec_phytxbyte2(u32 rspec) 121{ 122 return (rspec & 0xff00) >> 8; 123} 124 125static inline u32 rspec_get_bw(u32 rspec) 126{ 127 return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT; 128} 129 130static inline bool rspec_issgi(u32 rspec) 131{ 132 return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI; 133} 134 135static inline bool rspec_is40mhz(u32 rspec) 136{ 137 u32 bw = rspec_get_bw(rspec); 138 139 return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP; 140} 141 142static inline uint rspec2rate(u32 rspec) 143{ 144 if (rspec & RSPEC_MIMORATE) 145 return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec), 146 rspec_issgi(rspec)); 147 return rspec & RSPEC_RATE_MASK; 148} 149 150static inline u8 rspec_mimoplcp3(u32 rspec) 151{ 152 return (rspec & 0xf00000) >> 16; 153} 154 155static inline bool plcp3_issgi(u8 plcp) 156{ 157 return (plcp & (RSPEC_SHORT_GI >> 16)) != 0; 158} 159 160static inline uint rspec_stc(u32 rspec) 161{ 162 return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT; 163} 164 165static inline uint rspec_stf(u32 rspec) 166{ 167 return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT; 168} 169 170static inline bool is_mcs_rate(u32 ratespec) 171{ 172 return (ratespec & RSPEC_MIMORATE) != 0; 173} 174 175static inline bool is_ofdm_rate(u32 ratespec) 176{ 177 return !is_mcs_rate(ratespec) && 178 (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG); 179} 180 181static inline bool is_cck_rate(u32 ratespec) 182{ 183 u32 rate = (ratespec & BRCMS_RATE_MASK); 184 185 return !is_mcs_rate(ratespec) && ( 186 rate == BRCM_RATE_1M || rate == BRCM_RATE_2M || 187 rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M); 188} 189 190static inline bool is_single_stream(u8 mcs) 191{ 192 return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32; 193} 194 195static inline u8 cck_rspec(u8 cck) 196{ 197 return cck & RSPEC_RATE_MASK; 198} 199 200/* Convert encoded rate value in plcp header to numerical rates in 500 KHz 201 * increments */ 202static inline u8 ofdm_phy2mac_rate(u8 rlpt) 203{ 204 return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7]; 205} 206 207static inline u8 cck_phy2mac_rate(u8 signal) 208{ 209 return signal/5; 210} 211 212/* Rates specified in brcms_c_rateset_filter() */ 213#define BRCMS_RATES_CCK_OFDM 0 214#define BRCMS_RATES_CCK 1 215#define BRCMS_RATES_OFDM 2 216 217/* sanitize, and sort a rateset with the basic bit(s) preserved, validate 218 * rateset */ 219bool brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, 220 const struct brcms_c_rateset *hw_rs, 221 bool check_brate, u8 txstreams); 222/* copy rateset src to dst as-is (no masking or sorting) */ 223void brcms_c_rateset_copy(const struct brcms_c_rateset *src, 224 struct brcms_c_rateset *dst); 225 226/* would be nice to have these documented ... */ 227u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); 228 229void brcms_c_rateset_filter(struct brcms_c_rateset *src, 230 struct brcms_c_rateset *dst, bool basic_only, 231 u8 rates, uint xmask, bool mcsallow); 232 233void brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, 234 const struct brcms_c_rateset *rs_hw, uint phy_type, 235 int bandtype, bool cck_only, uint rate_mask, 236 bool mcsallow, u8 bw, u8 txstreams); 237 238s16 brcms_c_rate_legacy_phyctl(uint rate); 239 240void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); 241void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); 242void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams); 243void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw); 244 245#endif /* _BRCM_RATE_H_ */