Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2010 Broadcom Corporation
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0011  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
0013  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
0014  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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     /* phy rate in kbps [20Mhz] */
0035     u32 phy_rate_20;
0036     /* phy rate in kbps [40Mhz] */
0037     u32 phy_rate_40;
0038     /* phy rate in kbps [20Mhz] with SGI */
0039     u32 phy_rate_20_sgi;
0040     /* phy rate in kbps [40Mhz] with SGI */
0041     u32 phy_rate_40_sgi;
0042     /* phy ctl byte 3, code rate, modulation type, # of streams */
0043     u8 tx_phy_ctl3;
0044     /* matching legacy ofdm rate in 500bkps */
0045     u8 leg_ofdm;
0046 };
0047 
0048 #define BRCMS_MAXMCS    32  /* max valid mcs index */
0049 #define MCS_TABLE_SIZE  33  /* Number of mcs entries in the table */
0050 extern const struct brcms_mcs_info mcs_table[];
0051 
0052 #define MCS_TXS_MASK    0xc0    /* num tx streams - 1 bit mask */
0053 #define MCS_TXS_SHIFT   6   /* num tx streams - 1 bit shift */
0054 
0055 /* returns num tx streams - 1 */
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 /* Macro to use the rate_info table */
0075 #define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
0076 
0077 /*
0078  * rate spec : holds rate and mode specific information required to generate a
0079  * tx frame. Legacy CCK and OFDM information is held in the same manner as was
0080  * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
0081  * specific information
0082  */
0083 
0084 /* rate spec bit fields */
0085 
0086 /* Either 500Kbps units or MIMO MCS idx */
0087 #define RSPEC_RATE_MASK     0x0000007F
0088 /* mimo MCS is stored in RSPEC_RATE_MASK */
0089 #define RSPEC_MIMORATE      0x08000000
0090 /* mimo bw mask */
0091 #define RSPEC_BW_MASK       0x00000700
0092 /* mimo bw shift */
0093 #define RSPEC_BW_SHIFT      8
0094 /* mimo Space/Time/Frequency mode mask */
0095 #define RSPEC_STF_MASK      0x00003800
0096 /* mimo Space/Time/Frequency mode shift */
0097 #define RSPEC_STF_SHIFT     11
0098 /* mimo coding type mask */
0099 #define RSPEC_CT_MASK       0x0000C000
0100 /* mimo coding type shift */
0101 #define RSPEC_CT_SHIFT      14
0102 /* mimo num STC streams per PLCP defn. */
0103 #define RSPEC_STC_MASK      0x00300000
0104 /* mimo num STC streams per PLCP defn. */
0105 #define RSPEC_STC_SHIFT     20
0106 /* mimo bit indicates adv coding in use */
0107 #define RSPEC_LDPC_CODING   0x00400000
0108 /* mimo bit indicates short GI in use */
0109 #define RSPEC_SHORT_GI      0x00800000
0110 /* bit indicates override both rate & mode */
0111 #define RSPEC_OVERRIDE      0x80000000
0112 /* bit indicates override rate only */
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 /* Convert encoded rate value in plcp header to numerical rates in 500 KHz
0201  * increments */
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 /* Rates specified in brcms_c_rateset_filter() */
0213 #define BRCMS_RATES_CCK_OFDM    0
0214 #define BRCMS_RATES_CCK     1
0215 #define BRCMS_RATES_OFDM        2
0216 
0217 /* sanitize, and sort a rateset with the basic bit(s) preserved, validate
0218  * rateset */
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 /* copy rateset src to dst as-is (no masking or sorting) */
0223 void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
0224               struct brcms_c_rateset *dst);
0225 
0226 /* would be nice to have these documented ... */
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              /* _BRCM_RATE_H_ */