aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rtl8712
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rtl8712')
-rw-r--r--drivers/staging/rtl8712/drv_types.h7
-rw-r--r--drivers/staging/rtl8712/hal_init.c62
-rw-r--r--drivers/staging/rtl8712/os_intfs.c14
-rw-r--r--drivers/staging/rtl8712/rtl8712_hal.h1
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c1
-rw-r--r--drivers/staging/rtl8712/usb_intf.c10
6 files changed, 70 insertions, 25 deletions
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index 9b5d771e650..ed85b441520 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -37,6 +37,8 @@ struct _adapter;
37#include "wlan_bssdef.h" 37#include "wlan_bssdef.h"
38#include "rtl8712_spec.h" 38#include "rtl8712_spec.h"
39#include "rtl8712_hal.h" 39#include "rtl8712_hal.h"
40#include <linux/mutex.h>
41#include <linux/completion.h>
40 42
41enum _NIC_VERSION { 43enum _NIC_VERSION {
42 RTL8711_NIC, 44 RTL8711_NIC,
@@ -168,6 +170,7 @@ struct _adapter {
168 s32 bSurpriseRemoved; 170 s32 bSurpriseRemoved;
169 u32 IsrContent; 171 u32 IsrContent;
170 u32 ImrContent; 172 u32 ImrContent;
173 bool fw_found;
171 u8 EepromAddressSize; 174 u8 EepromAddressSize;
172 u8 hw_init_completed; 175 u8 hw_init_completed;
173 struct task_struct *cmdThread; 176 struct task_struct *cmdThread;
@@ -184,6 +187,10 @@ struct _adapter {
184 _workitem wkFilterRxFF0; 187 _workitem wkFilterRxFF0;
185 u8 blnEnableRxFF0Filter; 188 u8 blnEnableRxFF0Filter;
186 spinlock_t lockRxFF0Filter; 189 spinlock_t lockRxFF0Filter;
190 const struct firmware *fw;
191 struct usb_interface *pusb_intf;
192 struct mutex mutex_start;
193 struct completion rtl8712_fw_ready;
187}; 194};
188 195
189static inline u8 *myid(struct eeprom_priv *peepriv) 196static inline u8 *myid(struct eeprom_priv *peepriv)
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
index d0029aa4cd3..cc893c0f5ad 100644
--- a/drivers/staging/rtl8712/hal_init.c
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -42,29 +42,56 @@
42#define FWBUFF_ALIGN_SZ 512 42#define FWBUFF_ALIGN_SZ 512
43#define MAX_DUMP_FWSZ 49152 /*default = 49152 (48k)*/ 43#define MAX_DUMP_FWSZ 49152 /*default = 49152 (48k)*/
44 44
45static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, 45static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
46 const u8 **ppmappedfw)
47{ 46{
47 struct _adapter *padapter = context;
48
49 complete(&padapter->rtl8712_fw_ready);
50 if (!firmware) {
51 struct usb_device *udev = padapter->dvobjpriv.pusbdev;
52 struct usb_interface *pusb_intf = padapter->pusb_intf;
53 printk(KERN_ERR "r8712u: Firmware request failed\n");
54 padapter->fw_found = false;
55 usb_put_dev(udev);
56 usb_set_intfdata(pusb_intf, NULL);
57 return;
58 }
59 padapter->fw = firmware;
60 padapter->fw_found = true;
61 /* firmware available - start netdev */
62 register_netdev(padapter->pnetdev);
63}
64
65static const char firmware_file[] = "rtlwifi/rtl8712u.bin";
66
67int rtl871x_load_fw(struct _adapter *padapter)
68{
69 struct device *dev = &padapter->dvobjpriv.pusbdev->dev;
48 int rc; 70 int rc;
49 const char firmware_file[] = "rtlwifi/rtl8712u.bin";
50 const struct firmware **praw = (const struct firmware **)
51 (pphfwfile_hdl);
52 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)
53 (&padapter->dvobjpriv);
54 struct usb_device *pusbdev = pdvobjpriv->pusbdev;
55 71
72 init_completion(&padapter->rtl8712_fw_ready);
56 printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n", 73 printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n",
57 firmware_file); 74 firmware_file);
58 rc = request_firmware(praw, firmware_file, &pusbdev->dev); 75 rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev,
59 if (rc < 0) { 76 GFP_KERNEL, padapter, rtl871x_load_fw_cb);
60 printk(KERN_ERR "r8712u: Unable to load firmware\n"); 77 if (rc)
61 printk(KERN_ERR "r8712u: Install latest linux-firmware\n"); 78 printk(KERN_ERR "r8712u: Firmware request error %d\n", rc);
79 return rc;
80}
81MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
82
83static u32 rtl871x_open_fw(struct _adapter *padapter, const u8 **ppmappedfw)
84{
85 const struct firmware **praw = &padapter->fw;
86
87 if (padapter->fw->size > 200000) {
88 printk(KERN_ERR "r8172u: Badfw->size of %d\n",
89 (int)padapter->fw->size);
62 return 0; 90 return 0;
63 } 91 }
64 *ppmappedfw = (u8 *)((*praw)->data); 92 *ppmappedfw = (u8 *)((*praw)->data);
65 return (*praw)->size; 93 return (*praw)->size;
66} 94}
67MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
68 95
69static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) 96static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
70{ 97{
@@ -142,18 +169,17 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
142 uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ 169 uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */
143 struct fw_hdr fwhdr; 170 struct fw_hdr fwhdr;
144 u32 ulfilelength; /* FW file size */ 171 u32 ulfilelength; /* FW file size */
145 void *phfwfile_hdl = NULL;
146 const u8 *pmappedfw = NULL; 172 const u8 *pmappedfw = NULL;
147 u8 *ptmpchar = NULL, *ppayload, *ptr; 173 u8 *ptmpchar = NULL, *ppayload, *ptr;
148 struct tx_desc *ptx_desc; 174 struct tx_desc *ptx_desc;
149 u32 txdscp_sz = sizeof(struct tx_desc); 175 u32 txdscp_sz = sizeof(struct tx_desc);
150 u8 ret = _FAIL; 176 u8 ret = _FAIL;
151 177
152 ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw); 178 ulfilelength = rtl871x_open_fw(padapter, &pmappedfw);
153 if (pmappedfw && (ulfilelength > 0)) { 179 if (pmappedfw && (ulfilelength > 0)) {
154 update_fwhdr(&fwhdr, pmappedfw); 180 update_fwhdr(&fwhdr, pmappedfw);
155 if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL) 181 if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
156 goto firmware_rel; 182 return ret;
157 fill_fwpriv(padapter, &fwhdr.fwpriv); 183 fill_fwpriv(padapter, &fwhdr.fwpriv);
158 /* firmware check ok */ 184 /* firmware check ok */
159 maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ? 185 maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
@@ -161,7 +187,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
161 maxlen += txdscp_sz; 187 maxlen += txdscp_sz;
162 ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ); 188 ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
163 if (ptmpchar == NULL) 189 if (ptmpchar == NULL)
164 goto firmware_rel; 190 return ret;
165 191
166 ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ - 192 ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
167 ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1))); 193 ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
@@ -297,8 +323,6 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
297 323
298exit_fail: 324exit_fail:
299 kfree(ptmpchar); 325 kfree(ptmpchar);
300firmware_rel:
301 release_firmware((struct firmware *)phfwfile_hdl);
302 return ret; 326 return ret;
303} 327}
304 328
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
index 9a75c6dbe50..98a3d684f9b 100644
--- a/drivers/staging/rtl8712/os_intfs.c
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/kthread.h> 33#include <linux/kthread.h>
34#include <linux/firmware.h>
34#include "osdep_service.h" 35#include "osdep_service.h"
35#include "drv_types.h" 36#include "drv_types.h"
36#include "xmit_osdep.h" 37#include "xmit_osdep.h"
@@ -264,12 +265,12 @@ static void start_drv_timers(struct _adapter *padapter)
264void r8712_stop_drv_timers(struct _adapter *padapter) 265void r8712_stop_drv_timers(struct _adapter *padapter)
265{ 266{
266 _cancel_timer_ex(&padapter->mlmepriv.assoc_timer); 267 _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
267 _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
268 sitesurvey_ctrl_timer);
269 _cancel_timer_ex(&padapter->securitypriv.tkip_timer); 268 _cancel_timer_ex(&padapter->securitypriv.tkip_timer);
270 _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer); 269 _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
271 _cancel_timer_ex(&padapter->mlmepriv.dhcp_timer); 270 _cancel_timer_ex(&padapter->mlmepriv.dhcp_timer);
272 _cancel_timer_ex(&padapter->mlmepriv.wdg_timer); 271 _cancel_timer_ex(&padapter->mlmepriv.wdg_timer);
272 _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
273 sitesurvey_ctrl_timer);
273} 274}
274 275
275static u8 init_default_value(struct _adapter *padapter) 276static u8 init_default_value(struct _adapter *padapter)
@@ -347,7 +348,8 @@ u8 r8712_free_drv_sw(struct _adapter *padapter)
347 r8712_free_mlme_priv(&padapter->mlmepriv); 348 r8712_free_mlme_priv(&padapter->mlmepriv);
348 r8712_free_io_queue(padapter); 349 r8712_free_io_queue(padapter);
349 _free_xmit_priv(&padapter->xmitpriv); 350 _free_xmit_priv(&padapter->xmitpriv);
350 _r8712_free_sta_priv(&padapter->stapriv); 351 if (padapter->fw_found)
352 _r8712_free_sta_priv(&padapter->stapriv);
351 _r8712_free_recv_priv(&padapter->recvpriv); 353 _r8712_free_recv_priv(&padapter->recvpriv);
352 mp871xdeinit(padapter); 354 mp871xdeinit(padapter);
353 if (pnetdev) 355 if (pnetdev)
@@ -388,6 +390,7 @@ static int netdev_open(struct net_device *pnetdev)
388{ 390{
389 struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev); 391 struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev);
390 392
393 mutex_lock(&padapter->mutex_start);
391 if (padapter->bup == false) { 394 if (padapter->bup == false) {
392 padapter->bDriverStopped = false; 395 padapter->bDriverStopped = false;
393 padapter->bSurpriseRemoved = false; 396 padapter->bSurpriseRemoved = false;
@@ -435,11 +438,13 @@ static int netdev_open(struct net_device *pnetdev)
435 /* start driver mlme relation timer */ 438 /* start driver mlme relation timer */
436 start_drv_timers(padapter); 439 start_drv_timers(padapter);
437 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); 440 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
441 mutex_unlock(&padapter->mutex_start);
438 return 0; 442 return 0;
439netdev_open_error: 443netdev_open_error:
440 padapter->bup = false; 444 padapter->bup = false;
441 netif_carrier_off(pnetdev); 445 netif_carrier_off(pnetdev);
442 netif_stop_queue(pnetdev); 446 netif_stop_queue(pnetdev);
447 mutex_unlock(&padapter->mutex_start);
443 return -1; 448 return -1;
444} 449}
445 450
@@ -473,6 +478,9 @@ static int netdev_close(struct net_device *pnetdev)
473 r8712_free_network_queue(padapter); 478 r8712_free_network_queue(padapter);
474 /* The interface is no longer Up: */ 479 /* The interface is no longer Up: */
475 padapter->bup = false; 480 padapter->bup = false;
481 release_firmware(padapter->fw);
482 /* never exit with a firmware callback pending */
483 wait_for_completion(&padapter->rtl8712_fw_ready);
476 return 0; 484 return 0;
477} 485}
478 486
diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h
index 665e7183817..d19865a5a50 100644
--- a/drivers/staging/rtl8712/rtl8712_hal.h
+++ b/drivers/staging/rtl8712/rtl8712_hal.h
@@ -145,5 +145,6 @@ struct hal_priv {
145}; 145};
146 146
147uint rtl8712_hal_init(struct _adapter *padapter); 147uint rtl8712_hal_init(struct _adapter *padapter);
148int rtl871x_load_fw(struct _adapter *padapter);
148 149
149#endif 150#endif
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 64f56961883..81bde803c59 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -43,6 +43,7 @@ static void _init_stainfo(struct sta_info *psta)
43 _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); 43 _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
44 _r8712_init_sta_recv_priv(&psta->sta_recvpriv); 44 _r8712_init_sta_recv_priv(&psta->sta_recvpriv);
45#ifdef CONFIG_R8712_AP 45#ifdef CONFIG_R8712_AP
46 _init_listhead(&psta->asoc_list);
46 _init_listhead(&psta->auth_list); 47 _init_listhead(&psta->auth_list);
47#endif 48#endif
48} 49}
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 5385da2e9cd..9bade184883 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -89,6 +89,7 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = {
89 {USB_DEVICE(0x0DF6, 0x0045)}, 89 {USB_DEVICE(0x0DF6, 0x0045)},
90 {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ 90 {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */
91 {USB_DEVICE(0x0DF6, 0x004B)}, 91 {USB_DEVICE(0x0DF6, 0x004B)},
92 {USB_DEVICE(0x0DF6, 0x005B)},
92 {USB_DEVICE(0x0DF6, 0x005D)}, 93 {USB_DEVICE(0x0DF6, 0x005D)},
93 {USB_DEVICE(0x0DF6, 0x0063)}, 94 {USB_DEVICE(0x0DF6, 0x0063)},
94 /* Sweex */ 95 /* Sweex */
@@ -389,6 +390,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
389 pdvobjpriv = &padapter->dvobjpriv; 390 pdvobjpriv = &padapter->dvobjpriv;
390 pdvobjpriv->padapter = padapter; 391 pdvobjpriv->padapter = padapter;
391 padapter->dvobjpriv.pusbdev = udev; 392 padapter->dvobjpriv.pusbdev = udev;
393 padapter->pusb_intf = pusb_intf;
392 usb_set_intfdata(pusb_intf, pnetdev); 394 usb_set_intfdata(pusb_intf, pnetdev);
393 SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); 395 SET_NETDEV_DEV(pnetdev, &pusb_intf->dev);
394 /* step 2. */ 396 /* step 2. */
@@ -595,10 +597,11 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
595 "%pM\n", mac); 597 "%pM\n", mac);
596 memcpy(pnetdev->dev_addr, mac, ETH_ALEN); 598 memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
597 } 599 }
598 /* step 6. Tell the network stack we exist */ 600 /* step 6. Load the firmware asynchronously */
599 if (register_netdev(pnetdev) != 0) 601 if (rtl871x_load_fw(padapter))
600 goto error; 602 goto error;
601 spin_lock_init(&padapter->lockRxFF0Filter); 603 spin_lock_init(&padapter->lockRxFF0Filter);
604 mutex_init(&padapter->mutex_start);
602 return 0; 605 return 0;
603error: 606error:
604 usb_put_dev(udev); 607 usb_put_dev(udev);
@@ -629,7 +632,8 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
629 flush_scheduled_work(); 632 flush_scheduled_work();
630 udelay(1); 633 udelay(1);
631 /*Stop driver mlme relation timer */ 634 /*Stop driver mlme relation timer */
632 r8712_stop_drv_timers(padapter); 635 if (padapter->fw_found)
636 r8712_stop_drv_timers(padapter);
633 r871x_dev_unload(padapter); 637 r871x_dev_unload(padapter);
634 r8712_free_drv_sw(padapter); 638 r8712_free_drv_sw(padapter);
635 } 639 }