From: Reinette Chatre <reinette.chatre@intel.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net,
Johannes Berg <johannes.berg@intel.com>,
Reinette Chatre <reinette.chatre@intel.com>
Subject: [PATCH 21/47] iwlagn: prepare for new firmware file format
Date: Mon, 10 May 2010 15:27:52 -0700 [thread overview]
Message-ID: <1273530498-11876-22-git-send-email-reinette.chatre@intel.com> (raw)
In-Reply-To: <1273530498-11876-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
Currently the first four bytes in a firmware file
indicate the major, minor and api versions as well
as the serial number. These combined can never be
zero, so we can use that special case for a new,
future, file format.
This patch simply shuffles the code and prepares
for that new format.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 291 ++++++++++++++++++--------------
1 files changed, 168 insertions(+), 123 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 70094bb..65ae636 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1534,6 +1534,91 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
iwl_ucode_callback);
}
+struct iwlagn_firmware_pieces {
+ const void *inst, *data, *init, *init_data, *boot;
+ size_t inst_size, data_size, init_size, init_data_size, boot_size;
+
+ u32 build;
+};
+
+static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
+ const struct firmware *ucode_raw,
+ struct iwlagn_firmware_pieces *pieces)
+{
+ struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
+ u32 api_ver, hdr_size;
+ const u8 *src;
+
+ priv->ucode_ver = le32_to_cpu(ucode->ver);
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+
+ switch (api_ver) {
+ default:
+ /*
+ * 4965 doesn't revision the firmware file format
+ * along with the API version, it always uses v1
+ * file format.
+ */
+ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
+ CSR_HW_REV_TYPE_4965) {
+ hdr_size = 28;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
+ }
+ pieces->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);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+ pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
+ src = ucode->u.v2.data;
+ break;
+ }
+ /* fall through for 4965 */
+ case 0:
+ case 1:
+ case 2:
+ hdr_size = 24;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
+ }
+ pieces->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);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
+ pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
+ src = ucode->u.v1.data;
+ break;
+ }
+
+ /* 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 + pieces->boot_size) {
+
+ IWL_ERR(priv,
+ "uCode file size %d does not match expected size\n",
+ (int)ucode_raw->size);
+ return -EINVAL;
+ }
+
+ pieces->inst = src;
+ src += pieces->inst_size;
+ pieces->data = src;
+ src += pieces->data_size;
+ pieces->init = src;
+ src += pieces->init_size;
+ pieces->init_data = src;
+ src += pieces->init_data_size;
+ pieces->boot = src;
+ src += pieces->boot_size;
+
+ return 0;
+}
+
/**
* iwl_ucode_callback - callback when firmware was loaded
*
@@ -1544,14 +1629,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
{
struct iwl_priv *priv = context;
struct iwl_ucode_header *ucode;
+ int err;
+ struct iwlagn_firmware_pieces pieces;
const unsigned int api_max = priv->cfg->ucode_api_max;
const unsigned int api_min = priv->cfg->ucode_api_min;
- u8 *src;
- size_t len;
- u32 api_ver, build;
- u32 inst_size, data_size, init_size, init_data_size, boot_size;
- int err, hdr_size;
+ u32 api_ver;
char buildstr[25];
+ u32 build;
+
+ memset(&pieces, 0, sizeof(pieces));
if (!ucode_raw) {
IWL_ERR(priv, "request for firmware file '%s' failed.\n",
@@ -1571,54 +1657,22 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
/* Data from ucode file: header followed by uCode images */
ucode = (struct iwl_ucode_header *)ucode_raw->data;
- priv->ucode_ver = le32_to_cpu(ucode->ver);
- api_ver = IWL_UCODE_API(priv->ucode_ver);
+ if (ucode->ver)
+ err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
+ else
+ err = -EINVAL;
- switch (api_ver) {
- default:
- /*
- * 4965 doesn't revision the firmware file format
- * along with the API version, it always uses v1
- * file format.
- */
- if (priv->cfg != &iwl4965_agn_cfg) {
- hdr_size = 28;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- goto try_again;
- }
- build = ucode->u.v2.build;
- inst_size = ucode->u.v2.inst_size;
- data_size = ucode->u.v2.data_size;
- init_size = ucode->u.v2.init_size;
- init_data_size = ucode->u.v2.init_data_size;
- boot_size = ucode->u.v2.boot_size;
- src = ucode->u.v2.data;
- break;
- }
- /* fall through for 4965 */
- case 0:
- case 1:
- case 2:
- hdr_size = 24;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- goto try_again;
- }
- build = 0;
- inst_size = ucode->u.v1.inst_size;
- data_size = ucode->u.v1.data_size;
- init_size = ucode->u.v1.init_size;
- init_data_size = ucode->u.v1.init_data_size;
- boot_size = ucode->u.v1.boot_size;
- src = ucode->u.v1.data;
- break;
- }
+ if (err)
+ goto try_again;
- /* api_ver should match the api version forming part of the
- * firmware filename ... but we don't check for that and only rely
- * on the API version read from firmware header from here on forward */
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+ build = pieces.build;
+ /*
+ * api_ver should match the api version forming part of the
+ * firmware filename ... but we don't check for that and only rely
+ * on the API version read from firmware header from here on forward
+ */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
@@ -1653,75 +1707,69 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
IWL_UCODE_SERIAL(priv->ucode_ver),
buildstr);
- 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 = %u\n",
- inst_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
- data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
- init_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
- init_data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
- boot_size);
-
/*
* For any of the failures below (before allocating pci memory)
* we will try to load a version with a smaller API -- maybe the
* user just got a corrupted version of the latest API.
*/
- /* Verify size of file vs. image size info in file's header */
- if (ucode_raw->size != hdr_size + inst_size + data_size + init_size +
- init_data_size + boot_size) {
-
- IWL_DEBUG_INFO(priv,
- "uCode file size %d does not match expected size\n",
- (int)ucode_raw->size);
- goto try_again;
- }
+ 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",
+ pieces.inst_size);
+ IWL_DEBUG_INFO(priv, "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",
+ pieces.init_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
+ pieces.init_data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
+ pieces.boot_size);
/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
- inst_size);
+ if (pieces.inst_size > priv->hw_params.max_inst_size) {
+ IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
+ pieces.inst_size);
goto try_again;
}
- if (data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
- data_size);
+ if (pieces.data_size > priv->hw_params.max_data_size) {
+ IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
+ pieces.data_size);
goto try_again;
}
- if (init_size > priv->hw_params.max_inst_size) {
- IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
- init_size);
+
+ if (pieces.init_size > priv->hw_params.max_inst_size) {
+ IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
+ pieces.init_size);
goto try_again;
}
- if (init_data_size > priv->hw_params.max_data_size) {
- IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
- init_data_size);
+
+ if (pieces.init_data_size > priv->hw_params.max_data_size) {
+ IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
+ pieces.init_data_size);
goto try_again;
}
- if (boot_size > priv->hw_params.max_bsm_size) {
- IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
- boot_size);
+
+ if (pieces.boot_size > priv->hw_params.max_bsm_size) {
+ IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
+ pieces.boot_size);
goto try_again;
}
+
/* Allocate ucode buffers for card's bus-master loading ... */
/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
- priv->ucode_code.len = inst_size;
+ priv->ucode_code.len = pieces.inst_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
- priv->ucode_data.len = data_size;
+ priv->ucode_data.len = pieces.data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
- priv->ucode_data_backup.len = data_size;
+ priv->ucode_data_backup.len = pieces.data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
@@ -1729,11 +1777,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto err_pci_alloc;
/* Initialization instructions and data */
- if (init_size && init_data_size) {
- priv->ucode_init.len = init_size;
+ if (pieces.init_size && pieces.init_data_size) {
+ priv->ucode_init.len = pieces.init_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
- priv->ucode_init_data.len = init_data_size;
+ priv->ucode_init_data.len = pieces.init_data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
@@ -1741,8 +1789,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
}
/* Bootstrap (instructions only, no data) */
- if (boot_size) {
- priv->ucode_boot.len = boot_size;
+ if (pieces.boot_size) {
+ priv->ucode_boot.len = pieces.boot_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
if (!priv->ucode_boot.v_addr)
@@ -1752,44 +1800,41 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
/* Copy images into buffers for card's bus-master reads ... */
/* Runtime instructions (first block of data in file) */
- len = inst_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
- memcpy(priv->ucode_code.v_addr, src, len);
- src += len;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
+ pieces.inst_size);
+ memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
- /* Runtime data (2nd block)
- * NOTE: Copy into backup buffer will be done in iwl_up() */
- len = data_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
- memcpy(priv->ucode_data.v_addr, src, len);
- memcpy(priv->ucode_data_backup.v_addr, src, len);
- src += len;
-
- /* Initialization instructions (3rd block) */
- if (init_size) {
- len = init_size;
+ /*
+ * Runtime data
+ * NOTE: Copy into backup buffer will be done in iwl_up()
+ */
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
+ pieces.data_size);
+ memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
+ memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
+
+ /* Initialization instructions */
+ if (pieces.init_size) {
IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
- len);
- memcpy(priv->ucode_init.v_addr, src, len);
- src += len;
+ pieces.init_size);
+ memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
}
- /* Initialization data (4th block) */
- if (init_data_size) {
- len = init_data_size;
+ /* Initialization data */
+ if (pieces.init_data_size) {
IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
- len);
- memcpy(priv->ucode_init_data.v_addr, src, len);
- src += len;
+ pieces.init_data_size);
+ memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
+ pieces.init_data_size);
}
- /* Bootstrap instructions (5th block) */
- len = boot_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
- memcpy(priv->ucode_boot.v_addr, src, len);
+ /* Bootstrap instructions */
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
+ pieces.boot_size);
+ memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
/**************************************************
* This is still part of probe() in a sense...
--
1.6.3.3
next prev parent reply other threads:[~2010-05-10 22:28 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-10 22:27 [PATCH 00/47] iwlwifi updates for 2.6.35 Reinette Chatre
2010-05-10 22:27 ` [PATCH 01/47] iwlwifi: rename 6000 series Gen2 devices to Gen2a Reinette Chatre
2010-05-10 22:46 ` Gábor Stefanik
2010-05-10 22:52 ` Zhao, Shanyu
2010-05-10 22:27 ` [PATCH 02/47] iwl3945: fix scan races Reinette Chatre
2010-05-10 22:27 ` [PATCH 03/47] iwlwifi: remove powersave debugfs if it is not supported Reinette Chatre
2010-05-10 22:27 ` [PATCH 04/47] iwlwifi: rename "tx_power" to "chain_tx_power" Reinette Chatre
2010-05-10 22:27 ` [PATCH 05/47] iwlwifi: use vif iwl_bss_info_changed Reinette Chatre
2010-05-10 22:27 ` [PATCH 06/47] iwlwifi: remove device type checking for tx power in debugfs Reinette Chatre
2010-05-10 22:27 ` [PATCH 07/47] iwlwifi: use .cfg to enable/disable continuous ucode trace Reinette Chatre
2010-05-10 22:27 ` [PATCH 08/47] iwlwifi: use cfg to configure calibration operation Reinette Chatre
2010-05-10 22:27 ` [PATCH 09/47] iwlwifi: give correct return information for tx power debugfs Reinette Chatre
2010-05-10 22:27 ` [PATCH 10/47] iwlwifi: wimax co-exist code clean up Reinette Chatre
2010-05-10 22:27 ` [PATCH 11/47] iwlwifi: checking for all the possible failure cases Reinette Chatre
2010-05-10 22:27 ` [PATCH 12/47] iwlwifi: dump firmware build info in error case Reinette Chatre
2010-05-10 22:27 ` [PATCH 13/47] iwlwifi: make bcast LQ command available for later restore actions Reinette Chatre
2010-05-10 22:27 ` [PATCH 14/47] iwl3945: use iwl3945_add_bcast_station Reinette Chatre
2010-05-10 22:27 ` [PATCH 15/47] iwlwifi: pass address to iwl_remove_station Reinette Chatre
2010-05-10 22:27 ` [PATCH 16/47] iwlwifi: manage IBSS station properly Reinette Chatre
2010-05-10 22:27 ` [PATCH 17/47] iwlagn: show and store firmware build number Reinette Chatre
2010-05-10 22:27 ` [PATCH 18/47] iwl3945: remove ucode access indirection Reinette Chatre
2010-05-10 22:27 ` [PATCH 19/47] iwlwifi: remove ucode virtual functions Reinette Chatre
2010-05-10 22:27 ` [PATCH 20/47] iwlwifi: move eeprom version printout to eeprom init Reinette Chatre
2010-05-10 22:27 ` Reinette Chatre [this message]
2010-05-10 22:27 ` [PATCH 22/47] iwlagn: implement loading a new firmware file type Reinette Chatre
2010-05-10 22:27 ` [PATCH 23/47] iwl3945: add plcp error checking Reinette Chatre
2010-05-10 22:27 ` [PATCH 24/47] iwlwifi: remove rts_threshold Reinette Chatre
2010-05-10 22:27 ` [PATCH 25/47] iwlagn: move iwl_get_ra_sta_id to 4965 Reinette Chatre
2010-05-10 22:27 ` [PATCH 26/47] iwlagn: use vif->type to check station Reinette Chatre
2010-05-10 22:27 ` [PATCH 27/47] iwlwifi: apply filter flags directly Reinette Chatre
2010-05-10 22:27 ` [PATCH 28/47] iwlwifi: push virtual interface through Reinette Chatre
2010-05-10 22:28 ` [PATCH 29/47] iwlagn: use virtual interface in TX aggregation handling Reinette Chatre
2010-05-10 22:28 ` [PATCH 30/47] iwlwifi: remove useless priv->vif check Reinette Chatre
2010-05-10 22:28 ` [PATCH 31/47] iwlwifi: use vif in iwl_ht_conf Reinette Chatre
2010-05-10 22:28 ` [PATCH 32/47] iwlwifi: note that priv->bssid is used only by 3945 Reinette Chatre
2010-05-10 22:28 ` [PATCH 33/47] iwlwifi: fix iwl_sta_init_lq station ID Reinette Chatre
2010-05-10 22:28 ` [PATCH 34/47] iwlwifi: split allocation/sending local station LQ Reinette Chatre
2010-05-10 22:28 ` [PATCH 35/47] iwlwifi: rework broadcast station management Reinette Chatre
2010-05-10 22:28 ` [PATCH 36/47] iwlagn: work around rate scaling reset delay Reinette Chatre
2010-05-10 22:28 ` [PATCH 37/47] iwlwifi: "tx power per chain" are part of ucode_tx_stats Reinette Chatre
2010-05-10 22:28 ` [PATCH 38/47] iwlwifi: provide more comments for cfg structure Reinette Chatre
2010-05-10 22:28 ` [PATCH 39/47] iwlwifi: track station IDs Reinette Chatre
2010-05-10 22:28 ` [PATCH 40/47] iwlwifi: add iwl_sta_id() Reinette Chatre
2010-05-10 22:28 ` [PATCH 41/47] iwlwifi: use iwl_find_station less Reinette Chatre
2010-05-10 22:28 ` [PATCH 42/47] iwlagn: use iwl_sta_id() for aggregation Reinette Chatre
2010-05-10 22:28 ` [PATCH 43/47] iwlwifi: use iwl_sta_id() for TKIP key update Reinette Chatre
2010-05-10 22:28 ` [PATCH 44/47] iwlwifi: move iwl_find_station() to 4965 Reinette Chatre
2010-05-10 22:28 ` [PATCH 45/47] iwlwifi: rename iwl_add_local_station Reinette Chatre
2010-05-10 22:28 ` [PATCH 46/47] iwlwifi: remove pointless HT check Reinette Chatre
2010-05-10 22:28 ` [PATCH 47/47] iwlwifi: clear driver stations when going down Reinette Chatre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1273530498-11876-22-git-send-email-reinette.chatre@intel.com \
--to=reinette.chatre@intel.com \
--cc=ipw3945-devel@lists.sourceforge.net \
--cc=johannes.berg@intel.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox