0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef _BRCM_RATE_H_
0018 #define _BRCM_RATE_H_
0019
0020 #include "types.h"
0021 #include "d11.h"
0022 #include "phy_hal.h"
0023
0024 extern const u8 rate_info[];
0025 extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
0026 extern const struct brcms_c_rateset ofdm_mimo_rates;
0027 extern const struct brcms_c_rateset cck_ofdm_rates;
0028 extern const struct brcms_c_rateset ofdm_rates;
0029 extern const struct brcms_c_rateset cck_rates;
0030 extern const struct brcms_c_rateset gphy_legacy_rates;
0031 extern const struct brcms_c_rateset rate_limit_1_2;
0032
0033 struct brcms_mcs_info {
0034
0035 u32 phy_rate_20;
0036
0037 u32 phy_rate_40;
0038
0039 u32 phy_rate_20_sgi;
0040
0041 u32 phy_rate_40_sgi;
0042
0043 u8 tx_phy_ctl3;
0044
0045 u8 leg_ofdm;
0046 };
0047
0048 #define BRCMS_MAXMCS 32
0049 #define MCS_TABLE_SIZE 33
0050 extern const struct brcms_mcs_info mcs_table[];
0051
0052 #define MCS_TXS_MASK 0xc0
0053 #define MCS_TXS_SHIFT 6
0054
0055
0056 static inline u8 mcs_2_txstreams(u8 mcs)
0057 {
0058 return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
0059 }
0060
0061 static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
0062 {
0063 if (sgi) {
0064 if (is40)
0065 return mcs_table[mcs].phy_rate_40_sgi;
0066 return mcs_table[mcs].phy_rate_20_sgi;
0067 }
0068 if (is40)
0069 return mcs_table[mcs].phy_rate_40;
0070
0071 return mcs_table[mcs].phy_rate_20;
0072 }
0073
0074
0075 #define BRCMS_RATE_MASK_FULL 0xff
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 #define RSPEC_RATE_MASK 0x0000007F
0088
0089 #define RSPEC_MIMORATE 0x08000000
0090
0091 #define RSPEC_BW_MASK 0x00000700
0092
0093 #define RSPEC_BW_SHIFT 8
0094
0095 #define RSPEC_STF_MASK 0x00003800
0096
0097 #define RSPEC_STF_SHIFT 11
0098
0099 #define RSPEC_CT_MASK 0x0000C000
0100
0101 #define RSPEC_CT_SHIFT 14
0102
0103 #define RSPEC_STC_MASK 0x00300000
0104
0105 #define RSPEC_STC_SHIFT 20
0106
0107 #define RSPEC_LDPC_CODING 0x00400000
0108
0109 #define RSPEC_SHORT_GI 0x00800000
0110
0111 #define RSPEC_OVERRIDE 0x80000000
0112
0113 #define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
0114
0115 static inline bool rspec_active(u32 rspec)
0116 {
0117 return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
0118 }
0119
0120 static inline u8 rspec_phytxbyte2(u32 rspec)
0121 {
0122 return (rspec & 0xff00) >> 8;
0123 }
0124
0125 static inline u32 rspec_get_bw(u32 rspec)
0126 {
0127 return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
0128 }
0129
0130 static inline bool rspec_issgi(u32 rspec)
0131 {
0132 return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
0133 }
0134
0135 static inline bool rspec_is40mhz(u32 rspec)
0136 {
0137 u32 bw = rspec_get_bw(rspec);
0138
0139 return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
0140 }
0141
0142 static inline uint rspec2rate(u32 rspec)
0143 {
0144 if (rspec & RSPEC_MIMORATE)
0145 return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
0146 rspec_issgi(rspec));
0147 return rspec & RSPEC_RATE_MASK;
0148 }
0149
0150 static inline u8 rspec_mimoplcp3(u32 rspec)
0151 {
0152 return (rspec & 0xf00000) >> 16;
0153 }
0154
0155 static inline bool plcp3_issgi(u8 plcp)
0156 {
0157 return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
0158 }
0159
0160 static inline uint rspec_stc(u32 rspec)
0161 {
0162 return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
0163 }
0164
0165 static inline uint rspec_stf(u32 rspec)
0166 {
0167 return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
0168 }
0169
0170 static inline bool is_mcs_rate(u32 ratespec)
0171 {
0172 return (ratespec & RSPEC_MIMORATE) != 0;
0173 }
0174
0175 static inline bool is_ofdm_rate(u32 ratespec)
0176 {
0177 return !is_mcs_rate(ratespec) &&
0178 (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
0179 }
0180
0181 static inline bool is_cck_rate(u32 ratespec)
0182 {
0183 u32 rate = (ratespec & BRCMS_RATE_MASK);
0184
0185 return !is_mcs_rate(ratespec) && (
0186 rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
0187 rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
0188 }
0189
0190 static inline bool is_single_stream(u8 mcs)
0191 {
0192 return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
0193 }
0194
0195 static inline u8 cck_rspec(u8 cck)
0196 {
0197 return cck & RSPEC_RATE_MASK;
0198 }
0199
0200
0201
0202 static inline u8 ofdm_phy2mac_rate(u8 rlpt)
0203 {
0204 return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7];
0205 }
0206
0207 static inline u8 cck_phy2mac_rate(u8 signal)
0208 {
0209 return signal/5;
0210 }
0211
0212
0213 #define BRCMS_RATES_CCK_OFDM 0
0214 #define BRCMS_RATES_CCK 1
0215 #define BRCMS_RATES_OFDM 2
0216
0217
0218
0219 bool brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
0220 const struct brcms_c_rateset *hw_rs,
0221 bool check_brate, u8 txstreams);
0222
0223 void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
0224 struct brcms_c_rateset *dst);
0225
0226
0227 u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
0228
0229 void brcms_c_rateset_filter(struct brcms_c_rateset *src,
0230 struct brcms_c_rateset *dst, bool basic_only,
0231 u8 rates, uint xmask, bool mcsallow);
0232
0233 void brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
0234 const struct brcms_c_rateset *rs_hw, uint phy_type,
0235 int bandtype, bool cck_only, uint rate_mask,
0236 bool mcsallow, u8 bw, u8 txstreams);
0237
0238 s16 brcms_c_rate_legacy_phyctl(uint rate);
0239
0240 void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
0241 void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
0242 void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams);
0243 void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw);
0244
0245 #endif