Merge branch 'pm-cpufreq'
[linux-2.6-block.git] / drivers / staging / rtl8192e / rtl8192e / r8192E_firmware.c
CommitLineData
94a79942
LF
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 *
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7 * more details.
8 *
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12 *
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
15 *
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18******************************************************************************/
19
94a79942
LF
20#include "rtl_core.h"
21#include "r8192E_hw.h"
94a79942 22#include "r8192E_hwimg.h"
94a79942 23#include "r8192E_firmware.h"
94a79942 24#include <linux/firmware.h>
94a79942 25
16362f45 26void rtl92e_init_fw_param(struct net_device *dev)
94a79942 27{
e3e37629 28 struct r8192_priv *priv = rtllib_priv(dev);
5aca114d 29 struct rt_firmware *pfirmware = priv->pFirmware;
94a79942 30
11632a0e
LF
31 pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(
32 MAX_TRANSMIT_BUFFER_SIZE);
94a79942
LF
33}
34
49aab5fd
LF
35static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
36 u32 buffer_len)
94a79942 37{
e3e37629 38 struct r8192_priv *priv = rtllib_priv(dev);
94a79942
LF
39 u16 frag_threshold;
40 u16 frag_length, frag_offset = 0;
41 int i;
42
5aca114d 43 struct rt_firmware *pfirmware = priv->pFirmware;
94a79942
LF
44 struct sk_buff *skb;
45 unsigned char *seg_ptr;
3b83db43 46 struct cb_desc *tcb_desc;
94a79942
LF
47 u8 bLastIniPkt;
48
16362f45 49 rtl92e_init_fw_param(dev);
94a79942
LF
50 frag_threshold = pfirmware->cmdpacket_frag_thresold;
51 do {
52 if ((buffer_len - frag_offset) > frag_threshold) {
dc986e3e 53 frag_length = frag_threshold;
94a79942
LF
54 bLastIniPkt = 0;
55
56 } else {
57 frag_length = buffer_len - frag_offset;
58 bLastIniPkt = 1;
59
60 }
61
62 skb = dev_alloc_skb(frag_length + 4);
11632a0e 63 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
3b83db43 64 tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
94a79942
LF
65 tcb_desc->queue_index = TXCMD_QUEUE;
66 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
67 tcb_desc->bLastIniPkt = bLastIniPkt;
68
69 seg_ptr = skb->data;
11632a0e
LF
70 for (i = 0; i < frag_length; i += 4) {
71 *seg_ptr++ = ((i+0) < frag_length) ?
72 code_virtual_address[i+3] : 0;
73 *seg_ptr++ = ((i+1) < frag_length) ?
74 code_virtual_address[i+2] : 0;
75 *seg_ptr++ = ((i+2) < frag_length) ?
76 code_virtual_address[i+1] : 0;
77 *seg_ptr++ = ((i+3) < frag_length) ?
78 code_virtual_address[i+0] : 0;
94a79942 79 }
11632a0e 80 tcb_desc->txbuf_size = (u16)i;
94a79942
LF
81 skb_put(skb, i);
82
11632a0e
LF
83 if (!priv->rtllib->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
84 (!skb_queue_empty(&priv->rtllib->skb_waitQ[tcb_desc->queue_index])) ||
85 (priv->rtllib->queue_stop)) {
0822339b
MK
86 RT_TRACE(COMP_FIRMWARE,
87 "===================> tx full!\n");
11632a0e
LF
88 skb_queue_tail(&priv->rtllib->skb_waitQ
89 [tcb_desc->queue_index], skb);
94a79942 90 } else {
11632a0e 91 priv->rtllib->softmac_hard_start_xmit(skb, dev);
94a79942
LF
92 }
93
94 code_virtual_address += frag_length;
95 frag_offset += frag_length;
96
11632a0e 97 } while (frag_offset < buffer_len);
94a79942 98
d8ae1967 99 rtl92e_writeb(dev, TPPoll, TPPoll_CQ);
94a79942 100
e623d0f3 101 return true;
94a79942
LF
102}
103
49aab5fd 104static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
94a79942
LF
105{
106 bool rt_status = true;
107 u32 CPU_status = 0;
108 unsigned long timeout;
109
8b9733c1 110 timeout = jiffies + msecs_to_jiffies(200);
94a79942 111 while (time_before(jiffies, timeout)) {
99aa47e0 112 CPU_status = rtl92e_readl(dev, CPU_GEN);
94a79942
LF
113 if (CPU_status & CPU_GEN_PUT_CODE_OK)
114 break;
11632a0e 115 mdelay(2);
94a79942
LF
116 }
117
118 if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
3b4140af 119 netdev_err(dev, "Firmware download failed.\n");
94a79942
LF
120 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
121 } else {
122 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
123 }
124
99aa47e0 125 CPU_status = rtl92e_readl(dev, CPU_GEN);
d8ae1967
MK
126 rtl92e_writeb(dev, CPU_GEN,
127 (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
94a79942
LF
128 mdelay(1);
129
8b9733c1 130 timeout = jiffies + msecs_to_jiffies(200);
94a79942 131 while (time_before(jiffies, timeout)) {
99aa47e0 132 CPU_status = rtl92e_readl(dev, CPU_GEN);
94a79942
LF
133 if (CPU_status&CPU_GEN_BOOT_RDY)
134 break;
11632a0e 135 mdelay(2);
94a79942
LF
136 }
137
3b4140af
MK
138 if (!(CPU_status&CPU_GEN_BOOT_RDY)) {
139 netdev_err(dev, "Firmware boot failed.\n");
94a79942 140 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
3b4140af
MK
141 }
142
143 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
94a79942
LF
144
145 return rt_status;
146
147CPUCheckMainCodeOKAndTurnOnCPU_Fail:
94a79942
LF
148 rt_status = false;
149 return rt_status;
150}
151
49aab5fd 152static bool CPUcheck_firmware_ready(struct net_device *dev)
94a79942
LF
153{
154
155 bool rt_status = true;
156 u32 CPU_status = 0;
157 unsigned long timeout;
158
8b9733c1 159 timeout = jiffies + msecs_to_jiffies(20);
94a79942 160 while (time_before(jiffies, timeout)) {
99aa47e0 161 CPU_status = rtl92e_readl(dev, CPU_GEN);
94a79942
LF
162 if (CPU_status&CPU_GEN_FIRM_RDY)
163 break;
11632a0e 164 mdelay(2);
94a79942
LF
165 }
166
167 if (!(CPU_status&CPU_GEN_FIRM_RDY))
168 goto CPUCheckFirmwareReady_Fail;
169 else
170 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
171
172 return rt_status;
173
174CPUCheckFirmwareReady_Fail:
94a79942
LF
175 rt_status = false;
176 return rt_status;
177
178}
179
11632a0e
LF
180static bool firmware_check_ready(struct net_device *dev,
181 u8 load_fw_status)
94a79942 182{
e3e37629 183 struct r8192_priv *priv = rtllib_priv(dev);
5aca114d 184 struct rt_firmware *pfirmware = priv->pFirmware;
94a79942
LF
185 bool rt_status = true;
186
187 switch (load_fw_status) {
188 case FW_INIT_STEP0_BOOT:
189 pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
94a79942
LF
190 break;
191
192 case FW_INIT_STEP1_MAIN:
193 pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
194
195 rt_status = CPUcheck_maincodeok_turnonCPU(dev);
11632a0e 196 if (rt_status)
94a79942 197 pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
11632a0e 198 else
0822339b
MK
199 RT_TRACE(COMP_FIRMWARE,
200 "CPUcheck_maincodeok_turnonCPU fail!\n");
94a79942
LF
201
202 break;
203
204 case FW_INIT_STEP2_DATA:
205 pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
206 mdelay(1);
207
208 rt_status = CPUcheck_firmware_ready(dev);
11632a0e 209 if (rt_status)
94a79942 210 pfirmware->firmware_status = FW_STATUS_5_READY;
11632a0e 211 else
0822339b
MK
212 RT_TRACE(COMP_FIRMWARE,
213 "CPUcheck_firmware_ready fail(%d)!\n",
214 rt_status);
94a79942
LF
215
216 break;
217 default:
218 rt_status = false;
73e29189 219 RT_TRACE(COMP_FIRMWARE, "Unknown firmware status");
94a79942
LF
220 break;
221 }
222
223 return rt_status;
224}
225
b8216b69 226bool rtl92e_init_fw(struct net_device *dev)
94a79942 227{
e3e37629 228 struct r8192_priv *priv = rtllib_priv(dev);
94a79942
LF
229 bool rt_status = true;
230
94a79942
LF
231 u32 file_length = 0;
232 u8 *mapped_file = NULL;
35e33b04 233 u8 i = 0;
6bf04003 234 enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
cec07695 235 enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
94a79942 236
5aca114d 237 struct rt_firmware *pfirmware = priv->pFirmware;
94a79942
LF
238
239 RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
240
11632a0e 241 if (pfirmware->firmware_status == FW_STATUS_0_INIT) {
94a79942
LF
242 rst_opt = OPT_SYSTEM_RESET;
243 starting_state = FW_INIT_STEP0_BOOT;
244
11632a0e 245 } else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
94a79942
LF
246 rst_opt = OPT_FIRMWARE_RESET;
247 starting_state = FW_INIT_STEP2_DATA;
11632a0e 248 } else {
0822339b
MK
249 RT_TRACE(COMP_FIRMWARE,
250 "PlatformInitFirmware: undefined firmware state\n");
94a79942
LF
251 }
252
35e33b04 253 for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) {
94a79942 254 if (rst_opt == OPT_SYSTEM_RESET) {
35e33b04 255 if (pfirmware->firmware_buf_size[i] == 0) {
84fcb4b3
BH
256 const char *fw_name[3] = {
257 RTL8192E_BOOT_IMG_FW,
258 RTL8192E_MAIN_IMG_FW,
259 RTL8192E_DATA_IMG_FW
260 };
261 const struct firmware *fw_entry;
262 int rc;
3a6b70c3 263
84fcb4b3 264 rc = request_firmware(&fw_entry,
35e33b04 265 fw_name[i],
84fcb4b3
BH
266 &priv->pdev->dev);
267 if (rc < 0) {
0822339b
MK
268 RT_TRACE(COMP_FIRMWARE,
269 "request firmware fail!\n");
84fcb4b3
BH
270 goto download_firmware_fail;
271 }
272 if (fw_entry->size >
35e33b04 273 sizeof(pfirmware->firmware_buf[i])) {
0822339b
MK
274 RT_TRACE(COMP_FIRMWARE,
275 "img file size exceed the container struct buffer fail!\n");
84fcb4b3
BH
276 goto download_firmware_fail;
277 }
94a79942 278
35e33b04
MK
279 if (i != FW_INIT_STEP1_MAIN) {
280 memcpy(pfirmware->firmware_buf[i],
11632a0e 281 fw_entry->data, fw_entry->size);
35e33b04 282 pfirmware->firmware_buf_size[i] =
84fcb4b3 283 fw_entry->size;
94a79942 284
84fcb4b3 285 } else {
35e33b04 286 memset(pfirmware->firmware_buf[i],
11632a0e 287 0, 128);
35e33b04 288 memcpy(&pfirmware->firmware_buf[i][128],
11632a0e 289 fw_entry->data, fw_entry->size);
35e33b04 290 pfirmware->firmware_buf_size[i] =
84fcb4b3 291 fw_entry->size + 128;
94a79942 292 }
94a79942 293
84fcb4b3
BH
294 if (rst_opt == OPT_SYSTEM_RESET)
295 release_firmware(fw_entry);
94a79942 296 }
94a79942
LF
297 }
298
35e33b04
MK
299 mapped_file = pfirmware->firmware_buf[i];
300 file_length = pfirmware->firmware_buf_size[i];
84fcb4b3 301
11632a0e 302 rt_status = fw_download_code(dev, mapped_file, file_length);
bec027ea 303 if (!rt_status)
94a79942 304 goto download_firmware_fail;
94a79942 305
35e33b04 306 if (!firmware_check_ready(dev, i))
94a79942 307 goto download_firmware_fail;
94a79942
LF
308 }
309
310 RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
311 return rt_status;
312
313download_firmware_fail:
3b4140af 314 netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__);
94a79942
LF
315 rt_status = false;
316 return rt_status;
317
318}