diff options
author | Eyal Shapira <eyal@wizery.com> | 2014-08-09 03:57:59 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-09-14 05:56:36 -0400 |
commit | a3576ff28e3b6a75d79fdc33c8179e7e2b470e50 (patch) | |
tree | 80cfc972acf93028e1253adc9d04e94a31a01d92 | |
parent | 71511c866bce04f931e462ad0cce3f122aa0c447 (diff) |
iwlwifi: mvm: add LDPC support
Use LDPC for Tx and publish support for Rx in case the chip
supports LDPC. Enable it for the 7265 family.
Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-7000.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-config.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.h | 2 |
6 files changed, 40 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 8e99dffa88e8..79c8f74685d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -220,6 +220,12 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = { | |||
220 | {0}, | 220 | {0}, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | static const struct iwl_ht_params iwl7265_ht_params = { | ||
224 | .stbc = true, | ||
225 | .ldpc = true, | ||
226 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
227 | }; | ||
228 | |||
223 | const struct iwl_cfg iwl3165_2ac_cfg = { | 229 | const struct iwl_cfg iwl3165_2ac_cfg = { |
224 | .name = "Intel(R) Dual Band Wireless AC 3165", | 230 | .name = "Intel(R) Dual Band Wireless AC 3165", |
225 | .fw_name_pre = IWL3165_FW_PRE, | 231 | .fw_name_pre = IWL3165_FW_PRE, |
@@ -234,7 +240,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = { | |||
234 | .name = "Intel(R) Dual Band Wireless AC 7265", | 240 | .name = "Intel(R) Dual Band Wireless AC 7265", |
235 | .fw_name_pre = IWL7265_FW_PRE, | 241 | .fw_name_pre = IWL7265_FW_PRE, |
236 | IWL_DEVICE_7000, | 242 | IWL_DEVICE_7000, |
237 | .ht_params = &iwl7000_ht_params, | 243 | .ht_params = &iwl7265_ht_params, |
238 | .nvm_ver = IWL7265_NVM_VERSION, | 244 | .nvm_ver = IWL7265_NVM_VERSION, |
239 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 245 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
240 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 246 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
@@ -244,7 +250,7 @@ const struct iwl_cfg iwl7265_2n_cfg = { | |||
244 | .name = "Intel(R) Dual Band Wireless N 7265", | 250 | .name = "Intel(R) Dual Band Wireless N 7265", |
245 | .fw_name_pre = IWL7265_FW_PRE, | 251 | .fw_name_pre = IWL7265_FW_PRE, |
246 | IWL_DEVICE_7000, | 252 | IWL_DEVICE_7000, |
247 | .ht_params = &iwl7000_ht_params, | 253 | .ht_params = &iwl7265_ht_params, |
248 | .nvm_ver = IWL7265_NVM_VERSION, | 254 | .nvm_ver = IWL7265_NVM_VERSION, |
249 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 255 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
250 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 256 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
@@ -254,7 +260,7 @@ const struct iwl_cfg iwl7265_n_cfg = { | |||
254 | .name = "Intel(R) Wireless N 7265", | 260 | .name = "Intel(R) Wireless N 7265", |
255 | .fw_name_pre = IWL7265_FW_PRE, | 261 | .fw_name_pre = IWL7265_FW_PRE, |
256 | IWL_DEVICE_7000, | 262 | IWL_DEVICE_7000, |
257 | .ht_params = &iwl7000_ht_params, | 263 | .ht_params = &iwl7265_ht_params, |
258 | .nvm_ver = IWL7265_NVM_VERSION, | 264 | .nvm_ver = IWL7265_NVM_VERSION, |
259 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 265 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
260 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 266 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 3d7cc37420ae..07c0f1fdb993 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -171,6 +171,7 @@ struct iwl_base_params { | |||
171 | 171 | ||
172 | /* | 172 | /* |
173 | * @stbc: support Tx STBC and 1*SS Rx STBC | 173 | * @stbc: support Tx STBC and 1*SS Rx STBC |
174 | * @ldpc: support Tx/Rx with LDPC | ||
174 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 175 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
175 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 | 176 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 |
176 | */ | 177 | */ |
@@ -178,6 +179,7 @@ struct iwl_ht_params { | |||
178 | enum ieee80211_smps_mode smps_mode; | 179 | enum ieee80211_smps_mode smps_mode; |
179 | const bool ht_greenfield_support; /* if used set to true */ | 180 | const bool ht_greenfield_support; /* if used set to true */ |
180 | const bool stbc; | 181 | const bool stbc; |
182 | const bool ldpc; | ||
181 | bool use_rts_for_aggregation; | 183 | bool use_rts_for_aggregation; |
182 | u8 ht40_bands; | 184 | u8 ht40_bands; |
183 | }; | 185 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 07ff7e0028ee..74b796dc4242 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -758,6 +758,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, | |||
758 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | 758 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; |
759 | } | 759 | } |
760 | 760 | ||
761 | if (cfg->ht_params->ldpc) | ||
762 | ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
763 | |||
761 | if (iwlwifi_mod_params.amsdu_size_8K) | 764 | if (iwlwifi_mod_params.amsdu_size_8K) |
762 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | 765 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
763 | 766 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 40718f814f8d..c302e7468559 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -334,6 +334,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, | |||
334 | 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | | 334 | 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | |
335 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; | 335 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; |
336 | 336 | ||
337 | if (cfg->ht_params->ldpc) | ||
338 | vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; | ||
339 | |||
337 | if (num_tx_ants > 1) | 340 | if (num_tx_ants > 1) |
338 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; | 341 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; |
339 | else | 342 | else |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 17002cf437db..6a13120f96db 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -505,10 +505,10 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type) | |||
505 | static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, | 505 | static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, |
506 | const char *prefix) | 506 | const char *prefix) |
507 | { | 507 | { |
508 | IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n", | 508 | IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d\n", |
509 | prefix, rs_pretty_lq_type(rate->type), | 509 | prefix, rs_pretty_lq_type(rate->type), |
510 | rate->index, rs_pretty_ant(rate->ant), | 510 | rate->index, rs_pretty_ant(rate->ant), |
511 | rate->bw, rate->sgi); | 511 | rate->bw, rate->sgi, rate->ldpc); |
512 | } | 512 | } |
513 | 513 | ||
514 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) | 514 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) |
@@ -742,6 +742,8 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, | |||
742 | ucode_rate |= rate->bw; | 742 | ucode_rate |= rate->bw; |
743 | if (rate->sgi) | 743 | if (rate->sgi) |
744 | ucode_rate |= RATE_MCS_SGI_MSK; | 744 | ucode_rate |= RATE_MCS_SGI_MSK; |
745 | if (rate->ldpc) | ||
746 | ucode_rate |= RATE_MCS_LDPC_MSK; | ||
745 | 747 | ||
746 | return ucode_rate; | 748 | return ucode_rate; |
747 | } | 749 | } |
@@ -779,6 +781,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, | |||
779 | /* HT or VHT */ | 781 | /* HT or VHT */ |
780 | if (ucode_rate & RATE_MCS_SGI_MSK) | 782 | if (ucode_rate & RATE_MCS_SGI_MSK) |
781 | rate->sgi = true; | 783 | rate->sgi = true; |
784 | if (ucode_rate & RATE_MCS_LDPC_MSK) | ||
785 | rate->ldpc = true; | ||
782 | 786 | ||
783 | rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; | 787 | rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; |
784 | 788 | ||
@@ -965,13 +969,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, | |||
965 | rate->index > IWL_RATE_MCS_9_INDEX); | 969 | rate->index > IWL_RATE_MCS_9_INDEX); |
966 | 970 | ||
967 | rate->index = rs_ht_to_legacy[rate->index]; | 971 | rate->index = rs_ht_to_legacy[rate->index]; |
972 | rate->ldpc = false; | ||
968 | } else { | 973 | } else { |
969 | /* Downgrade to SISO with same MCS if in MIMO */ | 974 | /* Downgrade to SISO with same MCS if in MIMO */ |
970 | rate->type = is_vht_mimo2(rate) ? | 975 | rate->type = is_vht_mimo2(rate) ? |
971 | LQ_VHT_SISO : LQ_HT_SISO; | 976 | LQ_VHT_SISO : LQ_HT_SISO; |
972 | } | 977 | } |
973 | 978 | ||
974 | |||
975 | if (num_of_ant(rate->ant) > 1) | 979 | if (num_of_ant(rate->ant) > 1) |
976 | rate->ant = first_antenna(mvm->fw->valid_tx_ant); | 980 | rate->ant = first_antenna(mvm->fw->valid_tx_ant); |
977 | 981 | ||
@@ -1621,6 +1625,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, | |||
1621 | } | 1625 | } |
1622 | 1626 | ||
1623 | rate->bw = rs_bw_from_sta_bw(sta); | 1627 | rate->bw = rs_bw_from_sta_bw(sta); |
1628 | rate->ldpc = lq_sta->ldpc; | ||
1624 | search_tbl->column = col_id; | 1629 | search_tbl->column = col_id; |
1625 | rs_set_expected_tpt_table(lq_sta, search_tbl); | 1630 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
1626 | 1631 | ||
@@ -2342,6 +2347,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
2342 | rate->index = i; | 2347 | rate->index = i; |
2343 | rate->ant = first_antenna(valid_tx_ant); | 2348 | rate->ant = first_antenna(valid_tx_ant); |
2344 | rate->sgi = false; | 2349 | rate->sgi = false; |
2350 | rate->ldpc = false; | ||
2345 | rate->bw = RATE_MCS_CHAN_WIDTH_20; | 2351 | rate->bw = RATE_MCS_CHAN_WIDTH_20; |
2346 | if (band == IEEE80211_BAND_5GHZ) | 2352 | if (band == IEEE80211_BAND_5GHZ) |
2347 | rate->type = LQ_LEGACY_A; | 2353 | rate->type = LQ_LEGACY_A; |
@@ -2610,9 +2616,16 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2610 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; | 2616 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; |
2611 | 2617 | ||
2612 | lq_sta->is_vht = false; | 2618 | lq_sta->is_vht = false; |
2619 | if (mvm->cfg->ht_params->ldpc && | ||
2620 | (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) | ||
2621 | lq_sta->ldpc = true; | ||
2613 | } else { | 2622 | } else { |
2614 | rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); | 2623 | rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); |
2615 | lq_sta->is_vht = true; | 2624 | lq_sta->is_vht = true; |
2625 | |||
2626 | if (mvm->cfg->ht_params->ldpc && | ||
2627 | (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) | ||
2628 | lq_sta->ldpc = true; | ||
2616 | } | 2629 | } |
2617 | 2630 | ||
2618 | lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, | 2631 | lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, |
@@ -2622,11 +2635,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2622 | lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, | 2635 | lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, |
2623 | BITS_PER_LONG); | 2636 | BITS_PER_LONG); |
2624 | 2637 | ||
2625 | IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n", | 2638 | IWL_DEBUG_RATE(mvm, |
2639 | "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d\n", | ||
2626 | lq_sta->active_legacy_rate, | 2640 | lq_sta->active_legacy_rate, |
2627 | lq_sta->active_siso_rate, | 2641 | lq_sta->active_siso_rate, |
2628 | lq_sta->active_mimo2_rate, | 2642 | lq_sta->active_mimo2_rate, |
2629 | lq_sta->is_vht); | 2643 | lq_sta->is_vht, lq_sta->ldpc); |
2630 | IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", | 2644 | IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", |
2631 | lq_sta->max_legacy_rate_idx, | 2645 | lq_sta->max_legacy_rate_idx, |
2632 | lq_sta->max_siso_rate_idx, | 2646 | lq_sta->max_siso_rate_idx, |
@@ -3032,8 +3046,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3032 | (is_ht20(rate)) ? "20MHz" : | 3046 | (is_ht20(rate)) ? "20MHz" : |
3033 | (is_ht40(rate)) ? "40MHz" : | 3047 | (is_ht40(rate)) ? "40MHz" : |
3034 | (is_ht80(rate)) ? "80Mhz" : "BAD BW"); | 3048 | (is_ht80(rate)) ? "80Mhz" : "BAD BW"); |
3035 | desc += sprintf(buff+desc, " %s %s\n", | 3049 | desc += sprintf(buff+desc, " %s %s %s\n", |
3036 | (rate->sgi) ? "SGI" : "NGI", | 3050 | (rate->sgi) ? "SGI" : "NGI", |
3051 | (rate->ldpc) ? "LDPC" : "BCC", | ||
3037 | (lq_sta->is_agg) ? "AGG on" : ""); | 3052 | (lq_sta->is_agg) ? "AGG on" : ""); |
3038 | } | 3053 | } |
3039 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", | 3054 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index f27b9d687a25..824a7506fc04 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h | |||
@@ -207,6 +207,7 @@ struct rs_rate { | |||
207 | u8 ant; | 207 | u8 ant; |
208 | u32 bw; | 208 | u32 bw; |
209 | bool sgi; | 209 | bool sgi; |
210 | bool ldpc; | ||
210 | }; | 211 | }; |
211 | 212 | ||
212 | 213 | ||
@@ -329,6 +330,7 @@ struct iwl_lq_sta { | |||
329 | */ | 330 | */ |
330 | u64 last_tx; | 331 | u64 last_tx; |
331 | bool is_vht; | 332 | bool is_vht; |
333 | bool ldpc; /* LDPC Rx is supported by the STA */ | ||
332 | enum ieee80211_band band; | 334 | enum ieee80211_band band; |
333 | 335 | ||
334 | struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; | 336 | struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; |