1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
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
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
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
21 #include "r8192E_hw.h"
22 #include "r8192E_hwimg.h"
23 #include "r8192E_firmware.h"
24 #include <linux/firmware.h>
26 void firmware_init_param(struct net_device *dev)
28 struct r8192_priv *priv = rtllib_priv(dev);
29 struct rt_firmware *pfirmware = priv->pFirmware;
31 pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(
32 MAX_TRANSMIT_BUFFER_SIZE);
35 static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
38 struct r8192_priv *priv = rtllib_priv(dev);
40 u16 frag_length, frag_offset = 0;
43 struct rt_firmware *pfirmware = priv->pFirmware;
45 unsigned char *seg_ptr;
46 struct cb_desc *tcb_desc;
49 firmware_init_param(dev);
50 frag_threshold = pfirmware->cmdpacket_frag_thresold;
52 if ((buffer_len - frag_offset) > frag_threshold) {
53 frag_length = frag_threshold;
57 frag_length = buffer_len - frag_offset;
62 skb = dev_alloc_skb(frag_length + 4);
63 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
64 tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
65 tcb_desc->queue_index = TXCMD_QUEUE;
66 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
67 tcb_desc->bLastIniPkt = bLastIniPkt;
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;
80 tcb_desc->txbuf_size = (u16)i;
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)) {
86 RT_TRACE(COMP_FIRMWARE,
87 "===================> tx full!\n");
88 skb_queue_tail(&priv->rtllib->skb_waitQ
89 [tcb_desc->queue_index], skb);
91 priv->rtllib->softmac_hard_start_xmit(skb, dev);
94 code_virtual_address += frag_length;
95 frag_offset += frag_length;
97 } while (frag_offset < buffer_len);
99 write_nic_byte(dev, TPPoll, TPPoll_CQ);
104 static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
106 bool rt_status = true;
108 unsigned long timeout;
110 timeout = jiffies + msecs_to_jiffies(200);
111 while (time_before(jiffies, timeout)) {
112 CPU_status = read_nic_dword(dev, CPU_GEN);
113 if (CPU_status & CPU_GEN_PUT_CODE_OK)
118 if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
119 RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
120 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
122 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
125 CPU_status = read_nic_dword(dev, CPU_GEN);
126 write_nic_byte(dev, CPU_GEN,
127 (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
130 timeout = jiffies + msecs_to_jiffies(200);
131 while (time_before(jiffies, timeout)) {
132 CPU_status = read_nic_dword(dev, CPU_GEN);
133 if (CPU_status&CPU_GEN_BOOT_RDY)
138 if (!(CPU_status&CPU_GEN_BOOT_RDY))
139 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
141 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
145 CPUCheckMainCodeOKAndTurnOnCPU_Fail:
146 RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
151 static bool CPUcheck_firmware_ready(struct net_device *dev)
154 bool rt_status = true;
156 unsigned long timeout;
158 timeout = jiffies + msecs_to_jiffies(20);
159 while (time_before(jiffies, timeout)) {
160 CPU_status = read_nic_dword(dev, CPU_GEN);
161 if (CPU_status&CPU_GEN_FIRM_RDY)
166 if (!(CPU_status&CPU_GEN_FIRM_RDY))
167 goto CPUCheckFirmwareReady_Fail;
169 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
173 CPUCheckFirmwareReady_Fail:
174 RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
180 static bool firmware_check_ready(struct net_device *dev,
183 struct r8192_priv *priv = rtllib_priv(dev);
184 struct rt_firmware *pfirmware = priv->pFirmware;
185 bool rt_status = true;
187 switch (load_fw_status) {
188 case FW_INIT_STEP0_BOOT:
189 pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
192 case FW_INIT_STEP1_MAIN:
193 pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
195 rt_status = CPUcheck_maincodeok_turnonCPU(dev);
197 pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
199 RT_TRACE(COMP_FIRMWARE,
200 "CPUcheck_maincodeok_turnonCPU fail!\n");
204 case FW_INIT_STEP2_DATA:
205 pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
208 rt_status = CPUcheck_firmware_ready(dev);
210 pfirmware->firmware_status = FW_STATUS_5_READY;
212 RT_TRACE(COMP_FIRMWARE,
213 "CPUcheck_firmware_ready fail(%d)!\n",
219 RT_TRACE(COMP_FIRMWARE, "Unknown firmware status");
226 bool init_firmware(struct net_device *dev)
228 struct r8192_priv *priv = rtllib_priv(dev);
229 bool rt_status = true;
232 u8 *mapped_file = NULL;
234 enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
235 enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
237 struct rt_firmware *pfirmware = priv->pFirmware;
239 RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
241 if (pfirmware->firmware_status == FW_STATUS_0_INIT) {
242 rst_opt = OPT_SYSTEM_RESET;
243 starting_state = FW_INIT_STEP0_BOOT;
245 } else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
246 rst_opt = OPT_FIRMWARE_RESET;
247 starting_state = FW_INIT_STEP2_DATA;
249 RT_TRACE(COMP_FIRMWARE,
250 "PlatformInitFirmware: undefined firmware state\n");
253 for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA;
255 if (rst_opt == OPT_SYSTEM_RESET) {
256 if (pfirmware->firmware_buf_size[init_step] == 0) {
257 const char *fw_name[3] = {
258 RTL8192E_BOOT_IMG_FW,
259 RTL8192E_MAIN_IMG_FW,
262 const struct firmware *fw_entry;
265 rc = request_firmware(&fw_entry,
269 RT_TRACE(COMP_FIRMWARE,
270 "request firmware fail!\n");
271 goto download_firmware_fail;
274 sizeof(pfirmware->firmware_buf[init_step])) {
275 RT_TRACE(COMP_FIRMWARE,
276 "img file size exceed the container struct buffer fail!\n");
277 goto download_firmware_fail;
280 if (init_step != FW_INIT_STEP1_MAIN) {
281 memcpy(pfirmware->firmware_buf[init_step],
282 fw_entry->data, fw_entry->size);
283 pfirmware->firmware_buf_size[init_step] =
287 memset(pfirmware->firmware_buf[init_step],
289 memcpy(&pfirmware->firmware_buf[init_step][128],
290 fw_entry->data, fw_entry->size);
291 pfirmware->firmware_buf_size[init_step] =
292 fw_entry->size + 128;
295 if (rst_opt == OPT_SYSTEM_RESET)
296 release_firmware(fw_entry);
300 mapped_file = pfirmware->firmware_buf[init_step];
301 file_length = pfirmware->firmware_buf_size[init_step];
303 rt_status = fw_download_code(dev, mapped_file, file_length);
305 goto download_firmware_fail;
307 if (!firmware_check_ready(dev, init_step))
308 goto download_firmware_fail;
311 RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
314 download_firmware_fail:
315 RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);