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 _rtl92e_fw_boot_cpu(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 _rtl92e_is_fw_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 = _rtl92e_fw_boot_cpu(dev);
197 pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
199 RT_TRACE(COMP_FIRMWARE, "_rtl92e_fw_boot_cpu fail!\n");
203 case FW_INIT_STEP2_DATA:
204 pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
207 rt_status = _rtl92e_is_fw_ready(dev);
209 pfirmware->firmware_status = FW_STATUS_5_READY;
211 RT_TRACE(COMP_FIRMWARE,
212 "_rtl92e_is_fw_ready fail(%d)!\n",
218 RT_TRACE(COMP_FIRMWARE, "Unknown firmware status");
225 bool rtl92e_init_fw(struct net_device *dev)
227 struct r8192_priv *priv = rtllib_priv(dev);
228 bool rt_status = true;
231 u8 *mapped_file = NULL;
233 enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
234 enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
236 struct rt_firmware *pfirmware = priv->pFirmware;
238 RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
240 if (pfirmware->firmware_status == FW_STATUS_0_INIT) {
241 rst_opt = OPT_SYSTEM_RESET;
242 starting_state = FW_INIT_STEP0_BOOT;
244 } else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
245 rst_opt = OPT_FIRMWARE_RESET;
246 starting_state = FW_INIT_STEP2_DATA;
248 RT_TRACE(COMP_FIRMWARE,
249 "PlatformInitFirmware: undefined firmware state\n");
252 for (i = starting_state; i <= FW_INIT_STEP2_DATA; i++) {
253 if (rst_opt == OPT_SYSTEM_RESET) {
254 if (pfirmware->firmware_buf_size[i] == 0) {
255 const char *fw_name[3] = {
256 RTL8192E_BOOT_IMG_FW,
257 RTL8192E_MAIN_IMG_FW,
260 const struct firmware *fw_entry;
263 rc = request_firmware(&fw_entry,
267 RT_TRACE(COMP_FIRMWARE,
268 "request firmware fail!\n");
269 goto download_firmware_fail;
272 sizeof(pfirmware->firmware_buf[i])) {
273 RT_TRACE(COMP_FIRMWARE,
274 "img file size exceed the container struct buffer fail!\n");
275 release_firmware(fw_entry);
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__);