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 rtl92e_init_fw_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 rtl92e_init_fw_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 rtl92e_writeb(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 = rtl92e_readl(dev, CPU_GEN);
113 if (CPU_status & CPU_GEN_PUT_CODE_OK)
118 if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
119 netdev_err(dev, "Firmware download failed.\n");
120 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
122 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
125 CPU_status = rtl92e_readl(dev, CPU_GEN);
126 rtl92e_writeb(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 = rtl92e_readl(dev, CPU_GEN);
133 if (CPU_status&CPU_GEN_BOOT_RDY)
138 if (!(CPU_status&CPU_GEN_BOOT_RDY)) {
139 netdev_err(dev, "Firmware boot failed.\n");
140 goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
143 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
147 CPUCheckMainCodeOKAndTurnOnCPU_Fail:
152 static bool CPUcheck_firmware_ready(struct net_device *dev)
155 bool rt_status = true;
157 unsigned long timeout;
159 timeout = jiffies + msecs_to_jiffies(20);
160 while (time_before(jiffies, timeout)) {
161 CPU_status = rtl92e_readl(dev, CPU_GEN);
162 if (CPU_status&CPU_GEN_FIRM_RDY)
167 if (!(CPU_status&CPU_GEN_FIRM_RDY))
168 goto CPUCheckFirmwareReady_Fail;
170 RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
174 CPUCheckFirmwareReady_Fail:
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 rtl92e_init_fw(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 (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) {
254 if (rst_opt == OPT_SYSTEM_RESET) {
255 if (pfirmware->firmware_buf_size[i] == 0) {
256 const char *fw_name[3] = {
257 RTL8192E_BOOT_IMG_FW,
258 RTL8192E_MAIN_IMG_FW,
261 const struct firmware *fw_entry;
264 rc = request_firmware(&fw_entry,
268 RT_TRACE(COMP_FIRMWARE,
269 "request firmware fail!\n");
270 goto download_firmware_fail;
273 sizeof(pfirmware->firmware_buf[i])) {
274 RT_TRACE(COMP_FIRMWARE,
275 "img file size exceed the container struct buffer fail!\n");
276 goto download_firmware_fail;
279 if (i != FW_INIT_STEP1_MAIN) {
280 memcpy(pfirmware->firmware_buf[i],
281 fw_entry->data, fw_entry->size);
282 pfirmware->firmware_buf_size[i] =
286 memset(pfirmware->firmware_buf[i],
288 memcpy(&pfirmware->firmware_buf[i][128],
289 fw_entry->data, fw_entry->size);
290 pfirmware->firmware_buf_size[i] =
291 fw_entry->size + 128;
294 if (rst_opt == OPT_SYSTEM_RESET)
295 release_firmware(fw_entry);
299 mapped_file = pfirmware->firmware_buf[i];
300 file_length = pfirmware->firmware_buf_size[i];
302 rt_status = fw_download_code(dev, mapped_file, file_length);
304 goto download_firmware_fail;
306 if (!firmware_check_ready(dev, i))
307 goto download_firmware_fail;
310 RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
313 download_firmware_fail:
314 netdev_err(dev, "%s: Failed to initialize firmware.\n", __func__);