diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/nvm.c | 17 |
5 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index f0548b8a64b0..5234a0bf11e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | |||
@@ -94,6 +94,7 @@ struct iwl_nvm_data { | |||
94 | u32 nvm_version; | 94 | u32 nvm_version; |
95 | s8 max_tx_pwr_half_dbm; | 95 | s8 max_tx_pwr_half_dbm; |
96 | 96 | ||
97 | bool lar_enabled; | ||
97 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 98 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
98 | struct ieee80211_channel channels[]; | 99 | struct ieee80211_channel channels[]; |
99 | }; | 100 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 83ba307f0618..88ee84cbd7d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -105,6 +105,8 @@ enum family_8000_nvm_offsets { | |||
105 | 105 | ||
106 | /* NVM REGULATORY -Section offset (in words) definitions */ | 106 | /* NVM REGULATORY -Section offset (in words) definitions */ |
107 | NVM_CHANNELS_FAMILY_8000 = 0, | 107 | NVM_CHANNELS_FAMILY_8000 = 0, |
108 | NVM_LAR_OFFSET_FAMILY_8000 = 0x4C7, | ||
109 | NVM_LAR_ENABLED_FAMILY_8000 = 0x7, | ||
108 | 110 | ||
109 | /* NVM calibration section offset (in words) definitions */ | 111 | /* NVM calibration section offset (in words) definitions */ |
110 | NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8, | 112 | NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8, |
@@ -597,11 +599,12 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
597 | const __le16 *nvm_hw, const __le16 *nvm_sw, | 599 | const __le16 *nvm_hw, const __le16 *nvm_sw, |
598 | const __le16 *nvm_calib, const __le16 *regulatory, | 600 | const __le16 *nvm_calib, const __le16 *regulatory, |
599 | const __le16 *mac_override, u8 tx_chains, u8 rx_chains, | 601 | const __le16 *mac_override, u8 tx_chains, u8 rx_chains, |
600 | bool lar_supported) | 602 | bool lar_fw_supported) |
601 | { | 603 | { |
602 | struct iwl_nvm_data *data; | 604 | struct iwl_nvm_data *data; |
603 | u32 sku; | 605 | u32 sku; |
604 | u32 radio_cfg; | 606 | u32 radio_cfg; |
607 | u16 lar_config; | ||
605 | 608 | ||
606 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) | 609 | if (cfg->device_family != IWL_DEVICE_FAMILY_8000) |
607 | data = kzalloc(sizeof(*data) + | 610 | data = kzalloc(sizeof(*data) + |
@@ -653,15 +656,21 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
653 | 656 | ||
654 | iwl_init_sbands(dev, cfg, data, nvm_sw, | 657 | iwl_init_sbands(dev, cfg, data, nvm_sw, |
655 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, | 658 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, |
656 | rx_chains, lar_supported); | 659 | rx_chains, lar_fw_supported); |
657 | } else { | 660 | } else { |
661 | lar_config = le16_to_cpup(regulatory + | ||
662 | NVM_LAR_OFFSET_FAMILY_8000); | ||
663 | data->lar_enabled = !!(lar_config & | ||
664 | NVM_LAR_ENABLED_FAMILY_8000); | ||
665 | |||
658 | /* MAC address in family 8000 */ | 666 | /* MAC address in family 8000 */ |
659 | iwl_set_hw_address_family_8000(dev, cfg, data, mac_override, | 667 | iwl_set_hw_address_family_8000(dev, cfg, data, mac_override, |
660 | nvm_hw); | 668 | nvm_hw); |
661 | 669 | ||
662 | iwl_init_sbands(dev, cfg, data, regulatory, | 670 | iwl_init_sbands(dev, cfg, data, regulatory, |
663 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, | 671 | sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, |
664 | rx_chains, lar_supported); | 672 | rx_chains, lar_fw_supported && |
673 | data->lar_enabled); | ||
665 | } | 674 | } |
666 | 675 | ||
667 | data->calib_version = 255; | 676 | data->calib_version = 255; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index 1b3990d15dc1..c950c142ba0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | |||
@@ -78,7 +78,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, | |||
78 | const __le16 *nvm_hw, const __le16 *nvm_sw, | 78 | const __le16 *nvm_hw, const __le16 *nvm_sw, |
79 | const __le16 *nvm_calib, const __le16 *regulatory, | 79 | const __le16 *nvm_calib, const __le16 *regulatory, |
80 | const __le16 *mac_override, u8 tx_chains, u8 rx_chains, | 80 | const __le16 *mac_override, u8 tx_chains, u8 rx_chains, |
81 | bool lar_supported); | 81 | bool lar_fw_supported); |
82 | 82 | ||
83 | /** | 83 | /** |
84 | * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW | 84 | * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index df5a2286b409..a196c7859086 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -914,7 +914,17 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm) | |||
914 | 914 | ||
915 | static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) | 915 | static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) |
916 | { | 916 | { |
917 | return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_LAR_SUPPORT; | 917 | bool nvm_lar = mvm->nvm_data->lar_enabled; |
918 | bool tlv_lar = mvm->fw->ucode_capa.capa[0] & | ||
919 | IWL_UCODE_TLV_CAPA_LAR_SUPPORT; | ||
920 | /* | ||
921 | * Enable LAR only if it is supported by the FW (TLV) && | ||
922 | * enabled in the NVM | ||
923 | */ | ||
924 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000) | ||
925 | return nvm_lar && tlv_lar; | ||
926 | else | ||
927 | return tlv_lar; | ||
918 | } | 928 | } |
919 | 929 | ||
920 | static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) | 930 | static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index b88b4cd07a22..1c699c9aaad3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -303,7 +303,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) | |||
303 | regulatory, mac_override, | 303 | regulatory, mac_override, |
304 | mvm->fw->valid_tx_ant, | 304 | mvm->fw->valid_tx_ant, |
305 | mvm->fw->valid_rx_ant, | 305 | mvm->fw->valid_rx_ant, |
306 | iwl_mvm_is_lar_supported(mvm)); | 306 | mvm->fw->ucode_capa.capa[0] & |
307 | IWL_UCODE_TLV_CAPA_LAR_SUPPORT); | ||
307 | } | 308 | } |
308 | 309 | ||
309 | #define MAX_NVM_FILE_LEN 16384 | 310 | #define MAX_NVM_FILE_LEN 16384 |
@@ -659,6 +660,20 @@ exit: | |||
659 | 660 | ||
660 | int iwl_mvm_init_mcc(struct iwl_mvm *mvm) | 661 | int iwl_mvm_init_mcc(struct iwl_mvm *mvm) |
661 | { | 662 | { |
663 | bool tlv_lar; | ||
664 | bool nvm_lar; | ||
665 | |||
666 | if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000) { | ||
667 | tlv_lar = mvm->fw->ucode_capa.capa[0] & | ||
668 | IWL_UCODE_TLV_CAPA_LAR_SUPPORT; | ||
669 | nvm_lar = mvm->nvm_data->lar_enabled; | ||
670 | if (tlv_lar != nvm_lar) | ||
671 | IWL_INFO(mvm, | ||
672 | "Conflict between TLV & NVM regarding enabling LAR (TLV = %s NVM =%s)\n", | ||
673 | tlv_lar ? "enabled" : "disabled", | ||
674 | nvm_lar ? "enabled" : "disabled"); | ||
675 | } | ||
676 | |||
662 | if (!iwl_mvm_is_lar_supported(mvm)) | 677 | if (!iwl_mvm_is_lar_supported(mvm)) |
663 | return 0; | 678 | return 0; |
664 | 679 | ||