diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-ucode.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-ucode.c | 394 |
1 files changed, 185 insertions, 209 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 11b659ab261d..b16efc00ba6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -44,6 +44,7 @@ #include "iwl-agn-calib.h" #include "iwl-trans.h" #include "iwl-fh.h" +#include "iwl-op-mode.h" static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, @@ -82,29 +83,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc) +static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(trans->dev, desc->len, + dma_free_coherent(trans(nic)->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img) +static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) { - iwl_free_fw_desc(trans, &img->code); - iwl_free_fw_desc(trans, &img->data); + iwl_free_fw_desc(nic, &img->code); + iwl_free_fw_desc(nic, &img->data); } -void iwl_dealloc_ucode(struct iwl_trans *trans) +void iwl_dealloc_ucode(struct iwl_nic *nic) { - iwl_free_fw_img(trans, &trans->ucode_rt); - iwl_free_fw_img(trans, &trans->ucode_init); - iwl_free_fw_img(trans, &trans->ucode_wowlan); + iwl_free_fw_img(nic, &nic->fw.ucode_rt); + iwl_free_fw_img(nic, &nic->fw.ucode_init); + iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); } -static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, +static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -112,7 +113,7 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans->dev, len, + desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; @@ -122,16 +123,16 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, return 0; } -static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, +static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, enum iwl_ucode_type ucode_type) { switch (ucode_type) { case IWL_UCODE_INIT: - return &trans->ucode_init; + return &nic->fw.ucode_init; case IWL_UCODE_WOWLAN: - return &trans->ucode_wowlan; + return &nic->fw.ucode_wowlan; case IWL_UCODE_REGULAR: - return &trans->ucode_rt; + return &nic->fw.ucode_rt; case IWL_UCODE_NONE: break; } @@ -397,15 +398,16 @@ static int iwl_alive_notify(struct iwl_trans *trans) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_trans *trans, +static int iwl_verify_inst_sparse(struct iwl_nic *nic, struct fw_desc *fw_desc) { + struct iwl_trans *trans = trans(nic); __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; u32 val; u32 i; - IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ @@ -421,16 +423,17 @@ static int iwl_verify_inst_sparse(struct iwl_trans *trans, return 0; } -static void iwl_print_mismatch_inst(struct iwl_trans *trans, +static void iwl_print_mismatch_inst(struct iwl_nic *nic, struct fw_desc *fw_desc) { + struct iwl_trans *trans = trans(nic); __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; u32 val; u32 offs; int errors = 0; - IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); @@ -441,7 +444,7 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans, /* read data comes through single port, auto-incr addr */ val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(trans, "uCode INST section at " + IWL_ERR(nic, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", offs, val, le32_to_cpu(*image)); errors++; @@ -453,24 +456,24 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans, * iwl_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -static int iwl_verify_ucode(struct iwl_trans *trans, +static int iwl_verify_ucode(struct iwl_nic *nic, enum iwl_ucode_type ucode_type) { - struct fw_img *img = iwl_get_ucode_image(trans, ucode_type); + struct fw_img *img = iwl_get_ucode_image(nic, ucode_type); if (!img) { - IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type); + IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type); return -EINVAL; } - if (!iwl_verify_inst_sparse(trans, &img->code)) { - IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); + if (!iwl_verify_inst_sparse(nic, &img->code)) { + IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n"); return 0; } - IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); + IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(trans, &img->code); + iwl_print_mismatch_inst(nic, &img->code); return -EIO; } @@ -583,7 +586,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, old_type = trans->shrd->ucode_type; trans->shrd->ucode_type = ucode_type; - fw = iwl_get_ucode_image(trans, ucode_type); + fw = iwl_get_ucode_image(nic(trans), ucode_type); if (!fw) return -EINVAL; @@ -618,7 +621,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, * skip it for WoWLAN. */ if (ucode_type != IWL_UCODE_WOWLAN) { - ret = iwl_verify_ucode(trans, ucode_type); + ret = iwl_verify_ucode(nic(trans), ucode_type); if (ret) { trans->shrd->ucode_type = old_type; return ret; @@ -647,7 +650,7 @@ int iwl_run_init_ucode(struct iwl_trans *trans) lockdep_assert_held(&trans->shrd->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!trans->ucode_init.code.len) + if (!nic(trans)->fw.ucode_init.code.len) return 0; if (trans->shrd->ucode_type != IWL_UCODE_NONE) @@ -685,42 +688,42 @@ int iwl_run_init_ucode(struct iwl_trans *trans) static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); -#define UCODE_EXPERIMENTAL_INDEX 100 #define UCODE_EXPERIMENTAL_TAG "exp" -int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) +int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first) { - const char *name_pre = cfg(priv)->fw_name_pre; + struct iwl_cfg *cfg = cfg(nic); + const char *name_pre = cfg->fw_name_pre; char tag[8]; if (first) { #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - priv->fw_index = UCODE_EXPERIMENTAL_INDEX; + nic->fw_index = UCODE_EXPERIMENTAL_INDEX; strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { + } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { #endif - priv->fw_index = cfg(priv)->ucode_api_max; - sprintf(tag, "%d", priv->fw_index); + nic->fw_index = cfg->ucode_api_max; + sprintf(tag, "%d", nic->fw_index); } else { - priv->fw_index--; - sprintf(tag, "%d", priv->fw_index); + nic->fw_index--; + sprintf(tag, "%d", nic->fw_index); } - if (priv->fw_index < cfg(priv)->ucode_api_min) { - IWL_ERR(priv, "no suitable firmware found!\n"); + if (nic->fw_index < cfg->ucode_api_min) { + IWL_ERR(nic, "no suitable firmware found!\n"); return -ENOENT; } - sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) ? "EXPERIMENTAL " : "", - priv->firmware_name); + nic->firmware_name); - return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - trans(priv)->dev, - GFP_KERNEL, priv, iwl_ucode_callback); + return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, + trans(nic)->dev, + GFP_KERNEL, nic, iwl_ucode_callback); } struct iwlagn_firmware_pieces { @@ -728,31 +731,30 @@ struct iwlagn_firmware_pieces { size_t inst_size, data_size, init_size, init_data_size, wowlan_inst_size, wowlan_data_size; - u32 build; - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; }; -static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, +static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, const struct firmware *ucode_raw, struct iwlagn_firmware_pieces *pieces) { struct iwl_ucode_header *ucode = (void *)ucode_raw->data; - u32 api_ver, hdr_size; + u32 api_ver, hdr_size, build; + char buildstr[25]; const u8 *src; - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); + nic->fw.ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(nic->fw.ucode_ver); switch (api_ver) { default: hdr_size = 28; if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); + IWL_ERR(nic, "File size too small!\n"); return -EINVAL; } - pieces->build = le32_to_cpu(ucode->u.v2.build); + build = le32_to_cpu(ucode->u.v2.build); pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); @@ -764,10 +766,10 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, case 2: hdr_size = 24; if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); + IWL_ERR(nic, "File size too small!\n"); return -EINVAL; } - pieces->build = 0; + build = 0; pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); @@ -776,12 +778,28 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, break; } + if (build) + sprintf(buildstr, " build %u%s", build, + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(nic->fw.fw_version, + sizeof(nic->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(nic->fw.ucode_ver), + IWL_UCODE_MINOR(nic->fw.ucode_ver), + IWL_UCODE_API(nic->fw.ucode_ver), + IWL_UCODE_SERIAL(nic->fw.ucode_ver), + buildstr); + /* Verify size of file vs. image size info in file's header */ if (ucode_raw->size != hdr_size + pieces->inst_size + pieces->data_size + pieces->init_size + pieces->init_data_size) { - IWL_ERR(priv, + IWL_ERR(nic, "uCode file size %d does not match expected size\n", (int)ucode_raw->size); return -EINVAL; @@ -799,10 +817,10 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, return 0; } -static int iwlagn_load_firmware(struct iwl_priv *priv, +static int iwl_parse_tlv_firmware(struct iwl_nic *nic, const struct firmware *ucode_raw, struct iwlagn_firmware_pieces *pieces, - struct iwlagn_ucode_capabilities *capa) + struct iwl_ucode_capabilities *capa) { struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; struct iwl_ucode_tlv *tlv; @@ -814,14 +832,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, u32 tlv_len; enum iwl_ucode_tlv_type tlv_type; const u8 *tlv_data; + char buildstr[25]; + u32 build; if (len < sizeof(*ucode)) { - IWL_ERR(priv, "uCode has invalid length: %zd\n", len); + IWL_ERR(nic, "uCode has invalid length: %zd\n", len); return -EINVAL; } if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(priv, "invalid uCode magic: 0X%x\n", + IWL_ERR(nic, "invalid uCode magic: 0X%x\n", le32_to_cpu(ucode->magic)); return -EINVAL; } @@ -839,12 +859,29 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) wanted_alternative--; if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(priv, + IWL_WARN(nic, "uCode alternative %d not available, choosing %d\n", tmp, wanted_alternative); - priv->ucode_ver = le32_to_cpu(ucode->ver); - pieces->build = le32_to_cpu(ucode->build); + nic->fw.ucode_ver = le32_to_cpu(ucode->ver); + build = le32_to_cpu(ucode->build); + + if (build) + sprintf(buildstr, " build %u%s", build, + (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(nic->fw.fw_version, + sizeof(nic->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(nic->fw.ucode_ver), + IWL_UCODE_MINOR(nic->fw.ucode_ver), + IWL_UCODE_API(nic->fw.ucode_ver), + IWL_UCODE_SERIAL(nic->fw.ucode_ver), + buildstr); + data = ucode->data; len -= sizeof(*ucode); @@ -861,7 +898,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, tlv_data = tlv->data; if (len < tlv_len) { - IWL_ERR(priv, "invalid TLV len: %zd/%u\n", + IWL_ERR(nic, "invalid TLV len: %zd/%u\n", len, tlv_len); return -EINVAL; } @@ -894,7 +931,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, pieces->init_data_size = tlv_len; break; case IWL_UCODE_TLV_BOOT: - IWL_ERR(priv, "Found unexpected BOOT ucode\n"); + IWL_ERR(nic, "Found unexpected BOOT ucode\n"); break; case IWL_UCODE_TLV_PROBE_MAX_LEN: if (tlv_len != sizeof(u32)) @@ -962,7 +999,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, case IWL_UCODE_TLV_ENHANCE_SENS_TBL: if (tlv_len) goto invalid_tlv_len; - priv->enhance_sensitivity_table = true; + nic->fw.enhance_sensitivity_table = true; break; case IWL_UCODE_TLV_WOWLAN_INST: pieces->wowlan_inst = tlv_data; @@ -979,22 +1016,22 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, le32_to_cpup((__le32 *)tlv_data); break; default: - IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); + IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); break; } } if (len) { - IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); + IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); return -EINVAL; } return 0; invalid_tlv_len: - IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); + IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); return -EINVAL; } @@ -1007,21 +1044,20 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, */ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) { - struct iwl_priv *priv = context; + struct iwl_nic *nic = context; + struct iwl_cfg *cfg = cfg(nic); + struct iwl_fw *fw = &nic->fw; struct iwl_ucode_header *ucode; int err; struct iwlagn_firmware_pieces pieces; - const unsigned int api_max = cfg(priv)->ucode_api_max; - unsigned int api_ok = cfg(priv)->ucode_api_ok; - const unsigned int api_min = cfg(priv)->ucode_api_min; + const unsigned int api_max = cfg->ucode_api_max; + unsigned int api_ok = cfg->ucode_api_ok; + const unsigned int api_min = cfg->ucode_api_min; u32 api_ver; - char buildstr[25]; - u32 build; - struct iwlagn_ucode_capabilities ucode_capa = { - .max_probe_length = 200, - .standard_phy_calibration_size = - IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, - }; + + fw->ucode_capa.max_probe_length = 200; + fw->ucode_capa.standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; if (!api_ok) api_ok = api_max; @@ -1029,19 +1065,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) memset(&pieces, 0, sizeof(pieces)); if (!ucode_raw) { - if (priv->fw_index <= api_ok) - IWL_ERR(priv, + if (nic->fw_index <= api_ok) + IWL_ERR(nic, "request for firmware file '%s' failed.\n", - priv->firmware_name); + nic->firmware_name); goto try_again; } - IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", - priv->firmware_name, ucode_raw->size); + IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", + nic->firmware_name, ucode_raw->size); /* Make sure that we got at least the API version number */ if (ucode_raw->size < 4) { - IWL_ERR(priv, "File size way too small!\n"); + IWL_ERR(nic, "File size way too small!\n"); goto try_again; } @@ -1049,16 +1085,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ucode = (struct iwl_ucode_header *)ucode_raw->data; if (ucode->ver) - err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); + err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); else - err = iwlagn_load_firmware(priv, ucode_raw, &pieces, - &ucode_capa); + err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, + &fw->ucode_capa); if (err) goto try_again; - api_ver = IWL_UCODE_API(priv->ucode_ver); - build = pieces.build; + api_ver = IWL_UCODE_API(nic->fw.ucode_ver); /* * api_ver should match the api version forming part of the @@ -1066,9 +1101,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * on the API version read from firmware header from here on forward */ /* no api version check required for experimental uCode */ - if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, + IWL_ERR(nic, "Driver unable to support your firmware API. " "Driver supports v%u, firmware is v%u.\n", api_max, api_ver); @@ -1077,40 +1112,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (api_ver < api_ok) { if (api_ok != api_max) - IWL_ERR(priv, "Firmware has old API version, " + IWL_ERR(nic, "Firmware has old API version, " "expected v%u through v%u, got v%u.\n", api_ok, api_max, api_ver); else - IWL_ERR(priv, "Firmware has old API version, " + IWL_ERR(nic, "Firmware has old API version, " "expected v%u, got v%u.\n", api_max, api_ver); - IWL_ERR(priv, "New firmware can be obtained from " + IWL_ERR(nic, "New firmware can be obtained from " "http://www.intellinuxwireless.org/.\n"); } } - if (build) - sprintf(buildstr, " build %u%s", build, - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); + IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); /* * For any of the failures below (before allocating pci memory) @@ -1118,38 +1132,38 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * user just got a corrupted version of the latest API. */ - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", + IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", + nic->fw.ucode_ver); + IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", pieces.inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", + IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", pieces.data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", + IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", pieces.init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", + IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", pieces.init_data_size); /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", + if (pieces.inst_size > cfg->max_inst_size) { + IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", pieces.inst_size); goto try_again; } - if (pieces.data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", + if (pieces.data_size > cfg->max_data_size) { + IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", pieces.data_size); goto try_again; } - if (pieces.init_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", + if (pieces.init_size > cfg->max_inst_size) { + IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", pieces.init_size); goto try_again; } - if (pieces.init_data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", + if (pieces.init_data_size > cfg->max_data_size) { + IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", pieces.init_data_size); goto try_again; } @@ -1159,34 +1173,34 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, + if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, + if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.code, + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.data, + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } /* WoWLAN instructions and data */ if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.code, + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_wowlan.code, pieces.wowlan_inst, pieces.wowlan_inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.data, + if (iwl_alloc_fw_desc(nic, + &nic->fw.ucode_wowlan.data, pieces.wowlan_data, pieces.wowlan_data_size)) goto err_pci_alloc; @@ -1199,92 +1213,54 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * for each event, which is of mode 1 (including timestamp) for all * new microcodes that include this information. */ - priv->init_evtlog_ptr = pieces.init_evtlog_ptr; + nic->init_evtlog_ptr = pieces.init_evtlog_ptr; if (pieces.init_evtlog_size) - priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; else - priv->init_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->init_errlog_ptr = pieces.init_errlog_ptr; - priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + nic->init_evtlog_size = + cfg->base_params->max_event_log_size; + nic->init_errlog_ptr = pieces.init_errlog_ptr; + nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; if (pieces.inst_evtlog_size) - priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; else - priv->inst_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->inst_errlog_ptr = pieces.inst_errlog_ptr; -#ifndef CONFIG_IWLWIFI_P2P - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; -#endif - - priv->new_scan_threshold_behaviour = - !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + nic->inst_evtlog_size = + cfg->base_params->max_event_log_size; + nic->inst_errlog_ptr = pieces.inst_errlog_ptr; - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { - priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - } else { - priv->sta_key_max_num = STA_KEY_MAX_NUM; - priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - } /* * figure out the offset of chain noise reset and gain commands * base on the size of standard phy calibration commands table size */ - if (ucode_capa.standard_phy_calibration_size > + if (fw->ucode_capa.standard_phy_calibration_size > IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - ucode_capa.standard_phy_calibration_size = + fw->ucode_capa.standard_phy_calibration_size = IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - priv->phy_calib_chain_noise_reset_cmd = - ucode_capa.standard_phy_calibration_size; - priv->phy_calib_chain_noise_gain_cmd = - ucode_capa.standard_phy_calibration_size + 1; + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&nic->request_firmware_complete); - /* initialize all valid contexts */ - iwl_init_context(priv, ucode_capa.flags); + nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); - /************************************************** - * This is still part of probe() in a sense... - * - * 9. Setup and register with mac80211 and debugfs - **************************************************/ - err = iwlagn_mac_setup_register(priv, &ucode_capa); - if (err) + if (!nic->op_mode) goto out_unbind; - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - complete(&priv->firmware_loading_complete); return; try_again: /* try next, if any */ - if (iwl_request_firmware(priv, false)) - goto out_unbind; release_firmware(ucode_raw); + if (iwl_request_firmware(nic, false)) + goto out_unbind; return; err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(trans(priv)); - out_unbind: - complete(&priv->firmware_loading_complete); - device_release_driver(trans(priv)->dev); + IWL_ERR(nic, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(nic); release_firmware(ucode_raw); + out_unbind: + complete(&nic->request_firmware_complete); + device_release_driver(trans(nic)->dev); } |