rtlwifi: rtl8821ae: Simplify loading of WOWLAN firmware
The existing method for loading both normal and WOWLAN firmware for the device duplicates a lot of code. This solution is much cleaner. Signed-off-by: Troy Tan <troy_tan@realsil.com.cn> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Родитель
a844bae38b
Коммит
fe89707f0a
|
@ -95,7 +95,8 @@ void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtl_bb_delay);
|
EXPORT_SYMBOL(rtl_bb_delay);
|
||||||
|
|
||||||
void rtl_fw_cb(const struct firmware *firmware, void *context)
|
static void rtl_fw_do_work(const struct firmware *firmware, void *context,
|
||||||
|
bool is_wow)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw = context;
|
struct ieee80211_hw *hw = context;
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
@ -125,12 +126,31 @@ found_alt:
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
if (!is_wow) {
|
||||||
|
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data,
|
||||||
|
firmware->size);
|
||||||
|
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||||
|
} else {
|
||||||
|
memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data,
|
||||||
|
firmware->size);
|
||||||
|
rtlpriv->rtlhal.wowlan_fwsize = firmware->size;
|
||||||
|
}
|
||||||
rtlpriv->rtlhal.fwsize = firmware->size;
|
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtl_fw_cb(const struct firmware *firmware, void *context)
|
||||||
|
{
|
||||||
|
rtl_fw_do_work(firmware, context, false);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(rtl_fw_cb);
|
EXPORT_SYMBOL(rtl_fw_cb);
|
||||||
|
|
||||||
|
void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context)
|
||||||
|
{
|
||||||
|
rtl_fw_do_work(firmware, context, true);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rtl_wowlan_fw_cb);
|
||||||
|
|
||||||
/*mutex for start & stop is must here. */
|
/*mutex for start & stop is must here. */
|
||||||
static int rtl_op_start(struct ieee80211_hw *hw)
|
static int rtl_op_start(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
extern const struct ieee80211_ops rtl_ops;
|
extern const struct ieee80211_ops rtl_ops;
|
||||||
void rtl_fw_cb(const struct firmware *firmware, void *context);
|
void rtl_fw_cb(const struct firmware *firmware, void *context);
|
||||||
|
void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context);
|
||||||
void rtl_addr_delay(u32 addr);
|
void rtl_addr_delay(u32 addr);
|
||||||
void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
|
void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
|
||||||
u32 mask, u32 data);
|
u32 mask, u32 data);
|
||||||
|
|
|
@ -85,52 +85,6 @@ static void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw)
|
||||||
rtlpci->const_support_pciaspm = 1;
|
rtlpci->const_support_pciaspm = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_wowlan_fw(struct rtl_priv *rtlpriv)
|
|
||||||
{
|
|
||||||
/* callback routine to load wowlan firmware after main fw has
|
|
||||||
* been loaded
|
|
||||||
*/
|
|
||||||
const struct firmware *wowlan_firmware;
|
|
||||||
char *fw_name = NULL;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* for wowlan firmware buf */
|
|
||||||
rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000);
|
|
||||||
if (!rtlpriv->rtlhal.wowlan_firmware) {
|
|
||||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
|
||||||
"Can't alloc buffer for wowlan fw.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8821AE)
|
|
||||||
fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
|
|
||||||
else
|
|
||||||
fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
|
|
||||||
err = request_firmware(&wowlan_firmware, fw_name, rtlpriv->io.dev);
|
|
||||||
if (err) {
|
|
||||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
|
||||||
"Failed to request wowlan firmware!\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wowlan_firmware->size > 0x8000) {
|
|
||||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
|
||||||
"Wowlan Firmware is too big!\n");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(rtlpriv->rtlhal.wowlan_firmware, wowlan_firmware->data,
|
|
||||||
wowlan_firmware->size);
|
|
||||||
rtlpriv->rtlhal.wowlan_fwsize = wowlan_firmware->size;
|
|
||||||
release_firmware(wowlan_firmware);
|
|
||||||
|
|
||||||
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "WOWLAN FirmwareDownload OK\n");
|
|
||||||
return;
|
|
||||||
error:
|
|
||||||
release_firmware(wowlan_firmware);
|
|
||||||
vfree(rtlpriv->rtlhal.wowlan_firmware);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*InitializeVariables8812E*/
|
/*InitializeVariables8812E*/
|
||||||
int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +185,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
||||||
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
|
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
|
||||||
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
|
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
|
||||||
|
|
||||||
rtlpriv->rtl_fw_second_cb = load_wowlan_fw;
|
|
||||||
/* for firmware buf */
|
/* for firmware buf */
|
||||||
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
|
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
|
||||||
if (!rtlpriv->rtlhal.pfirmware) {
|
if (!rtlpriv->rtlhal.pfirmware) {
|
||||||
|
@ -239,20 +192,41 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
|
||||||
"Can't alloc buffer for fw.\n");
|
"Can't alloc buffer for fw.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000);
|
||||||
|
if (!rtlpriv->rtlhal.wowlan_firmware) {
|
||||||
|
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||||
|
"Can't alloc buffer for wowlan fw.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
|
if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
|
||||||
rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin";
|
rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin";
|
||||||
else
|
rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
|
||||||
|
} else {
|
||||||
rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin";
|
rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin";
|
||||||
|
rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
|
||||||
|
}
|
||||||
|
|
||||||
rtlpriv->max_fw_size = 0x8000;
|
rtlpriv->max_fw_size = 0x8000;
|
||||||
|
/*load normal firmware*/
|
||||||
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
|
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
|
||||||
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
|
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
|
||||||
rtlpriv->io.dev, GFP_KERNEL, hw,
|
rtlpriv->io.dev, GFP_KERNEL, hw,
|
||||||
rtl_fw_cb);
|
rtl_fw_cb);
|
||||||
if (err) {
|
if (err) {
|
||||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||||
"Failed to request firmware!\n");
|
"Failed to request normal firmware!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*load wowlan firmware*/
|
||||||
|
pr_info("Using firmware %s\n", rtlpriv->cfg->wowlan_fw_name);
|
||||||
|
err = request_firmware_nowait(THIS_MODULE, 1,
|
||||||
|
rtlpriv->cfg->wowlan_fw_name,
|
||||||
|
rtlpriv->io.dev, GFP_KERNEL, hw,
|
||||||
|
rtl_wowlan_fw_cb);
|
||||||
|
if (err) {
|
||||||
|
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||||
|
"Failed to request wowlan firmware!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2242,6 +2242,7 @@ struct rtl_hal_cfg {
|
||||||
char *name;
|
char *name;
|
||||||
char *fw_name;
|
char *fw_name;
|
||||||
char *alt_fw_name;
|
char *alt_fw_name;
|
||||||
|
char *wowlan_fw_name;
|
||||||
struct rtl_hal_ops *ops;
|
struct rtl_hal_ops *ops;
|
||||||
struct rtl_mod_params *mod_params;
|
struct rtl_mod_params *mod_params;
|
||||||
struct rtl_hal_usbint_cfg *usb_interface_cfg;
|
struct rtl_hal_usbint_cfg *usb_interface_cfg;
|
||||||
|
@ -2518,8 +2519,6 @@ struct proxim {
|
||||||
|
|
||||||
struct rtl_priv {
|
struct rtl_priv {
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
/* Used to load a second firmware */
|
|
||||||
void (*rtl_fw_second_cb)(struct rtl_priv *rtlpriv);
|
|
||||||
struct completion firmware_loading_complete;
|
struct completion firmware_loading_complete;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct rtl_priv *buddy_priv;
|
struct rtl_priv *buddy_priv;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче