aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2014-08-09 03:57:59 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-09-14 05:56:36 -0400
commita3576ff28e3b6a75d79fdc33c8179e7e2b470e50 (patch)
tree80cfc972acf93028e1253adc9d04e94a31a01d92
parent71511c866bce04f931e462ad0cce3f122aa0c447 (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.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h2
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
223static 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
223const struct iwl_cfg iwl3165_2ac_cfg = { 229const 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)
505static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, 505static 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
514static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 514static 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];