2009-11-03 09:17:11 +00:00
|
|
|
/**************************************************************************************************
|
|
|
|
* Procedure: Init boot code/firmware code/data session
|
|
|
|
*
|
2010-09-01 13:40:25 +00:00
|
|
|
* Description: This routine will initialize firmware. If any error occurs during the initialization
|
2012-12-05 20:40:18 +00:00
|
|
|
* process, the routine shall terminate immediately and return fail.
|
2009-11-03 09:17:11 +00:00
|
|
|
* NIC driver should call NdisOpenFile only from MiniportInitialize.
|
|
|
|
*
|
|
|
|
* Arguments: The pointer of the adapter
|
|
|
|
|
|
|
|
* Returns:
|
|
|
|
* NDIS_STATUS_FAILURE - the following initialization process should be terminated
|
|
|
|
* NDIS_STATUS_SUCCESS - if firmware initialization process success
|
|
|
|
**************************************************************************************************/
|
2010-07-03 03:04:44 +00:00
|
|
|
|
2009-11-03 09:17:11 +00:00
|
|
|
#include "r8192U.h"
|
|
|
|
#include "r8192U_hw.h"
|
|
|
|
#include "r819xU_firmware_img.h"
|
|
|
|
#include "r819xU_firmware.h"
|
|
|
|
#include <linux/firmware.h>
|
2014-03-19 11:47:24 +00:00
|
|
|
|
|
|
|
static void firmware_init_param(struct net_device *dev)
|
2009-11-03 09:17:11 +00:00
|
|
|
{
|
2012-12-05 20:40:18 +00:00
|
|
|
struct r8192_priv *priv = ieee80211_priv(dev);
|
2009-11-03 09:17:11 +00:00
|
|
|
rt_firmware *pfirmware = priv->pFirmware;
|
|
|
|
|
|
|
|
pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* segment the img and use the ptr and length to remember info on each segment
|
|
|
|
*
|
|
|
|
*/
|
2014-03-19 11:47:24 +00:00
|
|
|
static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
|
|
|
|
u32 buffer_len)
|
2009-11-03 09:17:11 +00:00
|
|
|
{
|
|
|
|
struct r8192_priv *priv = ieee80211_priv(dev);
|
2012-12-05 20:40:18 +00:00
|
|
|
bool rt_status = true;
|
2009-11-03 09:17:11 +00:00
|
|
|
u16 frag_threshold;
|
|
|
|
u16 frag_length, frag_offset = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
rt_firmware *pfirmware = priv->pFirmware;
|
|
|
|
struct sk_buff *skb;
|
|
|
|
unsigned char *seg_ptr;
|
|
|
|
cb_desc *tcb_desc;
|
|
|
|
u8 bLastIniPkt;
|
2014-10-03 12:36:13 +00:00
|
|
|
u8 index;
|
2009-11-03 09:17:11 +00:00
|
|
|
|
|
|
|
firmware_init_param(dev);
|
2015-02-20 05:54:10 +00:00
|
|
|
/* Fragmentation might be required */
|
2009-11-03 09:17:11 +00:00
|
|
|
frag_threshold = pfirmware->cmdpacket_frag_thresold;
|
|
|
|
do {
|
2013-05-13 17:15:56 +00:00
|
|
|
if ((buffer_len - frag_offset) > frag_threshold) {
|
2014-09-27 14:32:52 +00:00
|
|
|
frag_length = frag_threshold;
|
2009-11-03 09:17:11 +00:00
|
|
|
bLastIniPkt = 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
frag_length = buffer_len - frag_offset;
|
|
|
|
bLastIniPkt = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate skb buffer to contain firmware info and tx descriptor info
|
|
|
|
* add 4 to avoid packet appending overflow.
|
|
|
|
* */
|
|
|
|
skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
|
2013-09-21 20:42:26 +00:00
|
|
|
if (!skb)
|
|
|
|
return false;
|
2015-06-20 16:06:48 +00:00
|
|
|
memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
|
2013-05-11 14:22:21 +00:00
|
|
|
tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
|
2009-11-03 09:17:11 +00:00
|
|
|
tcb_desc->queue_index = TXCMD_QUEUE;
|
|
|
|
tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
|
|
|
|
tcb_desc->bLastIniPkt = bLastIniPkt;
|
|
|
|
|
|
|
|
skb_reserve(skb, USB_HWDESC_HEADER_LEN);
|
|
|
|
seg_ptr = skb->data;
|
|
|
|
/*
|
|
|
|
* Transform from little endian to big endian
|
2009-11-03 09:42:46 +00:00
|
|
|
* and pending zero
|
2009-11-03 09:17:11 +00:00
|
|
|
*/
|
2014-10-03 12:36:11 +00:00
|
|
|
for (i = 0; i < frag_length; i += 4) {
|
|
|
|
*seg_ptr++ = ((i+0) < frag_length)?code_virtual_address[i+3] : 0;
|
|
|
|
*seg_ptr++ = ((i+1) < frag_length)?code_virtual_address[i+2] : 0;
|
|
|
|
*seg_ptr++ = ((i+2) < frag_length)?code_virtual_address[i+1] : 0;
|
|
|
|
*seg_ptr++ = ((i+3) < frag_length)?code_virtual_address[i+0] : 0;
|
2009-11-03 09:17:11 +00:00
|
|
|
}
|
2014-10-03 12:36:11 +00:00
|
|
|
tcb_desc->txbuf_size = (u16)i;
|
2009-11-03 09:17:11 +00:00
|
|
|
skb_put(skb, i);
|
|
|
|
|
2014-10-03 12:36:13 +00:00
|
|
|
index = tcb_desc->queue_index;
|
|
|
|
if (!priv->ieee80211->check_nic_enough_desc(dev, index) ||
|
|
|
|
(!skb_queue_empty(&priv->ieee80211->skb_waitQ[index])) ||
|
|
|
|
(priv->ieee80211->queue_stop)) {
|
2015-07-27 06:37:25 +00:00
|
|
|
RT_TRACE(COMP_FIRMWARE, "=====================================================> tx full!\n");
|
2009-11-03 09:17:11 +00:00
|
|
|
skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
|
|
|
|
} else {
|
2014-08-24 09:57:36 +00:00
|
|
|
priv->ieee80211->softmac_hard_start_xmit(skb, dev);
|
2009-11-03 09:17:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
code_virtual_address += frag_length;
|
|
|
|
frag_offset += frag_length;
|
|
|
|
|
2014-09-27 14:18:38 +00:00
|
|
|
} while (frag_offset < buffer_len);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-02-20 05:54:10 +00:00
|
|
|
/*
|
|
|
|
* Procedure: Check whether main code is download OK. If OK, turn on CPU
|
|
|
|
*
|
|
|
|
* Description: CPU register locates in different page against general register.
|
|
|
|
* Switch to CPU register in the begin and switch back before return
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Arguments: The pointer of the adapter
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* NDIS_STATUS_FAILURE - the following initialization process should
|
|
|
|
* be terminated
|
|
|
|
* NDIS_STATUS_SUCCESS - if firmware initialization process success
|
|
|
|
*/
|
2014-03-19 11:47:24 +00:00
|
|
|
static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
|
2009-11-03 09:17:11 +00:00
|
|
|
{
|
|
|
|
bool rt_status = true;
|
|
|
|
int check_putcodeOK_time = 200000, check_bootOk_time = 200000;
|
2009-11-03 09:42:46 +00:00
|
|
|
u32 CPU_status = 0;
|
2009-11-03 09:17:11 +00:00
|
|
|
|
|
|
|
/* Check whether put code OK */
|
|
|
|
do {
|
staging: rtl8192u: fix read_nic_* functions
read_nic_*() functions are defined in r8192U_core.c.
They call internally usb_control_msg() to read the
nic registers and return the value read.
Following a remark made by Dan Carpenter, if usb_control_msg()
fails, the value returned will be invalid.
To accommodate for this, this patch changes the functions
to take a pointer as argument to set the value read and
return 0 on success and the error status on failure, so
that callers of read_nic_*() can check the return status.
Some other fixes introduced in read_nic_*() functions are:
The expressions (1<<EPROM_*_SHIFT) used to address and set
the individual bits of the eeprom register were replaced
with EPROM_*_BIT bitmasks to make the code more intuitive.
EPROM_*_BIT bitmasks were defined in r8192U_hw.h and
EPROM_*_SHIFT were removed.
In netdev_err(), which is called in case of failure,
the hardcoded function name in the error log message was
replaced with __func__ to reduce line size.
Also, from the error log message, it was omitted the word
"Timeout" and it is just reported the error code since the
failure can not only be due to timeout expiration but also
due to a memory allocation failure. In case of timeout
expiration, usb_start_wait_urb() prints an appropriate log
message when debug is enabled.
Finally, some minor fixes to the coding style were applied in
lines affected by the above changes, including the removal
of ifdef DEBUG_RX (the debugging of reads and writes of the
nic registers shall be done with explicit check on their
return status which will be added in a follow on patch).
Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-06-06 13:40:51 +00:00
|
|
|
read_nic_dword(dev, CPU_GEN, &CPU_status);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (CPU_status&CPU_GEN_PUT_CODE_OK)
|
2009-11-03 09:17:11 +00:00
|
|
|
break;
|
|
|
|
|
2014-09-27 14:18:38 +00:00
|
|
|
} while (check_putcodeOK_time--);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
|
2009-11-03 09:17:11 +00:00
|
|
|
RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
|
|
|
|
goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
|
|
|
|
} else {
|
|
|
|
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Turn On CPU */
|
staging: rtl8192u: fix read_nic_* functions
read_nic_*() functions are defined in r8192U_core.c.
They call internally usb_control_msg() to read the
nic registers and return the value read.
Following a remark made by Dan Carpenter, if usb_control_msg()
fails, the value returned will be invalid.
To accommodate for this, this patch changes the functions
to take a pointer as argument to set the value read and
return 0 on success and the error status on failure, so
that callers of read_nic_*() can check the return status.
Some other fixes introduced in read_nic_*() functions are:
The expressions (1<<EPROM_*_SHIFT) used to address and set
the individual bits of the eeprom register were replaced
with EPROM_*_BIT bitmasks to make the code more intuitive.
EPROM_*_BIT bitmasks were defined in r8192U_hw.h and
EPROM_*_SHIFT were removed.
In netdev_err(), which is called in case of failure,
the hardcoded function name in the error log message was
replaced with __func__ to reduce line size.
Also, from the error log message, it was omitted the word
"Timeout" and it is just reported the error code since the
failure can not only be due to timeout expiration but also
due to a memory allocation failure. In case of timeout
expiration, usb_start_wait_urb() prints an appropriate log
message when debug is enabled.
Finally, some minor fixes to the coding style were applied in
lines affected by the above changes, including the removal
of ifdef DEBUG_RX (the debugging of reads and writes of the
nic registers shall be done with explicit check on their
return status which will be added in a follow on patch).
Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-06-06 13:40:51 +00:00
|
|
|
read_nic_dword(dev, CPU_GEN, &CPU_status);
|
2015-08-02 16:14:50 +00:00
|
|
|
write_nic_byte(dev, CPU_GEN,
|
|
|
|
(u8)((CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff));
|
2009-11-03 09:17:11 +00:00
|
|
|
mdelay(1000);
|
|
|
|
|
|
|
|
/* Check whether CPU boot OK */
|
|
|
|
do {
|
staging: rtl8192u: fix read_nic_* functions
read_nic_*() functions are defined in r8192U_core.c.
They call internally usb_control_msg() to read the
nic registers and return the value read.
Following a remark made by Dan Carpenter, if usb_control_msg()
fails, the value returned will be invalid.
To accommodate for this, this patch changes the functions
to take a pointer as argument to set the value read and
return 0 on success and the error status on failure, so
that callers of read_nic_*() can check the return status.
Some other fixes introduced in read_nic_*() functions are:
The expressions (1<<EPROM_*_SHIFT) used to address and set
the individual bits of the eeprom register were replaced
with EPROM_*_BIT bitmasks to make the code more intuitive.
EPROM_*_BIT bitmasks were defined in r8192U_hw.h and
EPROM_*_SHIFT were removed.
In netdev_err(), which is called in case of failure,
the hardcoded function name in the error log message was
replaced with __func__ to reduce line size.
Also, from the error log message, it was omitted the word
"Timeout" and it is just reported the error code since the
failure can not only be due to timeout expiration but also
due to a memory allocation failure. In case of timeout
expiration, usb_start_wait_urb() prints an appropriate log
message when debug is enabled.
Finally, some minor fixes to the coding style were applied in
lines affected by the above changes, including the removal
of ifdef DEBUG_RX (the debugging of reads and writes of the
nic registers shall be done with explicit check on their
return status which will be added in a follow on patch).
Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-06-06 13:40:51 +00:00
|
|
|
read_nic_dword(dev, CPU_GEN, &CPU_status);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (CPU_status&CPU_GEN_BOOT_RDY)
|
2009-11-03 09:17:11 +00:00
|
|
|
break;
|
2014-09-27 14:18:38 +00:00
|
|
|
} while (check_bootOk_time--);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2014-09-04 15:11:03 +00:00
|
|
|
if (!(CPU_status&CPU_GEN_BOOT_RDY))
|
2009-11-03 09:17:11 +00:00
|
|
|
goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
|
2014-09-04 15:11:03 +00:00
|
|
|
else
|
2009-11-03 09:17:11 +00:00
|
|
|
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
|
|
|
|
|
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
CPUCheckMainCodeOKAndTurnOnCPU_Fail:
|
2014-05-24 05:13:20 +00:00
|
|
|
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
|
2015-02-27 23:14:34 +00:00
|
|
|
rt_status = false;
|
2009-11-03 09:17:11 +00:00
|
|
|
return rt_status;
|
|
|
|
}
|
|
|
|
|
2014-03-19 11:47:24 +00:00
|
|
|
static bool CPUcheck_firmware_ready(struct net_device *dev)
|
2009-11-03 09:17:11 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
bool rt_status = true;
|
|
|
|
int check_time = 200000;
|
|
|
|
u32 CPU_status = 0;
|
|
|
|
|
|
|
|
/* Check Firmware Ready */
|
|
|
|
do {
|
staging: rtl8192u: fix read_nic_* functions
read_nic_*() functions are defined in r8192U_core.c.
They call internally usb_control_msg() to read the
nic registers and return the value read.
Following a remark made by Dan Carpenter, if usb_control_msg()
fails, the value returned will be invalid.
To accommodate for this, this patch changes the functions
to take a pointer as argument to set the value read and
return 0 on success and the error status on failure, so
that callers of read_nic_*() can check the return status.
Some other fixes introduced in read_nic_*() functions are:
The expressions (1<<EPROM_*_SHIFT) used to address and set
the individual bits of the eeprom register were replaced
with EPROM_*_BIT bitmasks to make the code more intuitive.
EPROM_*_BIT bitmasks were defined in r8192U_hw.h and
EPROM_*_SHIFT were removed.
In netdev_err(), which is called in case of failure,
the hardcoded function name in the error log message was
replaced with __func__ to reduce line size.
Also, from the error log message, it was omitted the word
"Timeout" and it is just reported the error code since the
failure can not only be due to timeout expiration but also
due to a memory allocation failure. In case of timeout
expiration, usb_start_wait_urb() prints an appropriate log
message when debug is enabled.
Finally, some minor fixes to the coding style were applied in
lines affected by the above changes, including the removal
of ifdef DEBUG_RX (the debugging of reads and writes of the
nic registers shall be done with explicit check on their
return status which will be added in a follow on patch).
Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-06-06 13:40:51 +00:00
|
|
|
read_nic_dword(dev, CPU_GEN, &CPU_status);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (CPU_status&CPU_GEN_FIRM_RDY)
|
2009-11-03 09:17:11 +00:00
|
|
|
break;
|
|
|
|
|
2014-09-27 14:18:38 +00:00
|
|
|
} while (check_time--);
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (!(CPU_status&CPU_GEN_FIRM_RDY))
|
2009-11-03 09:17:11 +00:00
|
|
|
goto CPUCheckFirmwareReady_Fail;
|
|
|
|
else
|
|
|
|
RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
|
|
|
|
|
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
CPUCheckFirmwareReady_Fail:
|
2014-05-24 05:13:20 +00:00
|
|
|
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
|
2009-11-03 09:17:11 +00:00
|
|
|
rt_status = false;
|
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool init_firmware(struct net_device *dev)
|
|
|
|
{
|
2012-12-05 20:40:18 +00:00
|
|
|
struct r8192_priv *priv = ieee80211_priv(dev);
|
2015-02-27 23:14:34 +00:00
|
|
|
bool rt_status = true;
|
2009-11-03 09:17:11 +00:00
|
|
|
|
|
|
|
u32 file_length = 0;
|
|
|
|
u8 *mapped_file = NULL;
|
|
|
|
u32 init_step = 0;
|
|
|
|
opt_rst_type_e rst_opt = OPT_SYSTEM_RESET;
|
2012-12-05 20:40:18 +00:00
|
|
|
firmware_init_step_e starting_state = FW_INIT_STEP0_BOOT;
|
2009-11-03 09:17:11 +00:00
|
|
|
|
|
|
|
rt_firmware *pfirmware = priv->pFirmware;
|
2012-12-05 20:40:18 +00:00
|
|
|
const struct firmware *fw_entry;
|
2009-11-03 09:17:11 +00:00
|
|
|
const char *fw_name[3] = { "RTL8192U/boot.img",
|
2009-11-03 09:42:46 +00:00
|
|
|
"RTL8192U/main.img",
|
2009-11-03 09:17:11 +00:00
|
|
|
"RTL8192U/data.img"};
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
|
|
|
|
|
2014-09-27 14:47:21 +00:00
|
|
|
if (pfirmware->firmware_status == FW_STATUS_0_INIT) {
|
2009-11-03 09:17:11 +00:00
|
|
|
/* it is called by reset */
|
|
|
|
rst_opt = OPT_SYSTEM_RESET;
|
|
|
|
starting_state = FW_INIT_STEP0_BOOT;
|
2015-02-20 05:54:10 +00:00
|
|
|
/* TODO: system reset */
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2014-09-27 14:18:38 +00:00
|
|
|
} else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
|
2009-11-03 09:17:11 +00:00
|
|
|
/* it is called by Initialize */
|
|
|
|
rst_opt = OPT_FIRMWARE_RESET;
|
|
|
|
starting_state = FW_INIT_STEP2_DATA;
|
2014-09-27 14:18:38 +00:00
|
|
|
} else {
|
2009-11-03 09:17:11 +00:00
|
|
|
RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Download boot, main, and data image for System reset.
|
2012-04-30 14:41:36 +00:00
|
|
|
* Download data image for firmware reset
|
2009-11-03 09:17:11 +00:00
|
|
|
*/
|
2014-09-27 10:25:29 +00:00
|
|
|
for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
|
2009-11-03 09:17:11 +00:00
|
|
|
/*
|
2012-04-30 21:39:21 +00:00
|
|
|
* Open image file, and map file to continuous memory if open file success.
|
2009-11-03 09:17:11 +00:00
|
|
|
* or read image file from array. Default load from IMG file
|
|
|
|
*/
|
2013-05-13 17:15:56 +00:00
|
|
|
if (rst_opt == OPT_SYSTEM_RESET) {
|
2015-07-27 06:37:25 +00:00
|
|
|
rc = request_firmware(&fw_entry, fw_name[init_step], &priv->udev->dev);
|
2014-09-27 14:47:21 +00:00
|
|
|
if (rc < 0) {
|
2011-01-09 04:20:04 +00:00
|
|
|
RT_TRACE(COMP_ERR, "request firmware fail!\n");
|
|
|
|
goto download_firmware_fail;
|
2009-11-03 09:17:11 +00:00
|
|
|
}
|
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (fw_entry->size > sizeof(pfirmware->firmware_buf)) {
|
2011-01-09 04:20:04 +00:00
|
|
|
RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
|
|
|
|
goto download_firmware_fail;
|
|
|
|
}
|
2009-11-03 09:17:11 +00:00
|
|
|
|
2013-05-13 17:15:56 +00:00
|
|
|
if (init_step != FW_INIT_STEP1_MAIN) {
|
2015-07-27 06:37:25 +00:00
|
|
|
memcpy(pfirmware->firmware_buf, fw_entry->data, fw_entry->size);
|
2011-01-09 04:20:04 +00:00
|
|
|
mapped_file = pfirmware->firmware_buf;
|
|
|
|
file_length = fw_entry->size;
|
|
|
|
} else {
|
2014-08-24 09:57:36 +00:00
|
|
|
memset(pfirmware->firmware_buf, 0, 128);
|
2015-07-27 06:37:25 +00:00
|
|
|
memcpy(&pfirmware->firmware_buf[128], fw_entry->data, fw_entry->size);
|
2011-01-09 04:20:04 +00:00
|
|
|
mapped_file = pfirmware->firmware_buf;
|
|
|
|
file_length = fw_entry->size + 128;
|
|
|
|
}
|
|
|
|
pfirmware->firmware_buf_size = file_length;
|
2014-09-27 14:47:21 +00:00
|
|
|
} else if (rst_opt == OPT_FIRMWARE_RESET) {
|
2009-11-03 09:17:11 +00:00
|
|
|
/* we only need to download data.img here */
|
|
|
|
mapped_file = pfirmware->firmware_buf;
|
|
|
|
file_length = pfirmware->firmware_buf_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Download image file */
|
|
|
|
/* The firmware download process is just as following,
|
|
|
|
* 1. that is each packet will be segmented and inserted to the wait queue.
|
|
|
|
* 2. each packet segment will be put in the skb_buff packet.
|
|
|
|
* 3. each skb_buff packet data content will already include the firmware info
|
|
|
|
* and Tx descriptor info
|
|
|
|
* */
|
2014-08-24 09:57:36 +00:00
|
|
|
rt_status = fw_download_code(dev, mapped_file, file_length);
|
2014-04-28 11:12:54 +00:00
|
|
|
if (rst_opt == OPT_SYSTEM_RESET)
|
2009-11-03 09:17:11 +00:00
|
|
|
release_firmware(fw_entry);
|
|
|
|
|
2015-03-13 19:21:31 +00:00
|
|
|
if (!rt_status)
|
2009-11-03 09:17:11 +00:00
|
|
|
goto download_firmware_fail;
|
|
|
|
|
2013-05-12 00:15:08 +00:00
|
|
|
switch (init_step) {
|
2012-12-05 20:40:22 +00:00
|
|
|
case FW_INIT_STEP0_BOOT:
|
|
|
|
/* Download boot
|
|
|
|
* initialize command descriptor.
|
|
|
|
* will set polling bit when firmware code is also configured
|
|
|
|
*/
|
|
|
|
pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
|
2015-02-20 05:54:10 +00:00
|
|
|
/* mdelay(1000); */
|
2012-12-05 20:40:22 +00:00
|
|
|
/*
|
|
|
|
* To initialize IMEM, CPU move code from 0x80000080,
|
|
|
|
* hence, we send 0x80 byte packet
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FW_INIT_STEP1_MAIN:
|
|
|
|
/* Download firmware code. Wait until Boot Ready and Turn on CPU */
|
|
|
|
pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
|
|
|
|
|
|
|
|
/* Check Put Code OK and Turn On CPU */
|
|
|
|
rt_status = CPUcheck_maincodeok_turnonCPU(dev);
|
2015-03-13 19:21:31 +00:00
|
|
|
if (!rt_status) {
|
2012-12-05 20:40:22 +00:00
|
|
|
RT_TRACE(COMP_ERR, "CPUcheck_maincodeok_turnonCPU fail!\n");
|
|
|
|
goto download_firmware_fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FW_INIT_STEP2_DATA:
|
|
|
|
/* download initial data code */
|
|
|
|
pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
|
|
|
|
mdelay(1);
|
|
|
|
|
|
|
|
rt_status = CPUcheck_firmware_ready(dev);
|
2015-03-13 19:21:31 +00:00
|
|
|
if (!rt_status) {
|
2015-07-27 06:37:25 +00:00
|
|
|
RT_TRACE(COMP_ERR, "CPUcheck_firmware_ready fail(%d)!\n", rt_status);
|
2012-12-05 20:40:22 +00:00
|
|
|
goto download_firmware_fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wait until data code is initialized ready.*/
|
|
|
|
pfirmware->firmware_status = FW_STATUS_5_READY;
|
|
|
|
break;
|
2009-11-03 09:17:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
|
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
download_firmware_fail:
|
2014-05-24 05:13:20 +00:00
|
|
|
RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
|
2015-02-27 23:14:34 +00:00
|
|
|
rt_status = false;
|
2009-11-03 09:17:11 +00:00
|
|
|
return rt_status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-08-02 20:17:25 +00:00
|
|
|
MODULE_FIRMWARE("RTL8192U/boot.img");
|
|
|
|
MODULE_FIRMWARE("RTL8192U/main.img");
|
|
|
|
MODULE_FIRMWARE("RTL8192U/data.img");
|