1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>.
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/kthread.h>
34 #include "osdep_service.h"
35 #include "drv_types.h"
36 #include "xmit_osdep.h"
37 #include "recv_osdep.h"
38 #include "rtl871x_ioctl.h"
39 #include "usb_osintf.h"
41 MODULE_LICENSE("GPL");
42 MODULE_DESCRIPTION("rtl871x wireless lan driver");
43 MODULE_AUTHOR("Larry Finger");
45 static char ifname
[IFNAMSIZ
] = "wlan%d";
47 /* module param defaults */
48 static int chip_version
= RTL8712_2ndCUT
;
49 static int rfintfs
= HWPI
;
50 static int lbkmode
= RTL8712_AIR_TRX
;
51 static int hci
= RTL8712_USB
;
52 static int ampdu_enable
= 1;/*for enable tx_ampdu*/
54 /* The video_mode variable is for vedio mode.*/
55 /* It may be specify when inserting module with video_mode=1 parameter.*/
56 static int video_mode
= 1; /* enable video mode*/
58 /*Ndis802_11Infrastructure; infra, ad-hoc, auto*/
59 static int network_mode
= Ndis802_11IBSS
;
60 static int channel
= 1;/*ad-hoc support requirement*/
61 static int wireless_mode
= WIRELESS_11BG
;
62 static int vrtl_carrier_sense
= AUTO_VCS
;
63 static int vcs_type
= RTS_CTS
;
64 static int frag_thresh
= 2346;
65 static int preamble
= PREAMBLE_LONG
;/*long, short, auto*/
66 static int scan_mode
= 1;/*active, passive*/
67 static int adhoc_tx_pwr
= 1;
69 static int smart_ps
= 1;
70 static int power_mgnt
= PS_MODE_ACTIVE
;
71 static int radio_enable
= 1;
72 static int long_retry_lmt
= 7;
73 static int short_retry_lmt
= 7;
74 static int busy_thresh
= 40;
75 static int ack_policy
= NORMAL_ACK
;
77 static int software_encrypt
;
78 static int software_decrypt
;
80 static int wmm_enable
;/* default is set to disable the wmm.*/
81 static int uapsd_enable
;
82 static int uapsd_max_sp
= NO_LIMIT
;
83 static int uapsd_acbk_en
;
84 static int uapsd_acbe_en
;
85 static int uapsd_acvi_en
;
86 static int uapsd_acvo_en
;
88 static int ht_enable
= 1;
89 static int cbw40_enable
= 1;
90 static int rf_config
= RTL8712_RF_1T2R
; /* 1T2R*/
92 /* mac address to use instead of the one stored in Efuse */
95 /* if wifi_test = 1, driver will disable the turbo mode and pass it to
98 static int wifi_test
= 0;
100 module_param_string(ifname
, ifname
, sizeof(ifname
), S_IRUGO
|S_IWUSR
);
101 module_param(wifi_test
, int, 0644);
102 module_param(initmac
, charp
, 0644);
103 module_param(video_mode
, int, 0644);
104 module_param(chip_version
, int, 0644);
105 module_param(rfintfs
, int, 0644);
106 module_param(lbkmode
, int, 0644);
107 module_param(hci
, int, 0644);
108 module_param(network_mode
, int, 0644);
109 module_param(channel
, int, 0644);
110 module_param(mp_mode
, int, 0644);
111 module_param(wmm_enable
, int, 0644);
112 module_param(vrtl_carrier_sense
, int, 0644);
113 module_param(vcs_type
, int, 0644);
114 module_param(busy_thresh
, int, 0644);
115 module_param(ht_enable
, int, 0644);
116 module_param(cbw40_enable
, int, 0644);
117 module_param(ampdu_enable
, int, 0644);
118 module_param(rf_config
, int, 0644);
119 module_param(power_mgnt
, int, 0644);
120 module_param(low_power
, int, 0644);
122 MODULE_PARM_DESC(ifname
, " Net interface name, wlan%d=default");
123 MODULE_PARM_DESC(initmac
, "MAC-Address, default: use FUSE");
125 static uint
loadparam(struct _adapter
*padapter
, struct net_device
*pnetdev
);
126 static int netdev_open(struct net_device
*pnetdev
);
127 static int netdev_close(struct net_device
*pnetdev
);
129 static uint
loadparam(struct _adapter
*padapter
, struct net_device
*pnetdev
)
131 uint status
= _SUCCESS
;
132 struct registry_priv
*registry_par
= &padapter
->registrypriv
;
134 registry_par
->chip_version
= (u8
)chip_version
;
135 registry_par
->rfintfs
= (u8
)rfintfs
;
136 registry_par
->lbkmode
= (u8
)lbkmode
;
137 registry_par
->hci
= (u8
)hci
;
138 registry_par
->network_mode
= (u8
)network_mode
;
139 memcpy(registry_par
->ssid
.Ssid
, "ANY", 3);
140 registry_par
->ssid
.SsidLength
= 3;
141 registry_par
->channel
= (u8
)channel
;
142 registry_par
->wireless_mode
= (u8
)wireless_mode
;
143 registry_par
->vrtl_carrier_sense
= (u8
)vrtl_carrier_sense
;
144 registry_par
->vcs_type
= (u8
)vcs_type
;
145 registry_par
->frag_thresh
= (u16
)frag_thresh
;
146 registry_par
->preamble
= (u8
)preamble
;
147 registry_par
->scan_mode
= (u8
)scan_mode
;
148 registry_par
->adhoc_tx_pwr
= (u8
)adhoc_tx_pwr
;
149 registry_par
->soft_ap
= (u8
)soft_ap
;
150 registry_par
->smart_ps
= (u8
)smart_ps
;
151 registry_par
->power_mgnt
= (u8
)power_mgnt
;
152 registry_par
->radio_enable
= (u8
)radio_enable
;
153 registry_par
->long_retry_lmt
= (u8
)long_retry_lmt
;
154 registry_par
->short_retry_lmt
= (u8
)short_retry_lmt
;
155 registry_par
->busy_thresh
= (u16
)busy_thresh
;
156 registry_par
->ack_policy
= (u8
)ack_policy
;
157 registry_par
->mp_mode
= (u8
)mp_mode
;
158 registry_par
->software_encrypt
= (u8
)software_encrypt
;
159 registry_par
->software_decrypt
= (u8
)software_decrypt
;
161 registry_par
->wmm_enable
= (u8
)wmm_enable
;
162 registry_par
->uapsd_enable
= (u8
)uapsd_enable
;
163 registry_par
->uapsd_max_sp
= (u8
)uapsd_max_sp
;
164 registry_par
->uapsd_acbk_en
= (u8
)uapsd_acbk_en
;
165 registry_par
->uapsd_acbe_en
= (u8
)uapsd_acbe_en
;
166 registry_par
->uapsd_acvi_en
= (u8
)uapsd_acvi_en
;
167 registry_par
->uapsd_acvo_en
= (u8
)uapsd_acvo_en
;
168 registry_par
->ht_enable
= (u8
)ht_enable
;
169 registry_par
->cbw40_enable
= (u8
)cbw40_enable
;
170 registry_par
->ampdu_enable
= (u8
)ampdu_enable
;
171 registry_par
->rf_config
= (u8
)rf_config
;
172 registry_par
->low_power
= (u8
)low_power
;
173 registry_par
->wifi_test
= (u8
) wifi_test
;
174 r8712_initmac
= initmac
;
178 static int r871x_net_set_mac_address(struct net_device
*pnetdev
, void *p
)
180 struct _adapter
*padapter
= (struct _adapter
*)_netdev_priv(pnetdev
);
181 struct sockaddr
*addr
= p
;
183 if (padapter
->bup
== false)
184 memcpy(pnetdev
->dev_addr
, addr
->sa_data
, ETH_ALEN
);
188 static struct net_device_stats
*r871x_net_get_stats(struct net_device
*pnetdev
)
190 struct _adapter
*padapter
= (struct _adapter
*) _netdev_priv(pnetdev
);
191 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
192 struct recv_priv
*precvpriv
= &(padapter
->recvpriv
);
194 padapter
->stats
.tx_packets
= pxmitpriv
->tx_pkts
;
195 padapter
->stats
.rx_packets
= precvpriv
->rx_pkts
;
196 padapter
->stats
.tx_dropped
= pxmitpriv
->tx_drop
;
197 padapter
->stats
.rx_dropped
= precvpriv
->rx_drop
;
198 padapter
->stats
.tx_bytes
= pxmitpriv
->tx_bytes
;
199 padapter
->stats
.rx_bytes
= precvpriv
->rx_bytes
;
200 return &padapter
->stats
;
203 static const struct net_device_ops rtl8712_netdev_ops
= {
204 .ndo_open
= netdev_open
,
205 .ndo_stop
= netdev_close
,
206 .ndo_start_xmit
= r8712_xmit_entry
,
207 .ndo_set_mac_address
= r871x_net_set_mac_address
,
208 .ndo_get_stats
= r871x_net_get_stats
,
209 .ndo_do_ioctl
= r871x_ioctl
,
212 struct net_device
*r8712_init_netdev(void)
214 struct _adapter
*padapter
;
215 struct net_device
*pnetdev
;
217 pnetdev
= alloc_etherdev(sizeof(struct _adapter
));
220 if (dev_alloc_name(pnetdev
, ifname
) < 0) {
221 strcpy(ifname
, "wlan%d");
222 dev_alloc_name(pnetdev
, ifname
);
224 padapter
= (struct _adapter
*) _netdev_priv(pnetdev
);
225 padapter
->pnetdev
= pnetdev
;
226 printk(KERN_INFO
"r8712u: register rtl8712_netdev_ops to"
228 pnetdev
->netdev_ops
= &rtl8712_netdev_ops
;
229 pnetdev
->watchdog_timeo
= HZ
; /* 1 second timeout */
230 pnetdev
->wireless_handlers
= (struct iw_handler_def
*)
233 loadparam(padapter
, pnetdev
);
234 netif_carrier_off(pnetdev
);
235 padapter
->pid
= 0; /* Initial the PID value used for HW PBC.*/
239 static u32
start_drv_threads(struct _adapter
*padapter
)
241 padapter
->cmdThread
= kthread_run(r8712_cmd_thread
, padapter
,
242 padapter
->pnetdev
->name
);
243 if (IS_ERR(padapter
->cmdThread
) < 0)
248 void r8712_stop_drv_threads(struct _adapter
*padapter
)
250 /*Below is to termindate r8712_cmd_thread & event_thread...*/
251 up(&padapter
->cmdpriv
.cmd_queue_sema
);
252 if (padapter
->cmdThread
)
253 _down_sema(&padapter
->cmdpriv
.terminate_cmdthread_sema
);
254 padapter
->cmdpriv
.cmd_seq
= 1;
257 static void start_drv_timers(struct _adapter
*padapter
)
259 _set_timer(&padapter
->mlmepriv
.sitesurveyctrl
.sitesurvey_ctrl_timer
,
261 _set_timer(&padapter
->mlmepriv
.wdg_timer
, 2000);
264 static void stop_drv_timers(struct _adapter
*padapter
)
266 _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
);
270 _cancel_timer_ex(&padapter
->mlmepriv
.scan_to_timer
);
271 _cancel_timer_ex(&padapter
->mlmepriv
.dhcp_timer
);
272 _cancel_timer_ex(&padapter
->mlmepriv
.wdg_timer
);
275 static u8
init_default_value(struct _adapter
*padapter
)
278 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
279 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
280 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
281 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
284 pxmitpriv
->vcs_setting
= pregistrypriv
->vrtl_carrier_sense
;
285 pxmitpriv
->vcs
= pregistrypriv
->vcs_type
;
286 pxmitpriv
->vcs_type
= pregistrypriv
->vcs_type
;
287 pxmitpriv
->rts_thresh
= pregistrypriv
->rts_thresh
;
288 pxmitpriv
->frag_len
= pregistrypriv
->frag_thresh
;
292 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
294 phtpriv
->ampdu_enable
= false;/*set to disabled*/
295 for (i
= 0; i
< 16; i
++)
296 phtpriv
->baddbareq_issued
[i
] = false;
299 psecuritypriv
->sw_encrypt
= pregistrypriv
->software_encrypt
;
300 psecuritypriv
->sw_decrypt
= pregistrypriv
->software_decrypt
;
301 psecuritypriv
->binstallGrpkey
= _FAIL
;
304 r8712_init_registrypriv_dev_network(padapter
);
305 r8712_update_registrypriv_dev_network(padapter
);
310 u8
r8712_init_drv_sw(struct _adapter
*padapter
)
312 if ((r8712_init_cmd_priv(&padapter
->cmdpriv
)) == _FAIL
)
314 padapter
->cmdpriv
.padapter
= padapter
;
315 if ((r8712_init_evt_priv(&padapter
->evtpriv
)) == _FAIL
)
317 if (r8712_init_mlme_priv(padapter
) == _FAIL
)
319 _r8712_init_xmit_priv(&padapter
->xmitpriv
, padapter
);
320 _r8712_init_recv_priv(&padapter
->recvpriv
, padapter
);
321 memset((unsigned char *)&padapter
->securitypriv
, 0,
322 sizeof(struct security_priv
));
323 _init_timer(&(padapter
->securitypriv
.tkip_timer
), padapter
->pnetdev
,
324 r8712_use_tkipkey_handler
, padapter
);
325 _r8712_init_sta_priv(&padapter
->stapriv
);
326 padapter
->stapriv
.padapter
= padapter
;
327 r8712_init_bcmc_stainfo(padapter
);
328 r8712_init_pwrctrl_priv(padapter
);
329 sema_init(&(padapter
->pwrctrlpriv
.pnp_pwr_mgnt_sema
), 0);
330 mp871xinit(padapter
);
331 if (init_default_value(padapter
) != _SUCCESS
)
333 r8712_InitSwLeds(padapter
);
337 u8
r8712_free_drv_sw(struct _adapter
*padapter
)
339 struct net_device
*pnetdev
= (struct net_device
*)padapter
->pnetdev
;
341 r8712_free_cmd_priv(&padapter
->cmdpriv
);
342 r8712_free_evt_priv(&padapter
->evtpriv
);
343 r8712_DeInitSwLeds(padapter
);
344 r8712_free_mlme_priv(&padapter
->mlmepriv
);
345 r8712_free_io_queue(padapter
);
346 _free_xmit_priv(&padapter
->xmitpriv
);
347 _r8712_free_sta_priv(&padapter
->stapriv
);
348 _r8712_free_recv_priv(&padapter
->recvpriv
);
349 mp871xdeinit(padapter
);
351 os_free_netdev(pnetdev
);
356 static void enable_video_mode(struct _adapter
*padapter
, int cbw40_value
)
359 * 1 -> enable video mode to 96B AP
360 * 0 -> disable video mode to 96B AP
362 * 1 -> enable 40MHz mode
363 * 0 -> disable 40MHz mode
368 u32 intcmd
= 0xf4000500; /* enable bit8, bit10*/
371 /* if the driver supports the 40M bandwidth,
372 * we can enable the bit 9.*/
375 r8712_fw_cmd(padapter
, intcmd
);
378 static int netdev_open(struct net_device
*pnetdev
)
380 struct _adapter
*padapter
= (struct _adapter
*)_netdev_priv(pnetdev
);
382 if (padapter
->bup
== false) {
383 padapter
->bDriverStopped
= false;
384 padapter
->bSurpriseRemoved
= false;
385 padapter
->bup
= true;
386 if (rtl871x_hal_init(padapter
) != _SUCCESS
)
387 goto netdev_open_error
;
388 if (r8712_initmac
== NULL
)
389 /* Use the mac address stored in the Efuse */
390 memcpy(pnetdev
->dev_addr
,
391 padapter
->eeprompriv
.mac_addr
, ETH_ALEN
);
393 /* We have to inform f/w to use user-supplied MAC
397 r8712_setMacAddr_cmd(padapter
, (u8
*)pnetdev
->dev_addr
);
399 * The "myid" function will get the wifi mac address
400 * from eeprompriv structure instead of netdev
401 * structure. So, we have to overwrite the mac_addr
402 * stored in the eeprompriv structure. In this case,
403 * the real mac address won't be used anymore. So that,
404 * the eeprompriv.mac_addr should store the mac which
407 memcpy(padapter
->eeprompriv
.mac_addr
,
408 pnetdev
->dev_addr
, ETH_ALEN
);
410 if (start_drv_threads(padapter
) != _SUCCESS
)
411 goto netdev_open_error
;
412 if (padapter
->dvobjpriv
.inirp_init
== NULL
)
413 goto netdev_open_error
;
415 padapter
->dvobjpriv
.inirp_init(padapter
);
416 r8712_set_ps_mode(padapter
, padapter
->registrypriv
.power_mgnt
,
417 padapter
->registrypriv
.smart_ps
);
419 if (!netif_queue_stopped(pnetdev
))
420 netif_start_queue(pnetdev
);
422 netif_wake_queue(pnetdev
);
425 enable_video_mode(padapter
, cbw40_enable
);
426 /* start driver mlme relation timer */
427 start_drv_timers(padapter
);
428 padapter
->ledpriv
.LedControlHandler(padapter
, LED_CTL_NO_LINK
);
431 padapter
->bup
= false;
432 netif_carrier_off(pnetdev
);
433 netif_stop_queue(pnetdev
);
437 static int netdev_close(struct net_device
*pnetdev
)
439 struct _adapter
*padapter
= (struct _adapter
*) _netdev_priv(pnetdev
);
442 padapter
->ledpriv
.LedControlHandler(padapter
, LED_CTL_POWER_OFF
);
447 if (!netif_queue_stopped(pnetdev
))
448 netif_stop_queue(pnetdev
);
451 /*s2-1. issue disassoc_cmd to fw*/
452 r8712_disassoc_cmd(padapter
);
453 /*s2-2. indicate disconnect to os*/
454 r8712_ind_disconnect(padapter
);
456 r8712_free_assoc_resources(padapter
);
458 r8712_free_network_queue(padapter
);
459 /*Stop driver mlme relation timer*/
460 stop_drv_timers(padapter
);
464 #include "mlme_osdep.h"