aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2012-01-30 10:54:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-30 15:48:50 -0500
commitb0302aba812bcc39291cdab9ad7e37008f352a91 (patch)
tree82915b1e24f204babeb65e1d517115c0e31cfd9a /drivers
parentfeced2012e665468258a5c89b7f2a90b4e5695a4 (diff)
rtlwifi: Convert to asynchronous firmware load
This patch addresses a kernel bugzilla report and two recent mail threads. The kernel bugzilla report is https://bugzilla.kernel.org/show_bug.cgi?id=42632, which reports a udev timeout on boot. The first mail thread, which was on LKML (http://lkml.indiana.edu/hypermail/ linux/kernel/1112.3/00965.html) was for a WARNING that occurs after a suspend/resume cycle for rtl8192cu. The scond mail thread (http://marc.info/?l=linux-wireless&m=132655490826766&w=2) concerned changes in udev that break drivers that delay while firmware is loaded on modprobe. This patch converts all rtlwifi-based drivers to use the asynchronous firmware loading mechanism. Drivers rtl8192ce, rtl8192cu and rtl8192de share a common callback routine. Driver rtl8192se needs different handling of the firmware, thus it has its own code. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Stable <stable@vger.kernel.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rtlwifi/base.c1
-rw-r--r--drivers/net/wireless/rtlwifi/core.c46
-rw-r--r--drivers/net/wireless/rtlwifi/core.h2
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c26
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h1
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c10
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c24
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c29
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/fw.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c65
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c34
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h4
20 files changed, 194 insertions, 164 deletions
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 7a95a544a9b1..df5655cc55c0 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -410,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
410 410
411 wiphy_rfkill_start_polling(hw->wiphy); 411 wiphy_rfkill_start_polling(hw->wiphy);
412} 412}
413EXPORT_SYMBOL(rtl_init_rfkill);
413 414
414void rtl_deinit_rfkill(struct ieee80211_hw *hw) 415void rtl_deinit_rfkill(struct ieee80211_hw *hw)
415{ 416{
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 0ee01ab2e4f6..f231b9180436 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -31,8 +31,50 @@
31#include "core.h" 31#include "core.h"
32#include "cam.h" 32#include "cam.h"
33#include "base.h" 33#include "base.h"
34#include "pci.h"
34#include "ps.h" 35#include "ps.h"
35 36
37#include <linux/export.h>
38
39void rtl_fw_cb(const struct firmware *firmware, void *context)
40{
41 struct ieee80211_hw *hw = context;
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43 int err;
44
45 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
46 "Firmware callback routine entered!\n");
47 complete(&rtlpriv->firmware_loading_complete);
48 if (!firmware) {
49 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
50 rtlpriv->max_fw_size = 0;
51 return;
52 }
53 if (firmware->size > rtlpriv->max_fw_size) {
54 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
55 "Firmware is too big!\n");
56 release_firmware(firmware);
57 return;
58 }
59 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
60 rtlpriv->rtlhal.fwsize = firmware->size;
61 release_firmware(firmware);
62
63 err = ieee80211_register_hw(hw);
64 if (err) {
65 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
66 "Can't register mac80211 hw\n");
67 return;
68 } else {
69 rtlpriv->mac80211.mac80211_registered = 1;
70 }
71 set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
72
73 /*init rfkill */
74 rtl_init_rfkill(hw);
75}
76EXPORT_SYMBOL(rtl_fw_cb);
77
36/*mutex for start & stop is must here. */ 78/*mutex for start & stop is must here. */
37static int rtl_op_start(struct ieee80211_hw *hw) 79static int rtl_op_start(struct ieee80211_hw *hw)
38{ 80{
@@ -254,10 +296,12 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
254 * because that will cause nullfunc send by mac80211 296 * because that will cause nullfunc send by mac80211
255 * fail, and cause pkt loss, we have tested that 5mA 297 * fail, and cause pkt loss, we have tested that 5mA
256 * is worked very well */ 298 * is worked very well */
257 if (!rtlpriv->psc.multi_buffered) 299 if (!rtlpriv->psc.multi_buffered) {
258 queue_delayed_work(rtlpriv->works.rtl_wq, 300 queue_delayed_work(rtlpriv->works.rtl_wq,
259 &rtlpriv->works.ps_work, 301 &rtlpriv->works.ps_work,
260 MSECS(5)); 302 MSECS(5));
303 pr_info("In section\n");
304 }
261 } else { 305 } else {
262 rtl_swlps_rf_awake(hw); 306 rtl_swlps_rf_awake(hw);
263 rtlpriv->psc.sw_ps_enabled = false; 307 rtlpriv->psc.sw_ps_enabled = false;
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 57569e0e3d47..2fe46a1b4f1f 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -40,4 +40,6 @@
40#define RTL_SUPPORTED_CTRL_FILTER 0xFF 40#define RTL_SUPPORTED_CTRL_FILTER 0xFF
41 41
42extern const struct ieee80211_ops rtl_ops; 42extern const struct ieee80211_ops rtl_ops;
43void rtl_fw_cb(const struct firmware *firmware, void *context);
44
43#endif 45#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index e4d1dcfe8299..5cb2199435d2 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1565,6 +1565,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
1565 1565
1566 rtlpci->driver_is_goingto_unload = true; 1566 rtlpci->driver_is_goingto_unload = true;
1567 rtlpriv->cfg->ops->hw_disable(hw); 1567 rtlpriv->cfg->ops->hw_disable(hw);
1568 /* some things are not needed if firmware not available */
1569 if (!rtlpriv->max_fw_size)
1570 return;
1568 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 1571 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1569 1572
1570 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); 1573 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
@@ -1779,6 +1782,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
1779 rtlpriv = hw->priv; 1782 rtlpriv = hw->priv;
1780 pcipriv = (void *)rtlpriv->priv; 1783 pcipriv = (void *)rtlpriv->priv;
1781 pcipriv->dev.pdev = pdev; 1784 pcipriv->dev.pdev = pdev;
1785 init_completion(&rtlpriv->firmware_loading_complete);
1782 1786
1783 /* init cfg & intf_ops */ 1787 /* init cfg & intf_ops */
1784 rtlpriv->rtlhal.interface = INTF_PCI; 1788 rtlpriv->rtlhal.interface = INTF_PCI;
@@ -1799,7 +1803,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
1799 err = pci_request_regions(pdev, KBUILD_MODNAME); 1803 err = pci_request_regions(pdev, KBUILD_MODNAME);
1800 if (err) { 1804 if (err) {
1801 RT_ASSERT(false, "Can't obtain PCI resources\n"); 1805 RT_ASSERT(false, "Can't obtain PCI resources\n");
1802 return err; 1806 goto fail2;
1803 } 1807 }
1804 1808
1805 pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); 1809 pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
@@ -1862,15 +1866,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
1862 goto fail3; 1866 goto fail3;
1863 } 1867 }
1864 1868
1865 err = ieee80211_register_hw(hw);
1866 if (err) {
1867 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1868 "Can't register mac80211 hw\n");
1869 goto fail3;
1870 } else {
1871 rtlpriv->mac80211.mac80211_registered = 1;
1872 }
1873
1874 err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); 1869 err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
1875 if (err) { 1870 if (err) {
1876 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1871 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -1878,9 +1873,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
1878 goto fail3; 1873 goto fail3;
1879 } 1874 }
1880 1875
1881 /*init rfkill */
1882 rtl_init_rfkill(hw);
1883
1884 rtlpci = rtl_pcidev(pcipriv); 1876 rtlpci = rtl_pcidev(pcipriv);
1885 err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, 1877 err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
1886 IRQF_SHARED, KBUILD_MODNAME, hw); 1878 IRQF_SHARED, KBUILD_MODNAME, hw);
@@ -1889,24 +1881,22 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
1889 "%s: failed to register IRQ handler\n", 1881 "%s: failed to register IRQ handler\n",
1890 wiphy_name(hw->wiphy)); 1882 wiphy_name(hw->wiphy));
1891 goto fail3; 1883 goto fail3;
1892 } else {
1893 rtlpci->irq_alloc = 1;
1894 } 1884 }
1885 rtlpci->irq_alloc = 1;
1895 1886
1896 set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1897 return 0; 1887 return 0;
1898 1888
1899fail3: 1889fail3:
1900 pci_set_drvdata(pdev, NULL); 1890 pci_set_drvdata(pdev, NULL);
1901 rtl_deinit_core(hw); 1891 rtl_deinit_core(hw);
1902 _rtl_pci_io_handler_release(hw); 1892 _rtl_pci_io_handler_release(hw);
1903 ieee80211_free_hw(hw);
1904 1893
1905 if (rtlpriv->io.pci_mem_start != 0) 1894 if (rtlpriv->io.pci_mem_start != 0)
1906 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); 1895 pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
1907 1896
1908fail2: 1897fail2:
1909 pci_release_regions(pdev); 1898 pci_release_regions(pdev);
1899 complete(&rtlpriv->firmware_loading_complete);
1910 1900
1911fail1: 1901fail1:
1912 1902
@@ -1925,6 +1915,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
1925 struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); 1915 struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
1926 struct rtl_mac *rtlmac = rtl_mac(rtlpriv); 1916 struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
1927 1917
1918 /* just in case driver is removed before firmware callback */
1919 wait_for_completion(&rtlpriv->firmware_loading_complete);
1928 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); 1920 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1929 1921
1930 sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); 1922 sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 99d81ede17b8..241448fc9ed5 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
239void rtl_pci_disconnect(struct pci_dev *pdev); 239void rtl_pci_disconnect(struct pci_dev *pdev);
240int rtl_pci_suspend(struct device *dev); 240int rtl_pci_suspend(struct device *dev);
241int rtl_pci_resume(struct device *dev); 241int rtl_pci_resume(struct device *dev);
242
243static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) 242static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
244{ 243{
245 return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); 244 return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index b151266ef9f6..15f86eaa1cd6 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -47,7 +47,8 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
47 "Driver is already down!\n"); 47 "Driver is already down!\n");
48 48
49 /*<2> Enable Adapter */ 49 /*<2> Enable Adapter */
50 rtlpriv->cfg->ops->hw_init(hw); 50 if (rtlpriv->cfg->ops->hw_init(hw))
51 return 1;
51 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 52 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
52 53
53 /*<3> Enable Interrupt */ 54 /*<3> Enable Interrupt */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 82bbc8384aca..c20b3c30f62e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -257,10 +257,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
257 u32 fwsize; 257 u32 fwsize;
258 enum version_8192c version = rtlhal->version; 258 enum version_8192c version = rtlhal->version;
259 259
260 if (!rtlhal->pfirmware) 260 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
261 return 1; 261 return 1;
262 262
263 pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
264 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; 263 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
265 pfwdata = (u8 *) rtlhal->pfirmware; 264 pfwdata = (u8 *) rtlhal->pfirmware;
266 fwsize = rtlhal->fwsize; 265 fwsize = rtlhal->fwsize;
@@ -512,15 +511,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
512void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, 511void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
513 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) 512 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
514{ 513{
515 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
516 u32 tmp_cmdbuf[2]; 514 u32 tmp_cmdbuf[2];
517 515
518 if (rtlhal->fw_ready == false) {
519 RT_ASSERT(false,
520 "return H2C cmd because of Fw download fail!!!\n");
521 return;
522 }
523
524 memset(tmp_cmdbuf, 0, 8); 516 memset(tmp_cmdbuf, 0, 8);
525 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); 517 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
526 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); 518 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index c5aced459cd0..48c7b5d3fc5b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -917,10 +917,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
917 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 917 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
918 "Failed to download FW. Init HW without FW now..\n"); 918 "Failed to download FW. Init HW without FW now..\n");
919 err = 1; 919 err = 1;
920 rtlhal->fw_ready = false;
921 return err; 920 return err;
922 } else {
923 rtlhal->fw_ready = true;
924 } 921 }
925 922
926 rtlhal->last_hmeboxnum = 0; 923 rtlhal->last_hmeboxnum = 0;
@@ -1193,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
1193{ 1190{
1194 struct rtl_priv *rtlpriv = rtl_priv(hw); 1191 struct rtl_priv *rtlpriv = rtl_priv(hw);
1195 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); 1192 struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1196 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1197 u8 u1b_tmp; 1193 u8 u1b_tmp;
1198 u32 u4b_tmp; 1194 u32 u4b_tmp;
1199 1195
@@ -1204,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
1204 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 1200 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1205 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 1201 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1206 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); 1202 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
1207 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) 1203 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7))
1208 rtl92c_firmware_selfreset(hw); 1204 rtl92c_firmware_selfreset(hw);
1209 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); 1205 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
1210 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); 1206 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 460dc925b4e4..2c3b73366cd2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -91,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
91 int err; 91 int err;
92 struct rtl_priv *rtlpriv = rtl_priv(hw); 92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
94 const struct firmware *firmware;
95 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 94 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
96 char *fw_name = NULL;
97 95
98 rtl8192ce_bt_reg_init(hw); 96 rtl8192ce_bt_reg_init(hw);
99 97
@@ -165,26 +163,20 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
165 /* request fw */ 163 /* request fw */
166 if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && 164 if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
167 !IS_92C_SERIAL(rtlhal->version)) 165 !IS_92C_SERIAL(rtlhal->version))
168 fw_name = "rtlwifi/rtl8192cfwU.bin"; 166 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
169 else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) 167 else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
170 fw_name = "rtlwifi/rtl8192cfwU_B.bin"; 168 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
171 else 169
172 fw_name = rtlpriv->cfg->fw_name; 170 rtlpriv->max_fw_size = 0x4000;
173 err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); 171 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
172 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
173 rtlpriv->io.dev, GFP_KERNEL, hw,
174 rtl_fw_cb);
174 if (err) { 175 if (err) {
175 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 176 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
176 "Failed to request firmware!\n"); 177 "Failed to request firmware!\n");
177 return 1; 178 return 1;
178 } 179 }
179 if (firmware->size > 0x4000) {
180 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
181 "Firmware is too big!\n");
182 release_firmware(firmware);
183 return 1;
184 }
185 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
186 rtlpriv->rtlhal.fwsize = firmware->size;
187 release_firmware(firmware);
188 180
189 return 0; 181 return 0;
190} 182}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 7f171682d3d6..0c74d4f2eeb4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -997,10 +997,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
997 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 997 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
998 "Failed to download FW. Init HW without FW now..\n"); 998 "Failed to download FW. Init HW without FW now..\n");
999 err = 1; 999 err = 1;
1000 rtlhal->fw_ready = false;
1001 return err; 1000 return err;
1002 } else {
1003 rtlhal->fw_ready = true;
1004 } 1001 }
1005 rtlhal->last_hmeboxnum = 0; /* h2c */ 1002 rtlhal->last_hmeboxnum = 0; /* h2c */
1006 _rtl92cu_phy_param_tab_init(hw); 1003 _rtl92cu_phy_param_tab_init(hw);
@@ -1094,23 +1091,21 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM)
1094 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { 1091 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) {
1095 /* reset MCU ready status */ 1092 /* reset MCU ready status */
1096 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 1093 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
1097 if (rtlhal->fw_ready) { 1094 /* 8051 reset by self */
1098 /* 8051 reset by self */ 1095 rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
1099 rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); 1096 while ((retry_cnts++ < 100) &&
1100 while ((retry_cnts++ < 100) && 1097 (FEN_CPUEN & rtl_read_word(rtlpriv,
1101 (FEN_CPUEN & rtl_read_word(rtlpriv, 1098 REG_SYS_FUNC_EN))) {
1102 REG_SYS_FUNC_EN))) { 1099 udelay(50);
1103 udelay(50); 1100 }
1104 } 1101 if (retry_cnts >= 100) {
1105 if (retry_cnts >= 100) { 1102 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1106 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1103 "#####=> 8051 reset failed!.........................\n");
1107 "#####=> 8051 reset failed!.........................\n"); 1104 /* if 8051 reset fail, reset MAC. */
1108 /* if 8051 reset fail, reset MAC. */ 1105 rtl_write_byte(rtlpriv,
1109 rtl_write_byte(rtlpriv, 1106 REG_SYS_FUNC_EN + 1,
1110 REG_SYS_FUNC_EN + 1, 1107 0x50);
1111 0x50); 1108 udelay(100);
1112 udelay(100);
1113 }
1114 } 1109 }
1115 } 1110 }
1116 /* Reset MAC and Enable 8051 */ 1111 /* Reset MAC and Enable 8051 */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index c04c3be5bd4e..82c85286ab2e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -53,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
53static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) 53static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
54{ 54{
55 struct rtl_priv *rtlpriv = rtl_priv(hw); 55 struct rtl_priv *rtlpriv = rtl_priv(hw);
56 const struct firmware *firmware;
57 int err; 56 int err;
58 57
59 rtlpriv->dm.dm_initialgain_enable = true; 58 rtlpriv->dm.dm_initialgain_enable = true;
@@ -61,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
61 rtlpriv->dm.disable_framebursting = false; 60 rtlpriv->dm.disable_framebursting = false;
62 rtlpriv->dm.thermalvalue = 0; 61 rtlpriv->dm.thermalvalue = 0;
63 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; 62 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
64 rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); 63
64 /* for firmware buf */
65 rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
65 if (!rtlpriv->rtlhal.pfirmware) { 66 if (!rtlpriv->rtlhal.pfirmware) {
66 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 67 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
67 "Can't alloc buffer for fw\n"); 68 "Can't alloc buffer for fw\n");
68 return 1; 69 return 1;
69 } 70 }
70 /* request fw */ 71
71 err = request_firmware(&firmware, rtlpriv->cfg->fw_name, 72 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
72 rtlpriv->io.dev); 73 rtlpriv->max_fw_size = 0x4000;
73 if (err) { 74 err = request_firmware_nowait(THIS_MODULE, 1,
74 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 75 rtlpriv->cfg->fw_name, rtlpriv->io.dev,
75 "Failed to request firmware!\n"); 76 GFP_KERNEL, hw, rtl_fw_cb);
76 return 1; 77
77 }
78 if (firmware->size > 0x4000) {
79 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
80 "Firmware is too big!\n");
81 release_firmware(firmware);
82 return 1;
83 }
84 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
85 rtlpriv->rtlhal.fwsize = firmware->size;
86 release_firmware(firmware);
87 78
88 return 0; 79 return 0;
89} 80}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
index b59de75a3643..f548a8d0068d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
@@ -253,7 +253,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
253 bool fw_downloaded = false, fwdl_in_process = false; 253 bool fw_downloaded = false, fwdl_in_process = false;
254 unsigned long flags; 254 unsigned long flags;
255 255
256 if (!rtlhal->pfirmware) 256 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
257 return 1; 257 return 1;
258 fwsize = rtlhal->fwsize; 258 fwsize = rtlhal->fwsize;
259 pfwheader = (u8 *) rtlhal->pfirmware; 259 pfwheader = (u8 *) rtlhal->pfirmware;
@@ -532,14 +532,8 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
532void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, 532void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
533 u8 element_id, u32 cmd_len, u8 *cmdbuffer) 533 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
534{ 534{
535 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
536 u32 tmp_cmdbuf[2]; 535 u32 tmp_cmdbuf[2];
537 536
538 if (rtlhal->fw_ready == false) {
539 RT_ASSERT(false,
540 "return H2C cmd because of Fw download fail!!!\n");
541 return;
542 }
543 memset(tmp_cmdbuf, 0, 8); 537 memset(tmp_cmdbuf, 0, 8);
544 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); 538 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
545 _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); 539 _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 695bccb43750..7d877125db29 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -931,10 +931,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
931 if (err) { 931 if (err) {
932 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 932 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
933 "Failed to download FW. Init HW without FW..\n"); 933 "Failed to download FW. Init HW without FW..\n");
934 rtlhal->fw_ready = false;
935 return 1; 934 return 1;
936 } else {
937 rtlhal->fw_ready = true;
938 } 935 }
939 rtlhal->last_hmeboxnum = 0; 936 rtlhal->last_hmeboxnum = 0;
940 rtlpriv->psc.fw_current_inpsmode = false; 937 rtlpriv->psc.fw_current_inpsmode = false;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index bf625f9e632e..4898c502974d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -91,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
91 u8 tid; 91 u8 tid;
92 struct rtl_priv *rtlpriv = rtl_priv(hw); 92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
94 const struct firmware *firmware;
95 static int header_print; 94 static int header_print;
96 95
97 rtlpriv->dm.dm_initialgain_enable = true; 96 rtlpriv->dm.dm_initialgain_enable = true;
@@ -167,6 +166,15 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
167 else if (rtlpriv->psc.reg_fwctrl_lps == 3) 166 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
168 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; 167 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
169 168
169 /* for early mode */
170 rtlpriv->rtlhal.earlymode_enable = true;
171 for (tid = 0; tid < 8; tid++)
172 skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
173
174 /* Only load firmware for first MAC */
175 if (header_print)
176 return 0;
177
170 /* for firmware buf */ 178 /* for firmware buf */
171 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); 179 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
172 if (!rtlpriv->rtlhal.pfirmware) { 180 if (!rtlpriv->rtlhal.pfirmware) {
@@ -175,33 +183,21 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
175 return 1; 183 return 1;
176 } 184 }
177 185
178 if (!header_print) { 186 rtlpriv->max_fw_size = 0x8000;
179 pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); 187 pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
180 pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); 188 pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
181 header_print++; 189 header_print++;
182 } 190
183 /* request fw */ 191 /* request fw */
184 err = request_firmware(&firmware, rtlpriv->cfg->fw_name, 192 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
185 rtlpriv->io.dev); 193 rtlpriv->io.dev, GFP_KERNEL, hw,
194 rtl_fw_cb);
186 if (err) { 195 if (err) {
187 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 196 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
188 "Failed to request firmware!\n"); 197 "Failed to request firmware!\n");
189 return 1; 198 return 1;
190 } 199 }
191 if (firmware->size > 0x8000) {
192 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
193 "Firmware is too big!\n");
194 release_firmware(firmware);
195 return 1;
196 }
197 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
198 rtlpriv->rtlhal.fwsize = firmware->size;
199 release_firmware(firmware);
200 200
201 /* for early mode */
202 rtlpriv->rtlhal.earlymode_enable = true;
203 for (tid = 0; tid < 8; tid++)
204 skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
205 return 0; 201 return 0;
206} 202}
207 203
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
index 595ecd22ffa0..0d8bf5657008 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
364 u8 fwstatus = FW_STATUS_INIT; 364 u8 fwstatus = FW_STATUS_INIT;
365 bool rtstatus = true; 365 bool rtstatus = true;
366 366
367 if (!rtlhal->pfirmware) 367 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
368 return 1; 368 return 1;
369 369
370 firmware = (struct rt_firmware *)rtlhal->pfirmware; 370 firmware = (struct rt_firmware *)rtlhal->pfirmware;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index cbaf1f345c6e..22098c2f38f1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -949,10 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
949 rtstatus = rtl92s_download_fw(hw); 949 rtstatus = rtl92s_download_fw(hw);
950 if (!rtstatus) { 950 if (!rtstatus) {
951 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 951 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
952 "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); 952 "Failed to download FW. Init HW without FW now... "
953 rtlhal->fw_ready = false; 953 "Please copy FW into /lib/firmware/rtlwifi\n");
954 } else { 954 return 1;
955 rtlhal->fw_ready = true;
956 } 955 }
957 956
958 /* After FW download, we have to reset MAC register */ 957 /* After FW download, we have to reset MAC register */
@@ -1215,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
1215 1214
1216void rtl92se_disable_interrupt(struct ieee80211_hw *hw) 1215void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
1217{ 1216{
1218 struct rtl_priv *rtlpriv = rtl_priv(hw); 1217 struct rtl_priv *rtlpriv;
1219 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1218 struct rtl_pci *rtlpci;
1220 1219
1220 rtlpriv = rtl_priv(hw);
1221 /* if firmware not available, no interrupts */
1222 if (!rtlpriv || !rtlpriv->max_fw_size)
1223 return;
1224 rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1221 rtl_write_dword(rtlpriv, INTA_MASK, 0); 1225 rtl_write_dword(rtlpriv, INTA_MASK, 0);
1222 rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); 1226 rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
1223 1227
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
index ef4211bca587..44949b5cbb87 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
@@ -76,10 +76,13 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
76 76
77void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) 77void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
78{ 78{
79 struct rtl_priv *rtlpriv = rtl_priv(hw); 79 struct rtl_priv *rtlpriv;
80 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 80 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
81 u8 ledcfg; 81 u8 ledcfg;
82 82
83 rtlpriv = rtl_priv(hw);
84 if (!rtlpriv || rtlpriv->max_fw_size)
85 return;
83 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", 86 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
84 LEDCFG, pled->ledpin); 87 LEDCFG, pled->ledpin);
85 88
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 0c47310b39b9..ca38dd9f3564 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -30,6 +30,8 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../core.h" 31#include "../core.h"
32#include "../pci.h" 32#include "../pci.h"
33#include "../base.h"
34#include "../pci.h"
33#include "reg.h" 35#include "reg.h"
34#include "def.h" 36#include "def.h"
35#include "phy.h" 37#include "phy.h"
@@ -86,12 +88,53 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
86 rtlpci->const_support_pciaspm = 2; 88 rtlpci->const_support_pciaspm = 2;
87} 89}
88 90
91static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
92{
93 struct ieee80211_hw *hw = context;
94 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
95 struct rtl_priv *rtlpriv = rtl_priv(hw);
96 struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
97 struct rt_firmware *pfirmware = NULL;
98 int err;
99
100 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
101 "Firmware callback routine entered!\n");
102 complete(&rtlpriv->firmware_loading_complete);
103 if (!firmware) {
104 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
105 rtlpriv->max_fw_size = 0;
106 return;
107 }
108 if (firmware->size > rtlpriv->max_fw_size) {
109 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
110 "Firmware is too big!\n");
111 release_firmware(firmware);
112 return;
113 }
114 pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
115 memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
116 pfirmware->sz_fw_tmpbufferlen = firmware->size;
117 release_firmware(firmware);
118
119 err = ieee80211_register_hw(hw);
120 if (err) {
121 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
122 "Can't register mac80211 hw\n");
123 return;
124 } else {
125 rtlpriv->mac80211.mac80211_registered = 1;
126 }
127 rtlpci->irq_alloc = 1;
128 set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
129
130 /*init rfkill */
131 rtl_init_rfkill(hw);
132}
133
89static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) 134static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
90{ 135{
91 struct rtl_priv *rtlpriv = rtl_priv(hw); 136 struct rtl_priv *rtlpriv = rtl_priv(hw);
92 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 137 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
93 const struct firmware *firmware;
94 struct rt_firmware *pfirmware = NULL;
95 int err = 0; 138 int err = 0;
96 u16 earlyrxthreshold = 7; 139 u16 earlyrxthreshold = 7;
97 140
@@ -189,27 +232,19 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
189 return 1; 232 return 1;
190 } 233 }
191 234
235 rtlpriv->max_fw_size = sizeof(struct rt_firmware);
236
192 pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" 237 pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
193 "Loading firmware %s\n", rtlpriv->cfg->fw_name); 238 "Loading firmware %s\n", rtlpriv->cfg->fw_name);
194 /* request fw */ 239 /* request fw */
195 err = request_firmware(&firmware, rtlpriv->cfg->fw_name, 240 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
196 rtlpriv->io.dev); 241 rtlpriv->io.dev, GFP_KERNEL, hw,
242 rtl92se_fw_cb);
197 if (err) { 243 if (err) {
198 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 244 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
199 "Failed to request firmware!\n"); 245 "Failed to request firmware!\n");
200 return 1; 246 return 1;
201 } 247 }
202 if (firmware->size > sizeof(struct rt_firmware)) {
203 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
204 "Firmware is too big!\n");
205 release_firmware(firmware);
206 return 1;
207 }
208
209 pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
210 memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
211 pfirmware->sz_fw_tmpbufferlen = firmware->size;
212 release_firmware(firmware);
213 248
214 return err; 249 return err;
215} 250}
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index e7a7ea96f42b..ffcf89fe45e4 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -664,15 +664,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw)
664 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 664 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
665 665
666 err = rtlpriv->cfg->ops->hw_init(hw); 666 err = rtlpriv->cfg->ops->hw_init(hw);
667 rtl_init_rx_config(hw); 667 if (!err) {
668 rtl_init_rx_config(hw);
668 669
669 /* Enable software */ 670 /* Enable software */
670 SET_USB_START(rtlusb); 671 SET_USB_START(rtlusb);
671 /* should after adapter start and interrupt enable. */ 672 /* should after adapter start and interrupt enable. */
672 set_hal_start(rtlhal); 673 set_hal_start(rtlhal);
673 674
674 /* Start bulk IN */ 675 /* Start bulk IN */
675 _rtl_usb_receive(hw); 676 _rtl_usb_receive(hw);
677 }
676 678
677 return err; 679 return err;
678} 680}
@@ -949,6 +951,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
949 return -ENOMEM; 951 return -ENOMEM;
950 } 952 }
951 rtlpriv = hw->priv; 953 rtlpriv = hw->priv;
954 init_completion(&rtlpriv->firmware_loading_complete);
952 SET_IEEE80211_DEV(hw, &intf->dev); 955 SET_IEEE80211_DEV(hw, &intf->dev);
953 udev = interface_to_usbdev(intf); 956 udev = interface_to_usbdev(intf);
954 usb_get_dev(udev); 957 usb_get_dev(udev);
@@ -982,24 +985,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
982 goto error_out; 985 goto error_out;
983 } 986 }
984 987
985 /*init rfkill */
986 /* rtl_init_rfkill(hw); */
987
988 err = ieee80211_register_hw(hw);
989 if (err) {
990 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
991 "Can't register mac80211 hw\n");
992 goto error_out;
993 } else {
994 rtlpriv->mac80211.mac80211_registered = 1;
995 }
996 set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
997 return 0; 988 return 0;
998error_out: 989error_out:
999 rtl_deinit_core(hw); 990 rtl_deinit_core(hw);
1000 _rtl_usb_io_handler_release(hw); 991 _rtl_usb_io_handler_release(hw);
1001 ieee80211_free_hw(hw);
1002 usb_put_dev(udev); 992 usb_put_dev(udev);
993 complete(&rtlpriv->firmware_loading_complete);
1003 return -ENODEV; 994 return -ENODEV;
1004} 995}
1005EXPORT_SYMBOL(rtl_usb_probe); 996EXPORT_SYMBOL(rtl_usb_probe);
@@ -1013,6 +1004,9 @@ void rtl_usb_disconnect(struct usb_interface *intf)
1013 1004
1014 if (unlikely(!rtlpriv)) 1005 if (unlikely(!rtlpriv))
1015 return; 1006 return;
1007
1008 /* just in case driver is removed before firmware callback */
1009 wait_for_completion(&rtlpriv->firmware_loading_complete);
1016 /*ieee80211_unregister_hw will call ops_stop */ 1010 /*ieee80211_unregister_hw will call ops_stop */
1017 if (rtlmac->mac80211_registered == 1) { 1011 if (rtlmac->mac80211_registered == 1) {
1018 ieee80211_unregister_hw(hw); 1012 ieee80211_unregister_hw(hw);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 1e5fffb2db0b..b591614c3b9b 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -38,6 +38,7 @@
38#include <linux/vmalloc.h> 38#include <linux/vmalloc.h>
39#include <linux/usb.h> 39#include <linux/usb.h>
40#include <net/mac80211.h> 40#include <net/mac80211.h>
41#include <linux/completion.h>
41#include "debug.h" 42#include "debug.h"
42 43
43#define RF_CHANGE_BY_INIT 0 44#define RF_CHANGE_BY_INIT 0
@@ -1047,7 +1048,6 @@ struct rtl_hal {
1047 u16 fw_subversion; 1048 u16 fw_subversion;
1048 bool h2c_setinprogress; 1049 bool h2c_setinprogress;
1049 u8 last_hmeboxnum; 1050 u8 last_hmeboxnum;
1050 bool fw_ready;
1051 /*Reserve page start offset except beacon in TxQ. */ 1051 /*Reserve page start offset except beacon in TxQ. */
1052 u8 fw_rsvdpage_startoffset; 1052 u8 fw_rsvdpage_startoffset;
1053 u8 h2c_txcmd_seq; 1053 u8 h2c_txcmd_seq;
@@ -1593,6 +1593,7 @@ struct rtl_debug {
1593}; 1593};
1594 1594
1595struct rtl_priv { 1595struct rtl_priv {
1596 struct completion firmware_loading_complete;
1596 struct rtl_locks locks; 1597 struct rtl_locks locks;
1597 struct rtl_works works; 1598 struct rtl_works works;
1598 struct rtl_mac mac80211; 1599 struct rtl_mac mac80211;
@@ -1614,6 +1615,7 @@ struct rtl_priv {
1614 struct rtl_rate_priv *rate_priv; 1615 struct rtl_rate_priv *rate_priv;
1615 1616
1616 struct rtl_debug dbg; 1617 struct rtl_debug dbg;
1618 int max_fw_size;
1617 1619
1618 /* 1620 /*
1619 *hal_cfg : for diff cards 1621 *hal_cfg : for diff cards