Skip to content

Commit

Permalink
rtlwifi: rtl8821ae: Simplify loading of WOWLAN firmware
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
  • Loading branch information
troy-tan authored and Kalle Valo committed Dec 24, 2014
1 parent a844bae commit fe89707
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 54 deletions.
24 changes: 22 additions & 2 deletions drivers/net/wireless/rtlwifi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
}
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 rtl_priv *rtlpriv = rtl_priv(hw);
Expand Down Expand Up @@ -125,12 +126,31 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)
release_firmware(firmware);
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;
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);

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. */
static int rtl_op_start(struct ieee80211_hw *hw)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/rtlwifi/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

extern const struct ieee80211_ops rtl_ops;
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_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
u32 mask, u32 data);
Expand Down
74 changes: 24 additions & 50 deletions drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,52 +85,6 @@ static void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw)
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*/
int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
{
Expand Down Expand Up @@ -231,28 +185,48 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
else if (rtlpriv->psc.reg_fwctrl_lps == 3)
rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;

rtlpriv->rtl_fw_second_cb = load_wowlan_fw;
/* for firmware buf */
rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
if (!rtlpriv->rtlhal.pfirmware) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't alloc buffer for fw.\n");
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";
else
rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
} else {
rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin";
rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
}

rtlpriv->max_fw_size = 0x8000;
/*load normal firmware*/
pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
rtlpriv->io.dev, GFP_KERNEL, hw,
rtl_fw_cb);
if (err) {
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 0;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/rtlwifi/wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,7 @@ struct rtl_hal_cfg {
char *name;
char *fw_name;
char *alt_fw_name;
char *wowlan_fw_name;
struct rtl_hal_ops *ops;
struct rtl_mod_params *mod_params;
struct rtl_hal_usbint_cfg *usb_interface_cfg;
Expand Down Expand Up @@ -2518,8 +2519,6 @@ struct proxim {

struct rtl_priv {
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 list_head list;
struct rtl_priv *buddy_priv;
Expand Down

0 comments on commit fe89707

Please sign in to comment.