Talk:Intel Centrino Advanced-N 6205
Jump to navigation
Jump to search
Intel 5150 AGX/6205 AGN - 802.11n
%NIC_MPCIEX_6205AGN_2x2_HMC% = Install_MPCIEX_GEN_6205_AGN_2x2_HMC_XP_MOW , PCI\VEN_8086&DEV_0082&SUBSYS_13018086 ; MOW %NIC_MPCIEX_6205AGN_2x2_HMC% = Install_MPCIEX_GEN_6205_AGN_2x2_HMC_XP_ABG , PCI\VEN_8086&DEV_0082&SUBSYS_13068086 ; ABG %NIC_MPCIEX_6205AGN_2x2_HMC% = Install_MPCIEX_GEN_6205_AGN_2x2_HMC_XP_BG7 , PCI\VEN_8086&DEV_0082&SUBSYS_13078086 ; BG7 %NIC_MPCIEX_6205AGN_2x2_HMC% = Install_MPCIEX_GEN_6205_AGN_2x2_HMC_XP_MOW1 , PCI\VEN_8086&DEV_0082&SUBSYS_13048086 ; MOW1 %NIC_MPCIEX_6205AGN_2x2_HMC% = Install_MPCIEX_GEN_6205_AGN_2x2_HMC_XP_MOW2 , PCI\VEN_8086&DEV_0082&SUBSYS_13058086 ; MOW2
- CONFIG_IWLWIFI_DEBUG: iwlwifi debug=0x41
Some Intel Wi-Fi hardware has 80211N disabled by firmware. Patch EEPROM shadow copy to enable it on the 6xxx series. This code based on http://forum.ixbt.com/topic.cgi?id=14:51214:326#326 and https://github.com/0x90/iwleeprom Signed-off-by: Sergei A. Trusov <sergei.a.trusov@yandex.ru> --- drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 30 ++-- .../net/wireless/intel/iwlwifi/iwl-eeprom-read.c | 169 +++++++++++++++++++++ 2 files changed, 189 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c index 39335b7b0c16..2e37877d5643 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -144,13 +144,15 @@ const struct iwl_cfg iwl6005_2agn_cfg = { }; const struct iwl_cfg iwl6005_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", + .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG+N", IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl6005_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", + .name = "Intel(R) Centrino(R) Advanced-N 6205 BG+N", IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl6005_2agn_sff_cfg = { @@ -198,8 +200,9 @@ const struct iwl_cfg iwl6030_2agn_cfg = { }; const struct iwl_cfg iwl6030_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", + .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG+N", IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl6030_2bgn_cfg = { @@ -209,8 +212,9 @@ const struct iwl_cfg iwl6030_2bgn_cfg = { }; const struct iwl_cfg iwl6030_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", + .name = "Intel(R) Centrino(R) Advanced-N 6230 BG+N", IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, }; #define IWL_DEVICE_6035 \ @@ -246,8 +250,9 @@ const struct iwl_cfg iwl1030_bgn_cfg = { }; const struct iwl_cfg iwl1030_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", + .name = "Intel(R) Centrino(R) Wireless-N 1030 BG+N", IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl130_bgn_cfg = { @@ -258,8 +263,9 @@ const struct iwl_cfg iwl130_bgn_cfg = { }; const struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BG", + .name = "Intel(R) Centrino(R) Wireless-N 130 BG+N", IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, .rx_with_siso_diversity = true, }; @@ -289,13 +295,15 @@ const struct iwl_cfg iwl6000i_2agn_cfg = { }; const struct iwl_cfg iwl6000i_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", + .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG+N", IWL_DEVICE_6000i, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl6000i_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", + .name = "Intel(R) Centrino(R) Advanced-N 6200 BG+N", IWL_DEVICE_6000i, + .ht_params = &iwl6000_ht_params, }; #define IWL_DEVICE_6050 \ @@ -322,8 +330,9 @@ const struct iwl_cfg iwl6050_2agn_cfg = { }; const struct iwl_cfg iwl6050_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG+N", IWL_DEVICE_6050, + .ht_params = &iwl6000_ht_params, }; #define IWL_DEVICE_6150 \ @@ -348,8 +357,9 @@ const struct iwl_cfg iwl6150_bgn_cfg = { }; const struct iwl_cfg iwl6150_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG+N", IWL_DEVICE_6150, + .ht_params = &iwl6000_ht_params, }; const struct iwl_cfg iwl6000_3agn_cfg = { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index f2cea1c7befc..bb72f4e6ed87 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -347,6 +347,160 @@ static int iwl_find_otp_image(struct iwl_trans *trans, return -EINVAL; } +/* + * The following regulatory items and supporting code are from: + * iwleeprom - EEPROM reader/writer for intel wifi cards. + */ +struct regulatory_item +{ + unsigned addr; + u16 data; + u16 chn; +}; + +#define HT40 0x100 +struct regulatory_item regulatory[] = +{ + /* + * BAND 2.4GHz (@15e-179 with regulatory base @156) + * enabling channels 12-14 (1-11 should be enabled on all cards) + */ + { 0x1E, 0x0f21, 12 }, + { 0x20, 0x0f21, 13 }, + { 0x22, 0x0f21, 14 }, + + /* BAND 5GHz */ + + /* subband 5170-5320 MHz (@198-1af) */ +// { 0x42, 0x0fe1, 34 }, + { 0x44, 0x0fe1, 36 }, +// { 0x46, 0x0fe1, 38 }, + { 0x48, 0x0fe1, 40 }, +// { 0x4a, 0x0fe1, 42 }, + { 0x4c, 0x0fe1, 44 }, +// { 0x4e, 0x0fe1, 46 }, + { 0x50, 0x0fe1, 48 }, + { 0x52, 0x0f31, 52 }, + { 0x54, 0x0f31, 56 }, + { 0x56, 0x0f31, 60 }, + { 0x58, 0x0f31, 64 }, + + /* subband 5500-5700 MHz (@1b2-1c7) */ + { 0x5c, 0x0f31, 100 }, + { 0x5e, 0x0f31, 104 }, + { 0x60, 0x0f31, 108 }, + { 0x62, 0x0f31, 112 }, + { 0x64, 0x0f31, 116 }, + { 0x66, 0x0f31, 120 }, + { 0x68, 0x0f31, 124 }, + { 0x6a, 0x0f31, 128 }, + { 0x6c, 0x0f31, 132 }, + { 0x6e, 0x0f31, 136 }, + { 0x70, 0x0f31, 140 }, + + /* subband 5725-5825 MHz (@1ca-1d5) */ +// { 0x74, 0x0fa1, 145 }, + { 0x76, 0x0fa1, 149 }, + { 0x78, 0x0fa1, 153 }, + { 0x7a, 0x0fa1, 157 }, + { 0x7c, 0x0fa1, 161 }, + { 0x7e, 0x0fa1, 165 }, + + /* BAND 2.4GHz, HT40 channels (@1d8-1e5) */ + { 0x82, 0x0e6f, HT40 + 1 }, + { 0x84, 0x0f6f, HT40 + 2 }, + { 0x86, 0x0f6f, HT40 + 3 }, + { 0x88, 0x0f6f, HT40 + 4 }, + { 0x8a, 0x0f6f, HT40 + 5 }, + { 0x8c, 0x0f6f, HT40 + 6 }, + { 0x8e, 0x0f6f, HT40 + 7 }, + + /* BAND 5GHz, HT40 channels (@1e8-1fd) */ + { 0x92, 0x0fe1, HT40 + 36 }, + { 0x94, 0x0fe1, HT40 + 44 }, + { 0x96, 0x0f31, HT40 + 52 }, + { 0x98, 0x0f31, HT40 + 60 }, + { 0x9a, 0x0f31, HT40 + 100 }, + { 0x9c, 0x0f31, HT40 + 108 }, + { 0x9e, 0x0f31, HT40 + 116 }, + { 0xa0, 0x0f31, HT40 + 124 }, + { 0xa2, 0x0f31, HT40 + 132 }, + { 0xa4, 0x0f61, HT40 + 149 }, + { 0xa6, 0x0f61, HT40 + 157 }, + + { 0, 0} +}; + +/* This and bellow one are an EEPROM copy acessors actually */ +u16 iwl_eeprom_read16(__le16 *base, unsigned addr) +{ + return base[addr >> 1]; +} + +void iwl_eeprom_write16(__le16 *base, unsigned addr, u16 value) +{ + base[addr >> 1] = value; +} + +/* We get here whith EEPROM semaphore aquired */ +void iwl_eeprom_patch11n(struct iwl_trans *trans, __le16 *eeprom) +{ + uint16_t value; + unsigned reg_offs; + int idx; + + IWL_DEBUG_EEPROM(trans->dev, "Patching card EEPROM shadow RAM...\n"); + + /* This seems redundand but let's be intact with the original code */ + IWL_DEBUG_EEPROM(trans->dev, "-> Changing subdev ID\n"); + /* The magic number is EEPROM_SUBSYSTEM_ID from iwl-eeprom-parse.c */ + value = iwl_eeprom_read16(eeprom, 0x14); + if ((value & 0x000F) == 0x0006) { + iwl_eeprom_write16(eeprom, 0x14, (value & 0xFFF0) | 0x0001); + } + /* + * enabling .11n + * W @8A << 00F0 (00B0) <- xxxx xxxx x1xx xxxx + * W @8C << 103E (603F) <- x001 xxxx xxxx xxx0 + */ + IWL_DEBUG_EEPROM(trans->dev, "-> Enabling 11n mode\n"); + + /* SKU_CAP */ + value = iwl_eeprom_read16(eeprom, 0x8A); + if ((value & 0x0040) != 0x0040) { + IWL_DEBUG_EEPROM(trans->dev, " SKU CAP\n"); + iwl_eeprom_write16(eeprom, 0x8A, value | 0x0040); + } + + /* OEM_MODE */ + value = iwl_eeprom_read16(eeprom, 0x8C); + if ((value & 0x7001) != 0x1000) { + IWL_DEBUG_EEPROM(trans->dev, " OEM MODE\n"); + iwl_eeprom_write16(eeprom, 0x8C, (value & 0x9FFE) | 0x1000); + } + + /* writing SKU ID - 'MoW' signature */ + if (iwl_eeprom_read16(eeprom, 0x158) != 0x6f4d) + iwl_eeprom_write16(eeprom, 0x158, 0x6f4d); + if (iwl_eeprom_read16(eeprom, 0x15A) != 0x0057) + iwl_eeprom_write16(eeprom, 0x15A, 0x0057); + + IWL_DEBUG_EEPROM(trans->dev, "-> Checking and adding channels...\n"); + /* reading regulatory offset */ + reg_offs = 2 * iwl_eeprom_read16(eeprom, 0xCC); + IWL_DEBUG_EEPROM(trans->dev, "Regulatory base: %04x\n", reg_offs); + + /*writing channels regulatory.*/ + for (idx=0; regulatory[idx].addr; idx++) { + if (iwl_eeprom_read16(eeprom, reg_offs + regulatory[idx].addr) != regulatory[idx].data) { + IWL_DEBUG_EEPROM(trans->dev, " %d%s\n", regulatory[idx].chn & ~HT40, (regulatory[idx].chn & HT40) ? " (HT40)" : ""); + iwl_eeprom_write16(eeprom, reg_offs + regulatory[idx].addr, regulatory[idx].data); + } + } + + IWL_DEBUG_EEPROM(trans->dev, "\nCard EEPROM shadow RAM patched successfully\n"); +} + /** * iwl_read_eeprom - read EEPROM contents * @@ -448,6 +602,21 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) IWL_DEBUG_EEPROM(trans->dev, "NVM Type: %s\n", nvm_is_otp ? "OTP" : "EEPROM"); +#if IS_ENABLED(CONFIG_IWLDVM) + /* Hack EEPROM shadow to enable N mode on disabled hardware */ + if (trans->cfg == &iwl6005_2abg_cfg || + trans->cfg == &iwl6005_2bg_cfg || + trans->cfg == &iwl6030_2abg_cfg || + trans->cfg == &iwl6030_2bg_cfg || + trans->cfg == &iwl1030_bg_cfg || + trans->cfg == &iwl130_bg_cfg || + trans->cfg == &iwl6000i_2abg_cfg || + trans->cfg == &iwl6000i_2bg_cfg || + trans->cfg == &iwl6050_2abg_cfg || + trans->cfg == &iwl6150_bg_cfg) + iwl_eeprom_patch11n(trans, e); +#endif + iwl_eeprom_release_semaphore(trans); *eeprom_size = sz;