}
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);
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)
{
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)
{
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) {
"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;