ieee80211_softmac.c 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207
  1. /* IEEE 802.11 SoftMAC layer
  2. * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
  3. *
  4. * Mostly extracted from the rtl8180-sa2400 driver for the
  5. * in-kernel generic ieee802.11 stack.
  6. *
  7. * Few lines might be stolen from other part of the ieee80211
  8. * stack. Copyright who own it's copyright
  9. *
  10. * WPA code stolen from the ipw2200 driver.
  11. * Copyright who own it's copyright.
  12. *
  13. * released under the GPL
  14. */
  15. #include "ieee80211.h"
  16. #include <linux/random.h>
  17. #include <linux/delay.h>
  18. #include <linux/slab.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/etherdevice.h>
  21. #include "dot11d.h"
  22. short ieee80211_is_54g(const struct ieee80211_network *net)
  23. {
  24. return (net->rates_ex_len > 0) || (net->rates_len > 4);
  25. }
  26. EXPORT_SYMBOL(ieee80211_is_54g);
  27. short ieee80211_is_shortslot(const struct ieee80211_network *net)
  28. {
  29. return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
  30. }
  31. EXPORT_SYMBOL(ieee80211_is_shortslot);
  32. /* returns the total length needed for pleacing the RATE MFIE
  33. * tag and the EXTENDED RATE MFIE tag if needed.
  34. * It encludes two bytes per tag for the tag itself and its len
  35. */
  36. static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
  37. {
  38. unsigned int rate_len = 0;
  39. if (ieee->modulation & IEEE80211_CCK_MODULATION)
  40. rate_len = IEEE80211_CCK_RATE_LEN + 2;
  41. if (ieee->modulation & IEEE80211_OFDM_MODULATION)
  42. rate_len += IEEE80211_OFDM_RATE_LEN + 2;
  43. return rate_len;
  44. }
  45. /* pleace the MFIE rate, tag to the memory (double) poined.
  46. * Then it updates the pointer so that
  47. * it points after the new MFIE tag added.
  48. */
  49. static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
  50. {
  51. u8 *tag = *tag_p;
  52. if (ieee->modulation & IEEE80211_CCK_MODULATION) {
  53. *tag++ = MFIE_TYPE_RATES;
  54. *tag++ = 4;
  55. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  56. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  57. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  58. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  59. }
  60. /* We may add an option for custom rates that specific HW might support */
  61. *tag_p = tag;
  62. }
  63. static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
  64. {
  65. u8 *tag = *tag_p;
  66. if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
  67. *tag++ = MFIE_TYPE_RATES_EX;
  68. *tag++ = 8;
  69. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  70. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
  71. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  72. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
  73. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  74. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
  75. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
  76. *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
  77. }
  78. /* We may add an option for custom rates that specific HW might support */
  79. *tag_p = tag;
  80. }
  81. static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
  82. {
  83. u8 *tag = *tag_p;
  84. *tag++ = MFIE_TYPE_GENERIC; //0
  85. *tag++ = 7;
  86. *tag++ = 0x00;
  87. *tag++ = 0x50;
  88. *tag++ = 0xf2;
  89. *tag++ = 0x02;//5
  90. *tag++ = 0x00;
  91. *tag++ = 0x01;
  92. #ifdef SUPPORT_USPD
  93. if(ieee->current_network.wmm_info & 0x80) {
  94. *tag++ = 0x0f|MAX_SP_Len;
  95. } else {
  96. *tag++ = MAX_SP_Len;
  97. }
  98. #else
  99. *tag++ = MAX_SP_Len;
  100. #endif
  101. *tag_p = tag;
  102. }
  103. #ifdef THOMAS_TURBO
  104. static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
  105. {
  106. u8 *tag = *tag_p;
  107. *tag++ = MFIE_TYPE_GENERIC; //0
  108. *tag++ = 7;
  109. *tag++ = 0x00;
  110. *tag++ = 0xe0;
  111. *tag++ = 0x4c;
  112. *tag++ = 0x01;//5
  113. *tag++ = 0x02;
  114. *tag++ = 0x11;
  115. *tag++ = 0x00;
  116. *tag_p = tag;
  117. printk(KERN_ALERT "This is enable turbo mode IE process\n");
  118. }
  119. #endif
  120. static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
  121. {
  122. int nh;
  123. nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
  124. /*
  125. * if the queue is full but we have newer frames then
  126. * just overwrites the oldest.
  127. *
  128. * if (nh == ieee->mgmt_queue_tail)
  129. * return -1;
  130. */
  131. ieee->mgmt_queue_head = nh;
  132. ieee->mgmt_queue_ring[nh] = skb;
  133. //return 0;
  134. }
  135. static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
  136. {
  137. struct sk_buff *ret;
  138. if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
  139. return NULL;
  140. ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
  141. ieee->mgmt_queue_tail =
  142. (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
  143. return ret;
  144. }
  145. static void init_mgmt_queue(struct ieee80211_device *ieee)
  146. {
  147. ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
  148. }
  149. static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
  150. {
  151. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  152. u8 rate;
  153. // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
  154. if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
  155. rate = 0x0c;
  156. else
  157. rate = ieee->basic_rate & 0x7f;
  158. if (rate == 0) {
  159. // 2005.01.26, by rcnjko.
  160. if(ieee->mode == IEEE_A||
  161. ieee->mode== IEEE_N_5G||
  162. (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
  163. rate = 0x0c;
  164. else
  165. rate = 0x02;
  166. }
  167. /*
  168. // Data rate of ProbeReq is already decided. Annie, 2005-03-31
  169. if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
  170. {
  171. if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
  172. rate = 0x0c;
  173. else
  174. rate = 0x02;
  175. }
  176. */
  177. return rate;
  178. }
  179. void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
  180. inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  181. {
  182. unsigned long flags;
  183. short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  184. struct rtl_80211_hdr_3addr *header=
  185. (struct rtl_80211_hdr_3addr *) skb->data;
  186. cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
  187. spin_lock_irqsave(&ieee->lock, flags);
  188. /* called with 2nd param 0, no mgmt lock required */
  189. ieee80211_sta_wakeup(ieee, 0);
  190. tcb_desc->queue_index = MGNT_QUEUE;
  191. tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
  192. tcb_desc->RATRIndex = 7;
  193. tcb_desc->bTxDisableRateFallBack = 1;
  194. tcb_desc->bTxUseDriverAssingedRate = 1;
  195. if(single){
  196. if(ieee->queue_stop){
  197. enqueue_mgmt(ieee, skb);
  198. }else{
  199. header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
  200. if (ieee->seq_ctrl[0] == 0xFFF)
  201. ieee->seq_ctrl[0] = 0;
  202. else
  203. ieee->seq_ctrl[0]++;
  204. /* avoid watchdog triggers */
  205. ieee->dev->trans_start = jiffies;
  206. ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  207. //dev_kfree_skb_any(skb);//edit by thomas
  208. }
  209. spin_unlock_irqrestore(&ieee->lock, flags);
  210. }else{
  211. spin_unlock_irqrestore(&ieee->lock, flags);
  212. spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
  213. header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  214. if (ieee->seq_ctrl[0] == 0xFFF)
  215. ieee->seq_ctrl[0] = 0;
  216. else
  217. ieee->seq_ctrl[0]++;
  218. /* check whether the managed packet queued greater than 5 */
  219. if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
  220. (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
  221. (ieee->queue_stop) ) {
  222. /* insert the skb packet to the management queue */
  223. /* as for the completion function, it does not need
  224. * to check it any more.
  225. * */
  226. printk("%s():insert to waitqueue!\n",__func__);
  227. skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
  228. } else {
  229. ieee->softmac_hard_start_xmit(skb, ieee->dev);
  230. //dev_kfree_skb_any(skb);//edit by thomas
  231. }
  232. spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
  233. }
  234. }
  235. inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  236. {
  237. short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  238. struct rtl_80211_hdr_3addr *header =
  239. (struct rtl_80211_hdr_3addr *) skb->data;
  240. if(single){
  241. header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  242. if (ieee->seq_ctrl[0] == 0xFFF)
  243. ieee->seq_ctrl[0] = 0;
  244. else
  245. ieee->seq_ctrl[0]++;
  246. /* avoid watchdog triggers */
  247. ieee->dev->trans_start = jiffies;
  248. ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  249. }else{
  250. header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  251. if (ieee->seq_ctrl[0] == 0xFFF)
  252. ieee->seq_ctrl[0] = 0;
  253. else
  254. ieee->seq_ctrl[0]++;
  255. ieee->softmac_hard_start_xmit(skb, ieee->dev);
  256. }
  257. //dev_kfree_skb_any(skb);//edit by thomas
  258. }
  259. inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
  260. {
  261. unsigned int len, rate_len;
  262. u8 *tag;
  263. struct sk_buff *skb;
  264. struct ieee80211_probe_request *req;
  265. len = ieee->current_network.ssid_len;
  266. rate_len = ieee80211_MFIE_rate_len(ieee);
  267. skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  268. 2 + len + rate_len + ieee->tx_headroom);
  269. if (!skb)
  270. return NULL;
  271. skb_reserve(skb, ieee->tx_headroom);
  272. req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
  273. req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  274. req->header.duration_id = 0; //FIXME: is this OK ?
  275. memset(req->header.addr1, 0xff, ETH_ALEN);
  276. memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  277. memset(req->header.addr3, 0xff, ETH_ALEN);
  278. tag = (u8 *) skb_put(skb,len+2+rate_len);
  279. *tag++ = MFIE_TYPE_SSID;
  280. *tag++ = len;
  281. memcpy(tag, ieee->current_network.ssid, len);
  282. tag += len;
  283. ieee80211_MFIE_Brate(ieee,&tag);
  284. ieee80211_MFIE_Grate(ieee,&tag);
  285. return skb;
  286. }
  287. struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
  288. static void ieee80211_send_beacon(struct ieee80211_device *ieee)
  289. {
  290. struct sk_buff *skb;
  291. if(!ieee->ieee_up)
  292. return;
  293. //unsigned long flags;
  294. skb = ieee80211_get_beacon_(ieee);
  295. if (skb) {
  296. softmac_mgmt_xmit(skb, ieee);
  297. ieee->softmac_stats.tx_beacons++;
  298. //dev_kfree_skb_any(skb);//edit by thomas
  299. }
  300. // ieee->beacon_timer.expires = jiffies +
  301. // (MSECS( ieee->current_network.beacon_interval -5));
  302. //spin_lock_irqsave(&ieee->beacon_lock,flags);
  303. if (ieee->beacon_txing && ieee->ieee_up) {
  304. // if(!timer_pending(&ieee->beacon_timer))
  305. // add_timer(&ieee->beacon_timer);
  306. mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
  307. }
  308. //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  309. }
  310. static void ieee80211_send_beacon_cb(unsigned long _ieee)
  311. {
  312. struct ieee80211_device *ieee =
  313. (struct ieee80211_device *) _ieee;
  314. unsigned long flags;
  315. spin_lock_irqsave(&ieee->beacon_lock, flags);
  316. ieee80211_send_beacon(ieee);
  317. spin_unlock_irqrestore(&ieee->beacon_lock, flags);
  318. }
  319. static void ieee80211_send_probe(struct ieee80211_device *ieee)
  320. {
  321. struct sk_buff *skb;
  322. skb = ieee80211_probe_req(ieee);
  323. if (skb) {
  324. softmac_mgmt_xmit(skb, ieee);
  325. ieee->softmac_stats.tx_probe_rq++;
  326. //dev_kfree_skb_any(skb);//edit by thomas
  327. }
  328. }
  329. static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
  330. {
  331. if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
  332. ieee80211_send_probe(ieee);
  333. ieee80211_send_probe(ieee);
  334. }
  335. }
  336. /* this performs syncro scan blocking the caller until all channels
  337. * in the allowed channel map has been checked.
  338. */
  339. void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
  340. {
  341. short ch = 0;
  342. u8 channel_map[MAX_CHANNEL_NUMBER+1];
  343. memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  344. down(&ieee->scan_sem);
  345. while(1)
  346. {
  347. do{
  348. ch++;
  349. if (ch > MAX_CHANNEL_NUMBER)
  350. goto out; /* scan completed */
  351. }while(!channel_map[ch]);
  352. /* this function can be called in two situations
  353. * 1- We have switched to ad-hoc mode and we are
  354. * performing a complete syncro scan before conclude
  355. * there are no interesting cell and to create a
  356. * new one. In this case the link state is
  357. * IEEE80211_NOLINK until we found an interesting cell.
  358. * If so the ieee8021_new_net, called by the RX path
  359. * will set the state to IEEE80211_LINKED, so we stop
  360. * scanning
  361. * 2- We are linked and the root uses run iwlist scan.
  362. * So we switch to IEEE80211_LINKED_SCANNING to remember
  363. * that we are still logically linked (not interested in
  364. * new network events, despite for updating the net list,
  365. * but we are temporarly 'unlinked' as the driver shall
  366. * not filter RX frames and the channel is changing.
  367. * So the only situation in witch are interested is to check
  368. * if the state become LINKED because of the #1 situation
  369. */
  370. if (ieee->state == IEEE80211_LINKED)
  371. goto out;
  372. ieee->set_chan(ieee->dev, ch);
  373. if(channel_map[ch] == 1)
  374. ieee80211_send_probe_requests(ieee);
  375. /* this prevent excessive time wait when we
  376. * need to wait for a syncro scan to end..
  377. */
  378. if (ieee->state >= IEEE80211_LINKED && ieee->sync_scan_hurryup)
  379. goto out;
  380. msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
  381. }
  382. out:
  383. if(ieee->state < IEEE80211_LINKED){
  384. ieee->actscanning = false;
  385. up(&ieee->scan_sem);
  386. }
  387. else{
  388. ieee->sync_scan_hurryup = 0;
  389. if(IS_DOT11D_ENABLE(ieee))
  390. DOT11D_ScanComplete(ieee);
  391. up(&ieee->scan_sem);
  392. }
  393. }
  394. EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
  395. static void ieee80211_softmac_scan_wq(struct work_struct *work)
  396. {
  397. struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  398. struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
  399. static short watchdog;
  400. u8 channel_map[MAX_CHANNEL_NUMBER+1];
  401. memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  402. if(!ieee->ieee_up)
  403. return;
  404. down(&ieee->scan_sem);
  405. do{
  406. ieee->current_network.channel =
  407. (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
  408. if (watchdog++ > MAX_CHANNEL_NUMBER)
  409. {
  410. //if current channel is not in channel map, set to default channel.
  411. if (!channel_map[ieee->current_network.channel]) {
  412. ieee->current_network.channel = 6;
  413. goto out; /* no good chans */
  414. }
  415. }
  416. }while(!channel_map[ieee->current_network.channel]);
  417. if (ieee->scanning == 0 )
  418. goto out;
  419. ieee->set_chan(ieee->dev, ieee->current_network.channel);
  420. if(channel_map[ieee->current_network.channel] == 1)
  421. ieee80211_send_probe_requests(ieee);
  422. queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
  423. up(&ieee->scan_sem);
  424. return;
  425. out:
  426. if(IS_DOT11D_ENABLE(ieee))
  427. DOT11D_ScanComplete(ieee);
  428. ieee->actscanning = false;
  429. watchdog = 0;
  430. ieee->scanning = 0;
  431. up(&ieee->scan_sem);
  432. }
  433. static void ieee80211_beacons_start(struct ieee80211_device *ieee)
  434. {
  435. unsigned long flags;
  436. spin_lock_irqsave(&ieee->beacon_lock,flags);
  437. ieee->beacon_txing = 1;
  438. ieee80211_send_beacon(ieee);
  439. spin_unlock_irqrestore(&ieee->beacon_lock, flags);
  440. }
  441. static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
  442. {
  443. unsigned long flags;
  444. spin_lock_irqsave(&ieee->beacon_lock, flags);
  445. ieee->beacon_txing = 0;
  446. del_timer_sync(&ieee->beacon_timer);
  447. spin_unlock_irqrestore(&ieee->beacon_lock, flags);
  448. }
  449. void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
  450. {
  451. if(ieee->stop_send_beacons)
  452. ieee->stop_send_beacons(ieee->dev);
  453. if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  454. ieee80211_beacons_stop(ieee);
  455. }
  456. EXPORT_SYMBOL(ieee80211_stop_send_beacons);
  457. void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
  458. {
  459. if(ieee->start_send_beacons)
  460. ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
  461. if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  462. ieee80211_beacons_start(ieee);
  463. }
  464. EXPORT_SYMBOL(ieee80211_start_send_beacons);
  465. static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
  466. {
  467. // unsigned long flags;
  468. //ieee->sync_scan_hurryup = 1;
  469. down(&ieee->scan_sem);
  470. // spin_lock_irqsave(&ieee->lock, flags);
  471. if (ieee->scanning == 1) {
  472. ieee->scanning = 0;
  473. cancel_delayed_work(&ieee->softmac_scan_wq);
  474. }
  475. // spin_unlock_irqrestore(&ieee->lock, flags);
  476. up(&ieee->scan_sem);
  477. }
  478. void ieee80211_stop_scan(struct ieee80211_device *ieee)
  479. {
  480. if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  481. ieee80211_softmac_stop_scan(ieee);
  482. else
  483. ieee->stop_scan(ieee->dev);
  484. }
  485. EXPORT_SYMBOL(ieee80211_stop_scan);
  486. /* called with ieee->lock held */
  487. static void ieee80211_start_scan(struct ieee80211_device *ieee)
  488. {
  489. if (IS_DOT11D_ENABLE(ieee) )
  490. {
  491. if (IS_COUNTRY_IE_VALID(ieee))
  492. {
  493. RESET_CIE_WATCHDOG(ieee);
  494. }
  495. }
  496. if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
  497. if (ieee->scanning == 0) {
  498. ieee->scanning = 1;
  499. queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
  500. }
  501. }else
  502. ieee->start_scan(ieee->dev);
  503. }
  504. /* called with wx_sem held */
  505. void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
  506. {
  507. if (IS_DOT11D_ENABLE(ieee) )
  508. {
  509. if (IS_COUNTRY_IE_VALID(ieee))
  510. {
  511. RESET_CIE_WATCHDOG(ieee);
  512. }
  513. }
  514. ieee->sync_scan_hurryup = 0;
  515. if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  516. ieee80211_softmac_scan_syncro(ieee);
  517. else
  518. ieee->scan_syncro(ieee->dev);
  519. }
  520. EXPORT_SYMBOL(ieee80211_start_scan_syncro);
  521. inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
  522. struct ieee80211_device *ieee, int challengelen)
  523. {
  524. struct sk_buff *skb;
  525. struct ieee80211_authentication *auth;
  526. int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
  527. skb = dev_alloc_skb(len);
  528. if (!skb) return NULL;
  529. skb_reserve(skb, ieee->tx_headroom);
  530. auth = (struct ieee80211_authentication *)
  531. skb_put(skb, sizeof(struct ieee80211_authentication));
  532. if (challengelen)
  533. auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
  534. | IEEE80211_FCTL_WEP);
  535. else
  536. auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
  537. auth->header.duration_id = cpu_to_le16(0x013a);
  538. memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
  539. memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  540. memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
  541. //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
  542. if(ieee->auth_mode == 0)
  543. auth->algorithm = WLAN_AUTH_OPEN;
  544. else if(ieee->auth_mode == 1)
  545. auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
  546. else if(ieee->auth_mode == 2)
  547. auth->algorithm = WLAN_AUTH_OPEN;//0x80;
  548. printk("=================>%s():auth->algorithm is %d\n",__func__,auth->algorithm);
  549. auth->transaction = cpu_to_le16(ieee->associate_seq);
  550. ieee->associate_seq++;
  551. auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
  552. return skb;
  553. }
  554. static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
  555. {
  556. u8 *tag;
  557. int beacon_size;
  558. struct ieee80211_probe_response *beacon_buf;
  559. struct sk_buff *skb = NULL;
  560. int encrypt;
  561. int atim_len, erp_len;
  562. struct ieee80211_crypt_data *crypt;
  563. char *ssid = ieee->current_network.ssid;
  564. int ssid_len = ieee->current_network.ssid_len;
  565. int rate_len = ieee->current_network.rates_len+2;
  566. int rate_ex_len = ieee->current_network.rates_ex_len;
  567. int wpa_ie_len = ieee->wpa_ie_len;
  568. u8 erpinfo_content = 0;
  569. u8 *tmp_ht_cap_buf;
  570. u8 tmp_ht_cap_len=0;
  571. u8 *tmp_ht_info_buf;
  572. u8 tmp_ht_info_len=0;
  573. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  574. u8 *tmp_generic_ie_buf=NULL;
  575. u8 tmp_generic_ie_len=0;
  576. if(rate_ex_len > 0) rate_ex_len+=2;
  577. if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
  578. atim_len = 4;
  579. else
  580. atim_len = 0;
  581. if(ieee80211_is_54g(&ieee->current_network))
  582. erp_len = 3;
  583. else
  584. erp_len = 0;
  585. crypt = ieee->crypt[ieee->tx_keyidx];
  586. encrypt = ieee->host_encrypt && crypt && crypt->ops &&
  587. ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
  588. //HT ralated element
  589. tmp_ht_cap_buf =(u8 *) &(ieee->pHTInfo->SelfHTCap);
  590. tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
  591. tmp_ht_info_buf =(u8 *) &(ieee->pHTInfo->SelfHTInfo);
  592. tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
  593. HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
  594. HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
  595. if (pHTInfo->bRegRT2RTAggregation)
  596. {
  597. tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
  598. tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
  599. HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
  600. }
  601. // printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
  602. beacon_size = sizeof(struct ieee80211_probe_response)+2+
  603. ssid_len
  604. +3 //channel
  605. +rate_len
  606. +rate_ex_len
  607. +atim_len
  608. +erp_len
  609. +wpa_ie_len
  610. // +tmp_ht_cap_len
  611. // +tmp_ht_info_len
  612. // +tmp_generic_ie_len
  613. // +wmm_len+2
  614. +ieee->tx_headroom;
  615. skb = dev_alloc_skb(beacon_size);
  616. if (!skb)
  617. return NULL;
  618. skb_reserve(skb, ieee->tx_headroom);
  619. beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, (beacon_size - ieee->tx_headroom));
  620. memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
  621. memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  622. memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
  623. beacon_buf->header.duration_id = 0; //FIXME
  624. beacon_buf->beacon_interval =
  625. cpu_to_le16(ieee->current_network.beacon_interval);
  626. beacon_buf->capability =
  627. cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
  628. beacon_buf->capability |=
  629. cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
  630. if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
  631. beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  632. crypt = ieee->crypt[ieee->tx_keyidx];
  633. if (encrypt)
  634. beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  635. beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
  636. beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
  637. beacon_buf->info_element[0].len = ssid_len;
  638. tag = (u8 *) beacon_buf->info_element[0].data;
  639. memcpy(tag, ssid, ssid_len);
  640. tag += ssid_len;
  641. *(tag++) = MFIE_TYPE_RATES;
  642. *(tag++) = rate_len-2;
  643. memcpy(tag, ieee->current_network.rates, rate_len-2);
  644. tag+=rate_len-2;
  645. *(tag++) = MFIE_TYPE_DS_SET;
  646. *(tag++) = 1;
  647. *(tag++) = ieee->current_network.channel;
  648. if (atim_len) {
  649. *(tag++) = MFIE_TYPE_IBSS_SET;
  650. *(tag++) = 2;
  651. put_unaligned_le16(ieee->current_network.atim_window,
  652. (u8 *)tag);
  653. tag+=2;
  654. }
  655. if (erp_len) {
  656. *(tag++) = MFIE_TYPE_ERP;
  657. *(tag++) = 1;
  658. *(tag++) = erpinfo_content;
  659. }
  660. if (rate_ex_len) {
  661. *(tag++) = MFIE_TYPE_RATES_EX;
  662. *(tag++) = rate_ex_len-2;
  663. memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
  664. tag+=rate_ex_len-2;
  665. }
  666. if (wpa_ie_len)
  667. {
  668. if (ieee->iw_mode == IW_MODE_ADHOC)
  669. {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
  670. memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
  671. }
  672. memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  673. tag += wpa_ie_len;
  674. }
  675. //skb->dev = ieee->dev;
  676. return skb;
  677. }
  678. static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
  679. u8 *dest)
  680. {
  681. struct sk_buff *skb;
  682. u8 *tag;
  683. struct ieee80211_crypt_data *crypt;
  684. struct ieee80211_assoc_response_frame *assoc;
  685. short encrypt;
  686. unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  687. int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
  688. skb = dev_alloc_skb(len);
  689. if (!skb)
  690. return NULL;
  691. skb_reserve(skb, ieee->tx_headroom);
  692. assoc = (struct ieee80211_assoc_response_frame *)
  693. skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
  694. assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
  695. memcpy(assoc->header.addr1, dest,ETH_ALEN);
  696. memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  697. memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  698. assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
  699. WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
  700. if(ieee->short_slot)
  701. assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  702. if (ieee->host_encrypt)
  703. crypt = ieee->crypt[ieee->tx_keyidx];
  704. else crypt = NULL;
  705. encrypt = crypt && crypt->ops;
  706. if (encrypt)
  707. assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  708. assoc->status = 0;
  709. assoc->aid = cpu_to_le16(ieee->assoc_id);
  710. if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
  711. else ieee->assoc_id++;
  712. tag = (u8 *) skb_put(skb, rate_len);
  713. ieee80211_MFIE_Brate(ieee, &tag);
  714. ieee80211_MFIE_Grate(ieee, &tag);
  715. return skb;
  716. }
  717. static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
  718. int status, u8 *dest)
  719. {
  720. struct sk_buff *skb;
  721. struct ieee80211_authentication *auth;
  722. int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
  723. skb = dev_alloc_skb(len);
  724. if (!skb)
  725. return NULL;
  726. skb->len = sizeof(struct ieee80211_authentication);
  727. auth = (struct ieee80211_authentication *)skb->data;
  728. auth->status = cpu_to_le16(status);
  729. auth->transaction = cpu_to_le16(2);
  730. auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
  731. memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  732. memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  733. memcpy(auth->header.addr1, dest, ETH_ALEN);
  734. auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
  735. return skb;
  736. }
  737. static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
  738. short pwr)
  739. {
  740. struct sk_buff *skb;
  741. struct rtl_80211_hdr_3addr *hdr;
  742. skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
  743. if (!skb)
  744. return NULL;
  745. hdr = (struct rtl_80211_hdr_3addr *)skb_put(skb,sizeof(struct rtl_80211_hdr_3addr));
  746. memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
  747. memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
  748. memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
  749. hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
  750. IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
  751. (pwr ? IEEE80211_FCTL_PM:0));
  752. return skb;
  753. }
  754. static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
  755. {
  756. struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
  757. if (buf)
  758. softmac_mgmt_xmit(buf, ieee);
  759. }
  760. static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
  761. u8 *dest)
  762. {
  763. struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
  764. if (buf)
  765. softmac_mgmt_xmit(buf, ieee);
  766. }
  767. static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
  768. {
  769. struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
  770. if (buf)
  771. softmac_mgmt_xmit(buf, ieee);
  772. }
  773. inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
  774. {
  775. struct sk_buff *skb;
  776. //unsigned long flags;
  777. struct ieee80211_assoc_request_frame *hdr;
  778. u8 *tag;//,*rsn_ie;
  779. //short info_addr = 0;
  780. //int i;
  781. //u16 suite_count = 0;
  782. //u8 suit_select = 0;
  783. //unsigned int wpa_len = beacon->wpa_ie_len;
  784. //for HT
  785. u8 *ht_cap_buf = NULL;
  786. u8 ht_cap_len=0;
  787. u8 *realtek_ie_buf=NULL;
  788. u8 realtek_ie_len=0;
  789. int wpa_ie_len= ieee->wpa_ie_len;
  790. unsigned int ckip_ie_len=0;
  791. unsigned int ccxrm_ie_len=0;
  792. unsigned int cxvernum_ie_len=0;
  793. struct ieee80211_crypt_data *crypt;
  794. int encrypt;
  795. unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  796. unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
  797. #ifdef THOMAS_TURBO
  798. unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
  799. #endif
  800. int len = 0;
  801. crypt = ieee->crypt[ieee->tx_keyidx];
  802. encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
  803. //Include High Throuput capability && Realtek proprietary
  804. if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
  805. {
  806. ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
  807. ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
  808. HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
  809. if (ieee->pHTInfo->bCurrentRT2RTAggregation)
  810. {
  811. realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
  812. realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
  813. HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
  814. }
  815. }
  816. if (ieee->qos_support) {
  817. wmm_info_len = beacon->qos_data.supported?9:0;
  818. }
  819. if (beacon->bCkipSupported)
  820. {
  821. ckip_ie_len = 30+2;
  822. }
  823. if (beacon->bCcxRmEnable)
  824. {
  825. ccxrm_ie_len = 6+2;
  826. }
  827. if (beacon->BssCcxVerNumber >= 2)
  828. cxvernum_ie_len = 5+2;
  829. #ifdef THOMAS_TURBO
  830. len = sizeof(struct ieee80211_assoc_request_frame)+ 2
  831. + beacon->ssid_len//essid tagged val
  832. + rate_len//rates tagged val
  833. + wpa_ie_len
  834. + wmm_info_len
  835. + turbo_info_len
  836. + ht_cap_len
  837. + realtek_ie_len
  838. + ckip_ie_len
  839. + ccxrm_ie_len
  840. + cxvernum_ie_len
  841. + ieee->tx_headroom;
  842. #else
  843. len = sizeof(struct ieee80211_assoc_request_frame)+ 2
  844. + beacon->ssid_len//essid tagged val
  845. + rate_len//rates tagged val
  846. + wpa_ie_len
  847. + wmm_info_len
  848. + ht_cap_len
  849. + realtek_ie_len
  850. + ckip_ie_len
  851. + ccxrm_ie_len
  852. + cxvernum_ie_len
  853. + ieee->tx_headroom;
  854. #endif
  855. skb = dev_alloc_skb(len);
  856. if (!skb)
  857. return NULL;
  858. skb_reserve(skb, ieee->tx_headroom);
  859. hdr = (struct ieee80211_assoc_request_frame *)
  860. skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
  861. hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
  862. hdr->header.duration_id = cpu_to_le16(37);
  863. memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
  864. memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  865. memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
  866. memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
  867. hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
  868. if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
  869. hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  870. if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
  871. hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
  872. if(ieee->short_slot)
  873. hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  874. if (wmm_info_len) //QOS
  875. hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
  876. hdr->listen_interval = cpu_to_le16(0xa);
  877. hdr->info_element[0].id = MFIE_TYPE_SSID;
  878. hdr->info_element[0].len = beacon->ssid_len;
  879. tag = skb_put(skb, beacon->ssid_len);
  880. memcpy(tag, beacon->ssid, beacon->ssid_len);
  881. tag = skb_put(skb, rate_len);
  882. ieee80211_MFIE_Brate(ieee, &tag);
  883. ieee80211_MFIE_Grate(ieee, &tag);
  884. // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
  885. if (beacon->bCkipSupported) {
  886. static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
  887. u8 CcxAironetBuf[30];
  888. OCTET_STRING osCcxAironetIE;
  889. memset(CcxAironetBuf, 0, 30);
  890. osCcxAironetIE.Octet = CcxAironetBuf;
  891. osCcxAironetIE.Length = sizeof(CcxAironetBuf);
  892. //
  893. // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
  894. // We want to make the device type as "4500-client". 060926, by CCW.
  895. //
  896. memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
  897. // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
  898. // "The CKIP negotiation is started with the associate request from the client to the access point,
  899. // containing an Aironet element with both the MIC and KP bits set."
  900. osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
  901. tag = skb_put(skb, ckip_ie_len);
  902. *tag++ = MFIE_TYPE_AIRONET;
  903. *tag++ = osCcxAironetIE.Length;
  904. memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
  905. tag += osCcxAironetIE.Length;
  906. }
  907. if (beacon->bCcxRmEnable)
  908. {
  909. static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
  910. OCTET_STRING osCcxRmCap;
  911. osCcxRmCap.Octet = CcxRmCapBuf;
  912. osCcxRmCap.Length = sizeof(CcxRmCapBuf);
  913. tag = skb_put(skb, ccxrm_ie_len);
  914. *tag++ = MFIE_TYPE_GENERIC;
  915. *tag++ = osCcxRmCap.Length;
  916. memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
  917. tag += osCcxRmCap.Length;
  918. }
  919. if (beacon->BssCcxVerNumber >= 2) {
  920. u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
  921. OCTET_STRING osCcxVerNum;
  922. CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
  923. osCcxVerNum.Octet = CcxVerNumBuf;
  924. osCcxVerNum.Length = sizeof(CcxVerNumBuf);
  925. tag = skb_put(skb, cxvernum_ie_len);
  926. *tag++ = MFIE_TYPE_GENERIC;
  927. *tag++ = osCcxVerNum.Length;
  928. memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
  929. tag += osCcxVerNum.Length;
  930. }
  931. //HT cap element
  932. if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
  933. if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
  934. {
  935. tag = skb_put(skb, ht_cap_len);
  936. *tag++ = MFIE_TYPE_HT_CAP;
  937. *tag++ = ht_cap_len - 2;
  938. memcpy(tag, ht_cap_buf, ht_cap_len - 2);
  939. tag += ht_cap_len -2;
  940. }
  941. }
  942. //choose what wpa_supplicant gives to associate.
  943. tag = skb_put(skb, wpa_ie_len);
  944. if (wpa_ie_len) {
  945. memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  946. }
  947. tag = skb_put(skb, wmm_info_len);
  948. if (wmm_info_len) {
  949. ieee80211_WMM_Info(ieee, &tag);
  950. }
  951. #ifdef THOMAS_TURBO
  952. tag = skb_put(skb, turbo_info_len);
  953. if (turbo_info_len) {
  954. ieee80211_TURBO_Info(ieee, &tag);
  955. }
  956. #endif
  957. if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
  958. if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
  959. {
  960. tag = skb_put(skb, ht_cap_len);
  961. *tag++ = MFIE_TYPE_GENERIC;
  962. *tag++ = ht_cap_len - 2;
  963. memcpy(tag, ht_cap_buf, ht_cap_len - 2);
  964. tag += ht_cap_len -2;
  965. }
  966. if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
  967. tag = skb_put(skb, realtek_ie_len);
  968. *tag++ = MFIE_TYPE_GENERIC;
  969. *tag++ = realtek_ie_len - 2;
  970. memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
  971. }
  972. }
  973. // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
  974. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
  975. return skb;
  976. }
  977. void ieee80211_associate_abort(struct ieee80211_device *ieee)
  978. {
  979. unsigned long flags;
  980. spin_lock_irqsave(&ieee->lock, flags);
  981. ieee->associate_seq++;
  982. /* don't scan, and avoid to have the RX path possibily
  983. * try again to associate. Even do not react to AUTH or
  984. * ASSOC response. Just wait for the retry wq to be scheduled.
  985. * Here we will check if there are good nets to associate
  986. * with, so we retry or just get back to NO_LINK and scanning
  987. */
  988. if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
  989. IEEE80211_DEBUG_MGMT("Authentication failed\n");
  990. ieee->softmac_stats.no_auth_rs++;
  991. }else{
  992. IEEE80211_DEBUG_MGMT("Association failed\n");
  993. ieee->softmac_stats.no_ass_rs++;
  994. }
  995. ieee->state = IEEE80211_ASSOCIATING_RETRY;
  996. queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
  997. IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
  998. spin_unlock_irqrestore(&ieee->lock, flags);
  999. }
  1000. static void ieee80211_associate_abort_cb(unsigned long dev)
  1001. {
  1002. ieee80211_associate_abort((struct ieee80211_device *) dev);
  1003. }
  1004. static void ieee80211_associate_step1(struct ieee80211_device *ieee)
  1005. {
  1006. struct ieee80211_network *beacon = &ieee->current_network;
  1007. struct sk_buff *skb;
  1008. IEEE80211_DEBUG_MGMT("Stopping scan\n");
  1009. ieee->softmac_stats.tx_auth_rq++;
  1010. skb=ieee80211_authentication_req(beacon, ieee, 0);
  1011. if (!skb)
  1012. ieee80211_associate_abort(ieee);
  1013. else{
  1014. ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
  1015. IEEE80211_DEBUG_MGMT("Sending authentication request\n");
  1016. softmac_mgmt_xmit(skb, ieee);
  1017. //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
  1018. if (!timer_pending(&ieee->associate_timer)) {
  1019. ieee->associate_timer.expires = jiffies + (HZ / 2);
  1020. add_timer(&ieee->associate_timer);
  1021. }
  1022. //dev_kfree_skb_any(skb);//edit by thomas
  1023. }
  1024. }
  1025. static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
  1026. u8 *challenge,
  1027. int chlen)
  1028. {
  1029. u8 *c;
  1030. struct sk_buff *skb;
  1031. struct ieee80211_network *beacon = &ieee->current_network;
  1032. // int hlen = sizeof(struct ieee80211_authentication);
  1033. ieee->associate_seq++;
  1034. ieee->softmac_stats.tx_auth_rq++;
  1035. skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
  1036. if (!skb)
  1037. ieee80211_associate_abort(ieee);
  1038. else{
  1039. c = skb_put(skb, chlen+2);
  1040. *(c++) = MFIE_TYPE_CHALLENGE;
  1041. *(c++) = chlen;
  1042. memcpy(c, challenge, chlen);
  1043. IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
  1044. ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr ));
  1045. softmac_mgmt_xmit(skb, ieee);
  1046. mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
  1047. //dev_kfree_skb_any(skb);//edit by thomas
  1048. }
  1049. kfree(challenge);
  1050. }
  1051. static void ieee80211_associate_step2(struct ieee80211_device *ieee)
  1052. {
  1053. struct sk_buff *skb;
  1054. struct ieee80211_network *beacon = &ieee->current_network;
  1055. del_timer_sync(&ieee->associate_timer);
  1056. IEEE80211_DEBUG_MGMT("Sending association request\n");
  1057. ieee->softmac_stats.tx_ass_rq++;
  1058. skb=ieee80211_association_req(beacon, ieee);
  1059. if (!skb)
  1060. ieee80211_associate_abort(ieee);
  1061. else{
  1062. softmac_mgmt_xmit(skb, ieee);
  1063. mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
  1064. //dev_kfree_skb_any(skb);//edit by thomas
  1065. }
  1066. }
  1067. static void ieee80211_associate_complete_wq(struct work_struct *work)
  1068. {
  1069. struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
  1070. printk(KERN_INFO "Associated successfully\n");
  1071. if(ieee80211_is_54g(&ieee->current_network) &&
  1072. (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  1073. ieee->rate = 108;
  1074. printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
  1075. }else{
  1076. ieee->rate = 22;
  1077. printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
  1078. }
  1079. if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
  1080. {
  1081. printk("Successfully associated, ht enabled\n");
  1082. HTOnAssocRsp(ieee);
  1083. }
  1084. else
  1085. {
  1086. printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
  1087. memset(ieee->dot11HTOperationalRateSet, 0, 16);
  1088. //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  1089. }
  1090. ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
  1091. // To prevent the immediately calling watch_dog after association.
  1092. if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
  1093. {
  1094. ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
  1095. ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
  1096. }
  1097. ieee->link_change(ieee->dev);
  1098. if (!ieee->is_silent_reset) {
  1099. printk("============>normal associate\n");
  1100. notify_wx_assoc_event(ieee);
  1101. } else {
  1102. printk("==================>silent reset associate\n");
  1103. ieee->is_silent_reset = false;
  1104. }
  1105. if (ieee->data_hard_resume)
  1106. ieee->data_hard_resume(ieee->dev);
  1107. netif_carrier_on(ieee->dev);
  1108. }
  1109. static void ieee80211_associate_complete(struct ieee80211_device *ieee)
  1110. {
  1111. // int i;
  1112. // struct net_device* dev = ieee->dev;
  1113. del_timer_sync(&ieee->associate_timer);
  1114. ieee->state = IEEE80211_LINKED;
  1115. //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
  1116. queue_work(ieee->wq, &ieee->associate_complete_wq);
  1117. }
  1118. static void ieee80211_associate_procedure_wq(struct work_struct *work)
  1119. {
  1120. struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
  1121. ieee->sync_scan_hurryup = 1;
  1122. down(&ieee->wx_sem);
  1123. if (ieee->data_hard_stop)
  1124. ieee->data_hard_stop(ieee->dev);
  1125. ieee80211_stop_scan(ieee);
  1126. printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
  1127. //ieee->set_chan(ieee->dev, ieee->current_network.channel);
  1128. HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  1129. ieee->associate_seq = 1;
  1130. ieee80211_associate_step1(ieee);
  1131. up(&ieee->wx_sem);
  1132. }
  1133. inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
  1134. {
  1135. u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
  1136. int tmp_ssid_len = 0;
  1137. short apset, ssidset, ssidbroad, apmatch, ssidmatch;
  1138. /* we are interested in new new only if we are not associated
  1139. * and we are not associating / authenticating
  1140. */
  1141. if (ieee->state != IEEE80211_NOLINK)
  1142. return;
  1143. if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
  1144. return;
  1145. if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
  1146. return;
  1147. if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
  1148. /* if the user specified the AP MAC, we need also the essid
  1149. * This could be obtained by beacons or, if the network does not
  1150. * broadcast it, it can be put manually.
  1151. */
  1152. apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
  1153. ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
  1154. ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
  1155. apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
  1156. ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
  1157. (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
  1158. if ( /* if the user set the AP check if match.
  1159. * if the network does not broadcast essid we check the user supplyed ANY essid
  1160. * if the network does broadcast and the user does not set essid it is OK
  1161. * if the network does broadcast and the user did set essid chech if essid match
  1162. */
  1163. (apset && apmatch &&
  1164. ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
  1165. /* if the ap is not set, check that the user set the bssid
  1166. * and the network does broadcast and that those two bssid matches
  1167. */
  1168. (!apset && ssidset && ssidbroad && ssidmatch)
  1169. ){
  1170. /* if the essid is hidden replace it with the
  1171. * essid provided by the user.
  1172. */
  1173. if (!ssidbroad) {
  1174. strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
  1175. tmp_ssid_len = ieee->current_network.ssid_len;
  1176. }
  1177. memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
  1178. strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
  1179. ieee->current_network.ssid_len = tmp_ssid_len;
  1180. printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
  1181. //ieee->pHTInfo->IOTAction = 0;
  1182. HTResetIOTSetting(ieee->pHTInfo);
  1183. if (ieee->iw_mode == IW_MODE_INFRA){
  1184. /* Join the network for the first time */
  1185. ieee->AsocRetryCount = 0;
  1186. //for HT by amy 080514
  1187. if((ieee->current_network.qos_data.supported == 1) &&
  1188. // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
  1189. ieee->current_network.bssht.bdSupportHT)
  1190. /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
  1191. {
  1192. // ieee->pHTInfo->bCurrentHTSupport = true;
  1193. HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
  1194. }
  1195. else
  1196. {
  1197. ieee->pHTInfo->bCurrentHTSupport = false;
  1198. }
  1199. ieee->state = IEEE80211_ASSOCIATING;
  1200. queue_work(ieee->wq, &ieee->associate_procedure_wq);
  1201. }else{
  1202. if(ieee80211_is_54g(&ieee->current_network) &&
  1203. (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  1204. ieee->rate = 108;
  1205. ieee->SetWirelessMode(ieee->dev, IEEE_G);
  1206. printk(KERN_INFO"Using G rates\n");
  1207. }else{
  1208. ieee->rate = 22;
  1209. ieee->SetWirelessMode(ieee->dev, IEEE_B);
  1210. printk(KERN_INFO"Using B rates\n");
  1211. }
  1212. memset(ieee->dot11HTOperationalRateSet, 0, 16);
  1213. //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  1214. ieee->state = IEEE80211_LINKED;
  1215. }
  1216. }
  1217. }
  1218. }
  1219. void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
  1220. {
  1221. unsigned long flags;
  1222. struct ieee80211_network *target;
  1223. spin_lock_irqsave(&ieee->lock, flags);
  1224. list_for_each_entry(target, &ieee->network_list, list) {
  1225. /* if the state become different that NOLINK means
  1226. * we had found what we are searching for
  1227. */
  1228. if (ieee->state != IEEE80211_NOLINK)
  1229. break;
  1230. if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
  1231. ieee80211_softmac_new_net(ieee, target);
  1232. }
  1233. spin_unlock_irqrestore(&ieee->lock, flags);
  1234. }
  1235. static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
  1236. {
  1237. struct ieee80211_authentication *a;
  1238. u8 *t;
  1239. if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
  1240. IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
  1241. return 0xcafe;
  1242. }
  1243. *challenge = NULL;
  1244. a = (struct ieee80211_authentication *) skb->data;
  1245. if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
  1246. t = skb->data + sizeof(struct ieee80211_authentication);
  1247. if (*(t++) == MFIE_TYPE_CHALLENGE) {
  1248. *chlen = *(t++);
  1249. *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
  1250. if (!*challenge)
  1251. return -ENOMEM;
  1252. }
  1253. }
  1254. return le16_to_cpu(a->status);
  1255. }
  1256. static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
  1257. {
  1258. struct ieee80211_authentication *a;
  1259. if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
  1260. IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
  1261. return -1;
  1262. }
  1263. a = (struct ieee80211_authentication *) skb->data;
  1264. memcpy(dest,a->header.addr2, ETH_ALEN);
  1265. if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
  1266. return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
  1267. return WLAN_STATUS_SUCCESS;
  1268. }
  1269. static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
  1270. {
  1271. u8 *tag;
  1272. u8 *skbend;
  1273. u8 *ssid=NULL;
  1274. u8 ssidlen = 0;
  1275. struct rtl_80211_hdr_3addr *header =
  1276. (struct rtl_80211_hdr_3addr *) skb->data;
  1277. if (skb->len < sizeof (struct rtl_80211_hdr_3addr ))
  1278. return -1; /* corrupted */
  1279. memcpy(src,header->addr2, ETH_ALEN);
  1280. skbend = (u8 *)skb->data + skb->len;
  1281. tag = skb->data + sizeof (struct rtl_80211_hdr_3addr );
  1282. while (tag+1 < skbend){
  1283. if (*tag == 0) {
  1284. ssid = tag+2;
  1285. ssidlen = *(tag+1);
  1286. break;
  1287. }
  1288. tag++; /* point to the len field */
  1289. tag = tag + *(tag); /* point to the last data byte of the tag */
  1290. tag++; /* point to the next tag */
  1291. }
  1292. //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
  1293. if (ssidlen == 0) return 1;
  1294. if (!ssid) return 1; /* ssid not found in tagged param */
  1295. return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
  1296. }
  1297. static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
  1298. {
  1299. struct ieee80211_assoc_request_frame *a;
  1300. if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
  1301. sizeof(struct ieee80211_info_element))) {
  1302. IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
  1303. return -1;
  1304. }
  1305. a = (struct ieee80211_assoc_request_frame *) skb->data;
  1306. memcpy(dest,a->header.addr2,ETH_ALEN);
  1307. return 0;
  1308. }
  1309. static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
  1310. {
  1311. struct ieee80211_assoc_response_frame *response_head;
  1312. u16 status_code;
  1313. if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
  1314. IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
  1315. return 0xcafe;
  1316. }
  1317. response_head = (struct ieee80211_assoc_response_frame *) skb->data;
  1318. *aid = le16_to_cpu(response_head->aid) & 0x3fff;
  1319. status_code = le16_to_cpu(response_head->status);
  1320. if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
  1321. status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
  1322. ((ieee->mode == IEEE_G) &&
  1323. (ieee->current_network.mode == IEEE_N_24G) &&
  1324. (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
  1325. ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
  1326. }else {
  1327. ieee->AsocRetryCount = 0;
  1328. }
  1329. return le16_to_cpu(response_head->status);
  1330. }
  1331. static inline void
  1332. ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  1333. {
  1334. u8 dest[ETH_ALEN];
  1335. //IEEE80211DMESG("Rx probe");
  1336. ieee->softmac_stats.rx_probe_rq++;
  1337. //DMESG("Dest is "MACSTR, MAC2STR(dest));
  1338. if (probe_rq_parse(ieee, skb, dest)) {
  1339. //IEEE80211DMESG("Was for me!");
  1340. ieee->softmac_stats.tx_probe_rs++;
  1341. ieee80211_resp_to_probe(ieee, dest);
  1342. }
  1343. }
  1344. static inline void
  1345. ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  1346. {
  1347. u8 dest[ETH_ALEN];
  1348. int status;
  1349. //IEEE80211DMESG("Rx probe");
  1350. ieee->softmac_stats.rx_auth_rq++;
  1351. status = auth_rq_parse(skb, dest);
  1352. if (status != -1) {
  1353. ieee80211_resp_to_auth(ieee, status, dest);
  1354. }
  1355. //DMESG("Dest is "MACSTR, MAC2STR(dest));
  1356. }
  1357. static inline void
  1358. ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  1359. {
  1360. u8 dest[ETH_ALEN];
  1361. //unsigned long flags;
  1362. ieee->softmac_stats.rx_ass_rq++;
  1363. if (assoc_rq_parse(skb, dest) != -1) {
  1364. ieee80211_resp_to_assoc_rq(ieee, dest);
  1365. }
  1366. printk(KERN_INFO"New client associated: %pM\n", dest);
  1367. //FIXME
  1368. }
  1369. static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
  1370. short pwr)
  1371. {
  1372. struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
  1373. if (buf)
  1374. softmac_ps_mgmt_xmit(buf, ieee);
  1375. }
  1376. /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
  1377. static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
  1378. u32 *time_l)
  1379. {
  1380. int timeout = ieee->ps_timeout;
  1381. u8 dtim;
  1382. /*if(ieee->ps == IEEE80211_PS_DISABLED ||
  1383. ieee->iw_mode != IW_MODE_INFRA ||
  1384. ieee->state != IEEE80211_LINKED)
  1385. return 0;
  1386. */
  1387. dtim = ieee->current_network.dtim_data;
  1388. if(!(dtim & IEEE80211_DTIM_VALID))
  1389. return 0;
  1390. timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
  1391. ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
  1392. if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
  1393. return 2;
  1394. if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
  1395. return 0;
  1396. if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
  1397. return 0;
  1398. if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
  1399. (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
  1400. return 0;
  1401. if (time_l) {
  1402. *time_l = ieee->current_network.last_dtim_sta_time[0]
  1403. + (ieee->current_network.beacon_interval
  1404. * ieee->current_network.dtim_period) * 1000;
  1405. }
  1406. if (time_h) {
  1407. *time_h = ieee->current_network.last_dtim_sta_time[1];
  1408. if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
  1409. *time_h += 1;
  1410. }
  1411. return 1;
  1412. }
  1413. static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
  1414. {
  1415. u32 th, tl;
  1416. short sleep;
  1417. unsigned long flags, flags2;
  1418. spin_lock_irqsave(&ieee->lock, flags);
  1419. if ((ieee->ps == IEEE80211_PS_DISABLED ||
  1420. ieee->iw_mode != IW_MODE_INFRA ||
  1421. ieee->state != IEEE80211_LINKED)){
  1422. // #warning CHECK_LOCK_HERE
  1423. spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  1424. ieee80211_sta_wakeup(ieee, 1);
  1425. spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  1426. }
  1427. sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
  1428. /* 2 wake, 1 sleep, 0 do nothing */
  1429. if(sleep == 0)
  1430. goto out;
  1431. if(sleep == 1){
  1432. if(ieee->sta_sleep == 1)
  1433. ieee->enter_sleep_state(ieee->dev, th, tl);
  1434. else if(ieee->sta_sleep == 0){
  1435. // printk("send null 1\n");
  1436. spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  1437. if(ieee->ps_is_queue_empty(ieee->dev)){
  1438. ieee->sta_sleep = 2;
  1439. ieee->ps_request_tx_ack(ieee->dev);
  1440. ieee80211_sta_ps_send_null_frame(ieee, 1);
  1441. ieee->ps_th = th;
  1442. ieee->ps_tl = tl;
  1443. }
  1444. spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  1445. }
  1446. }else if(sleep == 2){
  1447. //#warning CHECK_LOCK_HERE
  1448. spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  1449. ieee80211_sta_wakeup(ieee, 1);
  1450. spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  1451. }
  1452. out:
  1453. spin_unlock_irqrestore(&ieee->lock, flags);
  1454. }
  1455. void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
  1456. {
  1457. if (ieee->sta_sleep == 0) {
  1458. if (nl) {
  1459. printk("Warning: driver is probably failing to report TX ps error\n");
  1460. ieee->ps_request_tx_ack(ieee->dev);
  1461. ieee80211_sta_ps_send_null_frame(ieee, 0);
  1462. }
  1463. return;
  1464. }
  1465. if(ieee->sta_sleep == 1)
  1466. ieee->sta_wake_up(ieee->dev);
  1467. ieee->sta_sleep = 0;
  1468. if (nl) {
  1469. ieee->ps_request_tx_ack(ieee->dev);
  1470. ieee80211_sta_ps_send_null_frame(ieee, 0);
  1471. }
  1472. }
  1473. void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
  1474. {
  1475. unsigned long flags, flags2;
  1476. spin_lock_irqsave(&ieee->lock, flags);
  1477. if(ieee->sta_sleep == 2){
  1478. /* Null frame with PS bit set */
  1479. if (success) {
  1480. ieee->sta_sleep = 1;
  1481. ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
  1482. }
  1483. /* if the card report not success we can't be sure the AP
  1484. * has not RXed so we can't assume the AP believe us awake
  1485. */
  1486. }
  1487. /* 21112005 - tx again null without PS bit if lost */
  1488. else {
  1489. if ((ieee->sta_sleep == 0) && !success) {
  1490. spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  1491. ieee80211_sta_ps_send_null_frame(ieee, 0);
  1492. spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  1493. }
  1494. }
  1495. spin_unlock_irqrestore(&ieee->lock, flags);
  1496. }
  1497. EXPORT_SYMBOL(ieee80211_ps_tx_ack);
  1498. static void ieee80211_process_action(struct ieee80211_device *ieee,
  1499. struct sk_buff *skb)
  1500. {
  1501. struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
  1502. u8 *act = ieee80211_get_payload(header);
  1503. u8 tmp = 0;
  1504. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
  1505. if (act == NULL)
  1506. {
  1507. IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
  1508. return;
  1509. }
  1510. tmp = *act;
  1511. act ++;
  1512. switch (tmp) {
  1513. case ACT_CAT_BA:
  1514. if (*act == ACT_ADDBAREQ)
  1515. ieee80211_rx_ADDBAReq(ieee, skb);
  1516. else if (*act == ACT_ADDBARSP)
  1517. ieee80211_rx_ADDBARsp(ieee, skb);
  1518. else if (*act == ACT_DELBA)
  1519. ieee80211_rx_DELBA(ieee, skb);
  1520. break;
  1521. default:
  1522. break;
  1523. }
  1524. return;
  1525. }
  1526. static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
  1527. struct sk_buff *skb)
  1528. {
  1529. /* default support N mode, disable halfNmode */
  1530. bool bSupportNmode = true, bHalfSupportNmode = false;
  1531. u16 errcode;
  1532. u8 *challenge;
  1533. int chlen = 0;
  1534. u32 iotAction;
  1535. errcode = auth_parse(skb, &challenge, &chlen);
  1536. if (!errcode) {
  1537. if (ieee->open_wep || !challenge) {
  1538. ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
  1539. ieee->softmac_stats.rx_auth_rs_ok++;
  1540. iotAction = ieee->pHTInfo->IOTAction;
  1541. if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
  1542. if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
  1543. /* WEP or TKIP encryption */
  1544. if (IsHTHalfNmodeAPs(ieee)) {
  1545. bSupportNmode = true;
  1546. bHalfSupportNmode = true;
  1547. } else {
  1548. bSupportNmode = false;
  1549. bHalfSupportNmode = false;
  1550. }
  1551. netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
  1552. bSupportNmode,
  1553. bHalfSupportNmode);
  1554. }
  1555. }
  1556. /* Dummy wirless mode setting- avoid encryption issue */
  1557. if (bSupportNmode) {
  1558. /* N mode setting */
  1559. ieee->SetWirelessMode(ieee->dev,
  1560. ieee->current_network.mode);
  1561. } else {
  1562. /* b/g mode setting - TODO */
  1563. ieee->SetWirelessMode(ieee->dev, IEEE_G);
  1564. }
  1565. if (ieee->current_network.mode == IEEE_N_24G &&
  1566. bHalfSupportNmode) {
  1567. netdev_dbg(ieee->dev, "enter half N mode\n");
  1568. ieee->bHalfWirelessN24GMode = true;
  1569. } else
  1570. ieee->bHalfWirelessN24GMode = false;
  1571. ieee80211_associate_step2(ieee);
  1572. } else {
  1573. ieee80211_auth_challenge(ieee, challenge, chlen);
  1574. }
  1575. } else {
  1576. ieee->softmac_stats.rx_auth_rs_err++;
  1577. IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
  1578. ieee80211_associate_abort(ieee);
  1579. }
  1580. }
  1581. inline int
  1582. ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
  1583. struct ieee80211_rx_stats *rx_stats, u16 type,
  1584. u16 stype)
  1585. {
  1586. struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *) skb->data;
  1587. u16 errcode;
  1588. int aid;
  1589. struct ieee80211_assoc_response_frame *assoc_resp;
  1590. // struct ieee80211_info_element *info_element;
  1591. if(!ieee->proto_started)
  1592. return 0;
  1593. if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
  1594. ieee->iw_mode == IW_MODE_INFRA &&
  1595. ieee->state == IEEE80211_LINKED))
  1596. tasklet_schedule(&ieee->ps_task);
  1597. if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
  1598. WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
  1599. ieee->last_rx_ps_time = jiffies;
  1600. switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  1601. case IEEE80211_STYPE_ASSOC_RESP:
  1602. case IEEE80211_STYPE_REASSOC_RESP:
  1603. IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
  1604. WLAN_FC_GET_STYPE(header->frame_ctl));
  1605. if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  1606. ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
  1607. ieee->iw_mode == IW_MODE_INFRA){
  1608. struct ieee80211_network network_resp;
  1609. struct ieee80211_network *network = &network_resp;
  1610. errcode = assoc_parse(ieee, skb, &aid);
  1611. if (!errcode) {
  1612. ieee->state=IEEE80211_LINKED;
  1613. ieee->assoc_id = aid;
  1614. ieee->softmac_stats.rx_ass_ok++;
  1615. /* station support qos */
  1616. /* Let the register setting defaultly with Legacy station */
  1617. if (ieee->qos_support) {
  1618. assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
  1619. memset(network, 0, sizeof(*network));
  1620. if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
  1621. rx_stats->len - sizeof(*assoc_resp),\
  1622. network,rx_stats)){
  1623. return 1;
  1624. }
  1625. else
  1626. { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
  1627. memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
  1628. memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
  1629. }
  1630. if (ieee->handle_assoc_response != NULL)
  1631. ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
  1632. }
  1633. ieee80211_associate_complete(ieee);
  1634. } else {
  1635. /* aid could not been allocated */
  1636. ieee->softmac_stats.rx_ass_err++;
  1637. printk(
  1638. "Association response status code 0x%x\n",
  1639. errcode);
  1640. IEEE80211_DEBUG_MGMT(
  1641. "Association response status code 0x%x\n",
  1642. errcode);
  1643. if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
  1644. queue_work(ieee->wq, &ieee->associate_procedure_wq);
  1645. } else {
  1646. ieee80211_associate_abort(ieee);
  1647. }
  1648. }
  1649. }
  1650. break;
  1651. case IEEE80211_STYPE_ASSOC_REQ:
  1652. case IEEE80211_STYPE_REASSOC_REQ:
  1653. if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  1654. ieee->iw_mode == IW_MODE_MASTER)
  1655. ieee80211_rx_assoc_rq(ieee, skb);
  1656. break;
  1657. case IEEE80211_STYPE_AUTH:
  1658. if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
  1659. if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
  1660. && ieee->iw_mode == IW_MODE_INFRA) {
  1661. IEEE80211_DEBUG_MGMT("Received auth response");
  1662. ieee80211_check_auth_response(ieee, skb);
  1663. } else if (ieee->iw_mode == IW_MODE_MASTER) {
  1664. ieee80211_rx_auth_rq(ieee, skb);
  1665. }
  1666. }
  1667. break;
  1668. case IEEE80211_STYPE_PROBE_REQ:
  1669. if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
  1670. ((ieee->iw_mode == IW_MODE_ADHOC ||
  1671. ieee->iw_mode == IW_MODE_MASTER) &&
  1672. ieee->state == IEEE80211_LINKED)){
  1673. ieee80211_rx_probe_rq(ieee, skb);
  1674. }
  1675. break;
  1676. case IEEE80211_STYPE_DISASSOC:
  1677. case IEEE80211_STYPE_DEAUTH:
  1678. /* FIXME for now repeat all the association procedure
  1679. * both for disassociation and deauthentication
  1680. */
  1681. if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  1682. ieee->state == IEEE80211_LINKED &&
  1683. ieee->iw_mode == IW_MODE_INFRA){
  1684. ieee->state = IEEE80211_ASSOCIATING;
  1685. ieee->softmac_stats.reassoc++;
  1686. notify_wx_assoc_event(ieee);
  1687. //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  1688. RemovePeerTS(ieee, header->addr2);
  1689. queue_work(ieee->wq, &ieee->associate_procedure_wq);
  1690. }
  1691. break;
  1692. case IEEE80211_STYPE_MANAGE_ACT:
  1693. ieee80211_process_action(ieee, skb);
  1694. break;
  1695. default:
  1696. return -1;
  1697. }
  1698. //dev_kfree_skb_any(skb);
  1699. return 0;
  1700. }
  1701. /* The following are for a simpler TX queue management.
  1702. * Instead of using netif_[stop/wake]_queue, the driver
  1703. * will use these two functions (plus a reset one) that
  1704. * will internally call the kernel netif_* and take care
  1705. * of the ieee802.11 fragmentation.
  1706. * So, the driver receives a fragment at a time and might
  1707. * call the stop function when it wants, without taking
  1708. * care to have enough room to TX an entire packet.
  1709. * This might be useful if each fragment needs its own
  1710. * descriptor. Thus, just keeping a total free memory > than
  1711. * the max fragmentation threshold is not enough. If the
  1712. * ieee802.11 stack passed a TXB struct, then you would need
  1713. * to keep N free descriptors where
  1714. * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
  1715. * In this way you need just one and the 802.11 stack
  1716. * will take care of buffering fragments and pass them to
  1717. * to the driver later, when it wakes the queue.
  1718. */
  1719. void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
  1720. {
  1721. unsigned int queue_index = txb->queue_index;
  1722. unsigned long flags;
  1723. int i;
  1724. cb_desc *tcb_desc = NULL;
  1725. spin_lock_irqsave(&ieee->lock, flags);
  1726. /* called with 2nd parm 0, no tx mgmt lock required */
  1727. ieee80211_sta_wakeup(ieee, 0);
  1728. /* update the tx status */
  1729. ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
  1730. ieee->stats.tx_packets++;
  1731. tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
  1732. if (tcb_desc->bMulticast) {
  1733. ieee->stats.multicast++;
  1734. }
  1735. /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
  1736. for(i = 0; i < txb->nr_frags; i++) {
  1737. #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
  1738. if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
  1739. #else
  1740. if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
  1741. #endif
  1742. (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
  1743. (ieee->queue_stop)) {
  1744. /* insert the skb packet to the wait queue */
  1745. /* as for the completion function, it does not need
  1746. * to check it any more.
  1747. * */
  1748. //printk("error:no descriptor left@queue_index %d\n", queue_index);
  1749. //ieee80211_stop_queue(ieee);
  1750. #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
  1751. skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
  1752. #else
  1753. skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
  1754. #endif
  1755. }else{
  1756. ieee->softmac_data_hard_start_xmit(
  1757. txb->fragments[i],
  1758. ieee->dev, ieee->rate);
  1759. //ieee->stats.tx_packets++;
  1760. //ieee->stats.tx_bytes += txb->fragments[i]->len;
  1761. //ieee->dev->trans_start = jiffies;
  1762. }
  1763. }
  1764. ieee80211_txb_free(txb);
  1765. //exit:
  1766. spin_unlock_irqrestore(&ieee->lock, flags);
  1767. }
  1768. EXPORT_SYMBOL(ieee80211_softmac_xmit);
  1769. /* called with ieee->lock acquired */
  1770. static void ieee80211_resume_tx(struct ieee80211_device *ieee)
  1771. {
  1772. int i;
  1773. for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
  1774. if (ieee->queue_stop){
  1775. ieee->tx_pending.frag = i;
  1776. return;
  1777. }else{
  1778. ieee->softmac_data_hard_start_xmit(
  1779. ieee->tx_pending.txb->fragments[i],
  1780. ieee->dev, ieee->rate);
  1781. //(i+1)<ieee->tx_pending.txb->nr_frags);
  1782. ieee->stats.tx_packets++;
  1783. ieee->dev->trans_start = jiffies;
  1784. }
  1785. }
  1786. ieee80211_txb_free(ieee->tx_pending.txb);
  1787. ieee->tx_pending.txb = NULL;
  1788. }
  1789. void ieee80211_reset_queue(struct ieee80211_device *ieee)
  1790. {
  1791. unsigned long flags;
  1792. spin_lock_irqsave(&ieee->lock, flags);
  1793. init_mgmt_queue(ieee);
  1794. if (ieee->tx_pending.txb) {
  1795. ieee80211_txb_free(ieee->tx_pending.txb);
  1796. ieee->tx_pending.txb = NULL;
  1797. }
  1798. ieee->queue_stop = 0;
  1799. spin_unlock_irqrestore(&ieee->lock, flags);
  1800. }
  1801. EXPORT_SYMBOL(ieee80211_reset_queue);
  1802. void ieee80211_wake_queue(struct ieee80211_device *ieee)
  1803. {
  1804. unsigned long flags;
  1805. struct sk_buff *skb;
  1806. struct rtl_80211_hdr_3addr *header;
  1807. spin_lock_irqsave(&ieee->lock, flags);
  1808. if (! ieee->queue_stop) goto exit;
  1809. ieee->queue_stop = 0;
  1810. if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
  1811. while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
  1812. header = (struct rtl_80211_hdr_3addr *) skb->data;
  1813. header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  1814. if (ieee->seq_ctrl[0] == 0xFFF)
  1815. ieee->seq_ctrl[0] = 0;
  1816. else
  1817. ieee->seq_ctrl[0]++;
  1818. ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  1819. //dev_kfree_skb_any(skb);//edit by thomas
  1820. }
  1821. }
  1822. if (!ieee->queue_stop && ieee->tx_pending.txb)
  1823. ieee80211_resume_tx(ieee);
  1824. if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
  1825. ieee->softmac_stats.swtxawake++;
  1826. netif_wake_queue(ieee->dev);
  1827. }
  1828. exit :
  1829. spin_unlock_irqrestore(&ieee->lock, flags);
  1830. }
  1831. EXPORT_SYMBOL(ieee80211_wake_queue);
  1832. void ieee80211_stop_queue(struct ieee80211_device *ieee)
  1833. {
  1834. //unsigned long flags;
  1835. //spin_lock_irqsave(&ieee->lock,flags);
  1836. if (!netif_queue_stopped(ieee->dev)) {
  1837. netif_stop_queue(ieee->dev);
  1838. ieee->softmac_stats.swtxstop++;
  1839. }
  1840. ieee->queue_stop = 1;
  1841. //spin_unlock_irqrestore(&ieee->lock,flags);
  1842. }
  1843. EXPORT_SYMBOL(ieee80211_stop_queue);
  1844. inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
  1845. {
  1846. random_ether_addr(ieee->current_network.bssid);
  1847. }
  1848. /* called in user context only */
  1849. void ieee80211_start_master_bss(struct ieee80211_device *ieee)
  1850. {
  1851. ieee->assoc_id = 1;
  1852. if (ieee->current_network.ssid_len == 0) {
  1853. strncpy(ieee->current_network.ssid,
  1854. IEEE80211_DEFAULT_TX_ESSID,
  1855. IW_ESSID_MAX_SIZE);
  1856. ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  1857. ieee->ssid_set = 1;
  1858. }
  1859. memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
  1860. ieee->set_chan(ieee->dev, ieee->current_network.channel);
  1861. ieee->state = IEEE80211_LINKED;
  1862. ieee->link_change(ieee->dev);
  1863. notify_wx_assoc_event(ieee);
  1864. if (ieee->data_hard_resume)
  1865. ieee->data_hard_resume(ieee->dev);
  1866. netif_carrier_on(ieee->dev);
  1867. }
  1868. static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
  1869. {
  1870. if (ieee->raw_tx) {
  1871. if (ieee->data_hard_resume)
  1872. ieee->data_hard_resume(ieee->dev);
  1873. netif_carrier_on(ieee->dev);
  1874. }
  1875. }
  1876. static void ieee80211_start_ibss_wq(struct work_struct *work)
  1877. {
  1878. struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  1879. struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
  1880. /* iwconfig mode ad-hoc will schedule this and return
  1881. * on the other hand this will block further iwconfig SET
  1882. * operations because of the wx_sem hold.
  1883. * Anyway some most set operations set a flag to speed-up
  1884. * (abort) this wq (when syncro scanning) before sleeping
  1885. * on the semaphore
  1886. */
  1887. if (!ieee->proto_started) {
  1888. printk("==========oh driver down return\n");
  1889. return;
  1890. }
  1891. down(&ieee->wx_sem);
  1892. if (ieee->current_network.ssid_len == 0) {
  1893. strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
  1894. ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  1895. ieee->ssid_set = 1;
  1896. }
  1897. /* check if we have this cell in our network list */
  1898. ieee80211_softmac_check_all_nets(ieee);
  1899. // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
  1900. if (ieee->state == IEEE80211_NOLINK)
  1901. ieee->current_network.channel = 6;
  1902. /* if not then the state is not linked. Maybe the user swithced to
  1903. * ad-hoc mode just after being in monitor mode, or just after
  1904. * being very few time in managed mode (so the card have had no
  1905. * time to scan all the chans..) or we have just run up the iface
  1906. * after setting ad-hoc mode. So we have to give another try..
  1907. * Here, in ibss mode, should be safe to do this without extra care
  1908. * (in bss mode we had to make sure no-one tryed to associate when
  1909. * we had just checked the ieee->state and we was going to start the
  1910. * scan) beacause in ibss mode the ieee80211_new_net function, when
  1911. * finds a good net, just set the ieee->state to IEEE80211_LINKED,
  1912. * so, at worst, we waste a bit of time to initiate an unneeded syncro
  1913. * scan, that will stop at the first round because it sees the state
  1914. * associated.
  1915. */
  1916. if (ieee->state == IEEE80211_NOLINK)
  1917. ieee80211_start_scan_syncro(ieee);
  1918. /* the network definitively is not here.. create a new cell */
  1919. if (ieee->state == IEEE80211_NOLINK) {
  1920. printk("creating new IBSS cell\n");
  1921. if(!ieee->wap_set)
  1922. ieee80211_randomize_cell(ieee);
  1923. if(ieee->modulation & IEEE80211_CCK_MODULATION){
  1924. ieee->current_network.rates_len = 4;
  1925. ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  1926. ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  1927. ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  1928. ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  1929. }else
  1930. ieee->current_network.rates_len = 0;
  1931. if(ieee->modulation & IEEE80211_OFDM_MODULATION){
  1932. ieee->current_network.rates_ex_len = 8;
  1933. ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  1934. ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
  1935. ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  1936. ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
  1937. ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  1938. ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
  1939. ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
  1940. ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
  1941. ieee->rate = 108;
  1942. }else{
  1943. ieee->current_network.rates_ex_len = 0;
  1944. ieee->rate = 22;
  1945. }
  1946. // By default, WMM function will be disabled in IBSS mode
  1947. ieee->current_network.QoS_Enable = 0;
  1948. ieee->SetWirelessMode(ieee->dev, IEEE_G);
  1949. ieee->current_network.atim_window = 0;
  1950. ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
  1951. if(ieee->short_slot)
  1952. ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
  1953. }
  1954. ieee->state = IEEE80211_LINKED;
  1955. ieee->set_chan(ieee->dev, ieee->current_network.channel);
  1956. ieee->link_change(ieee->dev);
  1957. notify_wx_assoc_event(ieee);
  1958. ieee80211_start_send_beacons(ieee);
  1959. if (ieee->data_hard_resume)
  1960. ieee->data_hard_resume(ieee->dev);
  1961. netif_carrier_on(ieee->dev);
  1962. up(&ieee->wx_sem);
  1963. }
  1964. inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
  1965. {
  1966. queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
  1967. }
  1968. /* this is called only in user context, with wx_sem held */
  1969. void ieee80211_start_bss(struct ieee80211_device *ieee)
  1970. {
  1971. unsigned long flags;
  1972. //
  1973. // Ref: 802.11d 11.1.3.3
  1974. // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
  1975. //
  1976. if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
  1977. {
  1978. if (! ieee->bGlobalDomain)
  1979. {
  1980. return;
  1981. }
  1982. }
  1983. /* check if we have already found the net we
  1984. * are interested in (if any).
  1985. * if not (we are disassociated and we are not
  1986. * in associating / authenticating phase) start the background scanning.
  1987. */
  1988. ieee80211_softmac_check_all_nets(ieee);
  1989. /* ensure no-one start an associating process (thus setting
  1990. * the ieee->state to ieee80211_ASSOCIATING) while we
  1991. * have just cheked it and we are going to enable scan.
  1992. * The ieee80211_new_net function is always called with
  1993. * lock held (from both ieee80211_softmac_check_all_nets and
  1994. * the rx path), so we cannot be in the middle of such function
  1995. */
  1996. spin_lock_irqsave(&ieee->lock, flags);
  1997. if (ieee->state == IEEE80211_NOLINK) {
  1998. ieee->actscanning = true;
  1999. ieee80211_start_scan(ieee);
  2000. }
  2001. spin_unlock_irqrestore(&ieee->lock, flags);
  2002. }
  2003. /* called only in userspace context */
  2004. void ieee80211_disassociate(struct ieee80211_device *ieee)
  2005. {
  2006. netif_carrier_off(ieee->dev);
  2007. if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
  2008. ieee80211_reset_queue(ieee);
  2009. if (ieee->data_hard_stop)
  2010. ieee->data_hard_stop(ieee->dev);
  2011. if(IS_DOT11D_ENABLE(ieee))
  2012. Dot11d_Reset(ieee);
  2013. ieee->state = IEEE80211_NOLINK;
  2014. ieee->is_set_key = false;
  2015. ieee->link_change(ieee->dev);
  2016. //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  2017. notify_wx_assoc_event(ieee);
  2018. }
  2019. EXPORT_SYMBOL(ieee80211_disassociate);
  2020. static void ieee80211_associate_retry_wq(struct work_struct *work)
  2021. {
  2022. struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  2023. struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
  2024. unsigned long flags;
  2025. down(&ieee->wx_sem);
  2026. if(!ieee->proto_started)
  2027. goto exit;
  2028. if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
  2029. goto exit;
  2030. /* until we do not set the state to IEEE80211_NOLINK
  2031. * there are no possibility to have someone else trying
  2032. * to start an association procedure (we get here with
  2033. * ieee->state = IEEE80211_ASSOCIATING).
  2034. * When we set the state to IEEE80211_NOLINK it is possible
  2035. * that the RX path run an attempt to associate, but
  2036. * both ieee80211_softmac_check_all_nets and the
  2037. * RX path works with ieee->lock held so there are no
  2038. * problems. If we are still disassociated then start a scan.
  2039. * the lock here is necessary to ensure no one try to start
  2040. * an association procedure when we have just checked the
  2041. * state and we are going to start the scan.
  2042. */
  2043. ieee->state = IEEE80211_NOLINK;
  2044. ieee80211_softmac_check_all_nets(ieee);
  2045. spin_lock_irqsave(&ieee->lock, flags);
  2046. if(ieee->state == IEEE80211_NOLINK)
  2047. ieee80211_start_scan(ieee);
  2048. spin_unlock_irqrestore(&ieee->lock, flags);
  2049. exit:
  2050. up(&ieee->wx_sem);
  2051. }
  2052. struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
  2053. {
  2054. u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  2055. struct sk_buff *skb;
  2056. struct ieee80211_probe_response *b;
  2057. skb = ieee80211_probe_resp(ieee, broadcast_addr);
  2058. if (!skb)
  2059. return NULL;
  2060. b = (struct ieee80211_probe_response *) skb->data;
  2061. b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
  2062. return skb;
  2063. }
  2064. struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
  2065. {
  2066. struct sk_buff *skb;
  2067. struct ieee80211_probe_response *b;
  2068. skb = ieee80211_get_beacon_(ieee);
  2069. if(!skb)
  2070. return NULL;
  2071. b = (struct ieee80211_probe_response *) skb->data;
  2072. b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  2073. if (ieee->seq_ctrl[0] == 0xFFF)
  2074. ieee->seq_ctrl[0] = 0;
  2075. else
  2076. ieee->seq_ctrl[0]++;
  2077. return skb;
  2078. }
  2079. EXPORT_SYMBOL(ieee80211_get_beacon);
  2080. void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
  2081. {
  2082. ieee->sync_scan_hurryup = 1;
  2083. down(&ieee->wx_sem);
  2084. ieee80211_stop_protocol(ieee);
  2085. up(&ieee->wx_sem);
  2086. }
  2087. EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
  2088. void ieee80211_stop_protocol(struct ieee80211_device *ieee)
  2089. {
  2090. if (!ieee->proto_started)
  2091. return;
  2092. ieee->proto_started = 0;
  2093. ieee80211_stop_send_beacons(ieee);
  2094. del_timer_sync(&ieee->associate_timer);
  2095. cancel_delayed_work(&ieee->associate_retry_wq);
  2096. cancel_delayed_work(&ieee->start_ibss_wq);
  2097. ieee80211_stop_scan(ieee);
  2098. ieee80211_disassociate(ieee);
  2099. RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
  2100. }
  2101. void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
  2102. {
  2103. ieee->sync_scan_hurryup = 0;
  2104. down(&ieee->wx_sem);
  2105. ieee80211_start_protocol(ieee);
  2106. up(&ieee->wx_sem);
  2107. }
  2108. EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
  2109. void ieee80211_start_protocol(struct ieee80211_device *ieee)
  2110. {
  2111. short ch = 0;
  2112. int i = 0;
  2113. if (ieee->proto_started)
  2114. return;
  2115. ieee->proto_started = 1;
  2116. if (ieee->current_network.channel == 0) {
  2117. do{
  2118. ch++;
  2119. if (ch > MAX_CHANNEL_NUMBER)
  2120. return; /* no channel found */
  2121. }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
  2122. ieee->current_network.channel = ch;
  2123. }
  2124. if (ieee->current_network.beacon_interval == 0)
  2125. ieee->current_network.beacon_interval = 100;
  2126. // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
  2127. // ieee->set_chan(ieee->dev,ieee->current_network.channel);
  2128. for(i = 0; i < 17; i++) {
  2129. ieee->last_rxseq_num[i] = -1;
  2130. ieee->last_rxfrag_num[i] = -1;
  2131. ieee->last_packet_time[i] = 0;
  2132. }
  2133. ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
  2134. /* if the user set the MAC of the ad-hoc cell and then
  2135. * switch to managed mode, shall we make sure that association
  2136. * attempts does not fail just because the user provide the essid
  2137. * and the nic is still checking for the AP MAC ??
  2138. */
  2139. if (ieee->iw_mode == IW_MODE_INFRA)
  2140. ieee80211_start_bss(ieee);
  2141. else if (ieee->iw_mode == IW_MODE_ADHOC)
  2142. ieee80211_start_ibss(ieee);
  2143. else if (ieee->iw_mode == IW_MODE_MASTER)
  2144. ieee80211_start_master_bss(ieee);
  2145. else if(ieee->iw_mode == IW_MODE_MONITOR)
  2146. ieee80211_start_monitor_mode(ieee);
  2147. }
  2148. #define DRV_NAME "Ieee80211"
  2149. void ieee80211_softmac_init(struct ieee80211_device *ieee)
  2150. {
  2151. int i;
  2152. memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
  2153. ieee->state = IEEE80211_NOLINK;
  2154. ieee->sync_scan_hurryup = 0;
  2155. for(i = 0; i < 5; i++) {
  2156. ieee->seq_ctrl[i] = 0;
  2157. }
  2158. ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
  2159. if (!ieee->pDot11dInfo)
  2160. IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
  2161. //added for AP roaming
  2162. ieee->LinkDetectInfo.SlotNum = 2;
  2163. ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
  2164. ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
  2165. ieee->assoc_id = 0;
  2166. ieee->queue_stop = 0;
  2167. ieee->scanning = 0;
  2168. ieee->softmac_features = 0; //so IEEE2100-like driver are happy
  2169. ieee->wap_set = 0;
  2170. ieee->ssid_set = 0;
  2171. ieee->proto_started = 0;
  2172. ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
  2173. ieee->rate = 22;
  2174. ieee->ps = IEEE80211_PS_DISABLED;
  2175. ieee->sta_sleep = 0;
  2176. ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
  2177. ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
  2178. ieee->Regdot11HTOperationalRateSet[4]= 0x01;
  2179. //added by amy
  2180. ieee->actscanning = false;
  2181. ieee->beinretry = false;
  2182. ieee->is_set_key = false;
  2183. init_mgmt_queue(ieee);
  2184. ieee->sta_edca_param[0] = 0x0000A403;
  2185. ieee->sta_edca_param[1] = 0x0000A427;
  2186. ieee->sta_edca_param[2] = 0x005E4342;
  2187. ieee->sta_edca_param[3] = 0x002F3262;
  2188. ieee->aggregation = true;
  2189. ieee->enable_rx_imm_BA = true;
  2190. ieee->tx_pending.txb = NULL;
  2191. setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
  2192. (unsigned long)ieee);
  2193. setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
  2194. (unsigned long)ieee);
  2195. ieee->wq = create_workqueue(DRV_NAME);
  2196. INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
  2197. INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
  2198. INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
  2199. INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
  2200. INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
  2201. INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
  2202. sema_init(&ieee->wx_sem, 1);
  2203. sema_init(&ieee->scan_sem, 1);
  2204. spin_lock_init(&ieee->mgmt_tx_lock);
  2205. spin_lock_init(&ieee->beacon_lock);
  2206. tasklet_init(&ieee->ps_task,
  2207. (void(*)(unsigned long)) ieee80211_sta_ps,
  2208. (unsigned long)ieee);
  2209. }
  2210. void ieee80211_softmac_free(struct ieee80211_device *ieee)
  2211. {
  2212. down(&ieee->wx_sem);
  2213. kfree(ieee->pDot11dInfo);
  2214. ieee->pDot11dInfo = NULL;
  2215. del_timer_sync(&ieee->associate_timer);
  2216. cancel_delayed_work(&ieee->associate_retry_wq);
  2217. destroy_workqueue(ieee->wq);
  2218. up(&ieee->wx_sem);
  2219. }
  2220. /********************************************************
  2221. * Start of WPA code. *
  2222. * this is stolen from the ipw2200 driver *
  2223. ********************************************************/
  2224. static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
  2225. {
  2226. /* This is called when wpa_supplicant loads and closes the driver
  2227. * interface. */
  2228. printk("%s WPA\n",value ? "enabling" : "disabling");
  2229. ieee->wpa_enabled = value;
  2230. return 0;
  2231. }
  2232. static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
  2233. char *wpa_ie, int wpa_ie_len)
  2234. {
  2235. /* make sure WPA is enabled */
  2236. ieee80211_wpa_enable(ieee, 1);
  2237. ieee80211_disassociate(ieee);
  2238. }
  2239. static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
  2240. {
  2241. int ret = 0;
  2242. switch (command) {
  2243. case IEEE_MLME_STA_DEAUTH:
  2244. // silently ignore
  2245. break;
  2246. case IEEE_MLME_STA_DISASSOC:
  2247. ieee80211_disassociate(ieee);
  2248. break;
  2249. default:
  2250. printk("Unknown MLME request: %d\n", command);
  2251. ret = -EOPNOTSUPP;
  2252. }
  2253. return ret;
  2254. }
  2255. static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
  2256. struct ieee_param *param, int plen)
  2257. {
  2258. u8 *buf;
  2259. if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
  2260. (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
  2261. return -EINVAL;
  2262. if (param->u.wpa_ie.len) {
  2263. buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
  2264. GFP_KERNEL);
  2265. if (buf == NULL)
  2266. return -ENOMEM;
  2267. kfree(ieee->wpa_ie);
  2268. ieee->wpa_ie = buf;
  2269. ieee->wpa_ie_len = param->u.wpa_ie.len;
  2270. } else {
  2271. kfree(ieee->wpa_ie);
  2272. ieee->wpa_ie = NULL;
  2273. ieee->wpa_ie_len = 0;
  2274. }
  2275. ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
  2276. return 0;
  2277. }
  2278. #define AUTH_ALG_OPEN_SYSTEM 0x1
  2279. #define AUTH_ALG_SHARED_KEY 0x2
  2280. static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
  2281. {
  2282. struct ieee80211_security sec = {
  2283. .flags = SEC_AUTH_MODE,
  2284. };
  2285. if (value & AUTH_ALG_SHARED_KEY) {
  2286. sec.auth_mode = WLAN_AUTH_SHARED_KEY;
  2287. ieee->open_wep = 0;
  2288. ieee->auth_mode = 1;
  2289. } else if (value & AUTH_ALG_OPEN_SYSTEM){
  2290. sec.auth_mode = WLAN_AUTH_OPEN;
  2291. ieee->open_wep = 1;
  2292. ieee->auth_mode = 0;
  2293. }
  2294. else if (value & IW_AUTH_ALG_LEAP){
  2295. sec.auth_mode = WLAN_AUTH_LEAP;
  2296. ieee->open_wep = 1;
  2297. ieee->auth_mode = 2;
  2298. }
  2299. if (ieee->set_security)
  2300. ieee->set_security(ieee->dev, &sec);
  2301. //else
  2302. // ret = -EOPNOTSUPP;
  2303. return 0;
  2304. }
  2305. static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
  2306. {
  2307. int ret=0;
  2308. unsigned long flags;
  2309. switch (name) {
  2310. case IEEE_PARAM_WPA_ENABLED:
  2311. ret = ieee80211_wpa_enable(ieee, value);
  2312. break;
  2313. case IEEE_PARAM_TKIP_COUNTERMEASURES:
  2314. ieee->tkip_countermeasures=value;
  2315. break;
  2316. case IEEE_PARAM_DROP_UNENCRYPTED: {
  2317. /* HACK:
  2318. *
  2319. * wpa_supplicant calls set_wpa_enabled when the driver
  2320. * is loaded and unloaded, regardless of if WPA is being
  2321. * used. No other calls are made which can be used to
  2322. * determine if encryption will be used or not prior to
  2323. * association being expected. If encryption is not being
  2324. * used, drop_unencrypted is set to false, else true -- we
  2325. * can use this to determine if the CAP_PRIVACY_ON bit should
  2326. * be set.
  2327. */
  2328. struct ieee80211_security sec = {
  2329. .flags = SEC_ENABLED,
  2330. .enabled = value,
  2331. };
  2332. ieee->drop_unencrypted = value;
  2333. /* We only change SEC_LEVEL for open mode. Others
  2334. * are set by ipw_wpa_set_encryption.
  2335. */
  2336. if (!value) {
  2337. sec.flags |= SEC_LEVEL;
  2338. sec.level = SEC_LEVEL_0;
  2339. }
  2340. else {
  2341. sec.flags |= SEC_LEVEL;
  2342. sec.level = SEC_LEVEL_1;
  2343. }
  2344. if (ieee->set_security)
  2345. ieee->set_security(ieee->dev, &sec);
  2346. break;
  2347. }
  2348. case IEEE_PARAM_PRIVACY_INVOKED:
  2349. ieee->privacy_invoked=value;
  2350. break;
  2351. case IEEE_PARAM_AUTH_ALGS:
  2352. ret = ieee80211_wpa_set_auth_algs(ieee, value);
  2353. break;
  2354. case IEEE_PARAM_IEEE_802_1X:
  2355. ieee->ieee802_1x=value;
  2356. break;
  2357. case IEEE_PARAM_WPAX_SELECT:
  2358. // added for WPA2 mixed mode
  2359. spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
  2360. ieee->wpax_type_set = 1;
  2361. ieee->wpax_type_notify = value;
  2362. spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
  2363. break;
  2364. default:
  2365. printk("Unknown WPA param: %d\n",name);
  2366. ret = -EOPNOTSUPP;
  2367. }
  2368. return ret;
  2369. }
  2370. /* implementation borrowed from hostap driver */
  2371. static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
  2372. struct ieee_param *param, int param_len)
  2373. {
  2374. int ret = 0;
  2375. struct ieee80211_crypto_ops *ops;
  2376. struct ieee80211_crypt_data **crypt;
  2377. struct ieee80211_security sec = {
  2378. .flags = 0,
  2379. };
  2380. param->u.crypt.err = 0;
  2381. param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
  2382. if (param_len !=
  2383. (int) ((char *) param->u.crypt.key - (char *) param) +
  2384. param->u.crypt.key_len) {
  2385. printk("Len mismatch %d, %d\n", param_len,
  2386. param->u.crypt.key_len);
  2387. return -EINVAL;
  2388. }
  2389. if (is_broadcast_ether_addr(param->sta_addr)) {
  2390. if (param->u.crypt.idx >= WEP_KEYS)
  2391. return -EINVAL;
  2392. crypt = &ieee->crypt[param->u.crypt.idx];
  2393. } else {
  2394. return -EINVAL;
  2395. }
  2396. if (strcmp(param->u.crypt.alg, "none") == 0) {
  2397. if (crypt) {
  2398. sec.enabled = 0;
  2399. // FIXME FIXME
  2400. //sec.encrypt = 0;
  2401. sec.level = SEC_LEVEL_0;
  2402. sec.flags |= SEC_ENABLED | SEC_LEVEL;
  2403. ieee80211_crypt_delayed_deinit(ieee, crypt);
  2404. }
  2405. goto done;
  2406. }
  2407. sec.enabled = 1;
  2408. // FIXME FIXME
  2409. // sec.encrypt = 1;
  2410. sec.flags |= SEC_ENABLED;
  2411. /* IPW HW cannot build TKIP MIC, host decryption still needed. */
  2412. if (!(ieee->host_encrypt || ieee->host_decrypt) &&
  2413. strcmp(param->u.crypt.alg, "TKIP"))
  2414. goto skip_host_crypt;
  2415. ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  2416. if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
  2417. request_module("ieee80211_crypt_wep");
  2418. ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  2419. //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
  2420. } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
  2421. request_module("ieee80211_crypt_tkip");
  2422. ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  2423. } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
  2424. request_module("ieee80211_crypt_ccmp");
  2425. ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  2426. }
  2427. if (ops == NULL) {
  2428. printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
  2429. param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
  2430. ret = -EINVAL;
  2431. goto done;
  2432. }
  2433. if (*crypt == NULL || (*crypt)->ops != ops) {
  2434. struct ieee80211_crypt_data *new_crypt;
  2435. ieee80211_crypt_delayed_deinit(ieee, crypt);
  2436. new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
  2437. if (new_crypt == NULL) {
  2438. ret = -ENOMEM;
  2439. goto done;
  2440. }
  2441. new_crypt->ops = ops;
  2442. if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  2443. new_crypt->priv =
  2444. new_crypt->ops->init(param->u.crypt.idx);
  2445. if (new_crypt->priv == NULL) {
  2446. kfree(new_crypt);
  2447. param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
  2448. ret = -EINVAL;
  2449. goto done;
  2450. }
  2451. *crypt = new_crypt;
  2452. }
  2453. if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
  2454. (*crypt)->ops->set_key(param->u.crypt.key,
  2455. param->u.crypt.key_len, param->u.crypt.seq,
  2456. (*crypt)->priv) < 0) {
  2457. printk("key setting failed\n");
  2458. param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
  2459. ret = -EINVAL;
  2460. goto done;
  2461. }
  2462. skip_host_crypt:
  2463. if (param->u.crypt.set_tx) {
  2464. ieee->tx_keyidx = param->u.crypt.idx;
  2465. sec.active_key = param->u.crypt.idx;
  2466. sec.flags |= SEC_ACTIVE_KEY;
  2467. } else
  2468. sec.flags &= ~SEC_ACTIVE_KEY;
  2469. if (param->u.crypt.alg != NULL) {
  2470. memcpy(sec.keys[param->u.crypt.idx],
  2471. param->u.crypt.key,
  2472. param->u.crypt.key_len);
  2473. sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
  2474. sec.flags |= (1 << param->u.crypt.idx);
  2475. if (strcmp(param->u.crypt.alg, "WEP") == 0) {
  2476. sec.flags |= SEC_LEVEL;
  2477. sec.level = SEC_LEVEL_1;
  2478. } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
  2479. sec.flags |= SEC_LEVEL;
  2480. sec.level = SEC_LEVEL_2;
  2481. } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
  2482. sec.flags |= SEC_LEVEL;
  2483. sec.level = SEC_LEVEL_3;
  2484. }
  2485. }
  2486. done:
  2487. if (ieee->set_security)
  2488. ieee->set_security(ieee->dev, &sec);
  2489. /* Do not reset port if card is in Managed mode since resetting will
  2490. * generate new IEEE 802.11 authentication which may end up in looping
  2491. * with IEEE 802.1X. If your hardware requires a reset after WEP
  2492. * configuration (for example... Prism2), implement the reset_port in
  2493. * the callbacks structures used to initialize the 802.11 stack. */
  2494. if (ieee->reset_on_keychange &&
  2495. ieee->iw_mode != IW_MODE_INFRA &&
  2496. ieee->reset_port &&
  2497. ieee->reset_port(ieee->dev)) {
  2498. printk("reset_port failed\n");
  2499. param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
  2500. return -EINVAL;
  2501. }
  2502. return ret;
  2503. }
  2504. inline struct sk_buff *ieee80211_disassociate_skb(
  2505. struct ieee80211_network *beacon,
  2506. struct ieee80211_device *ieee,
  2507. u8 asRsn)
  2508. {
  2509. struct sk_buff *skb;
  2510. struct ieee80211_disassoc *disass;
  2511. skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
  2512. if (!skb)
  2513. return NULL;
  2514. disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
  2515. disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
  2516. disass->header.duration_id = 0;
  2517. memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
  2518. memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  2519. memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
  2520. disass->reason = cpu_to_le16(asRsn);
  2521. return skb;
  2522. }
  2523. void
  2524. SendDisassociation(
  2525. struct ieee80211_device *ieee,
  2526. u8 *asSta,
  2527. u8 asRsn
  2528. )
  2529. {
  2530. struct ieee80211_network *beacon = &ieee->current_network;
  2531. struct sk_buff *skb;
  2532. skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
  2533. if (skb) {
  2534. softmac_mgmt_xmit(skb, ieee);
  2535. //dev_kfree_skb_any(skb);//edit by thomas
  2536. }
  2537. }
  2538. EXPORT_SYMBOL(SendDisassociation);
  2539. int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
  2540. {
  2541. struct ieee_param *param;
  2542. int ret=0;
  2543. down(&ieee->wx_sem);
  2544. //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
  2545. if (p->length < sizeof(struct ieee_param) || !p->pointer) {
  2546. ret = -EINVAL;
  2547. goto out;
  2548. }
  2549. param = memdup_user(p->pointer, p->length);
  2550. if (IS_ERR(param)) {
  2551. ret = PTR_ERR(param);
  2552. goto out;
  2553. }
  2554. switch (param->cmd) {
  2555. case IEEE_CMD_SET_WPA_PARAM:
  2556. ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
  2557. param->u.wpa_param.value);
  2558. break;
  2559. case IEEE_CMD_SET_WPA_IE:
  2560. ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
  2561. break;
  2562. case IEEE_CMD_SET_ENCRYPTION:
  2563. ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
  2564. break;
  2565. case IEEE_CMD_MLME:
  2566. ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
  2567. param->u.mlme.reason_code);
  2568. break;
  2569. default:
  2570. printk("Unknown WPA supplicant request: %d\n",param->cmd);
  2571. ret = -EOPNOTSUPP;
  2572. break;
  2573. }
  2574. if (ret == 0 && copy_to_user(p->pointer, param, p->length))
  2575. ret = -EFAULT;
  2576. kfree(param);
  2577. out:
  2578. up(&ieee->wx_sem);
  2579. return ret;
  2580. }
  2581. EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
  2582. void notify_wx_assoc_event(struct ieee80211_device *ieee)
  2583. {
  2584. union iwreq_data wrqu;
  2585. wrqu.ap_addr.sa_family = ARPHRD_ETHER;
  2586. if (ieee->state == IEEE80211_LINKED)
  2587. memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
  2588. else
  2589. eth_zero_addr(wrqu.ap_addr.sa_data);
  2590. wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
  2591. }
  2592. EXPORT_SYMBOL(notify_wx_assoc_event);