diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-drv.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 75103554cd63..0a3e841b44a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -128,7 +128,7 @@ struct iwl_drv { | |||
128 | const struct iwl_cfg *cfg; | 128 | const struct iwl_cfg *cfg; |
129 | 129 | ||
130 | int fw_index; /* firmware we're trying to load */ | 130 | int fw_index; /* firmware we're trying to load */ |
131 | char firmware_name[25]; /* name of firmware file to load */ | 131 | char firmware_name[32]; /* name of firmware file to load */ |
132 | 132 | ||
133 | struct completion request_firmware_complete; | 133 | struct completion request_firmware_complete; |
134 | 134 | ||
@@ -237,7 +237,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) | |||
237 | return -ENOENT; | 237 | return -ENOENT; |
238 | } | 238 | } |
239 | 239 | ||
240 | sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | 240 | snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode", |
241 | name_pre, tag); | ||
241 | 242 | ||
242 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | 243 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", |
243 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | 244 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) |
@@ -403,6 +404,38 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) | |||
403 | return 0; | 404 | return 0; |
404 | } | 405 | } |
405 | 406 | ||
407 | static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data, | ||
408 | struct iwl_ucode_capabilities *capa) | ||
409 | { | ||
410 | const struct iwl_ucode_api *ucode_api = (void *)data; | ||
411 | u32 api_index = le32_to_cpu(ucode_api->api_index); | ||
412 | |||
413 | if (api_index >= IWL_API_ARRAY_SIZE) { | ||
414 | IWL_ERR(drv, "api_index larger than supported by driver\n"); | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | |||
418 | capa->api[api_index] = le32_to_cpu(ucode_api->api_flags); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data, | ||
424 | struct iwl_ucode_capabilities *capa) | ||
425 | { | ||
426 | const struct iwl_ucode_capa *ucode_capa = (void *)data; | ||
427 | u32 api_index = le32_to_cpu(ucode_capa->api_index); | ||
428 | |||
429 | if (api_index >= IWL_CAPABILITIES_ARRAY_SIZE) { | ||
430 | IWL_ERR(drv, "api_index larger than supported by driver\n"); | ||
431 | return -EINVAL; | ||
432 | } | ||
433 | |||
434 | capa->capa[api_index] = le32_to_cpu(ucode_capa->api_capa); | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
406 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | 439 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, |
407 | const struct firmware *ucode_raw, | 440 | const struct firmware *ucode_raw, |
408 | struct iwl_firmware_pieces *pieces) | 441 | struct iwl_firmware_pieces *pieces) |
@@ -637,6 +670,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
637 | */ | 670 | */ |
638 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | 671 | capa->flags = le32_to_cpup((__le32 *)tlv_data); |
639 | break; | 672 | break; |
673 | case IWL_UCODE_TLV_API_CHANGES_SET: | ||
674 | if (tlv_len != sizeof(struct iwl_ucode_api)) | ||
675 | goto invalid_tlv_len; | ||
676 | if (iwl_set_ucode_api_flags(drv, tlv_data, capa)) | ||
677 | goto tlv_error; | ||
678 | break; | ||
679 | case IWL_UCODE_TLV_ENABLED_CAPABILITIES: | ||
680 | if (tlv_len != sizeof(struct iwl_ucode_capa)) | ||
681 | goto invalid_tlv_len; | ||
682 | if (iwl_set_ucode_capabilities(drv, tlv_data, capa)) | ||
683 | goto tlv_error; | ||
684 | break; | ||
640 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | 685 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: |
641 | if (tlv_len != sizeof(u32)) | 686 | if (tlv_len != sizeof(u32)) |
642 | goto invalid_tlv_len; | 687 | goto invalid_tlv_len; |
@@ -727,6 +772,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
727 | if (tlv_len != sizeof(u32)) | 772 | if (tlv_len != sizeof(u32)) |
728 | goto invalid_tlv_len; | 773 | goto invalid_tlv_len; |
729 | drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); | 774 | drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); |
775 | drv->fw.valid_tx_ant = (drv->fw.phy_config & | ||
776 | FW_PHY_CFG_TX_CHAIN) >> | ||
777 | FW_PHY_CFG_TX_CHAIN_POS; | ||
778 | drv->fw.valid_rx_ant = (drv->fw.phy_config & | ||
779 | FW_PHY_CFG_RX_CHAIN) >> | ||
780 | FW_PHY_CFG_RX_CHAIN_POS; | ||
730 | break; | 781 | break; |
731 | case IWL_UCODE_TLV_SECURE_SEC_RT: | 782 | case IWL_UCODE_TLV_SECURE_SEC_RT: |
732 | iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, | 783 | iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, |
@@ -1300,8 +1351,7 @@ MODULE_PARM_DESC(antenna_coupling, | |||
1300 | 1351 | ||
1301 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); | 1352 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); |
1302 | MODULE_PARM_DESC(wd_disable, | 1353 | MODULE_PARM_DESC(wd_disable, |
1303 | "Disable stuck queue watchdog timer 0=system default, " | 1354 | "Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)"); |
1304 | "1=disable, 2=enable (default: 0)"); | ||
1305 | 1355 | ||
1306 | module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); | 1356 | module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); |
1307 | MODULE_PARM_DESC(nvm_file, "NVM file name"); | 1357 | MODULE_PARM_DESC(nvm_file, "NVM file name"); |