/drivers/staging/rtl8712/os_intfs.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 464 lines · 345 code · 41 blank · 78 comment · 32 complexity · a17302cd6494522751a9b5b25bf52c4c MD5 · raw file

  1. /******************************************************************************
  2. * os_intfs.c
  3. *
  4. * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  5. * Linux device driver for RTL8192SU
  6. *
  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.
  10. *
  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
  14. * more details.
  15. *
  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
  19. *
  20. * Modifications for inclusion into the Linux staging tree are
  21. * Copyright(c) 2010 Larry Finger. All rights reserved.
  22. *
  23. * Contact information:
  24. * WLAN FAE <wlanfae@realtek.com>.
  25. * Larry Finger <Larry.Finger@lwfinger.net>
  26. *
  27. ******************************************************************************/
  28. #define _OS_INTFS_C_
  29. #include <linux/module.h>
  30. #include <linux/init.h>
  31. #include <linux/kthread.h>
  32. #include "osdep_service.h"
  33. #include "drv_types.h"
  34. #include "xmit_osdep.h"
  35. #include "recv_osdep.h"
  36. #include "rtl871x_ioctl.h"
  37. #include "usb_osintf.h"
  38. MODULE_LICENSE("GPL");
  39. MODULE_DESCRIPTION("rtl871x wireless lan driver");
  40. MODULE_AUTHOR("Larry Finger");
  41. static char ifname[IFNAMSIZ] = "wlan%d";
  42. /* module param defaults */
  43. static int chip_version = RTL8712_2ndCUT;
  44. static int rfintfs = HWPI;
  45. static int lbkmode = RTL8712_AIR_TRX;
  46. static int hci = RTL8712_USB;
  47. static int ampdu_enable = 1;/*for enable tx_ampdu*/
  48. /* The video_mode variable is for vedio mode.*/
  49. /* It may be specify when inserting module with video_mode=1 parameter.*/
  50. static int video_mode = 1; /* enable video mode*/
  51. /*Ndis802_11Infrastructure; infra, ad-hoc, auto*/
  52. static int network_mode = Ndis802_11IBSS;
  53. static int channel = 1;/*ad-hoc support requirement*/
  54. static int wireless_mode = WIRELESS_11BG;
  55. static int vrtl_carrier_sense = AUTO_VCS;
  56. static int vcs_type = RTS_CTS;
  57. static int frag_thresh = 2346;
  58. static int preamble = PREAMBLE_LONG;/*long, short, auto*/
  59. static int scan_mode = 1;/*active, passive*/
  60. static int adhoc_tx_pwr = 1;
  61. static int soft_ap;
  62. static int smart_ps = 1;
  63. static int power_mgnt = PS_MODE_ACTIVE;
  64. static int radio_enable = 1;
  65. static int long_retry_lmt = 7;
  66. static int short_retry_lmt = 7;
  67. static int busy_thresh = 40;
  68. static int ack_policy = NORMAL_ACK;
  69. static int mp_mode;
  70. static int software_encrypt;
  71. static int software_decrypt;
  72. static int wmm_enable;/* default is set to disable the wmm.*/
  73. static int uapsd_enable;
  74. static int uapsd_max_sp = NO_LIMIT;
  75. static int uapsd_acbk_en;
  76. static int uapsd_acbe_en;
  77. static int uapsd_acvi_en;
  78. static int uapsd_acvo_en;
  79. static int ht_enable = 1;
  80. static int cbw40_enable = 1;
  81. static int rf_config = RTL8712_RF_1T2R; /* 1T2R*/
  82. static int low_power;
  83. /* mac address to use instead of the one stored in Efuse */
  84. char *r8712_initmac;
  85. static char *initmac;
  86. /* if wifi_test = 1, driver will disable the turbo mode and pass it to
  87. * firmware private.
  88. */
  89. static int wifi_test = 0;
  90. module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
  91. module_param(wifi_test, int, 0644);
  92. module_param(initmac, charp, 0644);
  93. module_param(video_mode, int, 0644);
  94. module_param(chip_version, int, 0644);
  95. module_param(rfintfs, int, 0644);
  96. module_param(lbkmode, int, 0644);
  97. module_param(hci, int, 0644);
  98. module_param(network_mode, int, 0644);
  99. module_param(channel, int, 0644);
  100. module_param(mp_mode, int, 0644);
  101. module_param(wmm_enable, int, 0644);
  102. module_param(vrtl_carrier_sense, int, 0644);
  103. module_param(vcs_type, int, 0644);
  104. module_param(busy_thresh, int, 0644);
  105. module_param(ht_enable, int, 0644);
  106. module_param(cbw40_enable, int, 0644);
  107. module_param(ampdu_enable, int, 0644);
  108. module_param(rf_config, int, 0644);
  109. module_param(power_mgnt, int, 0644);
  110. module_param(low_power, int, 0644);
  111. MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
  112. MODULE_PARM_DESC(initmac, "MAC-Address, default: use FUSE");
  113. static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev);
  114. static int netdev_open(struct net_device *pnetdev);
  115. static int netdev_close(struct net_device *pnetdev);
  116. static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev)
  117. {
  118. uint status = _SUCCESS;
  119. struct registry_priv *registry_par = &padapter->registrypriv;
  120. registry_par->chip_version = (u8)chip_version;
  121. registry_par->rfintfs = (u8)rfintfs;
  122. registry_par->lbkmode = (u8)lbkmode;
  123. registry_par->hci = (u8)hci;
  124. registry_par->network_mode = (u8)network_mode;
  125. memcpy(registry_par->ssid.Ssid, "ANY", 3);
  126. registry_par->ssid.SsidLength = 3;
  127. registry_par->channel = (u8)channel;
  128. registry_par->wireless_mode = (u8)wireless_mode;
  129. registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense ;
  130. registry_par->vcs_type = (u8)vcs_type;
  131. registry_par->frag_thresh = (u16)frag_thresh;
  132. registry_par->preamble = (u8)preamble;
  133. registry_par->scan_mode = (u8)scan_mode;
  134. registry_par->adhoc_tx_pwr = (u8)adhoc_tx_pwr;
  135. registry_par->soft_ap = (u8)soft_ap;
  136. registry_par->smart_ps = (u8)smart_ps;
  137. registry_par->power_mgnt = (u8)power_mgnt;
  138. registry_par->radio_enable = (u8)radio_enable;
  139. registry_par->long_retry_lmt = (u8)long_retry_lmt;
  140. registry_par->short_retry_lmt = (u8)short_retry_lmt;
  141. registry_par->busy_thresh = (u16)busy_thresh;
  142. registry_par->ack_policy = (u8)ack_policy;
  143. registry_par->mp_mode = (u8)mp_mode;
  144. registry_par->software_encrypt = (u8)software_encrypt;
  145. registry_par->software_decrypt = (u8)software_decrypt;
  146. /*UAPSD*/
  147. registry_par->wmm_enable = (u8)wmm_enable;
  148. registry_par->uapsd_enable = (u8)uapsd_enable;
  149. registry_par->uapsd_max_sp = (u8)uapsd_max_sp;
  150. registry_par->uapsd_acbk_en = (u8)uapsd_acbk_en;
  151. registry_par->uapsd_acbe_en = (u8)uapsd_acbe_en;
  152. registry_par->uapsd_acvi_en = (u8)uapsd_acvi_en;
  153. registry_par->uapsd_acvo_en = (u8)uapsd_acvo_en;
  154. registry_par->ht_enable = (u8)ht_enable;
  155. registry_par->cbw40_enable = (u8)cbw40_enable;
  156. registry_par->ampdu_enable = (u8)ampdu_enable;
  157. registry_par->rf_config = (u8)rf_config;
  158. registry_par->low_power = (u8)low_power;
  159. registry_par->wifi_test = (u8) wifi_test;
  160. r8712_initmac = initmac;
  161. return status;
  162. }
  163. static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p)
  164. {
  165. struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev);
  166. struct sockaddr *addr = p;
  167. if (padapter->bup == false)
  168. memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN);
  169. return 0;
  170. }
  171. static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev)
  172. {
  173. struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev);
  174. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  175. struct recv_priv *precvpriv = &(padapter->recvpriv);
  176. padapter->stats.tx_packets = pxmitpriv->tx_pkts;
  177. padapter->stats.rx_packets = precvpriv->rx_pkts;
  178. padapter->stats.tx_dropped = pxmitpriv->tx_drop;
  179. padapter->stats.rx_dropped = precvpriv->rx_drop;
  180. padapter->stats.tx_bytes = pxmitpriv->tx_bytes;
  181. padapter->stats.rx_bytes = precvpriv->rx_bytes;
  182. return &padapter->stats;
  183. }
  184. static const struct net_device_ops rtl8712_netdev_ops = {
  185. .ndo_open = netdev_open,
  186. .ndo_stop = netdev_close,
  187. .ndo_start_xmit = r8712_xmit_entry,
  188. .ndo_set_mac_address = r871x_net_set_mac_address,
  189. .ndo_get_stats = r871x_net_get_stats,
  190. .ndo_do_ioctl = r871x_ioctl,
  191. };
  192. struct net_device *r8712_init_netdev(void)
  193. {
  194. struct _adapter *padapter;
  195. struct net_device *pnetdev;
  196. pnetdev = alloc_etherdev(sizeof(struct _adapter));
  197. if (!pnetdev)
  198. return NULL;
  199. if (dev_alloc_name(pnetdev, ifname) < 0) {
  200. strcpy(ifname, "wlan%d");
  201. dev_alloc_name(pnetdev, ifname);
  202. }
  203. padapter = (struct _adapter *) _netdev_priv(pnetdev);
  204. padapter->pnetdev = pnetdev;
  205. printk(KERN_INFO "r8712u: register rtl8712_netdev_ops to"
  206. " netdev_ops\n");
  207. pnetdev->netdev_ops = &rtl8712_netdev_ops;
  208. pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
  209. pnetdev->wireless_handlers = (struct iw_handler_def *)
  210. &r871x_handlers_def;
  211. /*step 2.*/
  212. loadparam(padapter, pnetdev);
  213. netif_carrier_off(pnetdev);
  214. padapter->pid = 0; /* Initial the PID value used for HW PBC.*/
  215. return pnetdev;
  216. }
  217. static u32 start_drv_threads(struct _adapter *padapter)
  218. {
  219. padapter->cmdThread = kthread_run(r8712_cmd_thread, padapter,
  220. padapter->pnetdev->name);
  221. if (IS_ERR(padapter->cmdThread) < 0)
  222. return _FAIL;
  223. return _SUCCESS;
  224. }
  225. void r8712_stop_drv_threads(struct _adapter *padapter)
  226. {
  227. /*Below is to termindate r8712_cmd_thread & event_thread...*/
  228. up(&padapter->cmdpriv.cmd_queue_sema);
  229. if (padapter->cmdThread)
  230. _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
  231. padapter->cmdpriv.cmd_seq = 1;
  232. }
  233. static void start_drv_timers(struct _adapter *padapter)
  234. {
  235. _set_timer(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer,
  236. 5000);
  237. _set_timer(&padapter->mlmepriv.wdg_timer, 2000);
  238. }
  239. static void stop_drv_timers(struct _adapter *padapter)
  240. {
  241. _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
  242. _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
  243. sitesurvey_ctrl_timer);
  244. _cancel_timer_ex(&padapter->securitypriv.tkip_timer);
  245. _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
  246. _cancel_timer_ex(&padapter->mlmepriv.dhcp_timer);
  247. _cancel_timer_ex(&padapter->mlmepriv.wdg_timer);
  248. }
  249. static u8 init_default_value(struct _adapter *padapter)
  250. {
  251. u8 ret = _SUCCESS;
  252. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  253. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  254. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  255. struct security_priv *psecuritypriv = &padapter->securitypriv;
  256. /*xmit_priv*/
  257. pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
  258. pxmitpriv->vcs = pregistrypriv->vcs_type;
  259. pxmitpriv->vcs_type = pregistrypriv->vcs_type;
  260. pxmitpriv->rts_thresh = pregistrypriv->rts_thresh;
  261. pxmitpriv->frag_len = pregistrypriv->frag_thresh;
  262. /*ht_priv*/
  263. {
  264. int i;
  265. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  266. phtpriv->ampdu_enable = false;/*set to disabled*/
  267. for (i = 0; i < 16; i++)
  268. phtpriv->baddbareq_issued[i] = false;
  269. }
  270. /*security_priv*/
  271. psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt;
  272. psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt;
  273. psecuritypriv->binstallGrpkey = _FAIL;
  274. /*pwrctrl_priv*/
  275. /*registry_priv*/
  276. r8712_init_registrypriv_dev_network(padapter);
  277. r8712_update_registrypriv_dev_network(padapter);
  278. /*misc.*/
  279. return ret;
  280. }
  281. u8 r8712_init_drv_sw(struct _adapter *padapter)
  282. {
  283. if ((r8712_init_cmd_priv(&padapter->cmdpriv)) == _FAIL)
  284. return _FAIL;
  285. padapter->cmdpriv.padapter = padapter;
  286. if ((r8712_init_evt_priv(&padapter->evtpriv)) == _FAIL)
  287. return _FAIL;
  288. if (r8712_init_mlme_priv(padapter) == _FAIL)
  289. return _FAIL;
  290. _r8712_init_xmit_priv(&padapter->xmitpriv, padapter);
  291. _r8712_init_recv_priv(&padapter->recvpriv, padapter);
  292. memset((unsigned char *)&padapter->securitypriv, 0,
  293. sizeof(struct security_priv));
  294. _init_timer(&(padapter->securitypriv.tkip_timer), padapter->pnetdev,
  295. r8712_use_tkipkey_handler, padapter);
  296. _r8712_init_sta_priv(&padapter->stapriv);
  297. padapter->stapriv.padapter = padapter;
  298. r8712_init_bcmc_stainfo(padapter);
  299. r8712_init_pwrctrl_priv(padapter);
  300. sema_init(&(padapter->pwrctrlpriv.pnp_pwr_mgnt_sema), 0);
  301. mp871xinit(padapter);
  302. if (init_default_value(padapter) != _SUCCESS)
  303. return _FAIL;
  304. r8712_InitSwLeds(padapter);
  305. return _SUCCESS;
  306. }
  307. u8 r8712_free_drv_sw(struct _adapter *padapter)
  308. {
  309. struct net_device *pnetdev = (struct net_device *)padapter->pnetdev;
  310. r8712_free_cmd_priv(&padapter->cmdpriv);
  311. r8712_free_evt_priv(&padapter->evtpriv);
  312. r8712_DeInitSwLeds(padapter);
  313. r8712_free_mlme_priv(&padapter->mlmepriv);
  314. r8712_free_io_queue(padapter);
  315. _free_xmit_priv(&padapter->xmitpriv);
  316. _r8712_free_sta_priv(&padapter->stapriv);
  317. _r8712_free_recv_priv(&padapter->recvpriv);
  318. mp871xdeinit(padapter);
  319. if (pnetdev)
  320. os_free_netdev(pnetdev);
  321. return _SUCCESS;
  322. }
  323. static void enable_video_mode(struct _adapter *padapter, int cbw40_value)
  324. {
  325. /* bit 8:
  326. * 1 -> enable video mode to 96B AP
  327. * 0 -> disable video mode to 96B AP
  328. * bit 9:
  329. * 1 -> enable 40MHz mode
  330. * 0 -> disable 40MHz mode
  331. * bit 10:
  332. * 1 -> enable STBC
  333. * 0 -> disable STBC
  334. */
  335. u32 intcmd = 0xf4000500; /* enable bit8, bit10*/
  336. if (cbw40_value) {
  337. /* if the driver supports the 40M bandwidth,
  338. * we can enable the bit 9.*/
  339. intcmd |= 0x200;
  340. }
  341. r8712_fw_cmd(padapter, intcmd);
  342. }
  343. static int netdev_open(struct net_device *pnetdev)
  344. {
  345. struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev);
  346. if (padapter->bup == false) {
  347. padapter->bDriverStopped = false;
  348. padapter->bSurpriseRemoved = false;
  349. padapter->bup = true;
  350. if (rtl871x_hal_init(padapter) != _SUCCESS)
  351. goto netdev_open_error;
  352. if (r8712_initmac == NULL)
  353. /* Use the mac address stored in the Efuse */
  354. memcpy(pnetdev->dev_addr,
  355. padapter->eeprompriv.mac_addr, ETH_ALEN);
  356. else {
  357. /* We have to inform f/w to use user-supplied MAC
  358. * address.
  359. */
  360. msleep(200);
  361. r8712_setMacAddr_cmd(padapter, (u8 *)pnetdev->dev_addr);
  362. /*
  363. * The "myid" function will get the wifi mac address
  364. * from eeprompriv structure instead of netdev
  365. * structure. So, we have to overwrite the mac_addr
  366. * stored in the eeprompriv structure. In this case,
  367. * the real mac address won't be used anymore. So that,
  368. * the eeprompriv.mac_addr should store the mac which
  369. * users specify.
  370. */
  371. memcpy(padapter->eeprompriv.mac_addr,
  372. pnetdev->dev_addr, ETH_ALEN);
  373. }
  374. if (start_drv_threads(padapter) != _SUCCESS)
  375. goto netdev_open_error;
  376. if (padapter->dvobjpriv.inirp_init == NULL)
  377. goto netdev_open_error;
  378. else
  379. padapter->dvobjpriv.inirp_init(padapter);
  380. r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
  381. padapter->registrypriv.smart_ps);
  382. }
  383. if (!netif_queue_stopped(pnetdev))
  384. netif_start_queue(pnetdev);
  385. else
  386. netif_wake_queue(pnetdev);
  387. if (video_mode)
  388. enable_video_mode(padapter, cbw40_enable);
  389. /* start driver mlme relation timer */
  390. start_drv_timers(padapter);
  391. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
  392. return 0;
  393. netdev_open_error:
  394. padapter->bup = false;
  395. netif_carrier_off(pnetdev);
  396. netif_stop_queue(pnetdev);
  397. return -1;
  398. }
  399. static int netdev_close(struct net_device *pnetdev)
  400. {
  401. struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev);
  402. /* Close LED*/
  403. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF);
  404. msleep(200);
  405. /*s1.*/
  406. if (pnetdev) {
  407. if (!netif_queue_stopped(pnetdev))
  408. netif_stop_queue(pnetdev);
  409. }
  410. /*s2.*/
  411. /*s2-1. issue disassoc_cmd to fw*/
  412. r8712_disassoc_cmd(padapter);
  413. /*s2-2. indicate disconnect to os*/
  414. r8712_ind_disconnect(padapter);
  415. /*s2-3.*/
  416. r8712_free_assoc_resources(padapter);
  417. /*s2-4.*/
  418. r8712_free_network_queue(padapter);
  419. /*Stop driver mlme relation timer*/
  420. stop_drv_timers(padapter);
  421. return 0;
  422. }
  423. #include "mlme_osdep.h"