linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/rate.h
<<
>>
Prefs
   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_ */
 246