rtl871x_mlme.c 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803
  1. /******************************************************************************
  2. * rtl871x_mlme.c
  3. *
  4. * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  5. * Linux device driver for RTL8192SU
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of version 2 of the GNU General Public License as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19. *
  20. * Modifications for inclusion into the Linux staging tree are
  21. * Copyright(c) 2010 Larry Finger. All rights reserved.
  22. *
  23. * Contact information:
  24. * WLAN FAE <wlanfae@realtek.com>
  25. * Larry Finger <Larry.Finger@lwfinger.net>
  26. *
  27. ******************************************************************************/
  28. #define _RTL871X_MLME_C_
  29. #include <linux/etherdevice.h>
  30. #include "osdep_service.h"
  31. #include "drv_types.h"
  32. #include "recv_osdep.h"
  33. #include "xmit_osdep.h"
  34. #include "mlme_osdep.h"
  35. #include "sta_info.h"
  36. #include "wifi.h"
  37. #include "wlan_bssdef.h"
  38. static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len);
  39. static sint _init_mlme_priv(struct _adapter *padapter)
  40. {
  41. sint i;
  42. u8 *pbuf;
  43. struct wlan_network *pnetwork;
  44. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  45. memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
  46. pmlmepriv->nic_hdl = (u8 *)padapter;
  47. pmlmepriv->pscanned = NULL;
  48. pmlmepriv->fw_state = 0;
  49. pmlmepriv->cur_network.network.InfrastructureMode =
  50. Ndis802_11AutoUnknown;
  51. /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/
  52. pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */
  53. spin_lock_init(&(pmlmepriv->lock));
  54. spin_lock_init(&(pmlmepriv->lock2));
  55. _init_queue(&(pmlmepriv->free_bss_pool));
  56. _init_queue(&(pmlmepriv->scanned_queue));
  57. set_scanned_network_val(pmlmepriv, 0);
  58. memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
  59. pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network),
  60. GFP_ATOMIC);
  61. if (pbuf == NULL)
  62. return _FAIL;
  63. pmlmepriv->free_bss_buf = pbuf;
  64. pnetwork = (struct wlan_network *)pbuf;
  65. for (i = 0; i < MAX_BSS_CNT; i++) {
  66. INIT_LIST_HEAD(&(pnetwork->list));
  67. list_add_tail(&(pnetwork->list),
  68. &(pmlmepriv->free_bss_pool.queue));
  69. pnetwork++;
  70. }
  71. pmlmepriv->sitesurveyctrl.last_rx_pkts = 0;
  72. pmlmepriv->sitesurveyctrl.last_tx_pkts = 0;
  73. pmlmepriv->sitesurveyctrl.traffic_busy = false;
  74. /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
  75. r8712_init_mlme_timer(padapter);
  76. return _SUCCESS;
  77. }
  78. struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
  79. {
  80. unsigned long irqL;
  81. struct wlan_network *pnetwork;
  82. struct __queue *free_queue = &pmlmepriv->free_bss_pool;
  83. struct list_head *plist = NULL;
  84. if (list_empty(&free_queue->queue))
  85. return NULL;
  86. spin_lock_irqsave(&free_queue->lock, irqL);
  87. plist = free_queue->queue.next;
  88. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  89. list_del_init(&pnetwork->list);
  90. pnetwork->last_scanned = jiffies;
  91. pmlmepriv->num_of_scanned++;
  92. spin_unlock_irqrestore(&free_queue->lock, irqL);
  93. return pnetwork;
  94. }
  95. static void _free_network(struct mlme_priv *pmlmepriv,
  96. struct wlan_network *pnetwork)
  97. {
  98. u32 curr_time, delta_time;
  99. unsigned long irqL;
  100. struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
  101. if (pnetwork == NULL)
  102. return;
  103. if (pnetwork->fixed)
  104. return;
  105. curr_time = jiffies;
  106. delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ;
  107. if (delta_time < SCANQUEUE_LIFETIME)
  108. return;
  109. spin_lock_irqsave(&free_queue->lock, irqL);
  110. list_del_init(&pnetwork->list);
  111. list_add_tail(&pnetwork->list, &free_queue->queue);
  112. pmlmepriv->num_of_scanned--;
  113. spin_unlock_irqrestore(&free_queue->lock, irqL);
  114. }
  115. static void _free_network_nolock(struct mlme_priv *pmlmepriv,
  116. struct wlan_network *pnetwork)
  117. {
  118. struct __queue *free_queue = &pmlmepriv->free_bss_pool;
  119. if (pnetwork == NULL)
  120. return;
  121. if (pnetwork->fixed)
  122. return;
  123. list_del_init(&pnetwork->list);
  124. list_add_tail(&pnetwork->list, &free_queue->queue);
  125. pmlmepriv->num_of_scanned--;
  126. }
  127. /*
  128. return the wlan_network with the matching addr
  129. Shall be called under atomic context...
  130. to avoid possible racing condition...
  131. */
  132. static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue,
  133. u8 *addr)
  134. {
  135. unsigned long irqL;
  136. struct list_head *phead, *plist;
  137. struct wlan_network *pnetwork = NULL;
  138. if (is_zero_ether_addr(addr))
  139. return NULL;
  140. spin_lock_irqsave(&scanned_queue->lock, irqL);
  141. phead = &scanned_queue->queue;
  142. plist = phead->next;
  143. while (plist != phead) {
  144. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  145. plist = plist->next;
  146. if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
  147. break;
  148. }
  149. spin_unlock_irqrestore(&scanned_queue->lock, irqL);
  150. return pnetwork;
  151. }
  152. static void _free_network_queue(struct _adapter *padapter)
  153. {
  154. unsigned long irqL;
  155. struct list_head *phead, *plist;
  156. struct wlan_network *pnetwork;
  157. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  158. struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
  159. spin_lock_irqsave(&scanned_queue->lock, irqL);
  160. phead = &scanned_queue->queue;
  161. plist = phead->next;
  162. while (!end_of_queue_search(phead, plist)) {
  163. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  164. plist = plist->next;
  165. _free_network(pmlmepriv, pnetwork);
  166. }
  167. spin_unlock_irqrestore(&scanned_queue->lock, irqL);
  168. }
  169. sint r8712_if_up(struct _adapter *padapter)
  170. {
  171. sint res;
  172. if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
  173. !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
  174. res = false;
  175. } else {
  176. res = true;
  177. }
  178. return res;
  179. }
  180. void r8712_generate_random_ibss(u8 *pibss)
  181. {
  182. u32 curtime = jiffies;
  183. pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */
  184. pibss[1] = 0x11;
  185. pibss[2] = 0x87;
  186. pibss[3] = (u8)(curtime & 0xff);
  187. pibss[4] = (u8)((curtime >> 8) & 0xff);
  188. pibss[5] = (u8)((curtime >> 16) & 0xff);
  189. }
  190. uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
  191. {
  192. return sizeof(*bss) + bss->IELength - MAX_IE_SZ;
  193. }
  194. u8 *r8712_get_capability_from_ie(u8 *ie)
  195. {
  196. return ie + 8 + 2;
  197. }
  198. int r8712_init_mlme_priv(struct _adapter *padapter)
  199. {
  200. return _init_mlme_priv(padapter);
  201. }
  202. void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv)
  203. {
  204. kfree(pmlmepriv->free_bss_buf);
  205. }
  206. static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv)
  207. {
  208. return _r8712_alloc_network(pmlmepriv);
  209. }
  210. static void free_network_nolock(struct mlme_priv *pmlmepriv,
  211. struct wlan_network *pnetwork)
  212. {
  213. _free_network_nolock(pmlmepriv, pnetwork);
  214. }
  215. void r8712_free_network_queue(struct _adapter *dev)
  216. {
  217. _free_network_queue(dev);
  218. }
  219. /*
  220. return the wlan_network with the matching addr
  221. Shall be called under atomic context...
  222. to avoid possible racing condition...
  223. */
  224. static struct wlan_network *r8712_find_network(struct __queue *scanned_queue,
  225. u8 *addr)
  226. {
  227. struct wlan_network *pnetwork = _r8712_find_network(scanned_queue,
  228. addr);
  229. return pnetwork;
  230. }
  231. int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork)
  232. {
  233. int ret = true;
  234. struct security_priv *psecuritypriv = &adapter->securitypriv;
  235. if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
  236. (pnetwork->network.Privacy == 0))
  237. ret = false;
  238. else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) &&
  239. (pnetwork->network.Privacy == 1))
  240. ret = false;
  241. else
  242. ret = true;
  243. return ret;
  244. }
  245. static int is_same_network(struct wlan_bssid_ex *src,
  246. struct wlan_bssid_ex *dst)
  247. {
  248. u16 s_cap, d_cap;
  249. memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2);
  250. memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2);
  251. return (src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
  252. (src->Configuration.DSConfig ==
  253. dst->Configuration.DSConfig) &&
  254. ((!memcmp(src->MacAddress, dst->MacAddress,
  255. ETH_ALEN))) &&
  256. ((!memcmp(src->Ssid.Ssid,
  257. dst->Ssid.Ssid,
  258. src->Ssid.SsidLength))) &&
  259. ((s_cap & WLAN_CAPABILITY_IBSS) ==
  260. (d_cap & WLAN_CAPABILITY_IBSS)) &&
  261. ((s_cap & WLAN_CAPABILITY_BSS) ==
  262. (d_cap & WLAN_CAPABILITY_BSS));
  263. }
  264. struct wlan_network *r8712_get_oldest_wlan_network(
  265. struct __queue *scanned_queue)
  266. {
  267. struct list_head *plist, *phead;
  268. struct wlan_network *pwlan = NULL;
  269. struct wlan_network *oldest = NULL;
  270. phead = &scanned_queue->queue;
  271. plist = phead->next;
  272. while (1) {
  273. if (end_of_queue_search(phead, plist) == true)
  274. break;
  275. pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
  276. if (pwlan->fixed != true) {
  277. if (oldest == NULL ||
  278. time_after((unsigned long)oldest->last_scanned,
  279. (unsigned long)pwlan->last_scanned))
  280. oldest = pwlan;
  281. }
  282. plist = plist->next;
  283. }
  284. return oldest;
  285. }
  286. static void update_network(struct wlan_bssid_ex *dst,
  287. struct wlan_bssid_ex *src,
  288. struct _adapter *padapter)
  289. {
  290. u32 last_evm = 0, tmpVal;
  291. if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
  292. is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
  293. if (padapter->recvpriv.signal_qual_data.total_num++ >=
  294. PHY_LINKQUALITY_SLID_WIN_MAX) {
  295. padapter->recvpriv.signal_qual_data.total_num =
  296. PHY_LINKQUALITY_SLID_WIN_MAX;
  297. last_evm = padapter->recvpriv.signal_qual_data.
  298. elements[padapter->recvpriv.
  299. signal_qual_data.index];
  300. padapter->recvpriv.signal_qual_data.total_val -=
  301. last_evm;
  302. }
  303. padapter->recvpriv.signal_qual_data.total_val += src->Rssi;
  304. padapter->recvpriv.signal_qual_data.
  305. elements[padapter->recvpriv.signal_qual_data.
  306. index++] = src->Rssi;
  307. if (padapter->recvpriv.signal_qual_data.index >=
  308. PHY_LINKQUALITY_SLID_WIN_MAX)
  309. padapter->recvpriv.signal_qual_data.index = 0;
  310. /* <1> Showed on UI for user, in percentage. */
  311. tmpVal = padapter->recvpriv.signal_qual_data.total_val /
  312. padapter->recvpriv.signal_qual_data.total_num;
  313. padapter->recvpriv.signal = (u8)tmpVal;
  314. src->Rssi = padapter->recvpriv.signal;
  315. } else {
  316. src->Rssi = (src->Rssi + dst->Rssi) / 2;
  317. }
  318. memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src));
  319. }
  320. static void update_current_network(struct _adapter *adapter,
  321. struct wlan_bssid_ex *pnetwork)
  322. {
  323. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  324. if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) {
  325. update_network(&(pmlmepriv->cur_network.network),
  326. pnetwork, adapter);
  327. r8712_update_protection(adapter,
  328. (pmlmepriv->cur_network.network.IEs) +
  329. sizeof(struct NDIS_802_11_FIXED_IEs),
  330. pmlmepriv->cur_network.network.IELength);
  331. }
  332. }
  333. /*
  334. Caller must hold pmlmepriv->lock first.
  335. */
  336. static void update_scanned_network(struct _adapter *adapter,
  337. struct wlan_bssid_ex *target)
  338. {
  339. struct list_head *plist, *phead;
  340. u32 bssid_ex_sz;
  341. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  342. struct __queue *queue = &pmlmepriv->scanned_queue;
  343. struct wlan_network *pnetwork = NULL;
  344. struct wlan_network *oldest = NULL;
  345. phead = &queue->queue;
  346. plist = phead->next;
  347. while (1) {
  348. if (end_of_queue_search(phead, plist))
  349. break;
  350. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  351. if (is_same_network(&pnetwork->network, target))
  352. break;
  353. if ((oldest == ((struct wlan_network *)0)) ||
  354. time_after((unsigned long)oldest->last_scanned,
  355. (unsigned long)pnetwork->last_scanned))
  356. oldest = pnetwork;
  357. plist = plist->next;
  358. }
  359. /* If we didn't find a match, then get a new network slot to initialize
  360. * with this beacon's information */
  361. if (end_of_queue_search(phead, plist)) {
  362. if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
  363. /* If there are no more slots, expire the oldest */
  364. pnetwork = oldest;
  365. target->Rssi = (pnetwork->network.Rssi +
  366. target->Rssi) / 2;
  367. memcpy(&pnetwork->network, target,
  368. r8712_get_wlan_bssid_ex_sz(target));
  369. pnetwork->last_scanned = jiffies;
  370. } else {
  371. /* Otherwise just pull from the free list */
  372. /* update scan_time */
  373. pnetwork = alloc_network(pmlmepriv);
  374. if (pnetwork == NULL)
  375. return;
  376. bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target);
  377. target->Length = bssid_ex_sz;
  378. memcpy(&pnetwork->network, target, bssid_ex_sz);
  379. list_add_tail(&pnetwork->list, &queue->queue);
  380. }
  381. } else {
  382. /* we have an entry and we are going to update it. But
  383. * this entry may be already expired. In this case we
  384. * do the same as we found a new net and call the new_net
  385. * handler
  386. */
  387. update_network(&pnetwork->network, target, adapter);
  388. pnetwork->last_scanned = jiffies;
  389. }
  390. }
  391. static void rtl8711_add_network(struct _adapter *adapter,
  392. struct wlan_bssid_ex *pnetwork)
  393. {
  394. unsigned long irqL;
  395. struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv);
  396. struct __queue *queue = &pmlmepriv->scanned_queue;
  397. spin_lock_irqsave(&queue->lock, irqL);
  398. update_current_network(adapter, pnetwork);
  399. update_scanned_network(adapter, pnetwork);
  400. spin_unlock_irqrestore(&queue->lock, irqL);
  401. }
  402. /*select the desired network based on the capability of the (i)bss.
  403. * check items: (1) security
  404. * (2) network_type
  405. * (3) WMM
  406. * (4) HT
  407. * (5) others
  408. */
  409. static int is_desired_network(struct _adapter *adapter,
  410. struct wlan_network *pnetwork)
  411. {
  412. u8 wps_ie[512];
  413. uint wps_ielen;
  414. int bselected = true;
  415. struct security_priv *psecuritypriv = &adapter->securitypriv;
  416. if (psecuritypriv->wps_phase) {
  417. if (r8712_get_wps_ie(pnetwork->network.IEs,
  418. pnetwork->network.IELength, wps_ie,
  419. &wps_ielen))
  420. return true;
  421. else
  422. return false;
  423. }
  424. if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
  425. (pnetwork->network.Privacy == 0))
  426. bselected = false;
  427. if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) {
  428. if (pnetwork->network.InfrastructureMode !=
  429. adapter->mlmepriv.cur_network.network.
  430. InfrastructureMode)
  431. bselected = false;
  432. }
  433. return bselected;
  434. }
  435. /* TODO: Perry : For Power Management */
  436. void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
  437. {
  438. }
  439. void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf)
  440. {
  441. unsigned long flags;
  442. u32 len;
  443. struct wlan_bssid_ex *pnetwork;
  444. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  445. pnetwork = (struct wlan_bssid_ex *)pbuf;
  446. #ifdef __BIG_ENDIAN
  447. /* endian_convert */
  448. pnetwork->Length = le32_to_cpu(pnetwork->Length);
  449. pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
  450. pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
  451. pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
  452. pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
  453. pnetwork->Configuration.ATIMWindow =
  454. le32_to_cpu(pnetwork->Configuration.ATIMWindow);
  455. pnetwork->Configuration.BeaconPeriod =
  456. le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
  457. pnetwork->Configuration.DSConfig =
  458. le32_to_cpu(pnetwork->Configuration.DSConfig);
  459. pnetwork->Configuration.FHConfig.DwellTime =
  460. le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
  461. pnetwork->Configuration.FHConfig.HopPattern =
  462. le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
  463. pnetwork->Configuration.FHConfig.HopSet =
  464. le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
  465. pnetwork->Configuration.FHConfig.Length =
  466. le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
  467. pnetwork->Configuration.Length =
  468. le32_to_cpu(pnetwork->Configuration.Length);
  469. pnetwork->InfrastructureMode =
  470. le32_to_cpu(pnetwork->InfrastructureMode);
  471. pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
  472. #endif
  473. len = r8712_get_wlan_bssid_ex_sz(pnetwork);
  474. if (len > sizeof(struct wlan_bssid_ex))
  475. return;
  476. spin_lock_irqsave(&pmlmepriv->lock2, flags);
  477. /* update IBSS_network 's timestamp */
  478. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
  479. if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress),
  480. pnetwork->MacAddress, ETH_ALEN)) {
  481. struct wlan_network *ibss_wlan = NULL;
  482. memcpy(pmlmepriv->cur_network.network.IEs,
  483. pnetwork->IEs, 8);
  484. ibss_wlan = r8712_find_network(
  485. &pmlmepriv->scanned_queue,
  486. pnetwork->MacAddress);
  487. if (ibss_wlan) {
  488. memcpy(ibss_wlan->network.IEs,
  489. pnetwork->IEs, 8);
  490. goto exit;
  491. }
  492. }
  493. }
  494. /* lock pmlmepriv->lock when you accessing network_q */
  495. if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
  496. if (pnetwork->Ssid.Ssid[0] != 0) {
  497. rtl8711_add_network(adapter, pnetwork);
  498. } else {
  499. pnetwork->Ssid.SsidLength = 8;
  500. memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8);
  501. rtl8711_add_network(adapter, pnetwork);
  502. }
  503. }
  504. exit:
  505. spin_unlock_irqrestore(&pmlmepriv->lock2, flags);
  506. }
  507. void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf)
  508. {
  509. unsigned long irqL;
  510. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  511. spin_lock_irqsave(&pmlmepriv->lock, irqL);
  512. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
  513. del_timer(&pmlmepriv->scan_to_timer);
  514. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  515. }
  516. if (pmlmepriv->to_join) {
  517. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  518. if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
  519. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  520. if (r8712_select_and_join_from_scan(pmlmepriv)
  521. == _SUCCESS)
  522. mod_timer(&pmlmepriv->assoc_timer, jiffies +
  523. msecs_to_jiffies(MAX_JOIN_TIMEOUT));
  524. else {
  525. struct wlan_bssid_ex *pdev_network =
  526. &(adapter->registrypriv.dev_network);
  527. u8 *pibss =
  528. adapter->registrypriv.
  529. dev_network.MacAddress;
  530. pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;
  531. memcpy(&pdev_network->Ssid,
  532. &pmlmepriv->assoc_ssid,
  533. sizeof(struct
  534. ndis_802_11_ssid));
  535. r8712_update_registrypriv_dev_network
  536. (adapter);
  537. r8712_generate_random_ibss(pibss);
  538. pmlmepriv->fw_state =
  539. WIFI_ADHOC_MASTER_STATE;
  540. pmlmepriv->to_join = false;
  541. }
  542. }
  543. } else {
  544. pmlmepriv->to_join = false;
  545. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  546. if (r8712_select_and_join_from_scan(pmlmepriv) ==
  547. _SUCCESS)
  548. mod_timer(&pmlmepriv->assoc_timer, jiffies +
  549. msecs_to_jiffies(MAX_JOIN_TIMEOUT));
  550. else
  551. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  552. }
  553. }
  554. spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
  555. }
  556. /*
  557. *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock
  558. */
  559. void r8712_free_assoc_resources(struct _adapter *adapter)
  560. {
  561. unsigned long irqL;
  562. struct wlan_network *pwlan = NULL;
  563. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  564. struct sta_priv *pstapriv = &adapter->stapriv;
  565. struct wlan_network *tgt_network = &pmlmepriv->cur_network;
  566. pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
  567. tgt_network->network.MacAddress);
  568. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
  569. struct sta_info *psta;
  570. psta = r8712_get_stainfo(&adapter->stapriv,
  571. tgt_network->network.MacAddress);
  572. spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
  573. r8712_free_stainfo(adapter, psta);
  574. spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
  575. }
  576. if (check_fwstate(pmlmepriv,
  577. WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
  578. r8712_free_all_stainfo(adapter);
  579. if (pwlan)
  580. pwlan->fixed = false;
  581. if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) &&
  582. (adapter->stapriv.asoc_sta_count == 1)))
  583. free_network_nolock(pmlmepriv, pwlan);
  584. }
  585. /*
  586. *r8712_indicate_connect: the caller has to lock pmlmepriv->lock
  587. */
  588. void r8712_indicate_connect(struct _adapter *padapter)
  589. {
  590. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  591. pmlmepriv->to_join = false;
  592. set_fwstate(pmlmepriv, _FW_LINKED);
  593. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK);
  594. r8712_os_indicate_connect(padapter);
  595. if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE)
  596. mod_timer(&pmlmepriv->dhcp_timer,
  597. jiffies + msecs_to_jiffies(60000));
  598. }
  599. /*
  600. *r8712_ind_disconnect: the caller has to lock pmlmepriv->lock
  601. */
  602. void r8712_ind_disconnect(struct _adapter *padapter)
  603. {
  604. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  605. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  606. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  607. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
  608. r8712_os_indicate_disconnect(padapter);
  609. }
  610. if (padapter->pwrctrlpriv.pwr_mode !=
  611. padapter->registrypriv.power_mgnt) {
  612. del_timer(&pmlmepriv->dhcp_timer);
  613. r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
  614. padapter->registrypriv.smart_ps);
  615. }
  616. }
  617. /*Notes:
  618. *pnetwork : returns from r8712_joinbss_event_callback
  619. *ptarget_wlan: found from scanned_queue
  620. *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if
  621. * "ptarget_sta" & "ptarget_wlan" exist.
  622. *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check
  623. * if "ptarget_wlan" exist.
  624. *if join_res > 0, update "cur_network->network" from
  625. * "pnetwork->network" if (ptarget_wlan !=NULL).
  626. */
  627. void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf)
  628. {
  629. unsigned long irqL = 0, irqL2;
  630. struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
  631. struct sta_priv *pstapriv = &adapter->stapriv;
  632. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  633. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  634. struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
  635. unsigned int the_same_macaddr = false;
  636. struct wlan_network *pnetwork;
  637. if (sizeof(struct list_head) == 4 * sizeof(u32)) {
  638. pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC);
  639. if (!pnetwork)
  640. return;
  641. memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8,
  642. sizeof(struct wlan_network) - 16);
  643. } else {
  644. pnetwork = (struct wlan_network *)pbuf;
  645. }
  646. #ifdef __BIG_ENDIAN
  647. /* endian_convert */
  648. pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
  649. pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
  650. pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
  651. pnetwork->network.Ssid.SsidLength =
  652. le32_to_cpu(pnetwork->network.Ssid.SsidLength);
  653. pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
  654. pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
  655. pnetwork->network.NetworkTypeInUse =
  656. le32_to_cpu(pnetwork->network.NetworkTypeInUse);
  657. pnetwork->network.Configuration.ATIMWindow =
  658. le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
  659. pnetwork->network.Configuration.BeaconPeriod =
  660. le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
  661. pnetwork->network.Configuration.DSConfig =
  662. le32_to_cpu(pnetwork->network.Configuration.DSConfig);
  663. pnetwork->network.Configuration.FHConfig.DwellTime =
  664. le32_to_cpu(pnetwork->network.Configuration.FHConfig.
  665. DwellTime);
  666. pnetwork->network.Configuration.FHConfig.HopPattern =
  667. le32_to_cpu(pnetwork->network.Configuration.
  668. FHConfig.HopPattern);
  669. pnetwork->network.Configuration.FHConfig.HopSet =
  670. le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
  671. pnetwork->network.Configuration.FHConfig.Length =
  672. le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
  673. pnetwork->network.Configuration.Length =
  674. le32_to_cpu(pnetwork->network.Configuration.Length);
  675. pnetwork->network.InfrastructureMode =
  676. le32_to_cpu(pnetwork->network.InfrastructureMode);
  677. pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
  678. #endif
  679. the_same_macaddr = !memcmp(pnetwork->network.MacAddress,
  680. cur_network->network.MacAddress, ETH_ALEN);
  681. pnetwork->network.Length =
  682. r8712_get_wlan_bssid_ex_sz(&pnetwork->network);
  683. spin_lock_irqsave(&pmlmepriv->lock, irqL);
  684. if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
  685. goto ignore_joinbss_callback;
  686. if (pnetwork->join_res > 0) {
  687. if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
  688. /*s1. find ptarget_wlan*/
  689. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  690. if (the_same_macaddr) {
  691. ptarget_wlan =
  692. r8712_find_network(&pmlmepriv->
  693. scanned_queue,
  694. cur_network->network.MacAddress);
  695. } else {
  696. pcur_wlan =
  697. r8712_find_network(&pmlmepriv->
  698. scanned_queue,
  699. cur_network->network.MacAddress);
  700. pcur_wlan->fixed = false;
  701. pcur_sta = r8712_get_stainfo(pstapriv,
  702. cur_network->network.MacAddress);
  703. spin_lock_irqsave(&pstapriv->
  704. sta_hash_lock, irqL2);
  705. r8712_free_stainfo(adapter, pcur_sta);
  706. spin_unlock_irqrestore(&(pstapriv->
  707. sta_hash_lock), irqL2);
  708. ptarget_wlan =
  709. r8712_find_network(&pmlmepriv->
  710. scanned_queue,
  711. pnetwork->network.
  712. MacAddress);
  713. if (ptarget_wlan)
  714. ptarget_wlan->fixed = true;
  715. }
  716. } else {
  717. ptarget_wlan = r8712_find_network(&pmlmepriv->
  718. scanned_queue,
  719. pnetwork->network.MacAddress);
  720. if (ptarget_wlan)
  721. ptarget_wlan->fixed = true;
  722. }
  723. if (ptarget_wlan == NULL) {
  724. if (check_fwstate(pmlmepriv,
  725. _FW_UNDER_LINKING))
  726. pmlmepriv->fw_state ^=
  727. _FW_UNDER_LINKING;
  728. goto ignore_joinbss_callback;
  729. }
  730. /*s2. find ptarget_sta & update ptarget_sta*/
  731. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  732. if (the_same_macaddr) {
  733. ptarget_sta =
  734. r8712_get_stainfo(pstapriv,
  735. pnetwork->network.MacAddress);
  736. if (ptarget_sta == NULL)
  737. ptarget_sta =
  738. r8712_alloc_stainfo(pstapriv,
  739. pnetwork->network.MacAddress);
  740. } else {
  741. ptarget_sta =
  742. r8712_alloc_stainfo(pstapriv,
  743. pnetwork->network.MacAddress);
  744. }
  745. if (ptarget_sta) /*update ptarget_sta*/ {
  746. ptarget_sta->aid = pnetwork->join_res;
  747. ptarget_sta->qos_option = 1;
  748. ptarget_sta->mac_id = 5;
  749. if (adapter->securitypriv.
  750. AuthAlgrthm == 2) {
  751. adapter->securitypriv.
  752. binstallGrpkey =
  753. false;
  754. adapter->securitypriv.
  755. busetkipkey =
  756. false;
  757. adapter->securitypriv.
  758. bgrpkey_handshake =
  759. false;
  760. ptarget_sta->ieee8021x_blocked
  761. = true;
  762. ptarget_sta->XPrivacy =
  763. adapter->securitypriv.
  764. PrivacyAlgrthm;
  765. memset((u8 *)&ptarget_sta->
  766. x_UncstKey,
  767. 0,
  768. sizeof(union Keytype));
  769. memset((u8 *)&ptarget_sta->
  770. tkiprxmickey,
  771. 0,
  772. sizeof(union Keytype));
  773. memset((u8 *)&ptarget_sta->
  774. tkiptxmickey,
  775. 0,
  776. sizeof(union Keytype));
  777. memset((u8 *)&ptarget_sta->
  778. txpn, 0,
  779. sizeof(union pn48));
  780. memset((u8 *)&ptarget_sta->
  781. rxpn, 0,
  782. sizeof(union pn48));
  783. }
  784. } else {
  785. if (check_fwstate(pmlmepriv,
  786. _FW_UNDER_LINKING))
  787. pmlmepriv->fw_state ^=
  788. _FW_UNDER_LINKING;
  789. goto ignore_joinbss_callback;
  790. }
  791. }
  792. /*s3. update cur_network & indicate connect*/
  793. memcpy(&cur_network->network, &pnetwork->network,
  794. pnetwork->network.Length);
  795. cur_network->aid = pnetwork->join_res;
  796. /*update fw_state will clr _FW_UNDER_LINKING*/
  797. switch (pnetwork->network.InfrastructureMode) {
  798. case Ndis802_11Infrastructure:
  799. pmlmepriv->fw_state = WIFI_STATION_STATE;
  800. break;
  801. case Ndis802_11IBSS:
  802. pmlmepriv->fw_state = WIFI_ADHOC_STATE;
  803. break;
  804. default:
  805. pmlmepriv->fw_state = WIFI_NULL_STATE;
  806. break;
  807. }
  808. r8712_update_protection(adapter,
  809. (cur_network->network.IEs) +
  810. sizeof(struct NDIS_802_11_FIXED_IEs),
  811. (cur_network->network.IELength));
  812. /*TODO: update HT_Capability*/
  813. update_ht_cap(adapter, cur_network->network.IEs,
  814. cur_network->network.IELength);
  815. /*indicate connect*/
  816. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  817. r8712_indicate_connect(adapter);
  818. del_timer(&pmlmepriv->assoc_timer);
  819. } else {
  820. goto ignore_joinbss_callback;
  821. }
  822. } else {
  823. if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
  824. mod_timer(&pmlmepriv->assoc_timer,
  825. jiffies + msecs_to_jiffies(1));
  826. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  827. }
  828. }
  829. ignore_joinbss_callback:
  830. spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
  831. if (sizeof(struct list_head) == 4 * sizeof(u32))
  832. kfree(pnetwork);
  833. }
  834. void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
  835. {
  836. unsigned long irqL;
  837. struct sta_info *psta;
  838. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  839. struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
  840. /* to do: */
  841. if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr))
  842. return;
  843. psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
  844. if (psta != NULL) {
  845. /*the sta have been in sta_info_queue => do nothing
  846. *(between drv has received this event before and
  847. * fw have not yet to set key to CAM_ENTRY) */
  848. return;
  849. }
  850. psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
  851. if (psta == NULL)
  852. return;
  853. /* to do : init sta_info variable */
  854. psta->qos_option = 0;
  855. psta->mac_id = le32_to_cpu((uint)pstassoc->cam_id);
  856. /* psta->aid = (uint)pstassoc->cam_id; */
  857. if (adapter->securitypriv.AuthAlgrthm == 2)
  858. psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm;
  859. psta->ieee8021x_blocked = false;
  860. spin_lock_irqsave(&pmlmepriv->lock, irqL);
  861. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
  862. check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  863. if (adapter->stapriv.asoc_sta_count == 2) {
  864. /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
  865. r8712_indicate_connect(adapter);
  866. }
  867. }
  868. spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
  869. }
  870. void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf)
  871. {
  872. unsigned long irqL, irqL2;
  873. struct sta_info *psta;
  874. struct wlan_network *pwlan = NULL;
  875. struct wlan_bssid_ex *pdev_network = NULL;
  876. u8 *pibss = NULL;
  877. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  878. struct stadel_event *pstadel = (struct stadel_event *)pbuf;
  879. struct sta_priv *pstapriv = &adapter->stapriv;
  880. struct wlan_network *tgt_network = &pmlmepriv->cur_network;
  881. spin_lock_irqsave(&pmlmepriv->lock, irqL2);
  882. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  883. r8712_ind_disconnect(adapter);
  884. r8712_free_assoc_resources(adapter);
  885. }
  886. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE |
  887. WIFI_ADHOC_STATE)) {
  888. psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr);
  889. spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
  890. r8712_free_stainfo(adapter, psta);
  891. spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
  892. if (adapter->stapriv.asoc_sta_count == 1) {
  893. /*a sta + bc/mc_stainfo (not Ibss_stainfo) */
  894. pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
  895. tgt_network->network.MacAddress);
  896. if (pwlan) {
  897. pwlan->fixed = false;
  898. free_network_nolock(pmlmepriv, pwlan);
  899. }
  900. /*re-create ibss*/
  901. pdev_network = &(adapter->registrypriv.dev_network);
  902. pibss = adapter->registrypriv.dev_network.MacAddress;
  903. memcpy(pdev_network, &tgt_network->network,
  904. r8712_get_wlan_bssid_ex_sz(&tgt_network->
  905. network));
  906. memcpy(&pdev_network->Ssid,
  907. &pmlmepriv->assoc_ssid,
  908. sizeof(struct ndis_802_11_ssid));
  909. r8712_update_registrypriv_dev_network(adapter);
  910. r8712_generate_random_ibss(pibss);
  911. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
  912. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
  913. set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  914. }
  915. }
  916. }
  917. spin_unlock_irqrestore(&pmlmepriv->lock, irqL2);
  918. }
  919. void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf)
  920. {
  921. struct reportpwrstate_parm *preportpwrstate =
  922. (struct reportpwrstate_parm *)pbuf;
  923. preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80);
  924. r8712_cpwm_int_hdl(adapter, preportpwrstate);
  925. }
  926. /* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send
  927. * the ADDBA req frame with start seq control = 0 to wifi client after
  928. * the WPA handshake and the seqence number of following data packet
  929. * will be 0. In this case, the Rx reorder sequence is not longer than 0
  930. * and the WiFi client will drop the data with seq number 0.
  931. * So, the 8712 firmware has to inform driver with receiving the
  932. * ADDBA-Req frame so that the driver can reset the
  933. * sequence value of Rx reorder control.
  934. */
  935. void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf)
  936. {
  937. struct ADDBA_Req_Report_parm *pAddbareq_pram =
  938. (struct ADDBA_Req_Report_parm *)pbuf;
  939. struct sta_info *psta;
  940. struct sta_priv *pstapriv = &adapter->stapriv;
  941. struct recv_reorder_ctrl *precvreorder_ctrl = NULL;
  942. psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress);
  943. if (psta) {
  944. precvreorder_ctrl =
  945. &psta->recvreorder_ctrl[pAddbareq_pram->tid];
  946. /* set the indicate_seq to 0xffff so that the rx reorder
  947. * can store any following data packet.
  948. */
  949. precvreorder_ctrl->indicate_seq = 0xffff;
  950. }
  951. }
  952. void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf)
  953. {
  954. if (!adapter->securitypriv.wps_hw_pbc_pressed)
  955. adapter->securitypriv.wps_hw_pbc_pressed = true;
  956. }
  957. void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter)
  958. {
  959. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  960. struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl;
  961. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  962. u64 current_tx_pkts;
  963. uint current_rx_pkts;
  964. current_tx_pkts = (adapter->xmitpriv.tx_pkts) -
  965. (psitesurveyctrl->last_tx_pkts);
  966. current_rx_pkts = (adapter->recvpriv.rx_pkts) -
  967. (psitesurveyctrl->last_rx_pkts);
  968. psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts;
  969. psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts;
  970. if ((current_tx_pkts > pregistrypriv->busy_thresh) ||
  971. (current_rx_pkts > pregistrypriv->busy_thresh))
  972. psitesurveyctrl->traffic_busy = true;
  973. else
  974. psitesurveyctrl->traffic_busy = false;
  975. }
  976. void _r8712_join_timeout_handler(struct _adapter *adapter)
  977. {
  978. unsigned long irqL;
  979. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  980. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  981. return;
  982. spin_lock_irqsave(&pmlmepriv->lock, irqL);
  983. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  984. pmlmepriv->to_join = false;
  985. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  986. r8712_os_indicate_disconnect(adapter);
  987. _clr_fwstate_(pmlmepriv, _FW_LINKED);
  988. }
  989. if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) {
  990. r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
  991. adapter->registrypriv.smart_ps);
  992. }
  993. spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
  994. }
  995. void r8712_scan_timeout_handler (struct _adapter *adapter)
  996. {
  997. unsigned long irqL;
  998. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  999. spin_lock_irqsave(&pmlmepriv->lock, irqL);
  1000. _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
  1001. pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */
  1002. spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
  1003. }
  1004. void _r8712_dhcp_timeout_handler (struct _adapter *adapter)
  1005. {
  1006. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  1007. return;
  1008. if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt)
  1009. r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
  1010. adapter->registrypriv.smart_ps);
  1011. }
  1012. void _r8712_wdg_timeout_handler(struct _adapter *adapter)
  1013. {
  1014. r8712_wdg_wk_cmd(adapter);
  1015. }
  1016. int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
  1017. {
  1018. struct list_head *phead;
  1019. unsigned char *dst_ssid, *src_ssid;
  1020. struct _adapter *adapter;
  1021. struct __queue *queue = NULL;
  1022. struct wlan_network *pnetwork = NULL;
  1023. struct wlan_network *pnetwork_max_rssi = NULL;
  1024. adapter = (struct _adapter *)pmlmepriv->nic_hdl;
  1025. queue = &pmlmepriv->scanned_queue;
  1026. phead = &queue->queue;
  1027. pmlmepriv->pscanned = phead->next;
  1028. while (1) {
  1029. if (end_of_queue_search(phead, pmlmepriv->pscanned)) {
  1030. if ((pmlmepriv->assoc_by_rssi) &&
  1031. (pnetwork_max_rssi != NULL)) {
  1032. pnetwork = pnetwork_max_rssi;
  1033. goto ask_for_joinbss;
  1034. }
  1035. return _FAIL;
  1036. }
  1037. pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
  1038. struct wlan_network, list);
  1039. if (pnetwork == NULL)
  1040. return _FAIL;
  1041. pmlmepriv->pscanned = pmlmepriv->pscanned->next;
  1042. if (pmlmepriv->assoc_by_bssid) {
  1043. dst_ssid = pnetwork->network.MacAddress;
  1044. src_ssid = pmlmepriv->assoc_bssid;
  1045. if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) {
  1046. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  1047. if (is_same_network(&pmlmepriv->
  1048. cur_network.network,
  1049. &pnetwork->network)) {
  1050. _clr_fwstate_(pmlmepriv,
  1051. _FW_UNDER_LINKING);
  1052. /*r8712_indicate_connect again*/
  1053. r8712_indicate_connect(adapter);
  1054. return 2;
  1055. }
  1056. r8712_disassoc_cmd(adapter);
  1057. r8712_ind_disconnect(adapter);
  1058. r8712_free_assoc_resources(adapter);
  1059. }
  1060. goto ask_for_joinbss;
  1061. }
  1062. } else if (pmlmepriv->assoc_ssid.SsidLength == 0) {
  1063. goto ask_for_joinbss;
  1064. }
  1065. dst_ssid = pnetwork->network.Ssid.Ssid;
  1066. src_ssid = pmlmepriv->assoc_ssid.Ssid;
  1067. if ((pnetwork->network.Ssid.SsidLength ==
  1068. pmlmepriv->assoc_ssid.SsidLength) &&
  1069. (!memcmp(dst_ssid, src_ssid,
  1070. pmlmepriv->assoc_ssid.SsidLength))) {
  1071. if (pmlmepriv->assoc_by_rssi) {
  1072. /* if the ssid is the same, select the bss
  1073. * which has the max rssi*/
  1074. if (pnetwork_max_rssi) {
  1075. if (pnetwork->network.Rssi >
  1076. pnetwork_max_rssi->network.Rssi)
  1077. pnetwork_max_rssi = pnetwork;
  1078. } else {
  1079. pnetwork_max_rssi = pnetwork;
  1080. }
  1081. } else if (is_desired_network(adapter, pnetwork)) {
  1082. if (check_fwstate(pmlmepriv, _FW_LINKED)) {
  1083. r8712_disassoc_cmd(adapter);
  1084. r8712_free_assoc_resources(adapter);
  1085. }
  1086. goto ask_for_joinbss;
  1087. }
  1088. }
  1089. }
  1090. ask_for_joinbss:
  1091. return r8712_joinbss_cmd(adapter, pnetwork);
  1092. }
  1093. sint r8712_set_auth(struct _adapter *adapter,
  1094. struct security_priv *psecuritypriv)
  1095. {
  1096. struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
  1097. struct cmd_obj *pcmd;
  1098. struct setauth_parm *psetauthparm;
  1099. pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
  1100. if (pcmd == NULL)
  1101. return _FAIL;
  1102. psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC);
  1103. if (psetauthparm == NULL) {
  1104. kfree(pcmd);
  1105. return _FAIL;
  1106. }
  1107. psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm;
  1108. pcmd->cmdcode = _SetAuth_CMD_;
  1109. pcmd->parmbuf = (unsigned char *)psetauthparm;
  1110. pcmd->cmdsz = sizeof(struct setauth_parm);
  1111. pcmd->rsp = NULL;
  1112. pcmd->rspsz = 0;
  1113. INIT_LIST_HEAD(&pcmd->list);
  1114. r8712_enqueue_cmd(pcmdpriv, pcmd);
  1115. return _SUCCESS;
  1116. }
  1117. sint r8712_set_key(struct _adapter *adapter,
  1118. struct security_priv *psecuritypriv,
  1119. sint keyid)
  1120. {
  1121. struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
  1122. struct cmd_obj *pcmd;
  1123. struct setkey_parm *psetkeyparm;
  1124. u8 keylen;
  1125. sint ret = _SUCCESS;
  1126. pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
  1127. if (pcmd == NULL)
  1128. return _FAIL;
  1129. psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC);
  1130. if (psetkeyparm == NULL) {
  1131. ret = _FAIL;
  1132. goto err_free_cmd;
  1133. }
  1134. if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */
  1135. psetkeyparm->algorithm =
  1136. (u8)psecuritypriv->XGrpPrivacy;
  1137. } else { /* WEP */
  1138. psetkeyparm->algorithm =
  1139. (u8)psecuritypriv->PrivacyAlgrthm;
  1140. }
  1141. psetkeyparm->keyid = (u8)keyid;
  1142. switch (psetkeyparm->algorithm) {
  1143. case _WEP40_:
  1144. keylen = 5;
  1145. memcpy(psetkeyparm->key,
  1146. psecuritypriv->DefKey[keyid].skey, keylen);
  1147. break;
  1148. case _WEP104_:
  1149. keylen = 13;
  1150. memcpy(psetkeyparm->key,
  1151. psecuritypriv->DefKey[keyid].skey, keylen);
  1152. break;
  1153. case _TKIP_:
  1154. if (keyid < 1 || keyid > 2) {
  1155. ret = _FAIL;
  1156. goto err_free_parm;
  1157. }
  1158. keylen = 16;
  1159. memcpy(psetkeyparm->key,
  1160. &psecuritypriv->XGrpKey[keyid - 1], keylen);
  1161. psetkeyparm->grpkey = 1;
  1162. break;
  1163. case _AES_:
  1164. if (keyid < 1 || keyid > 2) {
  1165. ret = _FAIL;
  1166. goto err_free_parm;
  1167. }
  1168. keylen = 16;
  1169. memcpy(psetkeyparm->key,
  1170. &psecuritypriv->XGrpKey[keyid - 1], keylen);
  1171. psetkeyparm->grpkey = 1;
  1172. break;
  1173. default:
  1174. ret = _FAIL;
  1175. goto err_free_parm;
  1176. }
  1177. pcmd->cmdcode = _SetKey_CMD_;
  1178. pcmd->parmbuf = (u8 *)psetkeyparm;
  1179. pcmd->cmdsz = (sizeof(struct setkey_parm));
  1180. pcmd->rsp = NULL;
  1181. pcmd->rspsz = 0;
  1182. INIT_LIST_HEAD(&pcmd->list);
  1183. r8712_enqueue_cmd(pcmdpriv, pcmd);
  1184. return ret;
  1185. err_free_parm:
  1186. kfree(psetkeyparm);
  1187. err_free_cmd:
  1188. kfree(pcmd);
  1189. return ret;
  1190. }
  1191. /* adjust IEs for r8712_joinbss_cmd in WMM */
  1192. int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie,
  1193. uint in_len, uint initial_out_len)
  1194. {
  1195. unsigned int ielength = 0;
  1196. unsigned int i, j;
  1197. i = 12; /* after the fixed IE */
  1198. while (i < in_len) {
  1199. ielength = initial_out_len;
  1200. if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
  1201. in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
  1202. in_ie[i + 5] == 0x02 && i + 5 < in_len) {
  1203. /*WMM element ID and OUI*/
  1204. for (j = i; j < i + 9; j++) {
  1205. out_ie[ielength] = in_ie[j];
  1206. ielength++;
  1207. }
  1208. out_ie[initial_out_len + 1] = 0x07;
  1209. out_ie[initial_out_len + 6] = 0x00;
  1210. out_ie[initial_out_len + 8] = 0x00;
  1211. break;
  1212. }
  1213. i += (in_ie[i + 1] + 2); /* to the next IE element */
  1214. }
  1215. return ielength;
  1216. }
  1217. /*
  1218. * Ported from 8185: IsInPreAuthKeyList().
  1219. *
  1220. * Search by BSSID,
  1221. * Return Value:
  1222. * -1 :if there is no pre-auth key in the table
  1223. * >=0 :if there is pre-auth key, and return the entry id
  1224. */
  1225. static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
  1226. {
  1227. struct security_priv *psecuritypriv = &Adapter->securitypriv;
  1228. int i = 0;
  1229. do {
  1230. if (psecuritypriv->PMKIDList[i].bUsed &&
  1231. (!memcmp(psecuritypriv->PMKIDList[i].Bssid,
  1232. bssid, ETH_ALEN)))
  1233. break;
  1234. else
  1235. i++;
  1236. } while (i < NUM_PMKID_CACHE);
  1237. if (i == NUM_PMKID_CACHE) {
  1238. i = -1; /* Could not find. */
  1239. } else {
  1240. ; /* There is one Pre-Authentication Key for the
  1241. * specific BSSID. */
  1242. }
  1243. return i;
  1244. }
  1245. sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
  1246. u8 *out_ie, uint in_len)
  1247. {
  1248. u8 authmode = 0, match;
  1249. u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
  1250. u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
  1251. uint ielength, cnt, remove_cnt;
  1252. int iEntry;
  1253. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1254. struct security_priv *psecuritypriv = &adapter->securitypriv;
  1255. uint ndisauthmode = psecuritypriv->ndisauthtype;
  1256. uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
  1257. if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
  1258. (ndisauthmode == Ndis802_11AuthModeWPAPSK)) {
  1259. authmode = _WPA_IE_ID_;
  1260. uncst_oui[0] = 0x0;
  1261. uncst_oui[1] = 0x50;
  1262. uncst_oui[2] = 0xf2;
  1263. }
  1264. if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
  1265. (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) {
  1266. authmode = _WPA2_IE_ID_;
  1267. uncst_oui[0] = 0x0;
  1268. uncst_oui[1] = 0x0f;
  1269. uncst_oui[2] = 0xac;
  1270. }
  1271. switch (ndissecuritytype) {
  1272. case Ndis802_11Encryption1Enabled:
  1273. case Ndis802_11Encryption1KeyAbsent:
  1274. uncst_oui[3] = 0x1;
  1275. break;
  1276. case Ndis802_11Encryption2Enabled:
  1277. case Ndis802_11Encryption2KeyAbsent:
  1278. uncst_oui[3] = 0x2;
  1279. break;
  1280. case Ndis802_11Encryption3Enabled:
  1281. case Ndis802_11Encryption3KeyAbsent:
  1282. uncst_oui[3] = 0x4;
  1283. break;
  1284. default:
  1285. break;
  1286. }
  1287. /*Search required WPA or WPA2 IE and copy to sec_ie[] */
  1288. cnt = 12;
  1289. match = false;
  1290. while (cnt < in_len) {
  1291. if (in_ie[cnt] == authmode) {
  1292. if ((authmode == _WPA_IE_ID_) &&
  1293. (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
  1294. memcpy(&sec_ie[0], &in_ie[cnt],
  1295. in_ie[cnt + 1] + 2);
  1296. match = true;
  1297. break;
  1298. }
  1299. if (authmode == _WPA2_IE_ID_) {
  1300. memcpy(&sec_ie[0], &in_ie[cnt],
  1301. in_ie[cnt + 1] + 2);
  1302. match = true;
  1303. break;
  1304. }
  1305. if (((authmode == _WPA_IE_ID_) &&
  1306. (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) ||
  1307. (authmode == _WPA2_IE_ID_))
  1308. memcpy(&bkup_ie[0], &in_ie[cnt],
  1309. in_ie[cnt + 1] + 2);
  1310. }
  1311. cnt += in_ie[cnt + 1] + 2; /*get next*/
  1312. }
  1313. /*restruct WPA IE or WPA2 IE in sec_ie[] */
  1314. if (match) {
  1315. if (sec_ie[0] == _WPA_IE_ID_) {
  1316. /* parsing SSN IE to select required encryption
  1317. * algorithm, and set the bc/mc encryption algorithm */
  1318. while (true) {
  1319. /*check wpa_oui tag*/
  1320. if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
  1321. match = false;
  1322. break;
  1323. }
  1324. if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) {
  1325. /*IE Ver error*/
  1326. match = false;
  1327. break;
  1328. }
  1329. if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
  1330. /* get bc/mc encryption type (group
  1331. * key type)*/
  1332. switch (sec_ie[11]) {
  1333. case 0x0: /*none*/
  1334. psecuritypriv->XGrpPrivacy =
  1335. _NO_PRIVACY_;
  1336. break;
  1337. case 0x1: /*WEP_40*/
  1338. psecuritypriv->XGrpPrivacy =
  1339. _WEP40_;
  1340. break;
  1341. case 0x2: /*TKIP*/
  1342. psecuritypriv->XGrpPrivacy =
  1343. _TKIP_;
  1344. break;
  1345. case 0x3: /*AESCCMP*/
  1346. case 0x4:
  1347. psecuritypriv->XGrpPrivacy =
  1348. _AES_;
  1349. break;
  1350. case 0x5: /*WEP_104*/
  1351. psecuritypriv->XGrpPrivacy =
  1352. _WEP104_;
  1353. break;
  1354. }
  1355. } else {
  1356. match = false;
  1357. break;
  1358. }
  1359. if (sec_ie[12] == 0x01) {
  1360. /*check the unicast encryption type*/
  1361. if (memcmp(&sec_ie[14],
  1362. &uncst_oui[0], 4)) {
  1363. match = false;
  1364. break;
  1365. } /*else the uncst_oui is match*/
  1366. } else { /*mixed mode, unicast_enc_type > 1*/
  1367. /*select the uncst_oui and remove
  1368. * the other uncst_oui*/
  1369. cnt = sec_ie[12];
  1370. remove_cnt = (cnt - 1) * 4;
  1371. sec_ie[12] = 0x01;
  1372. memcpy(&sec_ie[14], &uncst_oui[0], 4);
  1373. /*remove the other unicast suit*/
  1374. memcpy(&sec_ie[18],
  1375. &sec_ie[18 + remove_cnt],
  1376. sec_ie[1] - 18 + 2 -
  1377. remove_cnt);
  1378. sec_ie[1] = sec_ie[1] - remove_cnt;
  1379. }
  1380. break;
  1381. }
  1382. }
  1383. if (authmode == _WPA2_IE_ID_) {
  1384. /* parsing RSN IE to select required encryption
  1385. * algorithm, and set the bc/mc encryption algorithm */
  1386. while (true) {
  1387. if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
  1388. /*IE Ver error*/
  1389. match = false;
  1390. break;
  1391. }
  1392. if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) {
  1393. /*get bc/mc encryption type*/
  1394. switch (sec_ie[7]) {
  1395. case 0x1: /*WEP_40*/
  1396. psecuritypriv->XGrpPrivacy =
  1397. _WEP40_;
  1398. break;
  1399. case 0x2: /*TKIP*/
  1400. psecuritypriv->XGrpPrivacy =
  1401. _TKIP_;
  1402. break;
  1403. case 0x4: /*AESWRAP*/
  1404. psecuritypriv->XGrpPrivacy =
  1405. _AES_;
  1406. break;
  1407. case 0x5: /*WEP_104*/
  1408. psecuritypriv->XGrpPrivacy =
  1409. _WEP104_;
  1410. break;
  1411. default: /*one*/
  1412. psecuritypriv->XGrpPrivacy =
  1413. _NO_PRIVACY_;
  1414. break;
  1415. }
  1416. } else {
  1417. match = false;
  1418. break;
  1419. }
  1420. if (sec_ie[8] == 0x01) {
  1421. /*check the unicast encryption type*/
  1422. if (memcmp(&sec_ie[10],
  1423. &uncst_oui[0], 4)) {
  1424. match = false;
  1425. break;
  1426. } /*else the uncst_oui is match*/
  1427. } else { /*mixed mode, unicast_enc_type > 1*/
  1428. /*select the uncst_oui and remove the
  1429. * other uncst_oui*/
  1430. cnt = sec_ie[8];
  1431. remove_cnt = (cnt - 1) * 4;
  1432. sec_ie[8] = 0x01;
  1433. memcpy(&sec_ie[10], &uncst_oui[0], 4);
  1434. /*remove the other unicast suit*/
  1435. memcpy(&sec_ie[14],
  1436. &sec_ie[14 + remove_cnt],
  1437. (sec_ie[1] - 14 + 2 -
  1438. remove_cnt));
  1439. sec_ie[1] = sec_ie[1] - remove_cnt;
  1440. }
  1441. break;
  1442. }
  1443. }
  1444. }
  1445. if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
  1446. /*copy fixed ie*/
  1447. memcpy(out_ie, in_ie, 12);
  1448. ielength = 12;
  1449. /*copy RSN or SSN*/
  1450. if (match) {
  1451. memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2);
  1452. ielength += sec_ie[1] + 2;
  1453. if (authmode == _WPA2_IE_ID_) {
  1454. /*the Pre-Authentication bit should be zero*/
  1455. out_ie[ielength - 1] = 0;
  1456. out_ie[ielength - 2] = 0;
  1457. }
  1458. r8712_report_sec_ie(adapter, authmode, sec_ie);
  1459. }
  1460. } else {
  1461. /*copy fixed ie only*/
  1462. memcpy(out_ie, in_ie, 12);
  1463. ielength = 12;
  1464. if (psecuritypriv->wps_phase) {
  1465. memcpy(out_ie + ielength, psecuritypriv->wps_ie,
  1466. psecuritypriv->wps_ie_len);
  1467. ielength += psecuritypriv->wps_ie_len;
  1468. }
  1469. }
  1470. iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
  1471. if (iEntry < 0)
  1472. return ielength;
  1473. if (authmode == _WPA2_IE_ID_) {
  1474. out_ie[ielength] = 1;
  1475. ielength++;
  1476. out_ie[ielength] = 0; /*PMKID count = 0x0100*/
  1477. ielength++;
  1478. memcpy(&out_ie[ielength],
  1479. &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
  1480. ielength += 16;
  1481. out_ie[13] += 18;/*PMKID length = 2+16*/
  1482. }
  1483. return ielength;
  1484. }
  1485. void r8712_init_registrypriv_dev_network(struct _adapter *adapter)
  1486. {
  1487. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  1488. struct eeprom_priv *peepriv = &adapter->eeprompriv;
  1489. struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
  1490. u8 *myhwaddr = myid(peepriv);
  1491. memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
  1492. memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
  1493. sizeof(struct ndis_802_11_ssid));
  1494. pdev_network->Configuration.Length =
  1495. sizeof(struct NDIS_802_11_CONFIGURATION);
  1496. pdev_network->Configuration.BeaconPeriod = 100;
  1497. pdev_network->Configuration.FHConfig.Length = 0;
  1498. pdev_network->Configuration.FHConfig.HopPattern = 0;
  1499. pdev_network->Configuration.FHConfig.HopSet = 0;
  1500. pdev_network->Configuration.FHConfig.DwellTime = 0;
  1501. }
  1502. void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
  1503. {
  1504. int sz = 0;
  1505. struct registry_priv *pregistrypriv = &adapter->registrypriv;
  1506. struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
  1507. struct security_priv *psecuritypriv = &adapter->securitypriv;
  1508. struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
  1509. pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
  1510. > 0 ? 1 : 0); /* adhoc no 802.1x */
  1511. pdev_network->Rssi = 0;
  1512. switch (pregistrypriv->wireless_mode) {
  1513. case WIRELESS_11B:
  1514. pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11DS);
  1515. break;
  1516. case WIRELESS_11G:
  1517. case WIRELESS_11BG:
  1518. pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM24);
  1519. break;
  1520. case WIRELESS_11A:
  1521. pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM5);
  1522. break;
  1523. default:
  1524. /* TODO */
  1525. break;
  1526. }
  1527. pdev_network->Configuration.DSConfig = cpu_to_le32(
  1528. pregistrypriv->channel);
  1529. if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
  1530. pdev_network->Configuration.ATIMWindow = cpu_to_le32(3);
  1531. pdev_network->InfrastructureMode = cpu_to_le32(
  1532. cur_network->network.InfrastructureMode);
  1533. /* 1. Supported rates
  1534. * 2. IE
  1535. */
  1536. sz = r8712_generate_ie(pregistrypriv);
  1537. pdev_network->IELength = sz;
  1538. pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network);
  1539. }
  1540. /*the function is at passive_level*/
  1541. void r8712_joinbss_reset(struct _adapter *padapter)
  1542. {
  1543. int i;
  1544. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1545. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1546. /* todo: if you want to do something io/reg/hw setting before join_bss,
  1547. * please add code here */
  1548. phtpriv->ampdu_enable = false;/*reset to disabled*/
  1549. for (i = 0; i < 16; i++)
  1550. phtpriv->baddbareq_issued[i] = false;/*reset it*/
  1551. if (phtpriv->ht_option) {
  1552. /* validate usb rx aggregation */
  1553. r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/
  1554. } else {
  1555. /* invalidate usb rx aggregation */
  1556. /* TH=1 => means that invalidate usb rx aggregation */
  1557. r8712_write8(padapter, 0x102500D9, 1);
  1558. }
  1559. }
  1560. /*the function is >= passive_level*/
  1561. unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
  1562. u8 *out_ie, uint in_len, uint *pout_len)
  1563. {
  1564. u32 ielen, out_len;
  1565. unsigned char *p;
  1566. struct ieee80211_ht_cap ht_capie;
  1567. unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
  1568. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1569. struct qos_priv *pqospriv = &pmlmepriv->qospriv;
  1570. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1571. phtpriv->ht_option = 0;
  1572. p = r8712_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
  1573. if (p && (ielen > 0)) {
  1574. if (pqospriv->qos_option == 0) {
  1575. out_len = *pout_len;
  1576. r8712_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
  1577. _WMM_IE_Length_, WMM_IE, pout_len);
  1578. pqospriv->qos_option = 1;
  1579. }
  1580. out_len = *pout_len;
  1581. memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
  1582. ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
  1583. IEEE80211_HT_CAP_SGI_20 |
  1584. IEEE80211_HT_CAP_SGI_40 |
  1585. IEEE80211_HT_CAP_TX_STBC |
  1586. IEEE80211_HT_CAP_MAX_AMSDU |
  1587. IEEE80211_HT_CAP_DSSSCCK40;
  1588. ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR &
  1589. 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
  1590. r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
  1591. sizeof(struct ieee80211_ht_cap),
  1592. (unsigned char *)&ht_capie, pout_len);
  1593. phtpriv->ht_option = 1;
  1594. }
  1595. return phtpriv->ht_option;
  1596. }
  1597. /* the function is > passive_level (in critical_section) */
  1598. static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
  1599. {
  1600. u8 *p, max_ampdu_sz;
  1601. int i, len;
  1602. struct sta_info *bmc_sta, *psta;
  1603. struct ieee80211_ht_cap *pht_capie;
  1604. struct recv_reorder_ctrl *preorder_ctrl;
  1605. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1606. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1607. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  1608. struct wlan_network *pcur_network = &(pmlmepriv->cur_network);
  1609. if (!phtpriv->ht_option)
  1610. return;
  1611. /* maybe needs check if ap supports rx ampdu. */
  1612. if (!phtpriv->ampdu_enable &&
  1613. (pregistrypriv->ampdu_enable == 1))
  1614. phtpriv->ampdu_enable = true;
  1615. /*check Max Rx A-MPDU Size*/
  1616. len = 0;
  1617. p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
  1618. _HT_CAPABILITY_IE_,
  1619. &len, ie_len -
  1620. sizeof(struct NDIS_802_11_FIXED_IEs));
  1621. if (p && len > 0) {
  1622. pht_capie = (struct ieee80211_ht_cap *)(p + 2);
  1623. max_ampdu_sz = (pht_capie->ampdu_params_info &
  1624. IEEE80211_HT_CAP_AMPDU_FACTOR);
  1625. /* max_ampdu_sz (kbytes); */
  1626. max_ampdu_sz = 1 << (max_ampdu_sz + 3);
  1627. phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
  1628. }
  1629. /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
  1630. * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl
  1631. * wstart_b(indicate_seq) to default value=0xffff
  1632. * todo: check if AP can send A-MPDU packets
  1633. */
  1634. bmc_sta = r8712_get_bcmc_stainfo(padapter);
  1635. if (bmc_sta) {
  1636. for (i = 0; i < 16; i++) {
  1637. preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
  1638. preorder_ctrl->indicate_seq = 0xffff;
  1639. preorder_ctrl->wend_b = 0xffff;
  1640. }
  1641. }
  1642. psta = r8712_get_stainfo(&padapter->stapriv,
  1643. pcur_network->network.MacAddress);
  1644. if (psta) {
  1645. for (i = 0; i < 16; i++) {
  1646. preorder_ctrl = &psta->recvreorder_ctrl[i];
  1647. preorder_ctrl->indicate_seq = 0xffff;
  1648. preorder_ctrl->wend_b = 0xffff;
  1649. }
  1650. }
  1651. len = 0;
  1652. p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
  1653. _HT_ADD_INFO_IE_, &len,
  1654. ie_len - sizeof(struct NDIS_802_11_FIXED_IEs));
  1655. }
  1656. void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority)
  1657. {
  1658. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1659. struct ht_priv *phtpriv = &pmlmepriv->htpriv;
  1660. if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) {
  1661. if (!phtpriv->baddbareq_issued[priority]) {
  1662. r8712_addbareq_cmd(padapter, (u8)priority);
  1663. phtpriv->baddbareq_issued[priority] = true;
  1664. }
  1665. }
  1666. }