aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-04-16 11:29:24 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-04-22 13:21:18 -0400
commitdbf28e21ca391110e90ccad05dda79d2e2f60e0e (patch)
tree76aa45ec1cfb00c09b9cae51742c475ab821911a /drivers/net/wireless
parentca7966c88e44233fac113579071a6f55e00ef5ac (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')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c98
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h24
6 files changed, 65 insertions, 98 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 56dc7712aa70..c3ae2e44fcc9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -161,17 +161,16 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
161} 161}
162 162
163static int iwlagn_load_given_ucode(struct iwl_priv *priv, 163static int iwlagn_load_given_ucode(struct iwl_priv *priv,
164 struct fw_desc *inst_image, 164 struct fw_img *image)
165 struct fw_desc *data_image)
166{ 165{
167 int ret = 0; 166 int ret = 0;
168 167
169 ret = iwlagn_load_section(priv, "INST", inst_image, 168 ret = iwlagn_load_section(priv, "INST", &image->code,
170 IWLAGN_RTC_INST_LOWER_BOUND); 169 IWLAGN_RTC_INST_LOWER_BOUND);
171 if (ret) 170 if (ret)
172 return ret; 171 return ret;
173 172
174 return iwlagn_load_section(priv, "DATA", data_image, 173 return iwlagn_load_section(priv, "DATA", &image->data,
175 IWLAGN_RTC_DATA_LOWER_BOUND); 174 IWLAGN_RTC_DATA_LOWER_BOUND);
176} 175}
177 176
@@ -557,16 +556,16 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv,
557 * iwl_verify_ucode - determine which instruction image is in SRAM, 556 * iwl_verify_ucode - determine which instruction image is in SRAM,
558 * and verify its contents 557 * and verify its contents
559 */ 558 */
560static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc) 559static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img)
561{ 560{
562 if (!iwlcore_verify_inst_sparse(priv, fw_desc)) { 561 if (!iwlcore_verify_inst_sparse(priv, &img->code)) {
563 IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); 562 IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
564 return 0; 563 return 0;
565 } 564 }
566 565
567 IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); 566 IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
568 567
569 iwl_print_mismatch_inst(priv, fw_desc); 568 iwl_print_mismatch_inst(priv, &img->code);
570 return -EIO; 569 return -EIO;
571} 570}
572 571
@@ -602,8 +601,7 @@ static void iwlagn_alive_fn(struct iwl_priv *priv,
602#define UCODE_CALIB_TIMEOUT (2*HZ) 601#define UCODE_CALIB_TIMEOUT (2*HZ)
603 602
604int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, 603int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
605 struct fw_desc *inst_image, 604 struct fw_img *image,
606 struct fw_desc *data_image,
607 int subtype, int alternate_subtype) 605 int subtype, int alternate_subtype)
608{ 606{
609 struct iwl_notification_wait alive_wait; 607 struct iwl_notification_wait alive_wait;
@@ -621,7 +619,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
621 old_type = priv->ucode_type; 619 old_type = priv->ucode_type;
622 priv->ucode_type = subtype; 620 priv->ucode_type = subtype;
623 621
624 ret = iwlagn_load_given_ucode(priv, inst_image, data_image); 622 ret = iwlagn_load_given_ucode(priv, image);
625 if (ret) { 623 if (ret) {
626 priv->ucode_type = old_type; 624 priv->ucode_type = old_type;
627 iwlagn_remove_notification(priv, &alive_wait); 625 iwlagn_remove_notification(priv, &alive_wait);
@@ -656,7 +654,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
656 return -EIO; 654 return -EIO;
657 } 655 }
658 656
659 ret = iwl_verify_ucode(priv, inst_image); 657 ret = iwl_verify_ucode(priv, image);
660 if (ret) { 658 if (ret) {
661 priv->ucode_type = old_type; 659 priv->ucode_type = old_type;
662 return ret; 660 return ret;
@@ -684,7 +682,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
684 lockdep_assert_held(&priv->mutex); 682 lockdep_assert_held(&priv->mutex);
685 683
686 /* No init ucode required? Curious, but maybe ok */ 684 /* No init ucode required? Curious, but maybe ok */
687 if (!priv->ucode_init.len) 685 if (!priv->ucode_init.code.len)
688 return 0; 686 return 0;
689 687
690 if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) 688 if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
@@ -696,7 +694,6 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
696 694
697 /* Will also start the device */ 695 /* Will also start the device */
698 ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, 696 ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
699 &priv->ucode_init_data,
700 UCODE_SUBTYPE_INIT, -1); 697 UCODE_SUBTYPE_INIT, -1);
701 if (ret) 698 if (ret)
702 goto error; 699 goto error;
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
1176static 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
1185static 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
1191static 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
1176static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) 1208static 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
1184struct iwlagn_ucode_capabilities { 1214struct 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) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index cf05f87ec80e..c475ac427596 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -164,8 +164,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
164void iwlagn_send_prio_tbl(struct iwl_priv *priv); 164void iwlagn_send_prio_tbl(struct iwl_priv *priv);
165int iwlagn_run_init_ucode(struct iwl_priv *priv); 165int iwlagn_run_init_ucode(struct iwl_priv *priv);
166int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, 166int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
167 struct fw_desc *inst_image, 167 struct fw_img *image,
168 struct fw_desc *data_image,
169 int subtype, int alternate_subtype); 168 int subtype, int alternate_subtype);
170 169
171/* lib */ 170/* lib */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 2b606889b64b..7bd4f5af5b0d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -227,9 +227,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
227 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { 227 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
228 priv->dbgfs_sram_offset = 0x800000; 228 priv->dbgfs_sram_offset = 0x800000;
229 if (priv->ucode_type == UCODE_SUBTYPE_INIT) 229 if (priv->ucode_type == UCODE_SUBTYPE_INIT)
230 priv->dbgfs_sram_len = priv->ucode_init_data.len; 230 priv->dbgfs_sram_len = priv->ucode_init.data.len;
231 else 231 else
232 priv->dbgfs_sram_len = priv->ucode_data.len; 232 priv->dbgfs_sram_len = priv->ucode_rt.data.len;
233 } 233 }
234 len = priv->dbgfs_sram_len; 234 len = priv->dbgfs_sram_len;
235 235
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 414968c6b7cf..857eb0e9e397 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -479,6 +479,10 @@ struct fw_desc {
479 u32 len; /* bytes */ 479 u32 len; /* bytes */
480}; 480};
481 481
482struct fw_img {
483 struct fw_desc code, data;
484};
485
482/* v1/v2 uCode file layout */ 486/* v1/v2 uCode file layout */
483struct iwl_ucode_header { 487struct iwl_ucode_header {
484 __le32 ver; /* major/minor/API/serial */ 488 __le32 ver; /* major/minor/API/serial */
@@ -1266,10 +1270,9 @@ struct iwl_priv {
1266 int fw_index; /* firmware we're trying to load */ 1270 int fw_index; /* firmware we're trying to load */
1267 u32 ucode_ver; /* version of ucode, copy of 1271 u32 ucode_ver; /* version of ucode, copy of
1268 iwl_ucode.ver */ 1272 iwl_ucode.ver */
1269 struct fw_desc ucode_code; /* runtime inst */ 1273 struct fw_img ucode_rt;
1270 struct fw_desc ucode_data; /* runtime data original */ 1274 struct fw_img ucode_init;
1271 struct fw_desc ucode_init; /* initialization inst */ 1275
1272 struct fw_desc ucode_init_data; /* initialization data */
1273 enum iwlagn_ucode_subtype ucode_type; 1276 enum iwlagn_ucode_subtype ucode_type;
1274 u8 ucode_write_complete; /* the image write is complete */ 1277 u8 ucode_write_complete; /* the image write is complete */
1275 char firmware_name[25]; 1278 char firmware_name[25];
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 9309ff2df4c2..41207a3645b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
64 return --index & (n_bd - 1); 64 return --index & (n_bd - 1);
65} 65}
66 66
67/* TODO: Move fw_desc functions to iwl-pci.ko */
68static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
69 struct fw_desc *desc)
70{
71 if (desc->v_addr)
72 dma_free_coherent(&pci_dev->dev, desc->len,
73 desc->v_addr, desc->p_addr);
74 desc->v_addr = NULL;
75 desc->len = 0;
76}
77
78static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
79 struct fw_desc *desc)
80{
81 if (!desc->len) {
82 desc->v_addr = NULL;
83 return -EINVAL;
84 }
85
86 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
87 &desc->p_addr, GFP_KERNEL);
88 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
89}
90
91/* 67/*
92 * we have 8 bits used like this: 68 * we have 8 bits used like this:
93 * 69 *