os_intfs.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  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/kthread.h>
  31. #include <linux/firmware.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 video 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;
  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 int netdev_open(struct net_device *pnetdev);
  114. static int netdev_close(struct net_device *pnetdev);
  115. static void loadparam(struct _adapter *padapter, struct net_device *pnetdev)
  116. {
  117. struct registry_priv *registry_par = &padapter->registrypriv;
  118. registry_par->chip_version = (u8)chip_version;
  119. registry_par->rfintfs = (u8)rfintfs;
  120. registry_par->lbkmode = (u8)lbkmode;
  121. registry_par->hci = (u8)hci;
  122. registry_par->network_mode = (u8)network_mode;
  123. memcpy(registry_par->ssid.Ssid, "ANY", 3);
  124. registry_par->ssid.SsidLength = 3;
  125. registry_par->channel = (u8)channel;
  126. registry_par->wireless_mode = (u8)wireless_mode;
  127. registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense;
  128. registry_par->vcs_type = (u8)vcs_type;
  129. registry_par->frag_thresh = (u16)frag_thresh;
  130. registry_par->preamble = (u8)preamble;
  131. registry_par->scan_mode = (u8)scan_mode;
  132. registry_par->adhoc_tx_pwr = (u8)adhoc_tx_pwr;
  133. registry_par->soft_ap = (u8)soft_ap;
  134. registry_par->smart_ps = (u8)smart_ps;
  135. registry_par->power_mgnt = (u8)power_mgnt;
  136. registry_par->radio_enable = (u8)radio_enable;
  137. registry_par->long_retry_lmt = (u8)long_retry_lmt;
  138. registry_par->short_retry_lmt = (u8)short_retry_lmt;
  139. registry_par->busy_thresh = (u16)busy_thresh;
  140. registry_par->ack_policy = (u8)ack_policy;
  141. registry_par->mp_mode = (u8)mp_mode;
  142. registry_par->software_encrypt = (u8)software_encrypt;
  143. registry_par->software_decrypt = (u8)software_decrypt;
  144. /*UAPSD*/
  145. registry_par->wmm_enable = (u8)wmm_enable;
  146. registry_par->uapsd_enable = (u8)uapsd_enable;
  147. registry_par->uapsd_max_sp = (u8)uapsd_max_sp;
  148. registry_par->uapsd_acbk_en = (u8)uapsd_acbk_en;
  149. registry_par->uapsd_acbe_en = (u8)uapsd_acbe_en;
  150. registry_par->uapsd_acvi_en = (u8)uapsd_acvi_en;
  151. registry_par->uapsd_acvo_en = (u8)uapsd_acvo_en;
  152. registry_par->ht_enable = (u8)ht_enable;
  153. registry_par->cbw40_enable = (u8)cbw40_enable;
  154. registry_par->ampdu_enable = (u8)ampdu_enable;
  155. registry_par->rf_config = (u8)rf_config;
  156. registry_par->low_power = (u8)low_power;
  157. registry_par->wifi_test = (u8) wifi_test;
  158. r8712_initmac = initmac;
  159. }
  160. static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p)
  161. {
  162. struct _adapter *padapter = netdev_priv(pnetdev);
  163. struct sockaddr *addr = p;
  164. if (!padapter->bup)
  165. ether_addr_copy(pnetdev->dev_addr, addr->sa_data);
  166. return 0;
  167. }
  168. static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev)
  169. {
  170. struct _adapter *padapter = netdev_priv(pnetdev);
  171. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  172. struct recv_priv *precvpriv = &(padapter->recvpriv);
  173. padapter->stats.tx_packets = pxmitpriv->tx_pkts;
  174. padapter->stats.rx_packets = precvpriv->rx_pkts;
  175. padapter->stats.tx_dropped = pxmitpriv->tx_drop;
  176. padapter->stats.rx_dropped = precvpriv->rx_drop;
  177. padapter->stats.tx_bytes = pxmitpriv->tx_bytes;
  178. padapter->stats.rx_bytes = precvpriv->rx_bytes;
  179. return &padapter->stats;
  180. }
  181. static const struct net_device_ops rtl8712_netdev_ops = {
  182. .ndo_open = netdev_open,
  183. .ndo_stop = netdev_close,
  184. .ndo_start_xmit = r8712_xmit_entry,
  185. .ndo_set_mac_address = r871x_net_set_mac_address,
  186. .ndo_get_stats = r871x_net_get_stats,
  187. .ndo_do_ioctl = r871x_ioctl,
  188. };
  189. struct net_device *r8712_init_netdev(void)
  190. {
  191. struct _adapter *padapter;
  192. struct net_device *pnetdev;
  193. pnetdev = alloc_etherdev(sizeof(struct _adapter));
  194. if (!pnetdev)
  195. return NULL;
  196. if (dev_alloc_name(pnetdev, ifname) < 0) {
  197. strcpy(ifname, "wlan%d");
  198. dev_alloc_name(pnetdev, ifname);
  199. }
  200. padapter = netdev_priv(pnetdev);
  201. padapter->pnetdev = pnetdev;
  202. pr_info("r8712u: register rtl8712_netdev_ops to netdev_ops\n");
  203. pnetdev->netdev_ops = &rtl8712_netdev_ops;
  204. pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
  205. pnetdev->wireless_handlers = (struct iw_handler_def *)
  206. &r871x_handlers_def;
  207. loadparam(padapter, pnetdev);
  208. netif_carrier_off(pnetdev);
  209. padapter->pid = 0; /* Initial the PID value used for HW PBC.*/
  210. return pnetdev;
  211. }
  212. static u32 start_drv_threads(struct _adapter *padapter)
  213. {
  214. padapter->cmdThread = kthread_run(r8712_cmd_thread, padapter, "%s",
  215. padapter->pnetdev->name);
  216. if (IS_ERR(padapter->cmdThread))
  217. return _FAIL;
  218. return _SUCCESS;
  219. }
  220. void r8712_stop_drv_threads(struct _adapter *padapter)
  221. {
  222. /*Below is to terminate r8712_cmd_thread & event_thread...*/
  223. up(&padapter->cmdpriv.cmd_queue_sema);
  224. if (padapter->cmdThread)
  225. _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
  226. padapter->cmdpriv.cmd_seq = 1;
  227. }
  228. static void start_drv_timers(struct _adapter *padapter)
  229. {
  230. mod_timer(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer,
  231. jiffies + msecs_to_jiffies(5000));
  232. mod_timer(&padapter->mlmepriv.wdg_timer,
  233. jiffies + msecs_to_jiffies(2000));
  234. }
  235. void r8712_stop_drv_timers(struct _adapter *padapter)
  236. {
  237. del_timer_sync(&padapter->mlmepriv.assoc_timer);
  238. del_timer_sync(&padapter->securitypriv.tkip_timer);
  239. del_timer_sync(&padapter->mlmepriv.scan_to_timer);
  240. del_timer_sync(&padapter->mlmepriv.dhcp_timer);
  241. del_timer_sync(&padapter->mlmepriv.wdg_timer);
  242. del_timer_sync(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer);
  243. }
  244. static u8 init_default_value(struct _adapter *padapter)
  245. {
  246. u8 ret = _SUCCESS;
  247. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  248. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  249. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  250. struct security_priv *psecuritypriv = &padapter->securitypriv;
  251. /*xmit_priv*/
  252. pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
  253. pxmitpriv->vcs = pregistrypriv->vcs_type;
  254. pxmitpriv->vcs_type = pregistrypriv->vcs_type;
  255. pxmitpriv->rts_thresh = pregistrypriv->rts_thresh;
  256. pxmitpriv->frag_len = pregistrypriv->frag_thresh;
  257. /* mlme_priv */
  258. /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/
  259. pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */
  260. /*ht_priv*/
  261. {
  262. int i;
  263. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  264. phtpriv->ampdu_enable = false;/*set to disabled*/
  265. for (i = 0; i < 16; i++)
  266. phtpriv->baddbareq_issued[i] = false;
  267. }
  268. /*security_priv*/
  269. psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt;
  270. psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt;
  271. psecuritypriv->binstallGrpkey = _FAIL;
  272. /*pwrctrl_priv*/
  273. /*registry_priv*/
  274. r8712_init_registrypriv_dev_network(padapter);
  275. r8712_update_registrypriv_dev_network(padapter);
  276. /*misc.*/
  277. return ret;
  278. }
  279. u8 r8712_init_drv_sw(struct _adapter *padapter)
  280. {
  281. if ((r8712_init_cmd_priv(&padapter->cmdpriv)) == _FAIL)
  282. return _FAIL;
  283. padapter->cmdpriv.padapter = padapter;
  284. if ((r8712_init_evt_priv(&padapter->evtpriv)) == _FAIL)
  285. return _FAIL;
  286. if (r8712_init_mlme_priv(padapter) == _FAIL)
  287. return _FAIL;
  288. _r8712_init_xmit_priv(&padapter->xmitpriv, padapter);
  289. _r8712_init_recv_priv(&padapter->recvpriv, padapter);
  290. memset((unsigned char *)&padapter->securitypriv, 0,
  291. sizeof(struct security_priv));
  292. setup_timer(&padapter->securitypriv.tkip_timer,
  293. r8712_use_tkipkey_handler, (unsigned long)padapter);
  294. _r8712_init_sta_priv(&padapter->stapriv);
  295. padapter->stapriv.padapter = padapter;
  296. r8712_init_bcmc_stainfo(padapter);
  297. r8712_init_pwrctrl_priv(padapter);
  298. mp871xinit(padapter);
  299. if (init_default_value(padapter) != _SUCCESS)
  300. return _FAIL;
  301. r8712_InitSwLeds(padapter);
  302. return _SUCCESS;
  303. }
  304. u8 r8712_free_drv_sw(struct _adapter *padapter)
  305. {
  306. struct net_device *pnetdev = padapter->pnetdev;
  307. r8712_free_cmd_priv(&padapter->cmdpriv);
  308. r8712_free_evt_priv(&padapter->evtpriv);
  309. r8712_DeInitSwLeds(padapter);
  310. r8712_free_mlme_priv(&padapter->mlmepriv);
  311. r8712_free_io_queue(padapter);
  312. _free_xmit_priv(&padapter->xmitpriv);
  313. _r8712_free_sta_priv(&padapter->stapriv);
  314. _r8712_free_recv_priv(&padapter->recvpriv);
  315. mp871xdeinit(padapter);
  316. if (pnetdev)
  317. free_netdev(pnetdev);
  318. return _SUCCESS;
  319. }
  320. static void enable_video_mode(struct _adapter *padapter, int cbw40_value)
  321. {
  322. /* bit 8:
  323. * 1 -> enable video mode to 96B AP
  324. * 0 -> disable video mode to 96B AP
  325. * bit 9:
  326. * 1 -> enable 40MHz mode
  327. * 0 -> disable 40MHz mode
  328. * bit 10:
  329. * 1 -> enable STBC
  330. * 0 -> disable STBC
  331. */
  332. u32 intcmd = 0xf4000500; /* enable bit8, bit10*/
  333. if (cbw40_value) {
  334. /* if the driver supports the 40M bandwidth,
  335. * we can enable the bit 9.
  336. */
  337. intcmd |= 0x200;
  338. }
  339. r8712_fw_cmd(padapter, intcmd);
  340. }
  341. /**
  342. *
  343. * This function intends to handle the activation of an interface
  344. * i.e. when it is brought Up/Active from a Down state.
  345. *
  346. */
  347. static int netdev_open(struct net_device *pnetdev)
  348. {
  349. struct _adapter *padapter = netdev_priv(pnetdev);
  350. mutex_lock(&padapter->mutex_start);
  351. if (!padapter->bup) {
  352. padapter->bDriverStopped = false;
  353. padapter->bSurpriseRemoved = false;
  354. padapter->bup = true;
  355. if (rtl871x_hal_init(padapter) != _SUCCESS)
  356. goto netdev_open_error;
  357. if (r8712_initmac == NULL)
  358. /* Use the mac address stored in the Efuse */
  359. memcpy(pnetdev->dev_addr,
  360. padapter->eeprompriv.mac_addr, ETH_ALEN);
  361. else {
  362. /* We have to inform f/w to use user-supplied MAC
  363. * address.
  364. */
  365. msleep(200);
  366. r8712_setMacAddr_cmd(padapter, (u8 *)pnetdev->dev_addr);
  367. /*
  368. * The "myid" function will get the wifi mac address
  369. * from eeprompriv structure instead of netdev
  370. * structure. So, we have to overwrite the mac_addr
  371. * stored in the eeprompriv structure. In this case,
  372. * the real mac address won't be used anymore. So that,
  373. * the eeprompriv.mac_addr should store the mac which
  374. * users specify.
  375. */
  376. memcpy(padapter->eeprompriv.mac_addr,
  377. pnetdev->dev_addr, ETH_ALEN);
  378. }
  379. if (start_drv_threads(padapter) != _SUCCESS)
  380. goto netdev_open_error;
  381. if (padapter->dvobjpriv.inirp_init == NULL)
  382. goto netdev_open_error;
  383. else
  384. padapter->dvobjpriv.inirp_init(padapter);
  385. r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
  386. padapter->registrypriv.smart_ps);
  387. }
  388. if (!netif_queue_stopped(pnetdev))
  389. netif_start_queue(pnetdev);
  390. else
  391. netif_wake_queue(pnetdev);
  392. if (video_mode)
  393. enable_video_mode(padapter, cbw40_enable);
  394. /* start driver mlme relation timer */
  395. start_drv_timers(padapter);
  396. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
  397. mutex_unlock(&padapter->mutex_start);
  398. return 0;
  399. netdev_open_error:
  400. padapter->bup = false;
  401. netif_carrier_off(pnetdev);
  402. netif_stop_queue(pnetdev);
  403. mutex_unlock(&padapter->mutex_start);
  404. return -1;
  405. }
  406. /**
  407. *
  408. * This function intends to handle the shutdown of an interface
  409. * i.e. when it is brought Down from an Up/Active state.
  410. *
  411. */
  412. static int netdev_close(struct net_device *pnetdev)
  413. {
  414. struct _adapter *padapter = netdev_priv(pnetdev);
  415. /* Close LED*/
  416. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF);
  417. msleep(200);
  418. /*s1.*/
  419. if (pnetdev) {
  420. if (!netif_queue_stopped(pnetdev))
  421. netif_stop_queue(pnetdev);
  422. }
  423. /*s2.*/
  424. /*s2-1. issue disassoc_cmd to fw*/
  425. r8712_disassoc_cmd(padapter);
  426. /*s2-2. indicate disconnect to os*/
  427. r8712_ind_disconnect(padapter);
  428. /*s2-3.*/
  429. r8712_free_assoc_resources(padapter);
  430. /*s2-4.*/
  431. r8712_free_network_queue(padapter);
  432. return 0;
  433. }
  434. #include "mlme_osdep.h"