aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 03ff87fbe924..1d3efa9d01b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5296,25 +5296,41 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
5296static int iwl3945_read_ucode(struct iwl3945_priv *priv) 5296static int iwl3945_read_ucode(struct iwl3945_priv *priv)
5297{ 5297{
5298 struct iwl3945_ucode *ucode; 5298 struct iwl3945_ucode *ucode;
5299 int ret = 0; 5299 int ret = -EINVAL, index;
5300 const struct firmware *ucode_raw; 5300 const struct firmware *ucode_raw;
5301 /* firmware file name contains uCode/driver compatibility version */ 5301 /* firmware file name contains uCode/driver compatibility version */
5302 const char *name = priv->cfg->fw_name; 5302 const char *name_pre = priv->cfg->fw_name_pre;
5303 const unsigned int api_max = priv->cfg->ucode_api_max;
5304 const unsigned int api_min = priv->cfg->ucode_api_min;
5305 char buf[25];
5303 u8 *src; 5306 u8 *src;
5304 size_t len; 5307 size_t len;
5305 u32 inst_size, data_size, init_size, init_data_size, boot_size; 5308 u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
5306 5309
5307 /* Ask kernel firmware_class module to get the boot firmware off disk. 5310 /* Ask kernel firmware_class module to get the boot firmware off disk.
5308 * request_firmware() is synchronous, file is in memory on return. */ 5311 * request_firmware() is synchronous, file is in memory on return. */
5309 ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); 5312 for (index = api_max; index >= api_min; index--) {
5310 if (ret < 0) { 5313 sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
5311 IWL_ERROR("%s firmware file req failed: Reason %d\n", 5314 ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
5312 name, ret); 5315 if (ret < 0) {
5313 goto error; 5316 IWL_ERROR("%s firmware file req failed: Reason %d\n",
5317 buf, ret);
5318 if (ret == -ENOENT)
5319 continue;
5320 else
5321 goto error;
5322 } else {
5323 if (index < api_max)
5324 IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
5325 buf, api_max);
5326 IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
5327 buf, ucode_raw->size);
5328 break;
5329 }
5314 } 5330 }
5315 5331
5316 IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", 5332 if (ret < 0)
5317 name, ucode_raw->size); 5333 goto error;
5318 5334
5319 /* Make sure that we got at least our header! */ 5335 /* Make sure that we got at least our header! */
5320 if (ucode_raw->size < sizeof(*ucode)) { 5336 if (ucode_raw->size < sizeof(*ucode)) {
@@ -5327,25 +5343,45 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
5327 ucode = (void *)ucode_raw->data; 5343 ucode = (void *)ucode_raw->data;
5328 5344
5329 priv->ucode_ver = le32_to_cpu(ucode->ver); 5345 priv->ucode_ver = le32_to_cpu(ucode->ver);
5346 api_ver = IWL_UCODE_API(priv->ucode_ver);
5330 inst_size = le32_to_cpu(ucode->inst_size); 5347 inst_size = le32_to_cpu(ucode->inst_size);
5331 data_size = le32_to_cpu(ucode->data_size); 5348 data_size = le32_to_cpu(ucode->data_size);
5332 init_size = le32_to_cpu(ucode->init_size); 5349 init_size = le32_to_cpu(ucode->init_size);
5333 init_data_size = le32_to_cpu(ucode->init_data_size); 5350 init_data_size = le32_to_cpu(ucode->init_data_size);
5334 boot_size = le32_to_cpu(ucode->boot_size); 5351 boot_size = le32_to_cpu(ucode->boot_size);
5335 5352
5336 IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", 5353 /* api_ver should match the api version forming part of the
5337 priv->ucode_ver); 5354 * firmware filename ... but we don't check for that and only rely
5338 IWL_DEBUG_INFO("f/w package hdr ucode version = %u.%u.%u.%u\n", 5355 * on the API version read from firware header from here on forward */
5356
5357 if (api_ver < api_min || api_ver > api_max) {
5358 IWL_ERROR("Driver unable to support your firmware API. "
5359 "Driver supports v%u, firmware is v%u.\n",
5360 api_max, api_ver);
5361 priv->ucode_ver = 0;
5362 ret = -EINVAL;
5363 goto err_release;
5364 }
5365 if (api_ver != api_max)
5366 IWL_ERROR("Firmware has old API version. Expected %u, "
5367 "got %u. New firmware can be obtained "
5368 "from http://www.intellinuxwireless.org.\n",
5369 api_max, api_ver);
5370
5371 printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
5339 IWL_UCODE_MAJOR(priv->ucode_ver), 5372 IWL_UCODE_MAJOR(priv->ucode_ver),
5340 IWL_UCODE_MINOR(priv->ucode_ver), 5373 IWL_UCODE_MINOR(priv->ucode_ver),
5341 IWL_UCODE_API(priv->ucode_ver), 5374 IWL_UCODE_API(priv->ucode_ver),
5342 IWL_UCODE_SERIAL(priv->ucode_ver)); 5375 IWL_UCODE_SERIAL(priv->ucode_ver));
5376 IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
5377 priv->ucode_ver);
5343 IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); 5378 IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
5344 IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size); 5379 IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
5345 IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size); 5380 IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
5346 IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size); 5381 IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
5347 IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size); 5382 IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
5348 5383
5384
5349 /* Verify size of file vs. image size info in file's header */ 5385 /* Verify size of file vs. image size info in file's header */
5350 if (ucode_raw->size < sizeof(*ucode) + 5386 if (ucode_raw->size < sizeof(*ucode) +
5351 inst_size + data_size + init_size + 5387 inst_size + data_size + init_size +
@@ -8304,7 +8340,7 @@ static void __exit iwl3945_exit(void)
8304 iwl3945_rate_control_unregister(); 8340 iwl3945_rate_control_unregister();
8305} 8341}
8306 8342
8307MODULE_FIRMWARE("iwlwifi-3945" IWL3945_UCODE_API ".ucode"); 8343MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
8308 8344
8309module_param_named(antenna, iwl3945_param_antenna, int, 0444); 8345module_param_named(antenna, iwl3945_param_antenna, int, 0444);
8310MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); 8346MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");