132 lines
4.2 KiB
Diff
132 lines
4.2 KiB
Diff
|
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||
|
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||
|
@@ -265,7 +265,6 @@ int rtl92c_download_fw(struct ieee80211_
|
||
|
if (!rtlhal->pfirmware)
|
||
|
return 1;
|
||
|
|
||
|
- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
|
||
|
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
|
||
|
pfwdata = (u8 *) rtlhal->pfirmware;
|
||
|
fwsize = rtlhal->fwsize;
|
||
|
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||
|
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||
|
@@ -186,6 +186,7 @@ int rtl92c_init_sw_vars(struct ieee80211
|
||
|
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||
|
rtlpriv->rtlhal.fwsize = firmware->size;
|
||
|
release_firmware(firmware);
|
||
|
+ pr_info("rtl8192ce: Loaded firmware file %s\n", rtlpriv->cfg->fw_name);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||
|
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||
|
@@ -43,6 +43,8 @@
|
||
|
#include "hw.h"
|
||
|
#include <linux/vmalloc.h>
|
||
|
#include <linux/module.h>
|
||
|
+#include <linux/atomic.h>
|
||
|
+#include <linux/types.h>
|
||
|
|
||
|
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
|
||
|
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
|
||
|
@@ -51,6 +53,10 @@ MODULE_LICENSE("GPL");
|
||
|
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
|
||
|
MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
|
||
|
|
||
|
+static char *rtl8192cu_firmware; /* pointer to firmware */
|
||
|
+static int firmware_size;
|
||
|
+static atomic_t usage_count;
|
||
|
+
|
||
|
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
|
||
|
{
|
||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||
|
@@ -62,12 +68,21 @@ static int rtl92cu_init_sw_vars(struct i
|
||
|
rtlpriv->dm.disable_framebursting = false;
|
||
|
rtlpriv->dm.thermalvalue = 0;
|
||
|
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
|
||
|
- rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
|
||
|
- if (!rtlpriv->rtlhal.pfirmware) {
|
||
|
+
|
||
|
+ if (rtl8192cu_firmware) {
|
||
|
+ /* firmware already loaded - true for suspend/resume
|
||
|
+ * and multiple instances of the device */
|
||
|
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||
|
+ rtlpriv->rtlhal.fwsize = firmware_size;
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ rtl8192cu_firmware = vzalloc(0x4000);
|
||
|
+ if (!rtl8192cu_firmware) {
|
||
|
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||
|
("Can't alloc buffer for fw.\n"));
|
||
|
return 1;
|
||
|
}
|
||
|
+
|
||
|
/* request fw */
|
||
|
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
|
||
|
rtlpriv->io.dev);
|
||
|
@@ -82,9 +97,14 @@ static int rtl92cu_init_sw_vars(struct i
|
||
|
release_firmware(firmware);
|
||
|
return 1;
|
||
|
}
|
||
|
- memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||
|
+ pr_info("rtl8192cu: Loaded firmware from file %s\n",
|
||
|
+ rtlpriv->cfg->fw_name);
|
||
|
+ memcpy(rtl8192cu_firmware, firmware->data, firmware->size);
|
||
|
+ firmware_size = firmware->size;
|
||
|
rtlpriv->rtlhal.fwsize = firmware->size;
|
||
|
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||
|
release_firmware(firmware);
|
||
|
+ atomic_inc(&usage_count);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -93,12 +113,30 @@ static void rtl92cu_deinit_sw_vars(struc
|
||
|
{
|
||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||
|
|
||
|
- if (rtlpriv->rtlhal.pfirmware) {
|
||
|
- vfree(rtlpriv->rtlhal.pfirmware);
|
||
|
+ atomic_dec(&usage_count);
|
||
|
+ if (!atomic_read(&usage_count) && rtlpriv->rtlhal.pfirmware) {
|
||
|
+ vfree(rtl8192cu_firmware);
|
||
|
+ rtl8192cu_firmware = NULL;
|
||
|
rtlpriv->rtlhal.pfirmware = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+#ifdef CONFIG_PM_SLEEP
|
||
|
+static int rtl8192cu_usb_suspend(struct usb_interface *pusb_intf,
|
||
|
+ pm_message_t message)
|
||
|
+{
|
||
|
+ /* Increase usage_count to Save loaded fw across suspend/resume */
|
||
|
+ atomic_inc(&usage_count);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int rtl8192cu_usb_resume(struct usb_interface *pusb_intf)
|
||
|
+{
|
||
|
+ atomic_dec(&usage_count); /* after resume, decrease usage count */
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||
|
.init_sw_vars = rtl92cu_init_sw_vars,
|
||
|
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
|
||
|
@@ -374,11 +412,10 @@ static struct usb_driver rtl8192cu_drive
|
||
|
.disconnect = rtl_usb_disconnect,
|
||
|
.id_table = rtl8192c_usb_ids,
|
||
|
|
||
|
-#ifdef CONFIG_PM
|
||
|
- /* .suspend = rtl_usb_suspend, */
|
||
|
- /* .resume = rtl_usb_resume, */
|
||
|
- /* .reset_resume = rtl8192c_resume, */
|
||
|
-#endif /* CONFIG_PM */
|
||
|
+#ifdef CONFIG_PM_SLEEP
|
||
|
+ .suspend = rtl8192cu_usb_suspend,
|
||
|
+ .resume = rtl8192cu_usb_resume,
|
||
|
+#endif /* CONFIG_PM_SLEEP */
|
||
|
#ifdef CONFIG_AUTOSUSPEND
|
||
|
.supports_autosuspend = 1,
|
||
|
#endif
|