aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5912cdec33a7..b3c263d2724f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1570,24 +1570,40 @@ static void iwl_nic_start(struct iwl_priv *priv)
1570static int iwl_read_ucode(struct iwl_priv *priv) 1570static int iwl_read_ucode(struct iwl_priv *priv)
1571{ 1571{
1572 struct iwl_ucode *ucode; 1572 struct iwl_ucode *ucode;
1573 int ret; 1573 int ret = -EINVAL, index;
1574 const struct firmware *ucode_raw; 1574 const struct firmware *ucode_raw;
1575 const char *name = priv->cfg->fw_name; 1575 const char *name_pre = priv->cfg->fw_name_pre;
1576 const unsigned int api_max = priv->cfg->ucode_api_max;
1577 const unsigned int api_min = priv->cfg->ucode_api_min;
1578 char buf[25];
1576 u8 *src; 1579 u8 *src;
1577 size_t len; 1580 size_t len;
1578 u32 inst_size, data_size, init_size, init_data_size, boot_size; 1581 u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
1579 1582
1580 /* Ask kernel firmware_class module to get the boot firmware off disk. 1583 /* Ask kernel firmware_class module to get the boot firmware off disk.
1581 * request_firmware() is synchronous, file is in memory on return. */ 1584 * request_firmware() is synchronous, file is in memory on return. */
1582 ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); 1585 for (index = api_max; index >= api_min; index--) {
1583 if (ret < 0) { 1586 sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
1584 IWL_ERROR("%s firmware file req failed: Reason %d\n", 1587 ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
1585 name, ret); 1588 if (ret < 0) {
1586 goto error; 1589 IWL_ERROR("%s firmware file req failed: Reason %d\n",
1590 buf, ret);
1591 if (ret == -ENOENT)
1592 continue;
1593 else
1594 goto error;
1595 } else {
1596 if (index < api_max)
1597 IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
1598 buf, api_max);
1599 IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
1600 buf, ucode_raw->size);
1601 break;
1602 }
1587 } 1603 }
1588 1604
1589 IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", 1605 if (ret < 0)
1590 name, ucode_raw->size); 1606 goto error;
1591 1607
1592 /* Make sure that we got at least our header! */ 1608 /* Make sure that we got at least our header! */
1593 if (ucode_raw->size < sizeof(*ucode)) { 1609 if (ucode_raw->size < sizeof(*ucode)) {
@@ -1600,19 +1616,39 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1600 ucode = (void *)ucode_raw->data; 1616 ucode = (void *)ucode_raw->data;
1601 1617
1602 priv->ucode_ver = le32_to_cpu(ucode->ver); 1618 priv->ucode_ver = le32_to_cpu(ucode->ver);
1619 api_ver = IWL_UCODE_API(priv->ucode_ver);
1603 inst_size = le32_to_cpu(ucode->inst_size); 1620 inst_size = le32_to_cpu(ucode->inst_size);
1604 data_size = le32_to_cpu(ucode->data_size); 1621 data_size = le32_to_cpu(ucode->data_size);
1605 init_size = le32_to_cpu(ucode->init_size); 1622 init_size = le32_to_cpu(ucode->init_size);
1606 init_data_size = le32_to_cpu(ucode->init_data_size); 1623 init_data_size = le32_to_cpu(ucode->init_data_size);
1607 boot_size = le32_to_cpu(ucode->boot_size); 1624 boot_size = le32_to_cpu(ucode->boot_size);
1608 1625
1609 IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", 1626 /* api_ver should match the api version forming part of the
1610 priv->ucode_ver); 1627 * firmware filename ... but we don't check for that and only rely
1611 IWL_DEBUG_INFO("f/w package hdr ucode version = %u.%u.%u.%u\n", 1628 * on the API version read from firware header from here on forward */
1629
1630 if (api_ver < api_min || api_ver > api_max) {
1631 IWL_ERROR("Driver unable to support your firmware API. "
1632 "Driver supports v%u, firmware is v%u.\n",
1633 api_max, api_ver);
1634 priv->ucode_ver = 0;
1635 ret = -EINVAL;
1636 goto err_release;
1637 }
1638 if (api_ver != api_max)
1639 IWL_ERROR("Firmware has old API version. Expected v%u, "
1640 "got v%u. New firmware can be obtained "
1641 "from http://www.intellinuxwireless.org.\n",
1642 api_max, api_ver);
1643
1644 printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
1612 IWL_UCODE_MAJOR(priv->ucode_ver), 1645 IWL_UCODE_MAJOR(priv->ucode_ver),
1613 IWL_UCODE_MINOR(priv->ucode_ver), 1646 IWL_UCODE_MINOR(priv->ucode_ver),
1614 IWL_UCODE_API(priv->ucode_ver), 1647 IWL_UCODE_API(priv->ucode_ver),
1615 IWL_UCODE_SERIAL(priv->ucode_ver)); 1648 IWL_UCODE_SERIAL(priv->ucode_ver));
1649
1650 IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
1651 priv->ucode_ver);
1616 IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", 1652 IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n",
1617 inst_size); 1653 inst_size);
1618 IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", 1654 IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n",