diff --git a/dp/cmn_dp_api/dp_ratetable.c b/dp/cmn_dp_api/dp_ratetable.c index d135358d45..dcd1452e5a 100644 --- a/dp/cmn_dp_api/dp_ratetable.c +++ b/dp/cmn_dp_api/dp_ratetable.c @@ -3524,3 +3524,310 @@ int dp_rate_idx_to_kbps(uint8_t rate_idx, uint8_t gintval) } qdf_export_symbol(dp_rate_idx_to_kbps); + +/* dp_get_start_index - get start index as per bw, mode and nss + * @ch_width - channel bandwidth + * @mode - operating mode + * @nss - no. of spatial streams + * + * return - start index + */ +static int dp_get_start_index(int ch_width, int mode, int nss) +{ + if (mode == HW_RATECODE_PREAM_HT) { + if (nss >= NUM_HT_SPATIAL_STREAM) + nss = NUM_HT_SPATIAL_STREAM; + + if (ch_width == CMN_BW_20MHZ) + return HT_20_RATE_TABLE_INDEX + (nss - 1) * NUM_HT_MCS; + else if (ch_width == CMN_BW_40MHZ) + return HT_40_RATE_TABLE_INDEX + (nss - 1) * NUM_HT_MCS; + } else if (mode == HW_RATECODE_PREAM_VHT) { + if (nss >= NUM_SPATIAL_STREAMS) + nss = NUM_SPATIAL_STREAMS; + + if (ch_width == CMN_BW_20MHZ) { + return VHT_20_RATE_TABLE_INDEX + (nss - 1) * NUM_VHT_MCS; + } else if (ch_width == CMN_BW_40MHZ) { + return VHT_40_RATE_TABLE_INDEX + (nss - 1) * NUM_VHT_MCS; + } else if (ch_width == CMN_BW_80MHZ) { + return VHT_80_RATE_TABLE_INDEX + (nss - 1) * NUM_VHT_MCS; + } else if ((ch_width == CMN_BW_160MHZ) || + (ch_width == CMN_BW_80_80MHZ)) { + if (nss >= MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ) + nss = MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ; + + return VHT_160_RATE_TABLE_INDEX + (nss - 1) * NUM_VHT_MCS; + } + } else if (mode == HW_RATECODE_PREAM_HE) { + if (nss >= NUM_SPATIAL_STREAMS) + nss = NUM_SPATIAL_STREAMS; + + if (ch_width == CMN_BW_20MHZ) { + return HE_20_RATE_TABLE_INDEX + (nss - 1) * NUM_HE_MCS; + } else if (ch_width == CMN_BW_40MHZ) { + return HE_40_RATE_TABLE_INDEX + (nss - 1) * NUM_HE_MCS; + } else if (ch_width == CMN_BW_80MHZ) { + return HE_80_RATE_TABLE_INDEX + (nss - 1) * NUM_HE_MCS; + } else if ((ch_width == CMN_BW_160MHZ) || + (ch_width == CMN_BW_80_80MHZ)) { + if (nss >= MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ) + nss = MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ; + + return HE_160_RATE_TABLE_INDEX + (nss - 1) * NUM_HE_MCS; + } + } + + return -1; +} + +/* dp_get_end_index - get end index as per bw, mode and nss + * @ch_width - channel bandwidth + * @mode - operating mode + * @nss - no. of spatial streams + * + * return - end index + */ +static int dp_get_end_index(int ch_width, int mode, int nss) +{ + if (mode == HW_RATECODE_PREAM_HT) { + if (nss >= NUM_HT_SPATIAL_STREAM) + nss = NUM_HT_SPATIAL_STREAM; + + if (ch_width == CMN_BW_20MHZ) + return HT_20_RATE_TABLE_INDEX + nss * NUM_HT_MCS - 1; + else if (ch_width == CMN_BW_40MHZ) + return HT_40_RATE_TABLE_INDEX + nss * NUM_HT_MCS - 1; + } else if (mode == HW_RATECODE_PREAM_VHT) { + if (nss >= NUM_SPATIAL_STREAMS) + nss = NUM_SPATIAL_STREAMS; + + if (ch_width == CMN_BW_20MHZ) { + return VHT_20_RATE_TABLE_INDEX + nss * NUM_VHT_MCS - 1; + } else if (ch_width == CMN_BW_40MHZ) { + return VHT_40_RATE_TABLE_INDEX + nss * NUM_VHT_MCS - 1; + } else if (ch_width == CMN_BW_80MHZ) { + return VHT_80_RATE_TABLE_INDEX + nss * NUM_VHT_MCS - 1; + } else if ((ch_width == CMN_BW_160MHZ) || + (ch_width == CMN_BW_80_80MHZ)) { + if (nss >= MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ) + nss = MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ; + + return VHT_160_RATE_TABLE_INDEX + nss * NUM_VHT_MCS - 1; + } + } else if (mode == HW_RATECODE_PREAM_HE) { + if (nss >= NUM_SPATIAL_STREAMS) + nss = NUM_SPATIAL_STREAMS; + + if (ch_width == CMN_BW_20MHZ) { + return HE_20_RATE_TABLE_INDEX + nss * NUM_HE_MCS - 1; + } else if (ch_width == CMN_BW_40MHZ) { + return HE_40_RATE_TABLE_INDEX + nss * NUM_HE_MCS - 1; + } else if (ch_width == CMN_BW_80MHZ) { + return HE_80_RATE_TABLE_INDEX + nss * NUM_HE_MCS - 1; + } else if ((ch_width == CMN_BW_160MHZ) || + (ch_width == CMN_BW_80_80MHZ)) { + if (nss >= MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ) + nss = MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ; + + return HE_160_RATE_TABLE_INDEX + nss * NUM_HE_MCS - 1; + } + } + + return -1; +} + +/* __dp_get_supported_rates - get supported rates as per start and end index + * @shortgi - gi setting + * @start_index - starting index + * @end_index - ending index + * @rates - array to copy the rates into + * + * return - no. of rate entries copied + */ +static int __dp_get_supported_rates(int shortgi, int start_index, + int end_index, int **rates) +{ + int i, j = 1; + int *ratelist = *rates; + + /* Check if the index calculation is out of array bounds */ + if (start_index < 0 || start_index >= DP_RATE_TABLE_SIZE || + end_index < 0 || end_index >= DP_RATE_TABLE_SIZE) + return 0; + + if (!shortgi) { + for (i = start_index; i <= end_index; i++) { + if (dp_11abgnratetable.info[i].validmodemask) { + ratelist[j] = dp_11abgnratetable.info[i]. + ratekbps; + j++; + } + } + } else { + switch (shortgi) { + case CDP_SGI_0_4_US: + for (i = start_index; i <= end_index; i++) { + if (dp_11abgnratetable.info[i].validmodemask) { + ratelist[j] = dp_11abgnratetable. + info[i].ratekbpssgi; + j++; + } + } + break; + + case CDP_SGI_1_6_US: + for (i = start_index; i <= end_index; i++) { + if (dp_11abgnratetable.info[i].validmodemask) { + ratelist[j] = dp_11abgnratetable. + info[i].ratekbpsdgi; + j++; + } + } + break; + + case CDP_SGI_3_2_US: + for (i = start_index; i <= end_index; i++) { + if (dp_11abgnratetable.info[i].validmodemask) { + ratelist[j] = dp_11abgnratetable. + info[i].ratekbpsqgi; + j++; + } + } + break; + } + } + + ratelist[0] = j; + return j; +} + +#if ALL_POSSIBLE_RATES_SUPPORTED +/* dp_get_supported_rates -get all supported rates as per mode and gi setting + * @mode - operating mode + * @shortgi - gi setting + * @rates - array to copy the rate entries into + * + * return - no. of rate entries copied + */ +int dp_get_supported_rates(int mode, int shortgi, int **rates) +{ + int start_index = -1, end_index = -1; + + switch (mode) { + /* 11b CCK Rates */ + case CMN_IEEE80211_MODE_B: + start_index = CCK_RATE_TABLE_INDEX; + end_index = CCK_RATE_TABLE_END_INDEX; + break; + + /* 11a OFDM Rates */ + case CMN_IEEE80211_MODE_A: + start_index = OFDM_RATE_TABLE_INDEX; + end_index = OFDMA_RATE_TABLE_END_INDEX; + break; + + /* 11g CCK/OFDM Rates */ + case CMN_IEEE80211_MODE_G: + start_index = CCK_RATE_TABLE_INDEX; + end_index = OFDMA_RATE_TABLE_END_INDEX; + break; + + /* HT rates only */ + case CMN_IEEE80211_MODE_NA: + case CMN_IEEE80211_MODE_NG: + start_index = dp_get_start_index(CMN_BW_20MHZ, + HW_RATECODE_PREAM_HT, 1); + end_index = dp_get_end_index(CMN_BW_40MHZ, + HW_RATECODE_PREAM_HT, + NUM_HT_SPATIAL_STREAM); + break; + + /* VHT rates only */ + case CMN_IEEE80211_MODE_AC: + start_index = dp_get_start_index(CMN_BW_20MHZ, + HW_RATECODE_PREAM_VHT, 1); + end_index = dp_get_end_index(CMN_BW_160MHZ, + HW_RATECODE_PREAM_VHT, + MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ); + break; + + /* HE rates only */ + case CMN_IEEE80211_MODE_AXA: + case CMN_IEEE80211_MODE_AXG: + start_index = dp_get_start_index(CMN_BW_20MHZ, + HW_RATECODE_PREAM_HE, 1); + end_index = dp_get_end_index(CMN_BW_160MHZ, + HW_RATECODE_PREAM_HE, + MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ); + break; + } + + return __dp_get_supported_rates(shortgi, start_index, end_index, rates); +} +#else +/* dp_get_supported_rates - get all supported rates as per mode, bw, gi and nss + * @mode - operating mode + * @shortgi - gi setting + * @nss - no. of spatial streams + * @ch_width - channel bandwidth + * @rates - array to copy the rates into + * + * return - no. of rate entries copied + */ +int dp_get_supported_rates(int mode, int shortgi, int nss, + int ch_width, int **rates) +{ + int start_index = -1, end_index = -1; + + switch (mode) { + /* 11b CCK Rates */ + case CMN_IEEE80211_MODE_B: + start_index = CCK_RATE_TABLE_INDEX; + end_index = CCK_RATE_TABLE_END_INDEX; + break; + + /* 11a OFDM Rates */ + case CMN_IEEE80211_MODE_A: + start_index = OFDM_RATE_TABLE_INDEX; + end_index = OFDMA_RATE_TABLE_END_INDEX; + break; + + /* 11g CCK/OFDM Rates */ + case CMN_IEEE80211_MODE_G: + start_index = CCK_RATE_TABLE_INDEX; + end_index = OFDMA_RATE_TABLE_END_INDEX; + break; + + /* HT rates only */ + case CMN_IEEE80211_MODE_NA: + case CMN_IEEE80211_MODE_NG: + start_index = dp_get_start_index(ch_width, + HW_RATECODE_PREAM_HT, nss); + end_index = dp_get_end_index(ch_width, + HW_RATECODE_PREAM_HT, nss); + break; + + /* VHT rates only */ + case CMN_IEEE80211_MODE_AC: + start_index = dp_get_start_index(ch_width, + HW_RATECODE_PREAM_VHT, nss); + end_index = dp_get_end_index(ch_width, + HW_RATECODE_PREAM_VHT, nss); + break; + + /* HE rates only */ + case CMN_IEEE80211_MODE_AXA: + case CMN_IEEE80211_MODE_AXG: + start_index = dp_get_start_index(ch_width, + HW_RATECODE_PREAM_HE, nss); + end_index = dp_get_end_index(ch_width, + HW_RATECODE_PREAM_HE, nss); + break; + } + + return __dp_get_supported_rates(shortgi, start_index, end_index, rates); +} +#endif + +qdf_export_symbol(dp_get_supported_rates); diff --git a/dp/cmn_dp_api/dp_ratetable.h b/dp/cmn_dp_api/dp_ratetable.h index dbcef1af51..8fd5fe947b 100644 --- a/dp/cmn_dp_api/dp_ratetable.h +++ b/dp/cmn_dp_api/dp_ratetable.h @@ -29,10 +29,30 @@ enum CMN_BW_TYPES { CMN_BW_40MHZ, CMN_BW_80MHZ, CMN_BW_160MHZ, + CMN_BW_80_80MHZ, CMN_BW_CNT, CMN_BW_IDLE = 0xFF, /*default BW state */ }; +/* + * Modes Types + */ +enum CMN_MODE_TYPES { + CMN_IEEE80211_MODE_INVALID = 0, + CMN_IEEE80211_MODE_A, + CMN_IEEE80211_MODE_B, + CMN_IEEE80211_MODE_G, + CMN_IEEE80211_MODE_TURBO, + CMN_IEEE80211_MODE_NA, + CMN_IEEE80211_MODE_NG, + CMN_IEEE80211_MODE_N, + CMN_IEEE80211_MODE_AC, + CMN_IEEE80211_MODE_AXA, + CMN_IEEE80211_MODE_AXG, + CMN_IEEE80211_MODE_AX, + CMN_IEEE80211_MODE_MAX +}; + #define NUM_SPATIAL_STREAMS 8 #define MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ 4 #define VHT_EXTRA_MCS_SUPPORT @@ -103,12 +123,14 @@ static inline int dp_ath_rate_out(uint64_t _i) MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ) #define CCK_RATE_TABLE_INDEX 0 +#define CCK_RATE_TABLE_END_INDEX 3 #define CCK_RATE_11M_INDEX 0 #define CCK_FALLBACK_MIN_RATE 0x3 /** 1 Mbps */ #define CCK_FALLBACK_MAX_RATE 0x2 /** 2 Mbps */ #define OFDM_RATE_TABLE_INDEX 4 #define OFDMA_RATE_54M_INDEX 8 +#define OFDMA_RATE_TABLE_END_INDEX 11 #define HT_20_RATE_TABLE_INDEX 12 #define HT_40_RATE_TABLE_INDEX (HT_20_RATE_TABLE_INDEX + NUM_HT_RIX_PER_BW) @@ -170,4 +192,11 @@ dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble, int dp_rate_idx_to_kbps(uint8_t rate_idx, uint8_t gintval); +#if ALL_POSSIBLE_RATES_SUPPORTED +int dp_get_supported_rates(int mode, int shortgi, int **rates); +#else +int dp_get_supported_rates(int mode, int shortgi, int nss, + int ch_width, int **rates); +#endif + #endif /*_DP_RATES_H_*/