diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-03-16 13:23:30 -0400 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-03-25 14:17:20 -0400 |
commit | 81b8176eb8edac7d2135db2af03ab5fe0cb3b6f7 (patch) | |
tree | 21ffa7c8f03ad289288278091db32ba09c889dcc /drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |
parent | 792bc3cbe06cddabd865acc3122ee0415f854a11 (diff) |
iwlwifi: code cleanup for "load ucode" function
Loading uCode functions are shared across multiple agn devices.
Move those functions to iwl-agn-ucode.c file with other uCode
related functions.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-ucode.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 67f15c0d2a4a..f57a4f8033f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -30,9 +30,111 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | ||
33 | 34 | ||
34 | #include "iwl-dev.h" | 35 | #include "iwl-dev.h" |
35 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
37 | #include "iwl-io.h" | ||
38 | #include "iwl-5000-hw.h" | ||
39 | |||
40 | /* | ||
41 | * ucode | ||
42 | */ | ||
43 | static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | ||
44 | struct fw_desc *image, u32 dst_addr) | ||
45 | { | ||
46 | dma_addr_t phy_addr = image->p_addr; | ||
47 | u32 byte_cnt = image->len; | ||
48 | int ret; | ||
49 | |||
50 | priv->ucode_write_complete = 0; | ||
51 | |||
52 | iwl_write_direct32(priv, | ||
53 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
54 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | ||
55 | |||
56 | iwl_write_direct32(priv, | ||
57 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | ||
58 | |||
59 | iwl_write_direct32(priv, | ||
60 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | ||
61 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | ||
62 | |||
63 | iwl_write_direct32(priv, | ||
64 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | ||
65 | (iwl_get_dma_hi_addr(phy_addr) | ||
66 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | ||
67 | |||
68 | iwl_write_direct32(priv, | ||
69 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | ||
70 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | ||
71 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | ||
72 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | ||
73 | |||
74 | iwl_write_direct32(priv, | ||
75 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | ||
76 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
77 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | ||
78 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | ||
79 | |||
80 | IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); | ||
81 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | ||
82 | priv->ucode_write_complete, 5 * HZ); | ||
83 | if (ret == -ERESTARTSYS) { | ||
84 | IWL_ERR(priv, "Could not load the %s uCode section due " | ||
85 | "to interrupt\n", name); | ||
86 | return ret; | ||
87 | } | ||
88 | if (!ret) { | ||
89 | IWL_ERR(priv, "Could not load the %s uCode section\n", | ||
90 | name); | ||
91 | return -ETIMEDOUT; | ||
92 | } | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int iwlagn_load_given_ucode(struct iwl_priv *priv, | ||
98 | struct fw_desc *inst_image, | ||
99 | struct fw_desc *data_image) | ||
100 | { | ||
101 | int ret = 0; | ||
102 | |||
103 | ret = iwlagn_load_section(priv, "INST", inst_image, | ||
104 | IWL50_RTC_INST_LOWER_BOUND); | ||
105 | if (ret) | ||
106 | return ret; | ||
107 | |||
108 | return iwlagn_load_section(priv, "DATA", data_image, | ||
109 | IWL50_RTC_DATA_LOWER_BOUND); | ||
110 | } | ||
111 | |||
112 | int iwlagn_load_ucode(struct iwl_priv *priv) | ||
113 | { | ||
114 | int ret = 0; | ||
115 | |||
116 | /* check whether init ucode should be loaded, or rather runtime ucode */ | ||
117 | if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) { | ||
118 | IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n"); | ||
119 | ret = iwlagn_load_given_ucode(priv, | ||
120 | &priv->ucode_init, &priv->ucode_init_data); | ||
121 | if (!ret) { | ||
122 | IWL_DEBUG_INFO(priv, "Init ucode load complete.\n"); | ||
123 | priv->ucode_type = UCODE_INIT; | ||
124 | } | ||
125 | } else { | ||
126 | IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. " | ||
127 | "Loading runtime ucode...\n"); | ||
128 | ret = iwlagn_load_given_ucode(priv, | ||
129 | &priv->ucode_code, &priv->ucode_data); | ||
130 | if (!ret) { | ||
131 | IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n"); | ||
132 | priv->ucode_type = UCODE_RT; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } | ||
36 | 138 | ||
37 | #define IWL_UCODE_GET(item) \ | 139 | #define IWL_UCODE_GET(item) \ |
38 | static u32 iwlagn_ucode_get_##item(const struct iwl_ucode_header *ucode,\ | 140 | static u32 iwlagn_ucode_get_##item(const struct iwl_ucode_header *ucode,\ |