mlme_linux.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. #define _MLME_OSDEP_C_
  21. #include <drv_types.h>
  22. #ifdef RTK_DMP_PLATFORM
  23. void Linkup_workitem_callback(struct work_struct *work)
  24. {
  25. struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem);
  26. _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
  27. _func_enter_;
  28. RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkup_workitem_callback\n"));
  29. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
  30. kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP);
  31. #else
  32. kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP);
  33. #endif
  34. _func_exit_;
  35. }
  36. void Linkdown_workitem_callback(struct work_struct *work)
  37. {
  38. struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem);
  39. _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
  40. _func_enter_;
  41. RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkdown_workitem_callback\n"));
  42. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
  43. kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN);
  44. #else
  45. kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN);
  46. #endif
  47. _func_exit_;
  48. }
  49. #endif
  50. /*
  51. void sitesurvey_ctrl_handler(void *FunctionContext)
  52. {
  53. _adapter *adapter = (_adapter *)FunctionContext;
  54. _sitesurvey_ctrl_handler(adapter);
  55. _set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000);
  56. }
  57. */
  58. void rtw_join_timeout_handler (void *FunctionContext)
  59. {
  60. _adapter *adapter = (_adapter *)FunctionContext;
  61. _rtw_join_timeout_handler(adapter);
  62. }
  63. void _rtw_scan_timeout_handler (void *FunctionContext)
  64. {
  65. _adapter *adapter = (_adapter *)FunctionContext;
  66. rtw_scan_timeout_handler(adapter);
  67. }
  68. void _dynamic_check_timer_handlder (void *FunctionContext)
  69. {
  70. _adapter *adapter = (_adapter *)FunctionContext;
  71. #if (MP_DRIVER == 1)
  72. if (adapter->registrypriv.mp_mode == 1)
  73. return;
  74. #endif
  75. rtw_dynamic_check_timer_handlder(adapter);
  76. _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
  77. }
  78. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  79. void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
  80. {
  81. _adapter *adapter = (_adapter *)FunctionContext;
  82. rtw_set_scan_deny_timer_hdl(adapter);
  83. }
  84. #endif
  85. void rtw_init_mlme_timer(_adapter *padapter)
  86. {
  87. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  88. _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter);
  89. //_init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter);
  90. _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
  91. _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter);
  92. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  93. _init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter);
  94. #endif
  95. #ifdef RTK_DMP_PLATFORM
  96. _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
  97. _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
  98. #endif
  99. }
  100. extern void rtw_indicate_wx_assoc_event(_adapter *padapter);
  101. extern void rtw_indicate_wx_disassoc_event(_adapter *padapter);
  102. void rtw_os_indicate_connect(_adapter *adapter)
  103. {
  104. _func_enter_;
  105. #ifdef CONFIG_IOCTL_CFG80211
  106. rtw_cfg80211_indicate_connect(adapter);
  107. #endif //CONFIG_IOCTL_CFG80211
  108. rtw_indicate_wx_assoc_event(adapter);
  109. netif_carrier_on(adapter->pnetdev);
  110. if(adapter->pid[2] !=0)
  111. rtw_signal_process(adapter->pid[2], SIGALRM);
  112. #ifdef RTK_DMP_PLATFORM
  113. _set_workitem(&adapter->mlmepriv.Linkup_workitem);
  114. #endif
  115. _func_exit_;
  116. }
  117. extern void indicate_wx_scan_complete_event(_adapter *padapter);
  118. void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted)
  119. {
  120. #ifdef CONFIG_IOCTL_CFG80211
  121. rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), aborted);
  122. #endif
  123. indicate_wx_scan_complete_event(padapter);
  124. }
  125. static RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ];
  126. void rtw_reset_securitypriv( _adapter *adapter )
  127. {
  128. u8 backupPMKIDIndex = 0;
  129. u8 backupTKIPCountermeasure = 0x00;
  130. u32 backupTKIPcountermeasure_time = 0;
  131. if(adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)//802.1x
  132. {
  133. // Added by Albert 2009/02/18
  134. // We have to backup the PMK information for WiFi PMK Caching test item.
  135. //
  136. // Backup the btkip_countermeasure information.
  137. // When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds.
  138. _rtw_memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
  139. _rtw_memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
  140. backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
  141. backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
  142. backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;
  143. _rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv));
  144. //_init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter);
  145. // Added by Albert 2009/02/18
  146. // Restore the PMK information to securitypriv structure for the following connection.
  147. _rtw_memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
  148. adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
  149. adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
  150. adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;
  151. adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
  152. adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
  153. }
  154. else //reset values in securitypriv
  155. {
  156. //if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE)
  157. //{
  158. struct security_priv *psec_priv=&adapter->securitypriv;
  159. psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open; //open system
  160. psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
  161. psec_priv->dot11PrivacyKeyIndex = 0;
  162. psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
  163. psec_priv->dot118021XGrpKeyid = 1;
  164. psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
  165. psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
  166. //}
  167. }
  168. }
  169. void rtw_os_indicate_disconnect( _adapter *adapter )
  170. {
  171. //RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ];
  172. _func_enter_;
  173. netif_carrier_off(adapter->pnetdev); // Do it first for tx broadcast pkt after disconnection issue!
  174. #ifdef CONFIG_IOCTL_CFG80211
  175. rtw_cfg80211_indicate_disconnect(adapter);
  176. #endif //CONFIG_IOCTL_CFG80211
  177. rtw_indicate_wx_disassoc_event(adapter);
  178. #ifdef RTK_DMP_PLATFORM
  179. _set_workitem(&adapter->mlmepriv.Linkdown_workitem);
  180. #endif
  181. rtw_reset_securitypriv( adapter );
  182. _func_exit_;
  183. }
  184. void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie)
  185. {
  186. uint len;
  187. u8 *buff,*p,i;
  188. union iwreq_data wrqu;
  189. _func_enter_;
  190. RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode));
  191. buff = NULL;
  192. if(authmode==_WPA_IE_ID_)
  193. {
  194. RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode));
  195. buff = rtw_malloc(IW_CUSTOM_MAX);
  196. _rtw_memset(buff,0,IW_CUSTOM_MAX);
  197. p=buff;
  198. p+=sprintf(p,"ASSOCINFO(ReqIEs=");
  199. len = sec_ie[1]+2;
  200. len = (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX;
  201. for(i=0;i<len;i++){
  202. p+=sprintf(p,"%02x",sec_ie[i]);
  203. }
  204. p+=sprintf(p,")");
  205. _rtw_memset(&wrqu,0,sizeof(wrqu));
  206. wrqu.data.length=p-buff;
  207. wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
  208. #ifndef CONFIG_IOCTL_CFG80211
  209. wireless_send_event(adapter->pnetdev,IWEVCUSTOM,&wrqu,buff);
  210. #endif
  211. if(buff)
  212. rtw_mfree(buff, IW_CUSTOM_MAX);
  213. }
  214. _func_exit_;
  215. }
  216. void _survey_timer_hdl (void *FunctionContext)
  217. {
  218. _adapter *padapter = (_adapter *)FunctionContext;
  219. survey_timer_hdl(padapter);
  220. }
  221. void _link_timer_hdl (void *FunctionContext)
  222. {
  223. _adapter *padapter = (_adapter *)FunctionContext;
  224. link_timer_hdl(padapter);
  225. }
  226. void _addba_timer_hdl(void *FunctionContext)
  227. {
  228. struct sta_info *psta = (struct sta_info *)FunctionContext;
  229. addba_timer_hdl(psta);
  230. }
  231. void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta)
  232. {
  233. _init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
  234. }
  235. /*
  236. void _reauth_timer_hdl(void *FunctionContext)
  237. {
  238. _adapter *padapter = (_adapter *)FunctionContext;
  239. reauth_timer_hdl(padapter);
  240. }
  241. void _reassoc_timer_hdl(void *FunctionContext)
  242. {
  243. _adapter *padapter = (_adapter *)FunctionContext;
  244. reassoc_timer_hdl(padapter);
  245. }
  246. */
  247. void init_mlme_ext_timer(_adapter *padapter)
  248. {
  249. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  250. _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
  251. _init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
  252. //_init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter);
  253. //_init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter);
  254. //_init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter);
  255. }
  256. u8 rtw_handle_tkip_countermeasure(_adapter* padapter)
  257. {
  258. u8 status = _SUCCESS;
  259. u32 cur_time = 0;
  260. if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
  261. cur_time = rtw_get_current_time();
  262. if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
  263. {
  264. padapter->securitypriv.btkip_countermeasure = _FALSE;
  265. padapter->securitypriv.btkip_countermeasure_time = 0;
  266. }
  267. else
  268. {
  269. status = _FAIL;
  270. }
  271. }
  272. return status;
  273. }
  274. #ifdef CONFIG_AP_MODE
  275. void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta)
  276. {
  277. union iwreq_data wrqu;
  278. struct sta_priv *pstapriv = &padapter->stapriv;
  279. if(psta==NULL)
  280. return;
  281. if(psta->aid > NUM_STA)
  282. return;
  283. if(pstapriv->sta_aid[psta->aid - 1] != psta)
  284. return;
  285. wrqu.addr.sa_family = ARPHRD_ETHER;
  286. _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
  287. DBG_871X("+rtw_indicate_sta_assoc_event\n");
  288. #ifndef CONFIG_IOCTL_CFG80211
  289. wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL);
  290. #endif
  291. }
  292. void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta)
  293. {
  294. union iwreq_data wrqu;
  295. struct sta_priv *pstapriv = &padapter->stapriv;
  296. if(psta==NULL)
  297. return;
  298. if(psta->aid > NUM_STA)
  299. return;
  300. if(pstapriv->sta_aid[psta->aid - 1] != psta)
  301. return;
  302. wrqu.addr.sa_family = ARPHRD_ETHER;
  303. _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
  304. DBG_871X("+rtw_indicate_sta_disassoc_event\n");
  305. #ifndef CONFIG_IOCTL_CFG80211
  306. wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL);
  307. #endif
  308. }
  309. #ifdef CONFIG_HOSTAPD_MLME
  310. static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev)
  311. {
  312. struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
  313. _adapter *padapter = (_adapter *)phostapdpriv->padapter;
  314. //DBG_871X("%s\n", __FUNCTION__);
  315. return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb);
  316. }
  317. static int mgnt_netdev_open(struct net_device *pnetdev)
  318. {
  319. struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
  320. DBG_871X("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr));
  321. init_usb_anchor(&phostapdpriv->anchored);
  322. if(!rtw_netif_queue_stopped(pnetdev))
  323. rtw_netif_start_queue(pnetdev);
  324. else
  325. rtw_netif_wake_queue(pnetdev);
  326. netif_carrier_on(pnetdev);
  327. //rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100);//only excluding beacon
  328. return 0;
  329. }
  330. static int mgnt_netdev_close(struct net_device *pnetdev)
  331. {
  332. struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
  333. DBG_871X("%s\n", __FUNCTION__);
  334. usb_kill_anchored_urbs(&phostapdpriv->anchored);
  335. netif_carrier_off(pnetdev);
  336. if (!rtw_netif_queue_stopped(pnetdev))
  337. rtw_netif_stop_queue(pnetdev);
  338. //rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f);
  339. return 0;
  340. }
  341. #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
  342. static const struct net_device_ops rtl871x_mgnt_netdev_ops = {
  343. .ndo_open = mgnt_netdev_open,
  344. .ndo_stop = mgnt_netdev_close,
  345. .ndo_start_xmit = mgnt_xmit_entry,
  346. //.ndo_set_mac_address = r871x_net_set_mac_address,
  347. //.ndo_get_stats = r871x_net_get_stats,
  348. //.ndo_do_ioctl = r871x_mp_ioctl,
  349. };
  350. #endif
  351. int hostapd_mode_init(_adapter *padapter)
  352. {
  353. unsigned char mac[ETH_ALEN];
  354. struct hostapd_priv *phostapdpriv;
  355. struct net_device *pnetdev;
  356. pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));
  357. if (!pnetdev)
  358. return -ENOMEM;
  359. //SET_MODULE_OWNER(pnetdev);
  360. ether_setup(pnetdev);
  361. //pnetdev->type = ARPHRD_IEEE80211;
  362. phostapdpriv = rtw_netdev_priv(pnetdev);
  363. phostapdpriv->pmgnt_netdev = pnetdev;
  364. phostapdpriv->padapter= padapter;
  365. padapter->phostapdpriv = phostapdpriv;
  366. //pnetdev->init = NULL;
  367. #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
  368. DBG_871X("register rtl871x_mgnt_netdev_ops to netdev_ops\n");
  369. pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
  370. #else
  371. pnetdev->open = mgnt_netdev_open;
  372. pnetdev->stop = mgnt_netdev_close;
  373. pnetdev->hard_start_xmit = mgnt_xmit_entry;
  374. //pnetdev->set_mac_address = r871x_net_set_mac_address;
  375. //pnetdev->get_stats = r871x_net_get_stats;
  376. //pnetdev->do_ioctl = r871x_mp_ioctl;
  377. #endif
  378. pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
  379. //pnetdev->wireless_handlers = NULL;
  380. #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
  381. pnetdev->features |= NETIF_F_IP_CSUM;
  382. #endif
  383. if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0)
  384. {
  385. DBG_871X("hostapd_mode_init(): dev_alloc_name, fail! \n");
  386. }
  387. //SET_NETDEV_DEV(pnetdev, pintfpriv->udev);
  388. mac[0]=0x00;
  389. mac[1]=0xe0;
  390. mac[2]=0x4c;
  391. mac[3]=0x87;
  392. mac[4]=0x11;
  393. mac[5]=0x12;
  394. _rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
  395. netif_carrier_off(pnetdev);
  396. /* Tell the network stack we exist */
  397. if (register_netdev(pnetdev) != 0)
  398. {
  399. DBG_871X("hostapd_mode_init(): register_netdev fail!\n");
  400. if(pnetdev)
  401. {
  402. rtw_free_netdev(pnetdev);
  403. }
  404. }
  405. return 0;
  406. }
  407. void hostapd_mode_unload(_adapter *padapter)
  408. {
  409. struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
  410. struct net_device *pnetdev = phostapdpriv->pmgnt_netdev;
  411. unregister_netdev(pnetdev);
  412. rtw_free_netdev(pnetdev);
  413. }
  414. #endif
  415. #endif