diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-04-16 11:29:24 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-22 13:21:18 -0400 |
commit | dbf28e21ca391110e90ccad05dda79d2e2f60e0e (patch) | |
tree | 76aa45ec1cfb00c09b9cae51742c475ab821911a /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | ca7966c88e44233fac113579071a6f55e00ef5ac (diff) |
iwlagn: combine firmware code/data
On new hardware, ucode images always come in
pairs: code and data. Therefore, combine the
variables into an appropriate struct and use
that when both code and data are needed.
Also, combine allocation and copying so that
we have less code in total.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 98 |
1 files changed, 45 insertions, 53 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 12cd5e0352bc..f30735b656c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1173,12 +1173,42 @@ static struct attribute_group iwl_attribute_group = { | |||
1173 | * | 1173 | * |
1174 | ******************************************************************************/ | 1174 | ******************************************************************************/ |
1175 | 1175 | ||
1176 | static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) | ||
1177 | { | ||
1178 | if (desc->v_addr) | ||
1179 | dma_free_coherent(&pci_dev->dev, desc->len, | ||
1180 | desc->v_addr, desc->p_addr); | ||
1181 | desc->v_addr = NULL; | ||
1182 | desc->len = 0; | ||
1183 | } | ||
1184 | |||
1185 | static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) | ||
1186 | { | ||
1187 | iwl_free_fw_desc(pci_dev, &img->code); | ||
1188 | iwl_free_fw_desc(pci_dev, &img->data); | ||
1189 | } | ||
1190 | |||
1191 | static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, | ||
1192 | const void *data, size_t len) | ||
1193 | { | ||
1194 | if (!len) { | ||
1195 | desc->v_addr = NULL; | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, | ||
1200 | &desc->p_addr, GFP_KERNEL); | ||
1201 | if (!desc->v_addr) | ||
1202 | return -ENOMEM; | ||
1203 | desc->len = len; | ||
1204 | memcpy(desc->v_addr, data, len); | ||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1176 | static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | 1208 | static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) |
1177 | { | 1209 | { |
1178 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); | 1210 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); |
1179 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); | 1211 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); |
1180 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); | ||
1181 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); | ||
1182 | } | 1212 | } |
1183 | 1213 | ||
1184 | struct iwlagn_ucode_capabilities { | 1214 | struct iwlagn_ucode_capabilities { |
@@ -1647,24 +1677,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1647 | /* Runtime instructions and 2 copies of data: | 1677 | /* Runtime instructions and 2 copies of data: |
1648 | * 1) unmodified from disk | 1678 | * 1) unmodified from disk |
1649 | * 2) backup cache for save/restore during power-downs */ | 1679 | * 2) backup cache for save/restore during power-downs */ |
1650 | priv->ucode_code.len = pieces.inst_size; | 1680 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, |
1651 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); | 1681 | pieces.inst, pieces.inst_size)) |
1652 | 1682 | goto err_pci_alloc; | |
1653 | priv->ucode_data.len = pieces.data_size; | 1683 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, |
1654 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); | 1684 | pieces.data, pieces.data_size)) |
1655 | |||
1656 | if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr) | ||
1657 | goto err_pci_alloc; | 1685 | goto err_pci_alloc; |
1658 | 1686 | ||
1659 | /* Initialization instructions and data */ | 1687 | /* Initialization instructions and data */ |
1660 | if (pieces.init_size && pieces.init_data_size) { | 1688 | if (pieces.init_size && pieces.init_data_size) { |
1661 | priv->ucode_init.len = pieces.init_size; | 1689 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, |
1662 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); | 1690 | pieces.init, pieces.init_size)) |
1663 | 1691 | goto err_pci_alloc; | |
1664 | priv->ucode_init_data.len = pieces.init_data_size; | 1692 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, |
1665 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); | 1693 | pieces.init_data, pieces.init_data_size)) |
1666 | |||
1667 | if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) | ||
1668 | goto err_pci_alloc; | 1694 | goto err_pci_alloc; |
1669 | } | 1695 | } |
1670 | 1696 | ||
@@ -1701,39 +1727,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1701 | else | 1727 | else |
1702 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | 1728 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; |
1703 | 1729 | ||
1704 | /* Copy images into buffers for card's bus-master reads ... */ | ||
1705 | |||
1706 | /* Runtime instructions (first block of data in file) */ | ||
1707 | IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", | ||
1708 | pieces.inst_size); | ||
1709 | memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size); | ||
1710 | |||
1711 | IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", | ||
1712 | priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); | ||
1713 | |||
1714 | /* | ||
1715 | * Runtime data | ||
1716 | * NOTE: Copy into backup buffer will be done in iwl_up() | ||
1717 | */ | ||
1718 | IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", | ||
1719 | pieces.data_size); | ||
1720 | memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); | ||
1721 | |||
1722 | /* Initialization instructions */ | ||
1723 | if (pieces.init_size) { | ||
1724 | IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", | ||
1725 | pieces.init_size); | ||
1726 | memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size); | ||
1727 | } | ||
1728 | |||
1729 | /* Initialization data */ | ||
1730 | if (pieces.init_data_size) { | ||
1731 | IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", | ||
1732 | pieces.init_data_size); | ||
1733 | memcpy(priv->ucode_init_data.v_addr, pieces.init_data, | ||
1734 | pieces.init_data_size); | ||
1735 | } | ||
1736 | |||
1737 | /* | 1730 | /* |
1738 | * figure out the offset of chain noise reset and gain commands | 1731 | * figure out the offset of chain noise reset and gain commands |
1739 | * base on the size of standard phy calibration commands table size | 1732 | * base on the size of standard phy calibration commands table size |
@@ -2450,8 +2443,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2450 | } | 2443 | } |
2451 | 2444 | ||
2452 | ret = iwlagn_load_ucode_wait_alive(priv, | 2445 | ret = iwlagn_load_ucode_wait_alive(priv, |
2453 | &priv->ucode_code, | 2446 | &priv->ucode_rt, |
2454 | &priv->ucode_data, | ||
2455 | UCODE_SUBTYPE_REGULAR, | 2447 | UCODE_SUBTYPE_REGULAR, |
2456 | UCODE_SUBTYPE_REGULAR_NEW); | 2448 | UCODE_SUBTYPE_REGULAR_NEW); |
2457 | if (ret) { | 2449 | if (ret) { |