diff options
Diffstat (limited to 'drivers/staging/rtl8712')
-rw-r--r-- | drivers/staging/rtl8712/drv_types.h | 7 | ||||
-rw-r--r-- | drivers/staging/rtl8712/hal_init.c | 62 | ||||
-rw-r--r-- | drivers/staging/rtl8712/os_intfs.c | 14 | ||||
-rw-r--r-- | drivers/staging/rtl8712/rtl8712_hal.h | 1 | ||||
-rw-r--r-- | drivers/staging/rtl8712/rtl871x_sta_mgt.c | 1 | ||||
-rw-r--r-- | drivers/staging/rtl8712/usb_intf.c | 10 |
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 | ||
41 | enum _NIC_VERSION { | 43 | enum _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 | ||
189 | static inline u8 *myid(struct eeprom_priv *peepriv) | 196 | static 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 | ||
45 | static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, | 45 | static 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 | |||
65 | static const char firmware_file[] = "rtlwifi/rtl8712u.bin"; | ||
66 | |||
67 | int 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 | } | ||
81 | MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); | ||
82 | |||
83 | static 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 | } |
67 | MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); | ||
68 | 95 | ||
69 | static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) | 96 | static 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 | ||
298 | exit_fail: | 324 | exit_fail: |
299 | kfree(ptmpchar); | 325 | kfree(ptmpchar); |
300 | firmware_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) | |||
264 | void r8712_stop_drv_timers(struct _adapter *padapter) | 265 | void 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 | ||
275 | static u8 init_default_value(struct _adapter *padapter) | 276 | static 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; |
439 | netdev_open_error: | 443 | netdev_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 | ||
147 | uint rtl8712_hal_init(struct _adapter *padapter); | 147 | uint rtl8712_hal_init(struct _adapter *padapter); |
148 | int 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; |
603 | error: | 606 | error: |
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 | } |