rtw_mlme.c 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179
  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 _RTW_MLME_C_
  21. #include <linux/ieee80211.h>
  22. #include <osdep_service.h>
  23. #include <drv_types.h>
  24. #include <recv_osdep.h>
  25. #include <xmit_osdep.h>
  26. #include <hal_intf.h>
  27. #include <mlme_osdep.h>
  28. #include <sta_info.h>
  29. #include <wifi.h>
  30. #include <wlan_bssdef.h>
  31. #include <rtw_ioctl_set.h>
  32. #include <linux/vmalloc.h>
  33. extern unsigned char MCS_rate_2R[16];
  34. extern unsigned char MCS_rate_1R[16];
  35. int rtw_init_mlme_priv(struct adapter *padapter)
  36. {
  37. int i;
  38. u8 *pbuf;
  39. struct wlan_network *pnetwork;
  40. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  41. int res = _SUCCESS;
  42. /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
  43. pmlmepriv->nic_hdl = (u8 *)padapter;
  44. pmlmepriv->pscanned = NULL;
  45. pmlmepriv->fw_state = 0;
  46. pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
  47. pmlmepriv->scan_mode = SCAN_ACTIVE;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
  48. spin_lock_init(&(pmlmepriv->lock));
  49. _rtw_init_queue(&(pmlmepriv->free_bss_pool));
  50. _rtw_init_queue(&(pmlmepriv->scanned_queue));
  51. set_scanned_network_val(pmlmepriv, 0);
  52. memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
  53. pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
  54. if (pbuf == NULL) {
  55. res = _FAIL;
  56. goto exit;
  57. }
  58. pmlmepriv->free_bss_buf = pbuf;
  59. pnetwork = (struct wlan_network *)pbuf;
  60. for (i = 0; i < MAX_BSS_CNT; i++) {
  61. INIT_LIST_HEAD(&(pnetwork->list));
  62. list_add_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
  63. pnetwork++;
  64. }
  65. /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
  66. rtw_clear_scan_deny(padapter);
  67. rtw_init_mlme_timer(padapter);
  68. exit:
  69. return res;
  70. }
  71. #if defined(CONFIG_88EU_AP_MODE)
  72. static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
  73. {
  74. kfree(*ppie);
  75. *plen = 0;
  76. *ppie = NULL;
  77. }
  78. void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
  79. {
  80. rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
  81. rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
  82. rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
  83. rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
  84. rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
  85. rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
  86. rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
  87. rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
  88. rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
  89. rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
  90. rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
  91. }
  92. #else
  93. void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
  94. {
  95. }
  96. #endif
  97. void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
  98. {
  99. rtw_free_mlme_priv_ie_data(pmlmepriv);
  100. if (pmlmepriv) {
  101. if (pmlmepriv->free_bss_buf)
  102. vfree(pmlmepriv->free_bss_buf);
  103. }
  104. }
  105. struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *free_queue) */
  106. {
  107. struct wlan_network *pnetwork;
  108. struct __queue *free_queue = &pmlmepriv->free_bss_pool;
  109. struct list_head *plist = NULL;
  110. spin_lock_bh(&free_queue->lock);
  111. if (list_empty(&free_queue->queue)) {
  112. pnetwork = NULL;
  113. goto exit;
  114. }
  115. plist = free_queue->queue.next;
  116. pnetwork = container_of(plist, struct wlan_network, list);
  117. list_del_init(&pnetwork->list);
  118. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist));
  119. pnetwork->network_type = 0;
  120. pnetwork->fixed = false;
  121. pnetwork->last_scanned = jiffies;
  122. pnetwork->aid = 0;
  123. pnetwork->join_res = 0;
  124. pmlmepriv->num_of_scanned++;
  125. exit:
  126. spin_unlock_bh(&free_queue->lock);
  127. return pnetwork;
  128. }
  129. static void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall)
  130. {
  131. u32 curr_time, delta_time;
  132. u32 lifetime = SCANQUEUE_LIFETIME;
  133. struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
  134. if (pnetwork == NULL)
  135. return;
  136. if (pnetwork->fixed)
  137. return;
  138. curr_time = jiffies;
  139. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
  140. (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
  141. lifetime = 1;
  142. if (!isfreeall) {
  143. delta_time = (curr_time - pnetwork->last_scanned)/HZ;
  144. if (delta_time < lifetime)/* unit:sec */
  145. return;
  146. }
  147. spin_lock_bh(&free_queue->lock);
  148. list_del_init(&(pnetwork->list));
  149. list_add_tail(&(pnetwork->list), &(free_queue->queue));
  150. pmlmepriv->num_of_scanned--;
  151. spin_unlock_bh(&free_queue->lock);
  152. }
  153. void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
  154. {
  155. struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
  156. if (pnetwork == NULL)
  157. return;
  158. if (pnetwork->fixed)
  159. return;
  160. list_del_init(&(pnetwork->list));
  161. list_add_tail(&(pnetwork->list), get_list_head(free_queue));
  162. pmlmepriv->num_of_scanned--;
  163. }
  164. /*
  165. return the wlan_network with the matching addr
  166. Shall be calle under atomic context... to avoid possible racing condition...
  167. */
  168. struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
  169. {
  170. struct list_head *phead, *plist;
  171. struct wlan_network *pnetwork = NULL;
  172. u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
  173. if (!memcmp(zero_addr, addr, ETH_ALEN)) {
  174. pnetwork = NULL;
  175. goto exit;
  176. }
  177. phead = get_list_head(scanned_queue);
  178. plist = phead->next;
  179. while (plist != phead) {
  180. pnetwork = container_of(plist, struct wlan_network, list);
  181. if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
  182. break;
  183. plist = plist->next;
  184. }
  185. if (plist == phead)
  186. pnetwork = NULL;
  187. exit:
  188. return pnetwork;
  189. }
  190. void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
  191. {
  192. struct list_head *phead, *plist;
  193. struct wlan_network *pnetwork;
  194. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  195. struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
  196. spin_lock_bh(&scanned_queue->lock);
  197. phead = get_list_head(scanned_queue);
  198. plist = phead->next;
  199. while (phead != plist) {
  200. pnetwork = container_of(plist, struct wlan_network, list);
  201. plist = plist->next;
  202. _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
  203. }
  204. spin_unlock_bh(&scanned_queue->lock);
  205. }
  206. int rtw_if_up(struct adapter *padapter)
  207. {
  208. int res;
  209. if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
  210. (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false)) {
  211. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
  212. ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
  213. padapter->bDriverStopped, padapter->bSurpriseRemoved));
  214. res = false;
  215. } else {
  216. res = true;
  217. }
  218. return res;
  219. }
  220. void rtw_generate_random_ibss(u8 *pibss)
  221. {
  222. u32 curtime = jiffies;
  223. pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
  224. pibss[1] = 0x11;
  225. pibss[2] = 0x87;
  226. pibss[3] = (u8)(curtime & 0xff);/* p[0]; */
  227. pibss[4] = (u8)((curtime>>8) & 0xff);/* p[1]; */
  228. pibss[5] = (u8)((curtime>>16) & 0xff);/* p[2]; */
  229. return;
  230. }
  231. u8 *rtw_get_capability_from_ie(u8 *ie)
  232. {
  233. return ie + 8 + 2;
  234. }
  235. u16 rtw_get_capability(struct wlan_bssid_ex *bss)
  236. {
  237. __le16 val;
  238. memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
  239. return le16_to_cpu(val);
  240. }
  241. u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
  242. {
  243. return ie + 8;
  244. }
  245. static struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv)
  246. {
  247. return _rtw_alloc_network(pmlmepriv);
  248. }
  249. static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
  250. struct wlan_network *pnetwork)
  251. {
  252. _rtw_free_network_nolock(pmlmepriv, pnetwork);
  253. }
  254. int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
  255. {
  256. int ret = true;
  257. struct security_priv *psecuritypriv = &adapter->securitypriv;
  258. if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
  259. (pnetwork->network.Privacy == 0))
  260. ret = false;
  261. else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
  262. (pnetwork->network.Privacy == 1))
  263. ret = false;
  264. else
  265. ret = true;
  266. return ret;
  267. }
  268. static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
  269. {
  270. return (a->Ssid.SsidLength == b->Ssid.SsidLength) &&
  271. !memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength);
  272. }
  273. int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
  274. {
  275. u16 s_cap, d_cap;
  276. __le16 le_scap, le_dcap;
  277. memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->IEs), 2);
  278. memcpy((u8 *)&le_dcap, rtw_get_capability_from_ie(dst->IEs), 2);
  279. s_cap = le16_to_cpu(le_scap);
  280. d_cap = le16_to_cpu(le_dcap);
  281. return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
  282. ((!memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == true) &&
  283. ((!memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == true) &&
  284. ((s_cap & WLAN_CAPABILITY_IBSS) ==
  285. (d_cap & WLAN_CAPABILITY_IBSS)) &&
  286. ((s_cap & WLAN_CAPABILITY_ESS) ==
  287. (d_cap & WLAN_CAPABILITY_ESS)));
  288. }
  289. struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
  290. {
  291. struct list_head *plist, *phead;
  292. struct wlan_network *pwlan = NULL;
  293. struct wlan_network *oldest = NULL;
  294. phead = get_list_head(scanned_queue);
  295. plist = phead->next;
  296. while (1) {
  297. if (phead == plist)
  298. break;
  299. pwlan = container_of(plist, struct wlan_network, list);
  300. if (!pwlan->fixed) {
  301. if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned))
  302. oldest = pwlan;
  303. }
  304. plist = plist->next;
  305. }
  306. return oldest;
  307. }
  308. void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
  309. struct adapter *padapter, bool update_ie)
  310. {
  311. long rssi_ori = dst->Rssi;
  312. u8 sq_smp = src->PhyInfo.SignalQuality;
  313. u8 ss_final;
  314. u8 sq_final;
  315. long rssi_final;
  316. rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */
  317. /* The rule below is 1/5 for sample value, 4/5 for history value */
  318. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
  319. /* Take the recvpriv's value for the connected AP*/
  320. ss_final = padapter->recvpriv.signal_strength;
  321. sq_final = padapter->recvpriv.signal_qual;
  322. /* the rssi value here is undecorated, and will be used for antenna diversity */
  323. if (sq_smp != 101) /* from the right channel */
  324. rssi_final = (src->Rssi+dst->Rssi*4)/5;
  325. else
  326. rssi_final = rssi_ori;
  327. } else {
  328. if (sq_smp != 101) { /* from the right channel */
  329. ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
  330. sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
  331. rssi_final = (src->Rssi+dst->Rssi*4)/5;
  332. } else {
  333. /* bss info not receiving from the right channel, use the original RX signal infos */
  334. ss_final = dst->PhyInfo.SignalStrength;
  335. sq_final = dst->PhyInfo.SignalQuality;
  336. rssi_final = dst->Rssi;
  337. }
  338. }
  339. if (update_ie)
  340. memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
  341. dst->PhyInfo.SignalStrength = ss_final;
  342. dst->PhyInfo.SignalQuality = sq_final;
  343. dst->Rssi = rssi_final;
  344. }
  345. static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
  346. {
  347. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  348. if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) &&
  349. (is_same_network(&(pmlmepriv->cur_network.network), pnetwork))) {
  350. update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true);
  351. rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(struct ndis_802_11_fixed_ie),
  352. pmlmepriv->cur_network.network.IELength);
  353. }
  354. }
  355. /*
  356. Caller must hold pmlmepriv->lock first.
  357. */
  358. void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
  359. {
  360. struct list_head *plist, *phead;
  361. u32 bssid_ex_sz;
  362. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  363. struct __queue *queue = &(pmlmepriv->scanned_queue);
  364. struct wlan_network *pnetwork = NULL;
  365. struct wlan_network *oldest = NULL;
  366. spin_lock_bh(&queue->lock);
  367. phead = get_list_head(queue);
  368. plist = phead->next;
  369. while (phead != plist) {
  370. pnetwork = container_of(plist, struct wlan_network, list);
  371. if (is_same_network(&(pnetwork->network), target))
  372. break;
  373. if ((oldest == ((struct wlan_network *)0)) ||
  374. time_after(oldest->last_scanned, pnetwork->last_scanned))
  375. oldest = pnetwork;
  376. plist = plist->next;
  377. }
  378. /* If we didn't find a match, then get a new network slot to initialize
  379. * with this beacon's information */
  380. if (phead == plist) {
  381. if (list_empty(&(pmlmepriv->free_bss_pool.queue))) {
  382. /* If there are no more slots, expire the oldest */
  383. pnetwork = oldest;
  384. rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
  385. memcpy(&(pnetwork->network), target, get_wlan_bssid_ex_sz(target));
  386. /* variable initialize */
  387. pnetwork->fixed = false;
  388. pnetwork->last_scanned = jiffies;
  389. pnetwork->network_type = 0;
  390. pnetwork->aid = 0;
  391. pnetwork->join_res = 0;
  392. /* bss info not receiving from the right channel */
  393. if (pnetwork->network.PhyInfo.SignalQuality == 101)
  394. pnetwork->network.PhyInfo.SignalQuality = 0;
  395. } else {
  396. /* Otherwise just pull from the free list */
  397. pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */
  398. if (pnetwork == NULL) {
  399. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("\n\n\nsomething wrong here\n\n\n"));
  400. goto exit;
  401. }
  402. bssid_ex_sz = get_wlan_bssid_ex_sz(target);
  403. target->Length = bssid_ex_sz;
  404. rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
  405. memcpy(&(pnetwork->network), target, bssid_ex_sz);
  406. pnetwork->last_scanned = jiffies;
  407. /* bss info not receiving from the right channel */
  408. if (pnetwork->network.PhyInfo.SignalQuality == 101)
  409. pnetwork->network.PhyInfo.SignalQuality = 0;
  410. list_add_tail(&(pnetwork->list), &(queue->queue));
  411. }
  412. } else {
  413. /* we have an entry and we are going to update it. But this entry may
  414. * be already expired. In this case we do the same as we found a new
  415. * net and call the new_net handler
  416. */
  417. bool update_ie = true;
  418. pnetwork->last_scanned = jiffies;
  419. /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
  420. if ((pnetwork->network.IELength > target->IELength) && (target->Reserved[0] == 1))
  421. update_ie = false;
  422. update_network(&(pnetwork->network), target, adapter, update_ie);
  423. }
  424. exit:
  425. spin_unlock_bh(&queue->lock);
  426. }
  427. static void rtw_add_network(struct adapter *adapter,
  428. struct wlan_bssid_ex *pnetwork)
  429. {
  430. update_current_network(adapter, pnetwork);
  431. rtw_update_scanned_network(adapter, pnetwork);
  432. }
  433. /*
  434. * select the desired network based on the capability of the (i)bss.
  435. * check items: (1) security
  436. * (2) network_type
  437. * (3) WMM
  438. * (4) HT
  439. * (5) others
  440. */
  441. static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork)
  442. {
  443. struct security_priv *psecuritypriv = &adapter->securitypriv;
  444. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  445. u32 desired_encmode;
  446. u32 privacy;
  447. /* u8 wps_ie[512]; */
  448. uint wps_ielen;
  449. int bselected = true;
  450. desired_encmode = psecuritypriv->ndisencryptstatus;
  451. privacy = pnetwork->network.Privacy;
  452. if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
  453. if (rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen) != NULL)
  454. return true;
  455. else
  456. return false;
  457. }
  458. if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */
  459. if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
  460. bselected = false;
  461. }
  462. if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
  463. DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
  464. bselected = false;
  465. }
  466. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
  467. if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
  468. bselected = false;
  469. }
  470. return bselected;
  471. }
  472. /* TODO: Perry: For Power Management */
  473. void rtw_atimdone_event_callback(struct adapter *adapter, u8 *pbuf)
  474. {
  475. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n"));
  476. return;
  477. }
  478. void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf)
  479. {
  480. u32 len;
  481. struct wlan_bssid_ex *pnetwork;
  482. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  483. pnetwork = (struct wlan_bssid_ex *)pbuf;
  484. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_survey_event_callback, ssid=%s\n", pnetwork->Ssid.Ssid));
  485. len = get_wlan_bssid_ex_sz(pnetwork);
  486. if (len > (sizeof(struct wlan_bssid_ex))) {
  487. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("\n****rtw_survey_event_callback: return a wrong bss ***\n"));
  488. return;
  489. }
  490. spin_lock_bh(&pmlmepriv->lock);
  491. /* update IBSS_network 's timestamp */
  492. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) {
  493. if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) {
  494. struct wlan_network *ibss_wlan = NULL;
  495. memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
  496. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  497. ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress);
  498. if (ibss_wlan) {
  499. memcpy(ibss_wlan->network.IEs, pnetwork->IEs, 8);
  500. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  501. goto exit;
  502. }
  503. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  504. }
  505. }
  506. /* lock pmlmepriv->lock when you accessing network_q */
  507. if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) {
  508. if (pnetwork->Ssid.Ssid[0] == 0)
  509. pnetwork->Ssid.SsidLength = 0;
  510. rtw_add_network(adapter, pnetwork);
  511. }
  512. exit:
  513. spin_unlock_bh(&pmlmepriv->lock);
  514. return;
  515. }
  516. void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
  517. {
  518. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  519. spin_lock_bh(&pmlmepriv->lock);
  520. if (pmlmepriv->wps_probe_req_ie) {
  521. pmlmepriv->wps_probe_req_ie_len = 0;
  522. kfree(pmlmepriv->wps_probe_req_ie);
  523. pmlmepriv->wps_probe_req_ie = NULL;
  524. }
  525. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
  526. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
  527. del_timer_sync(&pmlmepriv->scan_to_timer);
  528. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  529. } else {
  530. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv)));
  531. }
  532. rtw_set_signal_stat_timer(&adapter->recvpriv);
  533. if (pmlmepriv->to_join) {
  534. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
  535. if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
  536. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  537. if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
  538. mod_timer(&pmlmepriv->assoc_timer,
  539. jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
  540. } else {
  541. struct wlan_bssid_ex *pdev_network = &(adapter->registrypriv.dev_network);
  542. u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
  543. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  544. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n"));
  545. memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
  546. rtw_update_registrypriv_dev_network(adapter);
  547. rtw_generate_random_ibss(pibss);
  548. pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
  549. if (rtw_createbss_cmd(adapter) != _SUCCESS)
  550. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Error=>rtw_createbss_cmd status FAIL\n"));
  551. pmlmepriv->to_join = false;
  552. }
  553. }
  554. } else {
  555. int s_ret;
  556. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  557. pmlmepriv->to_join = false;
  558. s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
  559. if (_SUCCESS == s_ret) {
  560. mod_timer(&pmlmepriv->assoc_timer,
  561. jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
  562. } else if (s_ret == 2) { /* there is no need to wait for join */
  563. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  564. rtw_indicate_connect(adapter);
  565. } else {
  566. DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", pmlmepriv->to_roaming);
  567. if (pmlmepriv->to_roaming != 0) {
  568. if (--pmlmepriv->to_roaming == 0 ||
  569. _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) {
  570. pmlmepriv->to_roaming = 0;
  571. rtw_free_assoc_resources(adapter);
  572. rtw_indicate_disconnect(adapter);
  573. } else {
  574. pmlmepriv->to_join = true;
  575. }
  576. }
  577. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  578. }
  579. }
  580. }
  581. indicate_wx_scan_complete_event(adapter);
  582. spin_unlock_bh(&pmlmepriv->lock);
  583. rtw_os_xmit_schedule(adapter);
  584. }
  585. void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf)
  586. {
  587. }
  588. void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf)
  589. {
  590. }
  591. static void free_scanqueue(struct mlme_priv *pmlmepriv)
  592. {
  593. struct __queue *free_queue = &pmlmepriv->free_bss_pool;
  594. struct __queue *scan_queue = &pmlmepriv->scanned_queue;
  595. struct list_head *plist, *phead, *ptemp;
  596. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n"));
  597. spin_lock_bh(&scan_queue->lock);
  598. spin_lock_bh(&free_queue->lock);
  599. phead = get_list_head(scan_queue);
  600. plist = phead->next;
  601. while (plist != phead) {
  602. ptemp = plist->next;
  603. list_del_init(plist);
  604. list_add_tail(plist, &free_queue->queue);
  605. plist = ptemp;
  606. pmlmepriv->num_of_scanned--;
  607. }
  608. spin_unlock_bh(&free_queue->lock);
  609. spin_unlock_bh(&scan_queue->lock);
  610. }
  611. /*
  612. *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
  613. */
  614. void rtw_free_assoc_resources(struct adapter *adapter)
  615. {
  616. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  617. spin_lock_bh(&pmlmepriv->scanned_queue.lock);
  618. rtw_free_assoc_resources_locked(adapter);
  619. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  620. }
  621. /*
  622. *rtw_free_assoc_resources_locked: the caller has to lock pmlmepriv->lock
  623. */
  624. void rtw_free_assoc_resources_locked(struct adapter *adapter)
  625. {
  626. struct wlan_network *pwlan = NULL;
  627. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  628. struct sta_priv *pstapriv = &adapter->stapriv;
  629. struct wlan_network *tgt_network = &pmlmepriv->cur_network;
  630. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n"));
  631. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
  632. ("tgt_network->network.MacAddress=%pM ssid=%s\n",
  633. tgt_network->network.MacAddress, tgt_network->network.Ssid.Ssid));
  634. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
  635. struct sta_info *psta;
  636. psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
  637. spin_lock_bh(&(pstapriv->sta_hash_lock));
  638. rtw_free_stainfo(adapter, psta);
  639. spin_unlock_bh(&pstapriv->sta_hash_lock);
  640. }
  641. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) {
  642. struct sta_info *psta;
  643. rtw_free_all_stainfo(adapter);
  644. psta = rtw_get_bcmc_stainfo(adapter);
  645. spin_lock_bh(&(pstapriv->sta_hash_lock));
  646. rtw_free_stainfo(adapter, psta);
  647. spin_unlock_bh(&pstapriv->sta_hash_lock);
  648. rtw_init_bcmc_stainfo(adapter);
  649. }
  650. pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
  651. if (pwlan)
  652. pwlan->fixed = false;
  653. else
  654. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("rtw_free_assoc_resources:pwlan==NULL\n\n"));
  655. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1)))
  656. rtw_free_network_nolock(pmlmepriv, pwlan);
  657. pmlmepriv->key_mask = 0;
  658. }
  659. /*
  660. *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
  661. */
  662. void rtw_indicate_connect(struct adapter *padapter)
  663. {
  664. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  665. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n"));
  666. pmlmepriv->to_join = false;
  667. if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
  668. set_fwstate(pmlmepriv, _FW_LINKED);
  669. rtw_led_control(padapter, LED_CTL_LINK);
  670. rtw_os_indicate_connect(padapter);
  671. }
  672. pmlmepriv->to_roaming = 0;
  673. rtw_set_scan_deny(padapter, 3000);
  674. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
  675. }
  676. /*
  677. *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
  678. */
  679. void rtw_indicate_disconnect(struct adapter *padapter)
  680. {
  681. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  682. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n"));
  683. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS);
  684. if (pmlmepriv->to_roaming > 0)
  685. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  686. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
  687. (pmlmepriv->to_roaming <= 0)) {
  688. rtw_os_indicate_disconnect(padapter);
  689. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  690. rtw_led_control(padapter, LED_CTL_NO_LINK);
  691. rtw_clear_scan_deny(padapter);
  692. }
  693. rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
  694. }
  695. inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted)
  696. {
  697. rtw_os_indicate_scan_done(padapter, aborted);
  698. }
  699. void rtw_scan_abort(struct adapter *adapter)
  700. {
  701. u32 start;
  702. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  703. struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
  704. start = jiffies;
  705. pmlmeext->scan_abort = true;
  706. while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
  707. rtw_get_passing_time_ms(start) <= 200) {
  708. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  709. break;
  710. DBG_88E(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
  711. msleep(20);
  712. }
  713. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
  714. if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
  715. DBG_88E(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
  716. rtw_indicate_scan_done(adapter, true);
  717. }
  718. pmlmeext->scan_abort = false;
  719. }
  720. static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
  721. {
  722. int i;
  723. struct sta_info *bmc_sta, *psta = NULL;
  724. struct recv_reorder_ctrl *preorder_ctrl;
  725. struct sta_priv *pstapriv = &padapter->stapriv;
  726. psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
  727. if (psta == NULL)
  728. psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
  729. if (psta) { /* update ptarget_sta */
  730. DBG_88E("%s\n", __func__);
  731. psta->aid = pnetwork->join_res;
  732. psta->mac_id = 0;
  733. /* sta mode */
  734. rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
  735. /* security related */
  736. if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
  737. padapter->securitypriv.binstallGrpkey = false;
  738. padapter->securitypriv.busetkipkey = false;
  739. padapter->securitypriv.bgrpkey_handshake = false;
  740. psta->ieee8021x_blocked = true;
  741. psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
  742. memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
  743. memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
  744. memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
  745. memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
  746. memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
  747. }
  748. /*
  749. * Commented by Albert 2012/07/21
  750. * When doing the WPS, the wps_ie_len won't equal to 0
  751. * And the Wi-Fi driver shouldn't allow the data
  752. * packet to be tramsmitted.
  753. */
  754. if (padapter->securitypriv.wps_ie_len != 0) {
  755. psta->ieee8021x_blocked = true;
  756. padapter->securitypriv.wps_ie_len = 0;
  757. }
  758. /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
  759. /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
  760. /* todo: check if AP can send A-MPDU packets */
  761. for (i = 0; i < 16; i++) {
  762. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  763. preorder_ctrl = &psta->recvreorder_ctrl[i];
  764. preorder_ctrl->enable = false;
  765. preorder_ctrl->indicate_seq = 0xffff;
  766. preorder_ctrl->wend_b = 0xffff;
  767. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
  768. }
  769. bmc_sta = rtw_get_bcmc_stainfo(padapter);
  770. if (bmc_sta) {
  771. for (i = 0; i < 16; i++) {
  772. /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
  773. preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
  774. preorder_ctrl->enable = false;
  775. preorder_ctrl->indicate_seq = 0xffff;
  776. preorder_ctrl->wend_b = 0xffff;
  777. preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
  778. }
  779. }
  780. /* misc. */
  781. update_sta_info(padapter, psta);
  782. }
  783. return psta;
  784. }
  785. /* pnetwork: returns from rtw_joinbss_event_callback */
  786. /* ptarget_wlan: found from scanned_queue */
  787. static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork)
  788. {
  789. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  790. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  791. DBG_88E("%s\n", __func__);
  792. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
  793. ("\nfw_state:%x, BSSID:%pM\n",
  794. get_fwstate(pmlmepriv), pnetwork->network.MacAddress));
  795. /* why not use ptarget_wlan?? */
  796. memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
  797. /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
  798. cur_network->network.IELength = ptarget_wlan->network.IELength;
  799. memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
  800. cur_network->aid = pnetwork->join_res;
  801. rtw_set_signal_stat_timer(&padapter->recvpriv);
  802. padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
  803. padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
  804. /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
  805. padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
  806. rtw_set_signal_stat_timer(&padapter->recvpriv);
  807. /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
  808. switch (pnetwork->network.InfrastructureMode) {
  809. case Ndis802_11Infrastructure:
  810. if (pmlmepriv->fw_state&WIFI_UNDER_WPS)
  811. pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
  812. else
  813. pmlmepriv->fw_state = WIFI_STATION_STATE;
  814. break;
  815. case Ndis802_11IBSS:
  816. pmlmepriv->fw_state = WIFI_ADHOC_STATE;
  817. break;
  818. default:
  819. pmlmepriv->fw_state = WIFI_NULL_STATE;
  820. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Invalid network_mode\n"));
  821. break;
  822. }
  823. rtw_update_protection(padapter, (cur_network->network.IEs) +
  824. sizeof(struct ndis_802_11_fixed_ie),
  825. (cur_network->network.IELength));
  826. rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength);
  827. }
  828. /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
  829. /* pnetwork: returns from rtw_joinbss_event_callback */
  830. /* ptarget_wlan: found from scanned_queue */
  831. /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
  832. /* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
  833. /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
  834. void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
  835. {
  836. struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
  837. struct sta_priv *pstapriv = &adapter->stapriv;
  838. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  839. struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
  840. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  841. struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
  842. unsigned int the_same_macaddr = false;
  843. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("joinbss event call back received with res=%d\n", pnetwork->join_res));
  844. rtw_get_encrypt_decrypt_from_registrypriv(adapter);
  845. if (pmlmepriv->assoc_ssid.SsidLength == 0)
  846. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ joinbss event call back for Any SSid\n"));
  847. else
  848. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
  849. the_same_macaddr = !memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
  850. pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
  851. if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
  852. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
  853. return;
  854. }
  855. spin_lock_bh(&pmlmepriv->lock);
  856. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("\nrtw_joinbss_event_callback!! _enter_critical\n"));
  857. if (pnetwork->join_res > 0) {
  858. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  859. if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
  860. /* s1. find ptarget_wlan */
  861. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  862. if (the_same_macaddr) {
  863. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  864. } else {
  865. pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  866. if (pcur_wlan)
  867. pcur_wlan->fixed = false;
  868. pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
  869. if (pcur_sta) {
  870. spin_lock_bh(&(pstapriv->sta_hash_lock));
  871. rtw_free_stainfo(adapter, pcur_sta);
  872. spin_unlock_bh(&pstapriv->sta_hash_lock);
  873. }
  874. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
  875. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
  876. if (ptarget_wlan)
  877. ptarget_wlan->fixed = true;
  878. }
  879. }
  880. } else {
  881. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
  882. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
  883. if (ptarget_wlan)
  884. ptarget_wlan->fixed = true;
  885. }
  886. }
  887. /* s2. update cur_network */
  888. if (ptarget_wlan) {
  889. rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
  890. } else {
  891. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Can't find ptarget_wlan when joinbss_event callback\n"));
  892. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  893. goto ignore_joinbss_callback;
  894. }
  895. /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
  896. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
  897. ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
  898. if (ptarget_sta == NULL) {
  899. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Can't update stainfo when joinbss_event callback\n"));
  900. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  901. goto ignore_joinbss_callback;
  902. }
  903. }
  904. /* s4. indicate connect */
  905. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
  906. rtw_indicate_connect(adapter);
  907. } else {
  908. /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
  909. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
  910. }
  911. /* s5. Cancle assoc_timer */
  912. del_timer_sync(&pmlmepriv->assoc_timer);
  913. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("Cancle assoc_timer\n"));
  914. } else {
  915. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv)));
  916. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  917. goto ignore_joinbss_callback;
  918. }
  919. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  920. } else if (pnetwork->join_res == -4) {
  921. rtw_reset_securitypriv(adapter);
  922. mod_timer(&pmlmepriv->assoc_timer,
  923. jiffies + msecs_to_jiffies(1));
  924. if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == true) {
  925. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv)));
  926. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  927. }
  928. } else { /* if join_res < 0 (join fails), then try again */
  929. mod_timer(&pmlmepriv->assoc_timer,
  930. jiffies + msecs_to_jiffies(1));
  931. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  932. }
  933. ignore_joinbss_callback:
  934. spin_unlock_bh(&pmlmepriv->lock);
  935. }
  936. void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf)
  937. {
  938. struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
  939. mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
  940. rtw_os_xmit_schedule(adapter);
  941. }
  942. static u8 search_max_mac_id(struct adapter *padapter)
  943. {
  944. u8 mac_id;
  945. #if defined(CONFIG_88EU_AP_MODE)
  946. u8 aid;
  947. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  948. struct sta_priv *pstapriv = &padapter->stapriv;
  949. #endif
  950. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  951. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  952. #if defined(CONFIG_88EU_AP_MODE)
  953. if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  954. for (aid = (pstapriv->max_num_sta); aid > 0; aid--) {
  955. if (pstapriv->sta_aid[aid-1] != NULL)
  956. break;
  957. }
  958. mac_id = aid + 1;
  959. } else
  960. #endif
  961. {/* adhoc id = 31~2 */
  962. for (mac_id = (NUM_STA-1); mac_id >= IBSS_START_MAC_ID; mac_id--) {
  963. if (pmlmeinfo->FW_sta_info[mac_id].status == 1)
  964. break;
  965. }
  966. }
  967. return mac_id;
  968. }
  969. /* FOR AP , AD-HOC mode */
  970. void rtw_stassoc_hw_rpt(struct adapter *adapter, struct sta_info *psta)
  971. {
  972. u16 media_status;
  973. u8 macid;
  974. if (psta == NULL)
  975. return;
  976. macid = search_max_mac_id(adapter);
  977. rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&macid);
  978. media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE:1 connect */
  979. rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
  980. }
  981. void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
  982. {
  983. struct sta_info *psta;
  984. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  985. struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
  986. struct wlan_network *cur_network = &(pmlmepriv->cur_network);
  987. struct wlan_network *ptarget_wlan = NULL;
  988. if (rtw_access_ctrl(adapter, pstassoc->macaddr) == false)
  989. return;
  990. #if defined(CONFIG_88EU_AP_MODE)
  991. if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  992. psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
  993. if (psta) {
  994. ap_sta_info_defer_update(adapter, psta);
  995. rtw_stassoc_hw_rpt(adapter, psta);
  996. }
  997. return;
  998. }
  999. #endif
  1000. /* for AD-HOC mode */
  1001. psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
  1002. if (psta != NULL) {
  1003. /* the sta have been in sta_info_queue => do nothing */
  1004. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue\n"));
  1005. return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
  1006. }
  1007. psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
  1008. if (psta == NULL) {
  1009. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
  1010. return;
  1011. }
  1012. /* to do: init sta_info variable */
  1013. psta->qos_option = 0;
  1014. psta->mac_id = (uint)pstassoc->cam_id;
  1015. DBG_88E("%s\n", __func__);
  1016. /* for ad-hoc mode */
  1017. rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true);
  1018. rtw_stassoc_hw_rpt(adapter, psta);
  1019. if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
  1020. psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
  1021. psta->ieee8021x_blocked = false;
  1022. spin_lock_bh(&pmlmepriv->lock);
  1023. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
  1024. (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))) {
  1025. if (adapter->stapriv.asoc_sta_count == 2) {
  1026. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  1027. ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
  1028. if (ptarget_wlan)
  1029. ptarget_wlan->fixed = true;
  1030. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  1031. /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
  1032. rtw_indicate_connect(adapter);
  1033. }
  1034. }
  1035. spin_unlock_bh(&pmlmepriv->lock);
  1036. mlmeext_sta_add_event_callback(adapter, psta);
  1037. }
  1038. void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
  1039. {
  1040. int mac_id = -1;
  1041. struct sta_info *psta;
  1042. struct wlan_network *pwlan = NULL;
  1043. struct wlan_bssid_ex *pdev_network = NULL;
  1044. u8 *pibss = NULL;
  1045. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1046. struct stadel_event *pstadel = (struct stadel_event *)pbuf;
  1047. struct sta_priv *pstapriv = &adapter->stapriv;
  1048. struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
  1049. psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
  1050. if (psta)
  1051. mac_id = psta->mac_id;
  1052. else
  1053. mac_id = pstadel->mac_id;
  1054. DBG_88E("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
  1055. if (mac_id >= 0) {
  1056. u16 media_status;
  1057. media_status = (mac_id<<8)|0; /* MACID|OPMODE:0 means disconnect */
  1058. /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
  1059. rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
  1060. }
  1061. if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
  1062. return;
  1063. mlmeext_sta_del_event_callback(adapter);
  1064. spin_lock_bh(&pmlmepriv->lock);
  1065. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  1066. if (pmlmepriv->to_roaming > 0)
  1067. pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
  1068. else if (pmlmepriv->to_roaming == 0)
  1069. pmlmepriv->to_roaming = adapter->registrypriv.max_roaming_times;
  1070. if (*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
  1071. pmlmepriv->to_roaming = 0; /* don't roam */
  1072. rtw_free_uc_swdec_pending_queue(adapter);
  1073. rtw_free_assoc_resources(adapter);
  1074. rtw_indicate_disconnect(adapter);
  1075. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  1076. /* remove the network entry in scanned_queue */
  1077. pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
  1078. if (pwlan) {
  1079. pwlan->fixed = false;
  1080. rtw_free_network_nolock(pmlmepriv, pwlan);
  1081. }
  1082. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  1083. _rtw_roaming(adapter, tgt_network);
  1084. }
  1085. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
  1086. check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  1087. spin_lock_bh(&(pstapriv->sta_hash_lock));
  1088. rtw_free_stainfo(adapter, psta);
  1089. spin_unlock_bh(&pstapriv->sta_hash_lock);
  1090. if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
  1091. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  1092. /* free old ibss network */
  1093. pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
  1094. if (pwlan) {
  1095. pwlan->fixed = false;
  1096. rtw_free_network_nolock(pmlmepriv, pwlan);
  1097. }
  1098. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  1099. /* re-create ibss */
  1100. pdev_network = &(adapter->registrypriv.dev_network);
  1101. pibss = adapter->registrypriv.dev_network.MacAddress;
  1102. memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
  1103. memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
  1104. rtw_update_registrypriv_dev_network(adapter);
  1105. rtw_generate_random_ibss(pibss);
  1106. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  1107. set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  1108. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
  1109. }
  1110. if (rtw_createbss_cmd(adapter) != _SUCCESS)
  1111. RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL***\n "));
  1112. }
  1113. }
  1114. spin_unlock_bh(&pmlmepriv->lock);
  1115. }
  1116. void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf)
  1117. {
  1118. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_cpwm_event_callback !!!\n"));
  1119. }
  1120. /*
  1121. * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
  1122. * @adapter: pointer to struct adapter structure
  1123. */
  1124. void _rtw_join_timeout_handler (unsigned long data)
  1125. {
  1126. struct adapter *adapter = (struct adapter *)data;
  1127. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1128. int do_join_r;
  1129. DBG_88E("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
  1130. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  1131. return;
  1132. spin_lock_bh(&pmlmepriv->lock);
  1133. if (pmlmepriv->to_roaming > 0) { /* join timeout caused by roaming */
  1134. while (1) {
  1135. pmlmepriv->to_roaming--;
  1136. if (pmlmepriv->to_roaming != 0) { /* try another , */
  1137. DBG_88E("%s try another roaming\n", __func__);
  1138. do_join_r = rtw_do_join(adapter);
  1139. if (_SUCCESS != do_join_r) {
  1140. DBG_88E("%s roaming do_join return %d\n", __func__, do_join_r);
  1141. continue;
  1142. }
  1143. break;
  1144. } else {
  1145. DBG_88E("%s We've try roaming but fail\n", __func__);
  1146. rtw_indicate_disconnect(adapter);
  1147. break;
  1148. }
  1149. }
  1150. } else {
  1151. rtw_indicate_disconnect(adapter);
  1152. free_scanqueue(pmlmepriv);/* */
  1153. }
  1154. spin_unlock_bh(&pmlmepriv->lock);
  1155. }
  1156. /*
  1157. * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
  1158. * @adapter: pointer to struct adapter structure
  1159. */
  1160. void rtw_scan_timeout_handler (unsigned long data)
  1161. {
  1162. struct adapter *adapter = (struct adapter *)data;
  1163. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1164. DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
  1165. spin_lock_bh(&pmlmepriv->lock);
  1166. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  1167. spin_unlock_bh(&pmlmepriv->lock);
  1168. rtw_indicate_scan_done(adapter, true);
  1169. }
  1170. static void rtw_auto_scan_handler(struct adapter *padapter)
  1171. {
  1172. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1173. /* auto site survey per 60sec */
  1174. if (pmlmepriv->scan_interval > 0) {
  1175. pmlmepriv->scan_interval--;
  1176. if (pmlmepriv->scan_interval == 0) {
  1177. DBG_88E("%s\n", __func__);
  1178. rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
  1179. pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
  1180. }
  1181. }
  1182. }
  1183. void rtw_dynamic_check_timer_handlder(unsigned long data)
  1184. {
  1185. struct adapter *adapter = (struct adapter *)data;
  1186. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  1187. if (!adapter)
  1188. return;
  1189. if (!adapter->hw_init_completed)
  1190. goto exit;
  1191. if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved))
  1192. goto exit;
  1193. if (adapter->net_closed)
  1194. goto exit;
  1195. rtw_dynamic_chk_wk_cmd(adapter);
  1196. if (pregistrypriv->wifi_spec == 1) {
  1197. /* auto site survey */
  1198. rtw_auto_scan_handler(adapter);
  1199. }
  1200. exit:
  1201. mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
  1202. jiffies + msecs_to_jiffies(2000));
  1203. }
  1204. #define RTW_SCAN_RESULT_EXPIRE 2000
  1205. /*
  1206. * Select a new join candidate from the original @param candidate and @param competitor
  1207. * @return true: candidate is updated
  1208. * @return false: candidate is not updated
  1209. */
  1210. static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
  1211. , struct wlan_network **candidate, struct wlan_network *competitor)
  1212. {
  1213. int updated = false;
  1214. struct adapter *adapter = container_of(pmlmepriv, struct adapter, mlmepriv);
  1215. /* check bssid, if needed */
  1216. if (pmlmepriv->assoc_by_bssid) {
  1217. if (memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN))
  1218. goto exit;
  1219. }
  1220. /* check ssid, if needed */
  1221. if (pmlmepriv->assoc_ssid.SsidLength) {
  1222. if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength ||
  1223. !memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength) == false)
  1224. goto exit;
  1225. }
  1226. if (rtw_is_desired_network(adapter, competitor) == false)
  1227. goto exit;
  1228. if (pmlmepriv->to_roaming) {
  1229. if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE ||
  1230. is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == false)
  1231. goto exit;
  1232. }
  1233. if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
  1234. *candidate = competitor;
  1235. updated = true;
  1236. }
  1237. if (updated) {
  1238. DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n",
  1239. pmlmepriv->assoc_by_bssid,
  1240. pmlmepriv->assoc_ssid.Ssid,
  1241. (*candidate)->network.Ssid.Ssid,
  1242. (*candidate)->network.MacAddress,
  1243. (int)(*candidate)->network.Rssi);
  1244. DBG_88E("[to_roaming:%u]\n", pmlmepriv->to_roaming);
  1245. }
  1246. exit:
  1247. return updated;
  1248. }
  1249. /*
  1250. Calling context:
  1251. The caller of the sub-routine will be in critical section...
  1252. The caller must hold the following spinlock
  1253. pmlmepriv->lock
  1254. */
  1255. int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
  1256. {
  1257. int ret;
  1258. struct list_head *phead;
  1259. struct adapter *adapter;
  1260. struct __queue *queue = &(pmlmepriv->scanned_queue);
  1261. struct wlan_network *pnetwork = NULL;
  1262. struct wlan_network *candidate = NULL;
  1263. u8 supp_ant_div = false;
  1264. spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  1265. phead = get_list_head(queue);
  1266. adapter = (struct adapter *)pmlmepriv->nic_hdl;
  1267. pmlmepriv->pscanned = phead->next;
  1268. while (phead != pmlmepriv->pscanned) {
  1269. pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
  1270. if (pnetwork == NULL) {
  1271. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s return _FAIL:(pnetwork==NULL)\n", __func__));
  1272. ret = _FAIL;
  1273. goto exit;
  1274. }
  1275. pmlmepriv->pscanned = pmlmepriv->pscanned->next;
  1276. rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
  1277. }
  1278. if (candidate == NULL) {
  1279. DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__);
  1280. ret = _FAIL;
  1281. goto exit;
  1282. } else {
  1283. DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__,
  1284. candidate->network.Ssid.Ssid, candidate->network.MacAddress,
  1285. candidate->network.Configuration.DSConfig);
  1286. }
  1287. /* check for situation of _FW_LINKED */
  1288. if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
  1289. DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__);
  1290. rtw_disassoc_cmd(adapter, 0, true);
  1291. rtw_indicate_disconnect(adapter);
  1292. rtw_free_assoc_resources_locked(adapter);
  1293. }
  1294. rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div));
  1295. if (supp_ant_div) {
  1296. u8 cur_ant;
  1297. rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant));
  1298. DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
  1299. (2 == candidate->network.PhyInfo.Optimum_antenna) ? "A" : "B",
  1300. (2 == cur_ant) ? "A" : "B"
  1301. );
  1302. }
  1303. ret = rtw_joinbss_cmd(adapter, candidate);
  1304. exit:
  1305. spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
  1306. return ret;
  1307. }
  1308. int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
  1309. {
  1310. struct cmd_obj *pcmd;
  1311. struct setauth_parm *psetauthparm;
  1312. struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
  1313. int res = _SUCCESS;
  1314. pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
  1315. if (pcmd == NULL) {
  1316. res = _FAIL; /* try again */
  1317. goto exit;
  1318. }
  1319. psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
  1320. if (psetauthparm == NULL) {
  1321. kfree(pcmd);
  1322. res = _FAIL;
  1323. goto exit;
  1324. }
  1325. memset(psetauthparm, 0, sizeof(struct setauth_parm));
  1326. psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
  1327. pcmd->cmdcode = _SetAuth_CMD_;
  1328. pcmd->parmbuf = (unsigned char *)psetauthparm;
  1329. pcmd->cmdsz = (sizeof(struct setauth_parm));
  1330. pcmd->rsp = NULL;
  1331. pcmd->rspsz = 0;
  1332. INIT_LIST_HEAD(&pcmd->list);
  1333. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
  1334. ("after enqueue set_auth_cmd, auth_mode=%x\n",
  1335. psecuritypriv->dot11AuthAlgrthm));
  1336. res = rtw_enqueue_cmd(pcmdpriv, pcmd);
  1337. exit:
  1338. return res;
  1339. }
  1340. int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, int keyid, u8 set_tx)
  1341. {
  1342. u8 keylen;
  1343. struct cmd_obj *pcmd;
  1344. struct setkey_parm *psetkeyparm;
  1345. struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
  1346. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  1347. int res = _SUCCESS;
  1348. pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
  1349. if (pcmd == NULL)
  1350. return _FAIL; /* try again */
  1351. psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
  1352. if (psetkeyparm == NULL) {
  1353. res = _FAIL;
  1354. goto err_free_cmd;
  1355. }
  1356. memset(psetkeyparm, 0, sizeof(struct setkey_parm));
  1357. if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
  1358. psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
  1359. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
  1360. ("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d\n",
  1361. psetkeyparm->algorithm));
  1362. } else {
  1363. psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
  1364. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
  1365. ("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d\n",
  1366. psetkeyparm->algorithm));
  1367. }
  1368. psetkeyparm->keyid = (u8)keyid;/* 0~3 */
  1369. psetkeyparm->set_tx = set_tx;
  1370. pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
  1371. DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n",
  1372. psetkeyparm->algorithm, psetkeyparm->keyid, pmlmepriv->key_mask);
  1373. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
  1374. ("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d\n",
  1375. psetkeyparm->algorithm, keyid));
  1376. switch (psetkeyparm->algorithm) {
  1377. case _WEP40_:
  1378. keylen = 5;
  1379. memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
  1380. break;
  1381. case _WEP104_:
  1382. keylen = 13;
  1383. memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
  1384. break;
  1385. case _TKIP_:
  1386. keylen = 16;
  1387. memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
  1388. psetkeyparm->grpkey = 1;
  1389. break;
  1390. case _AES_:
  1391. keylen = 16;
  1392. memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
  1393. psetkeyparm->grpkey = 1;
  1394. break;
  1395. default:
  1396. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
  1397. ("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm=%x (must be 1 or 2 or 4 or 5)\n",
  1398. psecuritypriv->dot11PrivacyAlgrthm));
  1399. res = _FAIL;
  1400. goto err_free_parm;
  1401. }
  1402. pcmd->cmdcode = _SetKey_CMD_;
  1403. pcmd->parmbuf = (u8 *)psetkeyparm;
  1404. pcmd->cmdsz = (sizeof(struct setkey_parm));
  1405. pcmd->rsp = NULL;
  1406. pcmd->rspsz = 0;
  1407. INIT_LIST_HEAD(&pcmd->list);
  1408. res = rtw_enqueue_cmd(pcmdpriv, pcmd);
  1409. return res;
  1410. err_free_parm:
  1411. kfree(psetkeyparm);
  1412. err_free_cmd:
  1413. kfree(pcmd);
  1414. return res;
  1415. }
  1416. /* adjust IEs for rtw_joinbss_cmd in WMM */
  1417. int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
  1418. {
  1419. unsigned int ielength = 0;
  1420. unsigned int i, j;
  1421. /* i = 12; after the fixed IE */
  1422. for (i = 12; i < in_len; i += (in_ie[i + 1] + 2) /* to the next IE element */) {
  1423. ielength = initial_out_len;
  1424. if (in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50 && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) {
  1425. /* WMM element ID and OUI */
  1426. /* Append WMM IE to the last index of out_ie */
  1427. for (j = i; j < i + 9; j++) {
  1428. out_ie[ielength] = in_ie[j];
  1429. ielength++;
  1430. }
  1431. out_ie[initial_out_len + 1] = 0x07;
  1432. out_ie[initial_out_len + 6] = 0x00;
  1433. out_ie[initial_out_len + 8] = 0x00;
  1434. break;
  1435. }
  1436. }
  1437. return ielength;
  1438. }
  1439. /*
  1440. * Ported from 8185: IsInPreAuthKeyList().
  1441. * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
  1442. * Added by Annie, 2006-05-07.
  1443. * Search by BSSID,
  1444. * Return Value:
  1445. * -1 :if there is no pre-auth key in the table
  1446. * >= 0 :if there is pre-auth key, and return the entry id
  1447. */
  1448. static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
  1449. {
  1450. struct security_priv *psecuritypriv = &Adapter->securitypriv;
  1451. int i = 0;
  1452. do {
  1453. if ((psecuritypriv->PMKIDList[i].bUsed) &&
  1454. (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) {
  1455. break;
  1456. } else {
  1457. i++;
  1458. /* continue; */
  1459. }
  1460. } while (i < NUM_PMKID_CACHE);
  1461. if (i == NUM_PMKID_CACHE)
  1462. i = -1;/* Could not find. */
  1463. return i;
  1464. }
  1465. /* */
  1466. /* Check the RSN IE length */
  1467. /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
  1468. /* 0-11th element in the array are the fixed IE */
  1469. /* 12th element in the array is the IE */
  1470. /* 13th element in the array is the IE length */
  1471. /* */
  1472. static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len)
  1473. {
  1474. struct security_priv *psecuritypriv = &Adapter->securitypriv;
  1475. if (ie[13] <= 20) {
  1476. /* The RSN IE didn't include the PMK ID, append the PMK information */
  1477. ie[ie_len] = 1;
  1478. ie_len++;
  1479. ie[ie_len] = 0; /* PMKID count = 0x0100 */
  1480. ie_len++;
  1481. memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
  1482. ie_len += 16;
  1483. ie[13] += 18;/* PMKID length = 2+16 */
  1484. }
  1485. return ie_len;
  1486. }
  1487. int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
  1488. {
  1489. u8 authmode;
  1490. uint ielength;
  1491. int iEntry;
  1492. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1493. struct security_priv *psecuritypriv = &adapter->securitypriv;
  1494. uint ndisauthmode = psecuritypriv->ndisauthtype;
  1495. uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
  1496. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  1497. ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
  1498. ndisauthmode, ndissecuritytype));
  1499. /* copy fixed ie only */
  1500. memcpy(out_ie, in_ie, 12);
  1501. ielength = 12;
  1502. if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
  1503. (ndisauthmode == Ndis802_11AuthModeWPAPSK))
  1504. authmode = _WPA_IE_ID_;
  1505. if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
  1506. (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
  1507. authmode = _WPA2_IE_ID_;
  1508. if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
  1509. memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
  1510. ielength += psecuritypriv->wps_ie_len;
  1511. } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
  1512. /* copy RSN or SSN */
  1513. memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
  1514. ielength += psecuritypriv->supplicant_ie[1]+2;
  1515. rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
  1516. }
  1517. iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
  1518. if (iEntry < 0) {
  1519. return ielength;
  1520. } else {
  1521. if (authmode == _WPA2_IE_ID_)
  1522. ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
  1523. }
  1524. return ielength;
  1525. }
  1526. void rtw_init_registrypriv_dev_network(struct adapter *adapter)
  1527. {
  1528. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  1529. struct eeprom_priv *peepriv = &adapter->eeprompriv;
  1530. struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
  1531. u8 *myhwaddr = myid(peepriv);
  1532. memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
  1533. memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid));
  1534. pdev_network->Configuration.Length = sizeof(struct ndis_802_11_config);
  1535. pdev_network->Configuration.BeaconPeriod = 100;
  1536. pdev_network->Configuration.FHConfig.Length = 0;
  1537. pdev_network->Configuration.FHConfig.HopPattern = 0;
  1538. pdev_network->Configuration.FHConfig.HopSet = 0;
  1539. pdev_network->Configuration.FHConfig.DwellTime = 0;
  1540. }
  1541. void rtw_update_registrypriv_dev_network(struct adapter *adapter)
  1542. {
  1543. int sz = 0;
  1544. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  1545. struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
  1546. struct security_priv *psecuritypriv = &adapter->securitypriv;
  1547. struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
  1548. pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0); /* adhoc no 802.1x */
  1549. pdev_network->Rssi = 0;
  1550. switch (pregistrypriv->wireless_mode) {
  1551. case WIRELESS_11B:
  1552. pdev_network->NetworkTypeInUse = (Ndis802_11DS);
  1553. break;
  1554. case WIRELESS_11G:
  1555. case WIRELESS_11BG:
  1556. case WIRELESS_11_24N:
  1557. case WIRELESS_11G_24N:
  1558. case WIRELESS_11BG_24N:
  1559. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
  1560. break;
  1561. case WIRELESS_11A:
  1562. case WIRELESS_11A_5N:
  1563. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
  1564. break;
  1565. case WIRELESS_11ABGN:
  1566. if (pregistrypriv->channel > 14)
  1567. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
  1568. else
  1569. pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
  1570. break;
  1571. default:
  1572. /* TODO */
  1573. break;
  1574. }
  1575. pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
  1576. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
  1577. ("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n",
  1578. pregistrypriv->channel, pdev_network->Configuration.DSConfig));
  1579. if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
  1580. pdev_network->Configuration.ATIMWindow = (0);
  1581. pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
  1582. /* 1. Supported rates */
  1583. /* 2. IE */
  1584. sz = rtw_generate_ie(pregistrypriv);
  1585. pdev_network->IELength = sz;
  1586. pdev_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
  1587. /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
  1588. /* pdev_network->IELength = cpu_to_le32(sz); */
  1589. }
  1590. void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter)
  1591. {
  1592. }
  1593. /* the function is at passive_level */
  1594. void rtw_joinbss_reset(struct adapter *padapter)
  1595. {
  1596. u8 threshold;
  1597. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1598. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1599. /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
  1600. pmlmepriv->num_FortyMHzIntolerant = 0;
  1601. pmlmepriv->num_sta_no_ht = 0;
  1602. phtpriv->ampdu_enable = false;/* reset to disabled */
  1603. /* TH = 1 => means that invalidate usb rx aggregation */
  1604. /* TH = 0 => means that validate usb rx aggregation, use init value. */
  1605. if (phtpriv->ht_option) {
  1606. if (padapter->registrypriv.wifi_spec == 1)
  1607. threshold = 1;
  1608. else
  1609. threshold = 0;
  1610. rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
  1611. } else {
  1612. threshold = 1;
  1613. rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
  1614. }
  1615. }
  1616. /* the function is >= passive_level */
  1617. unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
  1618. {
  1619. u32 ielen, out_len;
  1620. enum ht_cap_ampdu_factor max_rx_ampdu_factor;
  1621. unsigned char *p;
  1622. struct rtw_ieee80211_ht_cap ht_capie;
  1623. unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
  1624. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1625. struct qos_priv *pqospriv = &pmlmepriv->qospriv;
  1626. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1627. u32 rx_packet_offset, max_recvbuf_sz;
  1628. phtpriv->ht_option = false;
  1629. p = rtw_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12);
  1630. if (p && ielen > 0) {
  1631. if (pqospriv->qos_option == 0) {
  1632. out_len = *pout_len;
  1633. rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_,
  1634. _WMM_IE_Length_, WMM_IE, pout_len);
  1635. pqospriv->qos_option = 1;
  1636. }
  1637. out_len = *pout_len;
  1638. memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
  1639. ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
  1640. IEEE80211_HT_CAP_SGI_20 |
  1641. IEEE80211_HT_CAP_SGI_40 |
  1642. IEEE80211_HT_CAP_TX_STBC |
  1643. IEEE80211_HT_CAP_DSSSCCK40;
  1644. rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
  1645. rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
  1646. /*
  1647. AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
  1648. AMPDU_para [4:2]:Min MPDU Start Spacing
  1649. */
  1650. rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
  1651. ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
  1652. if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
  1653. ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
  1654. else
  1655. ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
  1656. rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_,
  1657. sizeof(struct rtw_ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
  1658. phtpriv->ht_option = true;
  1659. p = rtw_get_ie(in_ie+12, _HT_ADD_INFO_IE_, &ielen, in_len-12);
  1660. if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
  1661. out_len = *pout_len;
  1662. rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2, pout_len);
  1663. }
  1664. }
  1665. return phtpriv->ht_option;
  1666. }
  1667. /* the function is > passive_level (in critical_section) */
  1668. void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
  1669. {
  1670. u8 *p, max_ampdu_sz;
  1671. int len;
  1672. struct rtw_ieee80211_ht_cap *pht_capie;
  1673. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1674. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1675. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  1676. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1677. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1678. if (!phtpriv->ht_option)
  1679. return;
  1680. if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
  1681. return;
  1682. DBG_88E("+rtw_update_ht_cap()\n");
  1683. /* maybe needs check if ap supports rx ampdu. */
  1684. if ((!phtpriv->ampdu_enable) && (pregistrypriv->ampdu_enable == 1)) {
  1685. if (pregistrypriv->wifi_spec == 1)
  1686. phtpriv->ampdu_enable = false;
  1687. else
  1688. phtpriv->ampdu_enable = true;
  1689. } else if (pregistrypriv->ampdu_enable == 2) {
  1690. phtpriv->ampdu_enable = true;
  1691. }
  1692. /* check Max Rx A-MPDU Size */
  1693. len = 0;
  1694. p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fixed_ie), _HT_CAPABILITY_IE_, &len, ie_len-sizeof(struct ndis_802_11_fixed_ie));
  1695. if (p && len > 0) {
  1696. pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
  1697. max_ampdu_sz = pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
  1698. max_ampdu_sz = 1 << (max_ampdu_sz+3); /* max_ampdu_sz (kbytes); */
  1699. phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
  1700. }
  1701. len = 0;
  1702. p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fixed_ie), _HT_ADD_INFO_IE_, &len, ie_len-sizeof(struct ndis_802_11_fixed_ie));
  1703. /* update cur_bwmode & cur_ch_offset */
  1704. if ((pregistrypriv->cbw40_enable) &&
  1705. (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & BIT(1)) &&
  1706. (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
  1707. int i;
  1708. u8 rf_type;
  1709. padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  1710. /* update the MCS rates */
  1711. for (i = 0; i < 16; i++) {
  1712. if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
  1713. pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
  1714. else
  1715. pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
  1716. }
  1717. /* switch to the 40M Hz mode according to the AP */
  1718. pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
  1719. switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
  1720. case HT_EXTCHNL_OFFSET_UPPER:
  1721. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  1722. break;
  1723. case HT_EXTCHNL_OFFSET_LOWER:
  1724. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  1725. break;
  1726. default:
  1727. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  1728. break;
  1729. }
  1730. }
  1731. /* Config SM Power Save setting */
  1732. pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2;
  1733. if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
  1734. DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
  1735. /* Config current HT Protection mode. */
  1736. pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
  1737. }
  1738. void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe)
  1739. {
  1740. u8 issued;
  1741. int priority;
  1742. struct sta_info *psta = NULL;
  1743. struct ht_priv *phtpriv;
  1744. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  1745. s32 bmcst = IS_MCAST(pattrib->ra);
  1746. if (bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100))
  1747. return;
  1748. priority = pattrib->priority;
  1749. if (pattrib->psta)
  1750. psta = pattrib->psta;
  1751. else
  1752. psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
  1753. if (psta == NULL)
  1754. return;
  1755. phtpriv = &psta->htpriv;
  1756. if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
  1757. issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
  1758. issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
  1759. if (0 == issued) {
  1760. DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority);
  1761. psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
  1762. rtw_addbareq_cmd(padapter, (u8)priority, pattrib->ra);
  1763. }
  1764. }
  1765. }
  1766. void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
  1767. {
  1768. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1769. spin_lock_bh(&pmlmepriv->lock);
  1770. _rtw_roaming(padapter, tgt_network);
  1771. spin_unlock_bh(&pmlmepriv->lock);
  1772. }
  1773. void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
  1774. {
  1775. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1776. int do_join_r;
  1777. struct wlan_network *pnetwork;
  1778. if (tgt_network != NULL)
  1779. pnetwork = tgt_network;
  1780. else
  1781. pnetwork = &pmlmepriv->cur_network;
  1782. if (0 < pmlmepriv->to_roaming) {
  1783. DBG_88E("roaming from %s(%pM length:%d\n",
  1784. pnetwork->network.Ssid.Ssid, pnetwork->network.MacAddress,
  1785. pnetwork->network.Ssid.SsidLength);
  1786. memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
  1787. pmlmepriv->assoc_by_bssid = false;
  1788. while (1) {
  1789. do_join_r = rtw_do_join(padapter);
  1790. if (_SUCCESS == do_join_r) {
  1791. break;
  1792. } else {
  1793. DBG_88E("roaming do_join return %d\n", do_join_r);
  1794. pmlmepriv->to_roaming--;
  1795. if (0 < pmlmepriv->to_roaming) {
  1796. continue;
  1797. } else {
  1798. DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__, __LINE__);
  1799. rtw_indicate_disconnect(padapter);
  1800. break;
  1801. }
  1802. }
  1803. }
  1804. }
  1805. }