rtw_mlme_ext.c 373 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. #define _RTW_MLME_EXT_C_
  21. #include <drv_types.h>
  22. struct mlme_handler mlme_sta_tbl[]={
  23. {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
  24. {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
  25. {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
  26. {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
  27. {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
  28. {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
  29. /*----------------------------------------------------------
  30. below 2 are reserved
  31. -----------------------------------------------------------*/
  32. {0, "DoReserved", &DoReserved},
  33. {0, "DoReserved", &DoReserved},
  34. {WIFI_BEACON, "OnBeacon", &OnBeacon},
  35. {WIFI_ATIM, "OnATIM", &OnAtim},
  36. {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
  37. {WIFI_AUTH, "OnAuth", &OnAuthClient},
  38. {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
  39. {WIFI_ACTION, "OnAction", &OnAction},
  40. };
  41. #ifdef _CONFIG_NATIVEAP_MLME_
  42. struct mlme_handler mlme_ap_tbl[]={
  43. {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
  44. {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
  45. {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
  46. {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
  47. {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
  48. {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
  49. /*----------------------------------------------------------
  50. below 2 are reserved
  51. -----------------------------------------------------------*/
  52. {0, "DoReserved", &DoReserved},
  53. {0, "DoReserved", &DoReserved},
  54. {WIFI_BEACON, "OnBeacon", &OnBeacon},
  55. {WIFI_ATIM, "OnATIM", &OnAtim},
  56. {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
  57. {WIFI_AUTH, "OnAuth", &OnAuth},
  58. {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
  59. {WIFI_ACTION, "OnAction", &OnAction},
  60. };
  61. #endif
  62. struct action_handler OnAction_tbl[]={
  63. {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
  64. {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
  65. {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
  66. {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
  67. {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
  68. {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
  69. {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
  70. {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
  71. {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
  72. {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
  73. {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
  74. };
  75. u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
  76. /**************************************************
  77. OUI definitions for the vendor specific IE
  78. ***************************************************/
  79. unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
  80. unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
  81. unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
  82. unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
  83. unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
  84. unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
  85. unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
  86. unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
  87. unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
  88. extern unsigned char REALTEK_96B_IE[];
  89. /********************************************************
  90. MCS rate definitions
  91. *********************************************************/
  92. #ifdef CONFIG_DISABLE_MCS13TO15
  93. unsigned char MCS_rate_2R_MCS13TO15_OFF[16] = {0xff, 0x1f, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  94. unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  95. #else //CONFIG_DISABLE_MCS13TO15
  96. unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  97. #endif //CONFIG_DISABLE_MCS13TO15
  98. unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
  99. /********************************************************
  100. ChannelPlan definitions
  101. *********************************************************/
  102. /*static RT_CHANNEL_PLAN DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
  103. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},32}, // 0x00, RT_CHANNEL_DOMAIN_FCC
  104. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},31}, // 0x01, RT_CHANNEL_DOMAIN_IC
  105. {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x02, RT_CHANNEL_DOMAIN_ETSI
  106. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x03, RT_CHANNEL_DOMAIN_SPAIN
  107. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x04, RT_CHANNEL_DOMAIN_FRANCE
  108. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x05, RT_CHANNEL_DOMAIN_MKK
  109. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x06, RT_CHANNEL_DOMAIN_MKK1
  110. {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, // 0x07, RT_CHANNEL_DOMAIN_ISRAEL
  111. {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // 0x08, RT_CHANNEL_DOMAIN_TELEC
  112. {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
  113. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
  114. {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},26}, // 0x0B, RT_CHANNEL_DOMAIN_TAIWAN
  115. {{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18}, // 0x0C, RT_CHANNEL_DOMAIN_CHINA
  116. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, // 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
  117. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},31}, // 0x0E, RT_CHANNEL_DOMAIN_KOREA
  118. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, // 0x0F, RT_CHANNEL_DOMAIN_TURKEY
  119. {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x10, RT_CHANNEL_DOMAIN_JAPAN
  120. {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,149,153,157,161,165},20}, // 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
  121. {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48},17}, // 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
  122. {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},37}, // 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
  123. {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,149,153,157,161,165},19}, // 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
  124. };*/
  125. static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
  126. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13
  127. {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1
  128. {{1,2,3,4,5,6,7,8,9,10,11},11}, // 0x02, RT_CHANNEL_DOMAIN_2G_FCC1
  129. {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1
  130. {{10,11,12,13},4}, // 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2
  131. {{},0}, // 0x05, RT_CHANNEL_DOMAIN_2G_NULL
  132. };
  133. static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
  134. {{},0}, // 0x00, RT_CHANNEL_DOMAIN_5G_NULL
  135. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1
  136. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2
  137. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165},22}, // 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3
  138. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x04, RT_CHANNEL_DOMAIN_5G_FCC1
  139. {{36,40,44,48,149,153,157,161,165},9}, // 0x05, RT_CHANNEL_DOMAIN_5G_FCC2
  140. {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x06, RT_CHANNEL_DOMAIN_5G_FCC3
  141. {{36,40,44,48,52,56,60,64,149,153,157,161},12}, // 0x07, RT_CHANNEL_DOMAIN_5G_FCC4
  142. {{149,153,157,161,165},5}, // 0x08, RT_CHANNEL_DOMAIN_5G_FCC5
  143. {{36,40,44,48,52,56,60,64},8}, // 0x09, RT_CHANNEL_DOMAIN_5G_FCC6
  144. {{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20}, // 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1
  145. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},20}, // 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1
  146. {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1
  147. {{36,40,44,48,52,56,60,64},8}, // 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2
  148. {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3
  149. {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, // 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1
  150. {{56,60,64,149,153,157,161,165},8}, // 0x10, RT_CHANNEL_DOMAIN_5G_NCC2
  151. //===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition =====
  152. {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x11, RT_CHANNEL_DOMAIN_5G_FCC
  153. {{36,40,44,48},4}, // 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS
  154. {{36,40,44,48,149,153,157,161},8}, // 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS
  155. };
  156. static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
  157. //===== 0x00 ~ 0x1F , Old Define =====
  158. {0x02,0x11}, //0x00, RT_CHANNEL_DOMAIN_FCC
  159. {0x02,0x0A}, //0x01, RT_CHANNEL_DOMAIN_IC
  160. {0x01,0x01}, //0x02, RT_CHANNEL_DOMAIN_ETSI
  161. {0x01,0x00}, //0x03, RT_CHANNEL_DOMAIN_SPAIN
  162. {0x01,0x00}, //0x04, RT_CHANNEL_DOMAIN_FRANCE
  163. {0x03,0x00}, //0x05, RT_CHANNEL_DOMAIN_MKK
  164. {0x03,0x00}, //0x06, RT_CHANNEL_DOMAIN_MKK1
  165. {0x01,0x09}, //0x07, RT_CHANNEL_DOMAIN_ISRAEL
  166. {0x03,0x09}, //0x08, RT_CHANNEL_DOMAIN_TELEC
  167. {0x03,0x00}, //0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
  168. {0x00,0x00}, //0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
  169. {0x02,0x0F}, //0x0B, RT_CHANNEL_DOMAIN_TAIWAN
  170. {0x01,0x08}, //0x0C, RT_CHANNEL_DOMAIN_CHINA
  171. {0x02,0x06}, //0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
  172. {0x02,0x0B}, //0x0E, RT_CHANNEL_DOMAIN_KOREA
  173. {0x02,0x09}, //0x0F, RT_CHANNEL_DOMAIN_TURKEY
  174. {0x01,0x01}, //0x10, RT_CHANNEL_DOMAIN_JAPAN
  175. {0x02,0x05}, //0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
  176. {0x01,0x12}, //0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
  177. {0x00,0x04}, //0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
  178. {0x02,0x10}, //0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
  179. {0x00,0x12}, //0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS
  180. {0x00,0x13}, //0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS
  181. {0x03,0x12}, //0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
  182. {0x05,0x08}, //0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS
  183. {0x02,0x08}, //0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS
  184. {0x00,0x00}, //0x1A,
  185. {0x00,0x00}, //0x1B,
  186. {0x00,0x00}, //0x1C,
  187. {0x00,0x00}, //0x1D,
  188. {0x00,0x00}, //0x1E,
  189. {0x05,0x04}, //0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G
  190. //===== 0x20 ~ 0x7F ,New Define =====
  191. {0x00,0x00}, //0x20, RT_CHANNEL_DOMAIN_WORLD_NULL
  192. {0x01,0x00}, //0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL
  193. {0x02,0x00}, //0x22, RT_CHANNEL_DOMAIN_FCC1_NULL
  194. {0x03,0x00}, //0x23, RT_CHANNEL_DOMAIN_MKK1_NULL
  195. {0x04,0x00}, //0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL
  196. {0x02,0x04}, //0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1
  197. {0x00,0x01}, //0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1
  198. {0x03,0x0C}, //0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1
  199. {0x00,0x0B}, //0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1
  200. {0x00,0x05}, //0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2
  201. {0x00,0x00}, //0x2A,
  202. {0x00,0x00}, //0x2B,
  203. {0x00,0x00}, //0x2C,
  204. {0x00,0x00}, //0x2D,
  205. {0x00,0x00}, //0x2E,
  206. {0x00,0x00}, //0x2F,
  207. {0x00,0x06}, //0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3
  208. {0x00,0x07}, //0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4
  209. {0x00,0x08}, //0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5
  210. {0x00,0x09}, //0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6
  211. {0x02,0x0A}, //0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7
  212. {0x00,0x02}, //0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2
  213. {0x00,0x03}, //0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3
  214. {0x03,0x0D}, //0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2
  215. {0x03,0x0E}, //0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3
  216. {0x02,0x0F}, //0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1
  217. {0x00,0x00}, //0x3A,
  218. {0x00,0x00}, //0x3B,
  219. {0x00,0x00}, //0x3C,
  220. {0x00,0x00}, //0x3D,
  221. {0x00,0x00}, //0x3E,
  222. {0x00,0x00}, //0x3F,
  223. {0x02,0x10}, //0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2
  224. {0x03,0x00}, //0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G
  225. };
  226. static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; //use the conbination for max channel numbers
  227. /*
  228. * Search the @param channel_num in given @param channel_set
  229. * @ch_set: the given channel set
  230. * @ch: the given channel number
  231. *
  232. * return the index of channel_num in channel_set, -1 if not found
  233. */
  234. int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
  235. {
  236. int i;
  237. for(i=0;ch_set[i].ChannelNum!=0;i++){
  238. if(ch == ch_set[i].ChannelNum)
  239. break;
  240. }
  241. if(i >= ch_set[i].ChannelNum)
  242. return -1;
  243. return i;
  244. }
  245. /****************************************************************************
  246. Following are the initialization functions for WiFi MLME
  247. *****************************************************************************/
  248. int init_hw_mlme_ext(_adapter *padapter)
  249. {
  250. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  251. //set_opmode_cmd(padapter, infra_client_with_mlme);//removed
  252. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  253. return _SUCCESS;
  254. }
  255. static void init_mlme_ext_priv_value(_adapter* padapter)
  256. {
  257. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  258. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  259. #ifdef CONFIG_TDLS
  260. u8 i;
  261. #endif
  262. //unsigned char default_channel_set[MAX_CHANNEL_NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0};
  263. unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
  264. unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
  265. ATOMIC_SET(&pmlmeext->event_seq, 0);
  266. pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
  267. pmlmeext->cur_channel = padapter->registrypriv.channel;
  268. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  269. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  270. pmlmeext->retry = 0;
  271. pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
  272. //_rtw_memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len);
  273. //_rtw_memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM);
  274. _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
  275. _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
  276. if(pmlmeext->cur_channel > 14)
  277. pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
  278. else
  279. pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
  280. pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
  281. pmlmeext->sitesurvey_res.channel_idx = 0;
  282. pmlmeext->sitesurvey_res.bss_cnt = 0;
  283. pmlmeext->scan_abort = _FALSE;
  284. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  285. pmlmeinfo->reauth_count = 0;
  286. pmlmeinfo->reassoc_count = 0;
  287. pmlmeinfo->link_count = 0;
  288. pmlmeinfo->auth_seq = 0;
  289. pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
  290. pmlmeinfo->key_index = 0;
  291. pmlmeinfo->iv = 0;
  292. pmlmeinfo->enc_algo = _NO_PRIVACY_;
  293. pmlmeinfo->authModeToggle = 0;
  294. _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
  295. pmlmeinfo->slotTime = SHORT_SLOT_TIME;
  296. pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
  297. pmlmeinfo->dialogToken = 0;
  298. pmlmeext->action_public_rxseq = 0xffff;
  299. pmlmeext->action_public_dialog_token = 0xff;
  300. }
  301. static int has_channel(RT_CHANNEL_INFO *channel_set,
  302. u8 chanset_size,
  303. u8 chan) {
  304. int i;
  305. for (i = 0; i < chanset_size; i++) {
  306. if (channel_set[i].ChannelNum == chan) {
  307. return 1;
  308. }
  309. }
  310. return 0;
  311. }
  312. static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
  313. u8 chanset_size,
  314. struct p2p_channels *channel_list) {
  315. struct p2p_oper_class_map op_class[] = {
  316. { IEEE80211G, 81, 1, 13, 1, BW20 },
  317. { IEEE80211G, 82, 14, 14, 1, BW20 },
  318. #if 0 /* Do not enable HT40 on 2 GHz */
  319. { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
  320. { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
  321. #endif
  322. { IEEE80211A, 115, 36, 48, 4, BW20 },
  323. { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
  324. { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
  325. { IEEE80211A, 124, 149, 161, 4, BW20 },
  326. { IEEE80211A, 125, 149, 169, 4, BW20 },
  327. { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
  328. { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
  329. { -1, 0, 0, 0, 0, BW20 }
  330. };
  331. int cla, op;
  332. cla = 0;
  333. for (op = 0; op_class[op].op_class; op++) {
  334. u8 ch;
  335. struct p2p_oper_class_map *o = &op_class[op];
  336. struct p2p_reg_class *reg = NULL;
  337. for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
  338. if (!has_channel(channel_set, chanset_size, ch)) {
  339. continue;
  340. }
  341. if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
  342. continue;
  343. if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
  344. ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
  345. continue;
  346. if (reg == NULL) {
  347. reg = &channel_list->reg_class[cla];
  348. cla++;
  349. reg->reg_class = o->op_class;
  350. reg->channels = 0;
  351. }
  352. reg->channel[reg->channels] = ch;
  353. reg->channels++;
  354. }
  355. }
  356. channel_list->reg_classes = cla;
  357. }
  358. static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
  359. {
  360. u8 index,chanset_size = 0;
  361. u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
  362. u8 Index2G = 0, Index5G=0;
  363. _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
  364. if(ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
  365. {
  366. DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
  367. return chanset_size;
  368. }
  369. if(IsSupported24G(padapter->registrypriv.wireless_mode))
  370. {
  371. b2_4GBand = _TRUE;
  372. if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
  373. Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
  374. else
  375. Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
  376. }
  377. if(IsSupported5G(padapter->registrypriv.wireless_mode))
  378. {
  379. b5GBand = _TRUE;
  380. if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
  381. Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
  382. else
  383. Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
  384. }
  385. if(b2_4GBand)
  386. {
  387. for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
  388. {
  389. channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
  390. if( (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||//Channel 1~11 is active, and 12~14 is passive
  391. (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan) )
  392. {
  393. if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
  394. channel_set[chanset_size].ScanType = SCAN_ACTIVE;
  395. else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
  396. channel_set[chanset_size].ScanType = SCAN_PASSIVE;
  397. }
  398. else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
  399. RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
  400. RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan
  401. {
  402. if(channel_set[chanset_size].ChannelNum <= 11)
  403. channel_set[chanset_size].ScanType = SCAN_ACTIVE;
  404. else
  405. channel_set[chanset_size].ScanType = SCAN_PASSIVE;
  406. }
  407. else
  408. {
  409. channel_set[chanset_size].ScanType = SCAN_ACTIVE;
  410. }
  411. chanset_size++;
  412. }
  413. }
  414. if(b5GBand)
  415. {
  416. for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
  417. {
  418. #ifdef CONFIG_DFS
  419. channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
  420. if ( channel_set[chanset_size].ChannelNum <= 48
  421. || channel_set[chanset_size].ChannelNum >= 149 )
  422. {
  423. if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
  424. channel_set[chanset_size].ScanType = SCAN_PASSIVE;
  425. else
  426. channel_set[chanset_size].ScanType = SCAN_ACTIVE;
  427. }
  428. else
  429. {
  430. channel_set[chanset_size].ScanType = SCAN_PASSIVE;
  431. }
  432. chanset_size++;
  433. #else /* CONFIG_DFS */
  434. if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
  435. || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
  436. channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
  437. if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
  438. channel_set[chanset_size].ScanType = SCAN_PASSIVE;
  439. else
  440. channel_set[chanset_size].ScanType = SCAN_ACTIVE;
  441. DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
  442. chanset_size++;
  443. }
  444. #endif /* CONFIG_DFS */
  445. }
  446. }
  447. DBG_871X("%s ChannelPlan ID %x Chan num:%d \n",__FUNCTION__,ChannelPlan,chanset_size);
  448. return chanset_size;
  449. }
  450. int init_mlme_ext_priv(_adapter* padapter)
  451. {
  452. int res = _SUCCESS;
  453. struct registry_priv* pregistrypriv = &padapter->registrypriv;
  454. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  455. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  456. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  457. // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
  458. //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
  459. pmlmeext->padapter = padapter;
  460. //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
  461. init_mlme_ext_priv_value(padapter);
  462. pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
  463. init_mlme_ext_timer(padapter);
  464. #ifdef CONFIG_AP_MODE
  465. init_mlme_ap_info(padapter);
  466. #endif
  467. pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
  468. init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
  469. pmlmeext->chan_scan_time = SURVEY_TO;
  470. pmlmeext->mlmeext_init = _TRUE;
  471. #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
  472. pmlmeext->active_keep_alive_check = _TRUE;
  473. #endif
  474. #ifdef DBG_FIXED_CHAN
  475. pmlmeext->fixed_chan = 0xFF;
  476. #endif
  477. return res;
  478. }
  479. void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
  480. {
  481. _adapter *padapter = pmlmeext->padapter;
  482. if (!padapter)
  483. return;
  484. if (padapter->bDriverStopped == _TRUE)
  485. {
  486. _cancel_timer_ex(&pmlmeext->survey_timer);
  487. _cancel_timer_ex(&pmlmeext->link_timer);
  488. //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
  489. }
  490. }
  491. static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
  492. { // if the channel is same, return 0. else return channel differential
  493. uint len;
  494. u8 channel;
  495. u8 *p;
  496. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
  497. if (p)
  498. {
  499. channel = *(p + 2);
  500. if(padapter->mlmeextpriv.cur_channel >= channel)
  501. {
  502. return (padapter->mlmeextpriv.cur_channel - channel);
  503. }
  504. else
  505. {
  506. return (channel-padapter->mlmeextpriv.cur_channel);
  507. }
  508. }
  509. else
  510. {
  511. return 0;
  512. }
  513. }
  514. static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
  515. {
  516. u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
  517. u8 *pframe = precv_frame->u.hdr.rx_data;
  518. if(ptable->func)
  519. {
  520. //receive the frames that ra(a1) is my address or ra(a1) is bc address.
  521. if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
  522. !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
  523. {
  524. return;
  525. }
  526. ptable->func(padapter, precv_frame);
  527. }
  528. }
  529. void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
  530. {
  531. int index;
  532. struct mlme_handler *ptable;
  533. #ifdef CONFIG_AP_MODE
  534. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  535. #endif //CONFIG_AP_MODE
  536. u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
  537. u8 *pframe = precv_frame->u.hdr.rx_data;
  538. struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
  539. RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
  540. ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
  541. GetFrameType(pframe), GetFrameSubType(pframe)));
  542. #if 0
  543. {
  544. u8 *pbuf;
  545. pbuf = GetAddr1Ptr(pframe);
  546. DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
  547. pbuf = GetAddr2Ptr(pframe);
  548. DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
  549. pbuf = GetAddr3Ptr(pframe);
  550. DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
  551. }
  552. #endif
  553. if (GetFrameType(pframe) != WIFI_MGT_TYPE)
  554. {
  555. RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
  556. return;
  557. }
  558. //receive the frames that ra(a1) is my address or ra(a1) is bc address.
  559. if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
  560. !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
  561. {
  562. return;
  563. }
  564. ptable = mlme_sta_tbl;
  565. index = GetFrameSubType(pframe) >> 4;
  566. #ifdef CONFIG_TDLS
  567. if((index << 4)==WIFI_ACTION){
  568. //category==public (4), action==TDLS_DISCOVERY_RESPONSE
  569. if(*(pframe+24)==0x04 && *(pframe+25)==TDLS_DISCOVERY_RESPONSE){
  570. DBG_871X("recv tdls discovery response frame\n");
  571. On_TDLS_Dis_Rsp(padapter, precv_frame);
  572. }
  573. }
  574. #endif //CONFIG_TDLS
  575. if (index > 13)
  576. {
  577. RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
  578. return;
  579. }
  580. ptable += index;
  581. #if 1
  582. if (psta != NULL)
  583. {
  584. if (GetRetry(pframe))
  585. {
  586. if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
  587. {
  588. /* drop the duplicate management frame */
  589. DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
  590. return;
  591. }
  592. }
  593. psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
  594. }
  595. #else
  596. if(GetRetry(pframe))
  597. {
  598. //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
  599. //return;
  600. }
  601. #endif
  602. #ifdef CONFIG_AP_MODE
  603. switch (GetFrameSubType(pframe))
  604. {
  605. case WIFI_AUTH:
  606. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  607. ptable->func = &OnAuth;
  608. else
  609. ptable->func = &OnAuthClient;
  610. //pass through
  611. case WIFI_ASSOCREQ:
  612. case WIFI_REASSOCREQ:
  613. _mgt_dispatcher(padapter, ptable, precv_frame);
  614. #ifdef CONFIG_HOSTAPD_MLME
  615. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  616. rtw_hostapd_mlme_rx(padapter, precv_frame);
  617. #endif
  618. break;
  619. case WIFI_PROBEREQ:
  620. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  621. {
  622. #ifdef CONFIG_HOSTAPD_MLME
  623. rtw_hostapd_mlme_rx(padapter, precv_frame);
  624. #else
  625. _mgt_dispatcher(padapter, ptable, precv_frame);
  626. #endif
  627. }
  628. else
  629. _mgt_dispatcher(padapter, ptable, precv_frame);
  630. break;
  631. case WIFI_BEACON:
  632. _mgt_dispatcher(padapter, ptable, precv_frame);
  633. break;
  634. case WIFI_ACTION:
  635. //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  636. _mgt_dispatcher(padapter, ptable, precv_frame);
  637. break;
  638. default:
  639. _mgt_dispatcher(padapter, ptable, precv_frame);
  640. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  641. rtw_hostapd_mlme_rx(padapter, precv_frame);
  642. break;
  643. }
  644. #else
  645. _mgt_dispatcher(padapter, ptable, precv_frame);
  646. #endif
  647. }
  648. #ifdef CONFIG_P2P
  649. u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
  650. {
  651. bool response = _TRUE;
  652. #ifdef CONFIG_IOCTL_CFG80211
  653. if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
  654. {
  655. if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
  656. || padapter->mlmepriv.wps_probe_resp_ie == NULL
  657. || padapter->mlmepriv.p2p_probe_resp_ie == NULL
  658. )
  659. {
  660. DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
  661. wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
  662. padapter->mlmepriv.wps_probe_resp_ie,
  663. padapter->mlmepriv.p2p_probe_resp_ie);
  664. response = _FALSE;
  665. }
  666. }
  667. else
  668. #endif //CONFIG_IOCTL_CFG80211
  669. if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
  670. {
  671. // do nothing if the device name is empty
  672. if ( !padapter->wdinfo.device_name_len )
  673. {
  674. response = _FALSE;
  675. }
  676. }
  677. if (response == _TRUE)
  678. issue_probersp_p2p( padapter, da);
  679. return _SUCCESS;
  680. }
  681. #endif //CONFIG_P2P
  682. /****************************************************************************
  683. Following are the callback functions for each subtype of the management frames
  684. *****************************************************************************/
  685. unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
  686. {
  687. unsigned int ielen;
  688. unsigned char *p;
  689. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  690. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  691. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  692. WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
  693. u8 *pframe = precv_frame->u.hdr.rx_data;
  694. uint len = precv_frame->u.hdr.len;
  695. u8 is_valid_p2p_probereq = _FALSE;
  696. #ifdef CONFIG_P2P
  697. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  698. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  699. u8 wifi_test_chk_rate = 1;
  700. if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
  701. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
  702. !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
  703. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
  704. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
  705. )
  706. {
  707. // Commented by Albert 2011/03/17
  708. // mcs_rate = 0 -> CCK 1M rate
  709. // mcs_rate = 1 -> CCK 2M rate
  710. // mcs_rate = 2 -> CCK 5.5M rate
  711. // mcs_rate = 3 -> CCK 11M rate
  712. // In the P2P mode, the driver should not support the CCK rate
  713. // Commented by Kurt 2012/10/16
  714. // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
  715. #ifdef CONFIG_WIFI_TEST
  716. if ( pattrib->mcs_rate <= 3 )
  717. {
  718. wifi_test_chk_rate = 0;
  719. }
  720. #endif //CONFIG_WIFI_TEST
  721. if( wifi_test_chk_rate == 1 )
  722. {
  723. if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
  724. {
  725. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
  726. {
  727. p2p_listen_state_process( padapter, get_sa(pframe));
  728. return _SUCCESS;
  729. }
  730. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  731. {
  732. goto _continue;
  733. }
  734. }
  735. }
  736. }
  737. _continue:
  738. #endif //CONFIG_P2P
  739. if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  740. {
  741. return _SUCCESS;
  742. }
  743. if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
  744. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
  745. {
  746. return _SUCCESS;
  747. }
  748. //DBG_871X("+OnProbeReq\n");
  749. #ifdef CONFIG_AUTO_AP_MODE
  750. if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
  751. pmlmepriv->cur_network.join_res == _TRUE)
  752. {
  753. _irqL irqL;
  754. struct sta_info *psta;
  755. u8 *mac_addr, *peer_addr;
  756. struct sta_priv *pstapriv = &padapter->stapriv;
  757. u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
  758. //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
  759. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
  760. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  761. if(!p || ielen !=14)
  762. goto _non_rc_device;
  763. if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
  764. goto _non_rc_device;
  765. if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
  766. {
  767. DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
  768. MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
  769. goto _non_rc_device;
  770. }
  771. DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
  772. //new a station
  773. psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
  774. if (psta == NULL)
  775. {
  776. // allocate a new one
  777. DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
  778. psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
  779. if (psta == NULL)
  780. {
  781. //TODO:
  782. DBG_871X(" Exceed the upper limit of supported clients...\n");
  783. return _SUCCESS;
  784. }
  785. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  786. if (rtw_is_list_empty(&psta->asoc_list))
  787. {
  788. psta->expire_to = pstapriv->expire_to;
  789. rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
  790. pstapriv->asoc_list_cnt++;
  791. }
  792. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  793. //generate pairing ID
  794. mac_addr = myid(&(padapter->eeprompriv));
  795. peer_addr = psta->hwaddr;
  796. psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
  797. //update peer stainfo
  798. psta->isrc = _TRUE;
  799. //psta->aid = 0;
  800. //psta->mac_id = 2;
  801. /* get a unique AID */
  802. if (psta->aid > 0) {
  803. DBG_871X("old AID %d\n", psta->aid);
  804. } else {
  805. for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
  806. if (pstapriv->sta_aid[psta->aid - 1] == NULL)
  807. break;
  808. if (psta->aid > pstapriv->max_num_sta) {
  809. psta->aid = 0;
  810. DBG_871X("no room for more AIDs\n");
  811. return _SUCCESS;
  812. } else {
  813. pstapriv->sta_aid[psta->aid - 1] = psta;
  814. DBG_871X("allocate new AID = (%d)\n", psta->aid);
  815. }
  816. }
  817. psta->qos_option = 1;
  818. psta->htpriv.ht_option = _TRUE;
  819. psta->ieee8021x_blocked = _FALSE;
  820. psta->htpriv.ampdu_enable = _FALSE;
  821. psta->htpriv.sgi = _FALSE;
  822. psta->htpriv.bwmode = CHANNEL_WIDTH_20;
  823. psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  824. rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
  825. psta->htpriv.agg_enable_bitmap = 0x0;//reset
  826. psta->htpriv.candidate_tid_bitmap = 0x0;//reset
  827. _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
  828. _enter_critical_bh(&psta->lock, &irqL);
  829. psta->state |= _FW_LINKED;
  830. _exit_critical_bh(&psta->lock, &irqL);
  831. report_add_sta_event(padapter, psta->hwaddr, psta->aid);
  832. }
  833. issue_probersp(padapter, get_sa(pframe), _FALSE);
  834. return _SUCCESS;
  835. }
  836. _non_rc_device:
  837. return _SUCCESS;
  838. #endif //CONFIG_AUTO_AP_MODE
  839. #ifdef CONFIG_CONCURRENT_MODE
  840. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  841. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  842. {
  843. //don't process probe req
  844. return _SUCCESS;
  845. }
  846. #endif
  847. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
  848. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  849. //check (wildcard) SSID
  850. if (p != NULL)
  851. {
  852. if(is_valid_p2p_probereq == _TRUE)
  853. {
  854. goto _issue_probersp;
  855. }
  856. if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
  857. || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
  858. )
  859. {
  860. return _SUCCESS;
  861. }
  862. _issue_probersp:
  863. if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
  864. pmlmepriv->cur_network.join_res == _TRUE)
  865. {
  866. //DBG_871X("+issue_probersp during ap mode\n");
  867. issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
  868. }
  869. }
  870. return _SUCCESS;
  871. }
  872. unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
  873. {
  874. struct sta_info *psta;
  875. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  876. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  877. struct sta_priv *pstapriv = &padapter->stapriv;
  878. u8 *pframe = precv_frame->u.hdr.rx_data;
  879. #ifdef CONFIG_P2P
  880. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  881. #endif
  882. #ifdef CONFIG_P2P
  883. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  884. {
  885. if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
  886. {
  887. if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  888. {
  889. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
  890. {
  891. pwdinfo->tx_prov_disc_info.benable = _FALSE;
  892. issue_p2p_provision_request( padapter,
  893. pwdinfo->tx_prov_disc_info.ssid.Ssid,
  894. pwdinfo->tx_prov_disc_info.ssid.SsidLength,
  895. pwdinfo->tx_prov_disc_info.peerDevAddr );
  896. }
  897. else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  898. {
  899. pwdinfo->tx_prov_disc_info.benable = _FALSE;
  900. issue_p2p_provision_request( padapter,
  901. NULL,
  902. 0,
  903. pwdinfo->tx_prov_disc_info.peerDevAddr );
  904. }
  905. }
  906. }
  907. return _SUCCESS;
  908. }
  909. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  910. {
  911. if ( _TRUE == pwdinfo->nego_req_info.benable )
  912. {
  913. DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
  914. if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  915. {
  916. pwdinfo->nego_req_info.benable = _FALSE;
  917. issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
  918. }
  919. }
  920. }
  921. else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
  922. {
  923. if ( _TRUE == pwdinfo->invitereq_info.benable )
  924. {
  925. DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
  926. if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  927. {
  928. pwdinfo->invitereq_info.benable = _FALSE;
  929. issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
  930. }
  931. }
  932. }
  933. #endif
  934. if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  935. {
  936. report_survey_event(padapter, precv_frame);
  937. #ifdef CONFIG_CONCURRENT_MODE
  938. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  939. #endif
  940. #ifdef CONFIG_DUALMAC_CONCURRENT
  941. dc_report_survey_event(padapter, precv_frame);
  942. #endif
  943. return _SUCCESS;
  944. }
  945. #if 0 //move to validate_recv_mgnt_frame
  946. if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
  947. {
  948. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  949. {
  950. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  951. {
  952. psta->sta_stats.rx_mgnt_pkts++;
  953. }
  954. }
  955. }
  956. #endif
  957. return _SUCCESS;
  958. }
  959. unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
  960. {
  961. int cam_idx;
  962. struct sta_info *psta;
  963. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  964. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  965. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  966. struct sta_priv *pstapriv = &padapter->stapriv;
  967. u8 *pframe = precv_frame->u.hdr.rx_data;
  968. uint len = precv_frame->u.hdr.len;
  969. WLAN_BSSID_EX *pbss;
  970. int ret = _SUCCESS;
  971. u8 *p = NULL;
  972. u32 ielen = 0;
  973. #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
  974. p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
  975. if ((p != NULL) && (ielen > 0))
  976. {
  977. if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
  978. {
  979. /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
  980. DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
  981. *(p + 1) = ielen - 1;
  982. }
  983. }
  984. #endif
  985. if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  986. {
  987. report_survey_event(padapter, precv_frame);
  988. #ifdef CONFIG_CONCURRENT_MODE
  989. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  990. #endif
  991. #ifdef CONFIG_DUALMAC_CONCURRENT
  992. dc_report_survey_event(padapter, precv_frame);
  993. #endif
  994. return _SUCCESS;
  995. }
  996. if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
  997. {
  998. if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
  999. {
  1000. //we should update current network before auth, or some IE is wrong
  1001. pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
  1002. if (pbss) {
  1003. if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
  1004. update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
  1005. rtw_get_bcn_info(&(pmlmepriv->cur_network));
  1006. }
  1007. rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
  1008. }
  1009. //check the vendor of the assoc AP
  1010. pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
  1011. //update TSF Value
  1012. update_TSF(pmlmeext, pframe, len);
  1013. //start auth
  1014. start_clnt_auth(padapter);
  1015. return _SUCCESS;
  1016. }
  1017. if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  1018. {
  1019. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  1020. {
  1021. #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
  1022. //Merge from 8712 FW code
  1023. if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
  1024. { // join wrong channel, deauth and reconnect
  1025. issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
  1026. report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
  1027. pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
  1028. return _SUCCESS;
  1029. }
  1030. #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
  1031. ret = rtw_check_bcn_info(padapter, pframe, len);
  1032. if (!ret) {
  1033. DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
  1034. receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
  1035. return _SUCCESS;
  1036. }
  1037. //update WMM, ERP in the beacon
  1038. //todo: the timer is used instead of the number of the beacon received
  1039. if ((sta_rx_pkts(psta) & 0xf) == 0)
  1040. {
  1041. //DBG_871X("update_bcn_info\n");
  1042. update_beacon_info(padapter, pframe, len, psta);
  1043. }
  1044. #ifdef CONFIG_DFS
  1045. process_csa_ie(padapter, pframe, len); //channel switch announcement
  1046. #endif //CONFIG_DFS
  1047. #ifdef CONFIG_P2P_PS
  1048. process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
  1049. #endif //CONFIG_P2P_PS
  1050. #if 0 //move to validate_recv_mgnt_frame
  1051. psta->sta_stats.rx_mgnt_pkts++;
  1052. #endif
  1053. }
  1054. }
  1055. else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  1056. {
  1057. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  1058. {
  1059. //update WMM, ERP in the beacon
  1060. //todo: the timer is used instead of the number of the beacon received
  1061. if ((sta_rx_pkts(psta) & 0xf) == 0)
  1062. {
  1063. //DBG_871X("update_bcn_info\n");
  1064. update_beacon_info(padapter, pframe, len, psta);
  1065. }
  1066. #if 0 //move to validate_recv_mgnt_frame
  1067. psta->sta_stats.rx_mgnt_pkts++;
  1068. #endif
  1069. }
  1070. else
  1071. {
  1072. //allocate a new CAM entry for IBSS station
  1073. if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
  1074. {
  1075. goto _END_ONBEACON_;
  1076. }
  1077. //get supported rate
  1078. if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL)
  1079. {
  1080. pmlmeinfo->FW_sta_info[cam_idx].status = 0;
  1081. goto _END_ONBEACON_;
  1082. }
  1083. //update TSF Value
  1084. update_TSF(pmlmeext, pframe, len);
  1085. //report sta add event
  1086. report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
  1087. }
  1088. }
  1089. }
  1090. _END_ONBEACON_:
  1091. return _SUCCESS;
  1092. }
  1093. unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
  1094. {
  1095. #ifdef CONFIG_AP_MODE
  1096. _irqL irqL;
  1097. unsigned int auth_mode, seq, ie_len;
  1098. unsigned char *sa, *p;
  1099. u16 algorithm;
  1100. int status;
  1101. static struct sta_info stat;
  1102. struct sta_info *pstat=NULL;
  1103. struct sta_priv *pstapriv = &padapter->stapriv;
  1104. struct security_priv *psecuritypriv = &padapter->securitypriv;
  1105. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1106. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1107. u8 *pframe = precv_frame->u.hdr.rx_data;
  1108. uint len = precv_frame->u.hdr.len;
  1109. u8 offset = 0;
  1110. #ifdef CONFIG_CONCURRENT_MODE
  1111. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  1112. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  1113. {
  1114. //don't process auth request;
  1115. return _SUCCESS;
  1116. }
  1117. #endif //CONFIG_CONCURRENT_MODE
  1118. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  1119. return _FAIL;
  1120. DBG_871X("+OnAuth\n");
  1121. sa = GetAddr2Ptr(pframe);
  1122. auth_mode = psecuritypriv->dot11AuthAlgrthm;
  1123. if (GetPrivacy(pframe))
  1124. {
  1125. u8 *iv;
  1126. struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
  1127. prxattrib->hdrlen = WLAN_HDR_A3_LEN;
  1128. prxattrib->encrypt = _WEP40_;
  1129. iv = pframe+prxattrib->hdrlen;
  1130. prxattrib->key_index = ((iv[3]>>6)&0x3);
  1131. prxattrib->iv_len = 4;
  1132. prxattrib->icv_len = 4;
  1133. rtw_wep_decrypt(padapter, (u8 *)precv_frame);
  1134. offset = 4;
  1135. }
  1136. algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
  1137. seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
  1138. DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
  1139. if (auth_mode == 2 &&
  1140. psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
  1141. psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
  1142. auth_mode = 0;
  1143. if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
  1144. (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
  1145. {
  1146. DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
  1147. algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
  1148. status = _STATS_NO_SUPP_ALG_;
  1149. goto auth_fail;
  1150. }
  1151. #if 0 //ACL control
  1152. phead = &priv->wlan_acl_list;
  1153. plist = phead->next;
  1154. //check sa
  1155. if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
  1156. res = FAIL;
  1157. else
  1158. res = SUCCESS;
  1159. while(plist != phead)
  1160. {
  1161. paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
  1162. plist = plist->next;
  1163. if (!memcmp((void *)sa, paclnode->addr, 6)) {
  1164. if (paclnode->mode & 2) { // deny
  1165. res = FAIL;
  1166. break;
  1167. }
  1168. else {
  1169. res = SUCCESS;
  1170. break;
  1171. }
  1172. }
  1173. }
  1174. if (res != SUCCESS) {
  1175. RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
  1176. return FAIL;
  1177. }
  1178. #else
  1179. if(rtw_access_ctrl(padapter, sa) == _FALSE)
  1180. {
  1181. status = _STATS_UNABLE_HANDLE_STA_;
  1182. goto auth_fail;
  1183. }
  1184. #endif
  1185. pstat = rtw_get_stainfo(pstapriv, sa);
  1186. if (pstat == NULL)
  1187. {
  1188. // allocate a new one
  1189. DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
  1190. pstat = rtw_alloc_stainfo(pstapriv, sa);
  1191. if (pstat == NULL)
  1192. {
  1193. DBG_871X(" Exceed the upper limit of supported clients...\n");
  1194. status = _STATS_UNABLE_HANDLE_STA_;
  1195. goto auth_fail;
  1196. }
  1197. pstat->state = WIFI_FW_AUTH_NULL;
  1198. pstat->auth_seq = 0;
  1199. //pstat->flags = 0;
  1200. //pstat->capability = 0;
  1201. }
  1202. else
  1203. {
  1204. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1205. if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
  1206. {
  1207. rtw_list_delete(&pstat->asoc_list);
  1208. pstapriv->asoc_list_cnt--;
  1209. if (pstat->expire_to > 0)
  1210. {
  1211. //TODO: STA re_auth within expire_to
  1212. }
  1213. }
  1214. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1215. if (seq==1) {
  1216. //TODO: STA re_auth and auth timeout
  1217. }
  1218. }
  1219. _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1220. if (rtw_is_list_empty(&pstat->auth_list))
  1221. {
  1222. rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
  1223. pstapriv->auth_list_cnt++;
  1224. }
  1225. _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1226. if (pstat->auth_seq == 0)
  1227. pstat->expire_to = pstapriv->auth_to;
  1228. if ((pstat->auth_seq + 1) != seq)
  1229. {
  1230. DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1231. seq, pstat->auth_seq+1);
  1232. status = _STATS_OUT_OF_AUTH_SEQ_;
  1233. goto auth_fail;
  1234. }
  1235. if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
  1236. {
  1237. if (seq == 1)
  1238. {
  1239. pstat->state &= ~WIFI_FW_AUTH_NULL;
  1240. pstat->state |= WIFI_FW_AUTH_SUCCESS;
  1241. pstat->expire_to = pstapriv->assoc_to;
  1242. pstat->authalg = algorithm;
  1243. }
  1244. else
  1245. {
  1246. DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1247. seq, pstat->auth_seq+1);
  1248. status = _STATS_OUT_OF_AUTH_SEQ_;
  1249. goto auth_fail;
  1250. }
  1251. }
  1252. else // shared system or auto authentication
  1253. {
  1254. if (seq == 1)
  1255. {
  1256. //prepare for the challenging txt...
  1257. //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
  1258. _rtw_memset((void *)pstat->chg_txt, 78, 128);
  1259. pstat->state &= ~WIFI_FW_AUTH_NULL;
  1260. pstat->state |= WIFI_FW_AUTH_STATE;
  1261. pstat->authalg = algorithm;
  1262. pstat->auth_seq = 2;
  1263. }
  1264. else if (seq == 3)
  1265. {
  1266. //checking for challenging txt...
  1267. DBG_871X("checking for challenging txt...\n");
  1268. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
  1269. len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
  1270. if((p==NULL) || (ie_len<=0))
  1271. {
  1272. DBG_871X("auth rejected because challenge failure!(1)\n");
  1273. status = _STATS_CHALLENGE_FAIL_;
  1274. goto auth_fail;
  1275. }
  1276. if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
  1277. {
  1278. pstat->state &= (~WIFI_FW_AUTH_STATE);
  1279. pstat->state |= WIFI_FW_AUTH_SUCCESS;
  1280. // challenging txt is correct...
  1281. pstat->expire_to = pstapriv->assoc_to;
  1282. }
  1283. else
  1284. {
  1285. DBG_871X("auth rejected because challenge failure!\n");
  1286. status = _STATS_CHALLENGE_FAIL_;
  1287. goto auth_fail;
  1288. }
  1289. }
  1290. else
  1291. {
  1292. DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1293. seq, pstat->auth_seq+1);
  1294. status = _STATS_OUT_OF_AUTH_SEQ_;
  1295. goto auth_fail;
  1296. }
  1297. }
  1298. // Now, we are going to issue_auth...
  1299. pstat->auth_seq = seq + 1;
  1300. #ifdef CONFIG_NATIVEAP_MLME
  1301. issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
  1302. #endif
  1303. if (pstat->state & WIFI_FW_AUTH_SUCCESS)
  1304. pstat->auth_seq = 0;
  1305. return _SUCCESS;
  1306. auth_fail:
  1307. if(pstat)
  1308. rtw_free_stainfo(padapter , pstat);
  1309. pstat = &stat;
  1310. _rtw_memset((char *)pstat, '\0', sizeof(stat));
  1311. pstat->auth_seq = 2;
  1312. _rtw_memcpy(pstat->hwaddr, sa, 6);
  1313. #ifdef CONFIG_NATIVEAP_MLME
  1314. issue_auth(padapter, pstat, (unsigned short)status);
  1315. #endif
  1316. #endif
  1317. return _FAIL;
  1318. }
  1319. unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
  1320. {
  1321. unsigned int seq, len, status, algthm, offset;
  1322. unsigned char *p;
  1323. unsigned int go2asoc = 0;
  1324. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1325. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1326. u8 *pframe = precv_frame->u.hdr.rx_data;
  1327. uint pkt_len = precv_frame->u.hdr.len;
  1328. DBG_871X("%s\n", __FUNCTION__);
  1329. //check A1 matches or not
  1330. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  1331. return _SUCCESS;
  1332. if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
  1333. return _SUCCESS;
  1334. offset = (GetPrivacy(pframe))? 4: 0;
  1335. algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
  1336. seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
  1337. status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
  1338. if (status != 0)
  1339. {
  1340. DBG_871X("clnt auth fail, status: %d\n", status);
  1341. if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
  1342. {
  1343. if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1344. pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
  1345. else
  1346. pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
  1347. //pmlmeinfo->reauth_count = 0;
  1348. }
  1349. set_link_timer(pmlmeext, 1);
  1350. goto authclnt_fail;
  1351. }
  1352. if (seq == 2)
  1353. {
  1354. if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1355. {
  1356. // legendary shared system
  1357. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
  1358. pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
  1359. if (p == NULL)
  1360. {
  1361. //DBG_871X("marc: no challenge text?\n");
  1362. goto authclnt_fail;
  1363. }
  1364. _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
  1365. pmlmeinfo->auth_seq = 3;
  1366. issue_auth(padapter, NULL, 0);
  1367. set_link_timer(pmlmeext, REAUTH_TO);
  1368. return _SUCCESS;
  1369. }
  1370. else
  1371. {
  1372. // open system
  1373. go2asoc = 1;
  1374. }
  1375. }
  1376. else if (seq == 4)
  1377. {
  1378. if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1379. {
  1380. go2asoc = 1;
  1381. }
  1382. else
  1383. {
  1384. goto authclnt_fail;
  1385. }
  1386. }
  1387. else
  1388. {
  1389. // this is also illegal
  1390. //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
  1391. goto authclnt_fail;
  1392. }
  1393. if (go2asoc)
  1394. {
  1395. DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
  1396. start_clnt_assoc(padapter);
  1397. return _SUCCESS;
  1398. }
  1399. authclnt_fail:
  1400. //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
  1401. return _FAIL;
  1402. }
  1403. unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
  1404. {
  1405. #ifdef CONFIG_AP_MODE
  1406. _irqL irqL;
  1407. u16 capab_info, listen_interval;
  1408. struct rtw_ieee802_11_elems elems;
  1409. struct sta_info *pstat;
  1410. unsigned char reassoc, *p, *pos, *wpa_ie;
  1411. unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
  1412. int i, ie_len, wpa_ie_len, left;
  1413. unsigned char supportRate[16];
  1414. int supportRateNum;
  1415. unsigned short status = _STATS_SUCCESSFUL_;
  1416. unsigned short frame_type, ie_offset=0;
  1417. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1418. struct security_priv *psecuritypriv = &padapter->securitypriv;
  1419. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1420. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1421. WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
  1422. struct sta_priv *pstapriv = &padapter->stapriv;
  1423. u8 *pframe = precv_frame->u.hdr.rx_data;
  1424. uint pkt_len = precv_frame->u.hdr.len;
  1425. #ifdef CONFIG_P2P
  1426. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  1427. u8 p2p_status_code = P2P_STATUS_SUCCESS;
  1428. u8 *p2pie;
  1429. u32 p2pielen = 0;
  1430. #ifdef CONFIG_WFD
  1431. u8 wfd_ie[ 128 ] = { 0x00 };
  1432. u32 wfd_ielen = 0;
  1433. #endif // CONFIG_WFD
  1434. #endif //CONFIG_P2P
  1435. #ifdef CONFIG_CONCURRENT_MODE
  1436. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  1437. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  1438. {
  1439. //don't process assoc request;
  1440. return _SUCCESS;
  1441. }
  1442. #endif //CONFIG_CONCURRENT_MODE
  1443. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  1444. return _FAIL;
  1445. frame_type = GetFrameSubType(pframe);
  1446. if (frame_type == WIFI_ASSOCREQ)
  1447. {
  1448. reassoc = 0;
  1449. ie_offset = _ASOCREQ_IE_OFFSET_;
  1450. }
  1451. else // WIFI_REASSOCREQ
  1452. {
  1453. reassoc = 1;
  1454. ie_offset = _REASOCREQ_IE_OFFSET_;
  1455. }
  1456. if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
  1457. DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
  1458. "\n", reassoc, (unsigned long)pkt_len);
  1459. return _FAIL;
  1460. }
  1461. pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  1462. if (pstat == (struct sta_info *)NULL)
  1463. {
  1464. status = _RSON_CLS2_;
  1465. goto asoc_class2_error;
  1466. }
  1467. capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
  1468. //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  1469. //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
  1470. listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
  1471. left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
  1472. pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
  1473. DBG_871X("%s\n", __FUNCTION__);
  1474. // check if this stat has been successfully authenticated/assocated
  1475. if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
  1476. {
  1477. if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
  1478. {
  1479. status = _RSON_CLS2_;
  1480. goto asoc_class2_error;
  1481. }
  1482. else
  1483. {
  1484. pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
  1485. pstat->state |= WIFI_FW_ASSOC_STATE;
  1486. }
  1487. }
  1488. else
  1489. {
  1490. pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
  1491. pstat->state |= WIFI_FW_ASSOC_STATE;
  1492. }
  1493. #if 0// todo:tkip_countermeasures
  1494. if (hapd->tkip_countermeasures) {
  1495. resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
  1496. goto fail;
  1497. }
  1498. #endif
  1499. pstat->capability = capab_info;
  1500. #if 0//todo:
  1501. //check listen_interval
  1502. if (listen_interval > hapd->conf->max_listen_interval) {
  1503. hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
  1504. HOSTAPD_LEVEL_DEBUG,
  1505. "Too large Listen Interval (%d)",
  1506. listen_interval);
  1507. resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
  1508. goto fail;
  1509. }
  1510. pstat->listen_interval = listen_interval;
  1511. #endif
  1512. //now parse all ieee802_11 ie to point to elems
  1513. if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
  1514. !elems.ssid) {
  1515. DBG_871X("STA " MAC_FMT " sent invalid association request\n",
  1516. MAC_ARG(pstat->hwaddr));
  1517. status = _STATS_FAILURE_;
  1518. goto OnAssocReqFail;
  1519. }
  1520. // now we should check all the fields...
  1521. // checking SSID
  1522. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
  1523. pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1524. if (p == NULL)
  1525. {
  1526. status = _STATS_FAILURE_;
  1527. }
  1528. if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
  1529. status = _STATS_FAILURE_;
  1530. else
  1531. {
  1532. // check if ssid match
  1533. if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
  1534. status = _STATS_FAILURE_;
  1535. if (ie_len != cur->Ssid.SsidLength)
  1536. status = _STATS_FAILURE_;
  1537. }
  1538. if(_STATS_SUCCESSFUL_ != status)
  1539. goto OnAssocReqFail;
  1540. // check if the supported rate is ok
  1541. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1542. if (p == NULL) {
  1543. DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
  1544. // use our own rate set as statoin used
  1545. //_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
  1546. //supportRateNum = AP_BSSRATE_LEN;
  1547. status = _STATS_FAILURE_;
  1548. goto OnAssocReqFail;
  1549. }
  1550. else {
  1551. _rtw_memcpy(supportRate, p+2, ie_len);
  1552. supportRateNum = ie_len;
  1553. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
  1554. pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1555. if (p != NULL) {
  1556. if(supportRateNum<=sizeof(supportRate))
  1557. {
  1558. _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
  1559. supportRateNum += ie_len;
  1560. }
  1561. }
  1562. }
  1563. //todo: mask supportRate between AP & STA -> move to update raid
  1564. //get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
  1565. //update station supportRate
  1566. pstat->bssratelen = supportRateNum;
  1567. _rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
  1568. UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
  1569. //check RSN/WPA/WPS
  1570. pstat->dot8021xalg = 0;
  1571. pstat->wpa_psk = 0;
  1572. pstat->wpa_group_cipher = 0;
  1573. pstat->wpa2_group_cipher = 0;
  1574. pstat->wpa_pairwise_cipher = 0;
  1575. pstat->wpa2_pairwise_cipher = 0;
  1576. _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
  1577. if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
  1578. int group_cipher=0, pairwise_cipher=0;
  1579. wpa_ie = elems.rsn_ie;
  1580. wpa_ie_len = elems.rsn_ie_len;
  1581. if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
  1582. {
  1583. pstat->dot8021xalg = 1;//psk, todo:802.1x
  1584. pstat->wpa_psk |= BIT(1);
  1585. pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
  1586. pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
  1587. if(!pstat->wpa2_group_cipher)
  1588. status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
  1589. if(!pstat->wpa2_pairwise_cipher)
  1590. status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
  1591. }
  1592. else
  1593. {
  1594. status = WLAN_STATUS_INVALID_IE;
  1595. }
  1596. } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
  1597. int group_cipher=0, pairwise_cipher=0;
  1598. wpa_ie = elems.wpa_ie;
  1599. wpa_ie_len = elems.wpa_ie_len;
  1600. if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
  1601. {
  1602. pstat->dot8021xalg = 1;//psk, todo:802.1x
  1603. pstat->wpa_psk |= BIT(0);
  1604. pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
  1605. pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
  1606. if(!pstat->wpa_group_cipher)
  1607. status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
  1608. if(!pstat->wpa_pairwise_cipher)
  1609. status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
  1610. }
  1611. else
  1612. {
  1613. status = WLAN_STATUS_INVALID_IE;
  1614. }
  1615. } else {
  1616. wpa_ie = NULL;
  1617. wpa_ie_len = 0;
  1618. }
  1619. if(_STATS_SUCCESSFUL_ != status)
  1620. goto OnAssocReqFail;
  1621. pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
  1622. //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
  1623. if(wpa_ie == NULL) {
  1624. if (elems.wps_ie) {
  1625. DBG_871X("STA included WPS IE in "
  1626. "(Re)Association Request - assume WPS is "
  1627. "used\n");
  1628. pstat->flags |= WLAN_STA_WPS;
  1629. //wpabuf_free(sta->wps_ie);
  1630. //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
  1631. // elems.wps_ie_len - 4);
  1632. } else {
  1633. DBG_871X("STA did not include WPA/RSN IE "
  1634. "in (Re)Association Request - possible WPS "
  1635. "use\n");
  1636. pstat->flags |= WLAN_STA_MAYBE_WPS;
  1637. }
  1638. // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
  1639. // that the selected registrar of AP is _FLASE
  1640. if((psecuritypriv->wpa_psk >0)
  1641. && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
  1642. {
  1643. if(pmlmepriv->wps_beacon_ie)
  1644. {
  1645. u8 selected_registrar = 0;
  1646. rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
  1647. if(!selected_registrar)
  1648. {
  1649. DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
  1650. status = _STATS_UNABLE_HANDLE_STA_;
  1651. goto OnAssocReqFail;
  1652. }
  1653. }
  1654. }
  1655. }
  1656. else
  1657. {
  1658. int copy_len;
  1659. if(psecuritypriv->wpa_psk == 0)
  1660. {
  1661. DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
  1662. "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
  1663. status = WLAN_STATUS_INVALID_IE;
  1664. goto OnAssocReqFail;
  1665. }
  1666. if (elems.wps_ie) {
  1667. DBG_871X("STA included WPS IE in "
  1668. "(Re)Association Request - WPS is "
  1669. "used\n");
  1670. pstat->flags |= WLAN_STA_WPS;
  1671. copy_len=0;
  1672. }
  1673. else
  1674. {
  1675. copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
  1676. }
  1677. if(copy_len>0)
  1678. _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
  1679. }
  1680. // check if there is WMM IE & support WWM-PS
  1681. pstat->flags &= ~WLAN_STA_WME;
  1682. pstat->qos_option = 0;
  1683. pstat->qos_info = 0;
  1684. pstat->has_legacy_ac = _TRUE;
  1685. pstat->uapsd_vo = 0;
  1686. pstat->uapsd_vi = 0;
  1687. pstat->uapsd_be = 0;
  1688. pstat->uapsd_bk = 0;
  1689. if (pmlmepriv->qospriv.qos_option)
  1690. {
  1691. p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
  1692. for (;;)
  1693. {
  1694. p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1695. if (p != NULL) {
  1696. if (_rtw_memcmp(p+2, WMM_IE, 6)) {
  1697. pstat->flags |= WLAN_STA_WME;
  1698. pstat->qos_option = 1;
  1699. pstat->qos_info = *(p+8);
  1700. pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
  1701. if((pstat->qos_info&0xf) !=0xf)
  1702. pstat->has_legacy_ac = _TRUE;
  1703. else
  1704. pstat->has_legacy_ac = _FALSE;
  1705. if(pstat->qos_info&0xf)
  1706. {
  1707. if(pstat->qos_info&BIT(0))
  1708. pstat->uapsd_vo = BIT(0)|BIT(1);
  1709. else
  1710. pstat->uapsd_vo = 0;
  1711. if(pstat->qos_info&BIT(1))
  1712. pstat->uapsd_vi = BIT(0)|BIT(1);
  1713. else
  1714. pstat->uapsd_vi = 0;
  1715. if(pstat->qos_info&BIT(2))
  1716. pstat->uapsd_bk = BIT(0)|BIT(1);
  1717. else
  1718. pstat->uapsd_bk = 0;
  1719. if(pstat->qos_info&BIT(3))
  1720. pstat->uapsd_be = BIT(0)|BIT(1);
  1721. else
  1722. pstat->uapsd_be = 0;
  1723. }
  1724. break;
  1725. }
  1726. }
  1727. else {
  1728. break;
  1729. }
  1730. p = p + ie_len + 2;
  1731. }
  1732. }
  1733. #ifdef CONFIG_80211N_HT
  1734. /* save HT capabilities in the sta object */
  1735. _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
  1736. if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
  1737. {
  1738. pstat->flags |= WLAN_STA_HT;
  1739. pstat->flags |= WLAN_STA_WME;
  1740. _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
  1741. } else
  1742. pstat->flags &= ~WLAN_STA_HT;
  1743. if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
  1744. {
  1745. status = _STATS_FAILURE_;
  1746. goto OnAssocReqFail;
  1747. }
  1748. if ((pstat->flags & WLAN_STA_HT) &&
  1749. ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
  1750. (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
  1751. {
  1752. DBG_871X("HT: " MAC_FMT " tried to "
  1753. "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
  1754. //status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
  1755. //goto OnAssocReqFail;
  1756. }
  1757. #endif /* CONFIG_80211N_HT */
  1758. #ifdef CONFIG_80211AC_VHT
  1759. _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
  1760. if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
  1761. pstat->flags |= WLAN_STA_VHT;
  1762. _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
  1763. if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
  1764. pstat->vhtpriv.bwmode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(elems.vht_op_mode_notify);
  1765. }
  1766. }
  1767. else {
  1768. pstat->flags &= ~WLAN_STA_HT;
  1769. }
  1770. if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
  1771. {
  1772. status = _STATS_FAILURE_;
  1773. goto OnAssocReqFail;
  1774. }
  1775. #endif /* CONFIG_80211AC_VHT */
  1776. //
  1777. //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
  1778. pstat->flags |= WLAN_STA_NONERP;
  1779. for (i = 0; i < pstat->bssratelen; i++) {
  1780. if ((pstat->bssrateset[i] & 0x7f) > 22) {
  1781. pstat->flags &= ~WLAN_STA_NONERP;
  1782. break;
  1783. }
  1784. }
  1785. if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
  1786. pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
  1787. else
  1788. pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  1789. if (status != _STATS_SUCCESSFUL_)
  1790. goto OnAssocReqFail;
  1791. #ifdef CONFIG_P2P
  1792. pstat->is_p2p_device = _FALSE;
  1793. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1794. {
  1795. if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
  1796. {
  1797. pstat->is_p2p_device = _TRUE;
  1798. if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
  1799. {
  1800. pstat->p2p_status_code = p2p_status_code;
  1801. status = _STATS_CAP_FAIL_;
  1802. goto OnAssocReqFail;
  1803. }
  1804. }
  1805. #ifdef CONFIG_WFD
  1806. if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
  1807. {
  1808. u8 attr_content[ 10 ] = { 0x00 };
  1809. u32 attr_contentlen = 0;
  1810. DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
  1811. rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
  1812. if ( attr_contentlen )
  1813. {
  1814. pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
  1815. DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
  1816. }
  1817. }
  1818. #endif
  1819. }
  1820. pstat->p2p_status_code = p2p_status_code;
  1821. #endif //CONFIG_P2P
  1822. //TODO: identify_proprietary_vendor_ie();
  1823. // Realtek proprietary IE
  1824. // identify if this is Broadcom sta
  1825. // identify if this is ralink sta
  1826. // Customer proprietary IE
  1827. /* get a unique AID */
  1828. if (pstat->aid > 0) {
  1829. DBG_871X(" old AID %d\n", pstat->aid);
  1830. } else {
  1831. for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
  1832. if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
  1833. break;
  1834. //if (pstat->aid > NUM_STA) {
  1835. if (pstat->aid > pstapriv->max_num_sta) {
  1836. pstat->aid = 0;
  1837. DBG_871X(" no room for more AIDs\n");
  1838. status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
  1839. goto OnAssocReqFail;
  1840. } else {
  1841. pstapriv->sta_aid[pstat->aid - 1] = pstat;
  1842. DBG_871X("allocate new AID = (%d)\n", pstat->aid);
  1843. }
  1844. }
  1845. pstat->state &= (~WIFI_FW_ASSOC_STATE);
  1846. pstat->state |= WIFI_FW_ASSOC_SUCCESS;
  1847. _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1848. if (!rtw_is_list_empty(&pstat->auth_list))
  1849. {
  1850. rtw_list_delete(&pstat->auth_list);
  1851. pstapriv->auth_list_cnt--;
  1852. }
  1853. _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1854. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1855. if (rtw_is_list_empty(&pstat->asoc_list))
  1856. {
  1857. pstat->expire_to = pstapriv->expire_to;
  1858. rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
  1859. pstapriv->asoc_list_cnt++;
  1860. }
  1861. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1862. // now the station is qualified to join our BSS...
  1863. if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
  1864. {
  1865. #ifdef CONFIG_NATIVEAP_MLME
  1866. //.1 bss_cap_update & sta_info_update
  1867. bss_cap_update_on_sta_join(padapter, pstat);
  1868. sta_info_update(padapter, pstat);
  1869. //issue assoc rsp before notify station join event.
  1870. if (frame_type == WIFI_ASSOCREQ)
  1871. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1872. else
  1873. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1874. //.2 - report to upper layer
  1875. DBG_871X("indicate_sta_join_event to upper layer - hostapd\n");
  1876. #ifdef CONFIG_IOCTL_CFG80211
  1877. #ifdef COMPAT_KERNEL_RELEASE
  1878. rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
  1879. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1880. rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
  1881. #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1882. _enter_critical_bh(&pstat->lock, &irqL);
  1883. if(pstat->passoc_req)
  1884. {
  1885. rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
  1886. pstat->passoc_req = NULL;
  1887. pstat->assoc_req_len = 0;
  1888. }
  1889. pstat->passoc_req = rtw_zmalloc(pkt_len);
  1890. if(pstat->passoc_req)
  1891. {
  1892. _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
  1893. pstat->assoc_req_len = pkt_len;
  1894. }
  1895. _exit_critical_bh(&pstat->lock, &irqL);
  1896. #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1897. #else
  1898. rtw_indicate_sta_assoc_event(padapter, pstat);
  1899. #endif //CONFIG_IOCTL_CFG80211
  1900. //.3-(1) report sta add event
  1901. report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
  1902. /*
  1903. //issue assoc rsp before notify station join event.
  1904. if (frame_type == WIFI_ASSOCREQ)
  1905. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1906. else
  1907. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1908. */
  1909. #endif
  1910. }
  1911. return _SUCCESS;
  1912. asoc_class2_error:
  1913. #ifdef CONFIG_NATIVEAP_MLME
  1914. issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
  1915. #endif
  1916. return _FAIL;
  1917. OnAssocReqFail:
  1918. #ifdef CONFIG_NATIVEAP_MLME
  1919. pstat->aid = 0;
  1920. if (frame_type == WIFI_ASSOCREQ)
  1921. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1922. else
  1923. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1924. #endif
  1925. #endif /* CONFIG_AP_MODE */
  1926. return _FAIL;
  1927. }
  1928. unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
  1929. {
  1930. uint i;
  1931. int res;
  1932. unsigned short status;
  1933. PNDIS_802_11_VARIABLE_IEs pIE;
  1934. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1935. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1936. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1937. //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  1938. u8 *pframe = precv_frame->u.hdr.rx_data;
  1939. uint pkt_len = precv_frame->u.hdr.len;
  1940. PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
  1941. DBG_871X("%s\n", __FUNCTION__);
  1942. //check A1 matches or not
  1943. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  1944. return _SUCCESS;
  1945. if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
  1946. return _SUCCESS;
  1947. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  1948. return _SUCCESS;
  1949. _cancel_timer_ex(&pmlmeext->link_timer);
  1950. //status
  1951. if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
  1952. {
  1953. DBG_871X("assoc reject, status code: %d\n", status);
  1954. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  1955. res = -4;
  1956. goto report_assoc_result;
  1957. }
  1958. //get capabilities
  1959. pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  1960. //set slot time
  1961. pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
  1962. //AID
  1963. res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
  1964. //following are moved to join event callback function
  1965. //to handle HT, WMM, rate adaptive, update MAC reg
  1966. //for not to handle the synchronous IO in the tasklet
  1967. for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
  1968. {
  1969. pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
  1970. switch (pIE->ElementID)
  1971. {
  1972. case _VENDOR_SPECIFIC_IE_:
  1973. if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
  1974. {
  1975. WMM_param_handler(padapter, pIE);
  1976. }
  1977. #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
  1978. else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
  1979. {
  1980. DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
  1981. WFD_info_handler( padapter, pIE );
  1982. }
  1983. #endif
  1984. break;
  1985. #ifdef CONFIG_WAPI_SUPPORT
  1986. case _WAPI_IE_:
  1987. pWapiIE = pIE;
  1988. break;
  1989. #endif
  1990. case _HT_CAPABILITY_IE_: //HT caps
  1991. HT_caps_handler(padapter, pIE);
  1992. break;
  1993. case _HT_EXTRA_INFO_IE_: //HT info
  1994. HT_info_handler(padapter, pIE);
  1995. break;
  1996. #ifdef CONFIG_80211AC_VHT
  1997. case EID_VHTCapability:
  1998. VHT_caps_handler(padapter, pIE);
  1999. break;
  2000. case EID_VHTOperation:
  2001. VHT_operation_handler(padapter, pIE);
  2002. break;
  2003. #endif
  2004. case _ERPINFO_IE_:
  2005. ERP_IE_handler(padapter, pIE);
  2006. default:
  2007. break;
  2008. }
  2009. i += (pIE->Length + 2);
  2010. }
  2011. #ifdef CONFIG_WAPI_SUPPORT
  2012. rtw_wapi_on_assoc_ok(padapter, pIE);
  2013. #endif
  2014. pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
  2015. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  2016. //Update Basic Rate Table for spec, 2010-12-28 , by thomas
  2017. UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
  2018. report_assoc_result:
  2019. if (res > 0) {
  2020. rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
  2021. } else {
  2022. rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
  2023. }
  2024. report_join_res(padapter, res);
  2025. return _SUCCESS;
  2026. }
  2027. unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
  2028. {
  2029. unsigned short reason;
  2030. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2031. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2032. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2033. u8 *pframe = precv_frame->u.hdr.rx_data;
  2034. #ifdef CONFIG_P2P
  2035. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  2036. #endif //CONFIG_P2P
  2037. //check A3
  2038. if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  2039. return _SUCCESS;
  2040. #ifdef CONFIG_P2P
  2041. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  2042. {
  2043. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  2044. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  2045. }
  2046. #endif //CONFIG_P2P
  2047. reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  2048. DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
  2049. #ifdef CONFIG_AP_MODE
  2050. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  2051. {
  2052. _irqL irqL;
  2053. struct sta_info *psta;
  2054. struct sta_priv *pstapriv = &padapter->stapriv;
  2055. //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2056. //rtw_free_stainfo(padapter, psta);
  2057. //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2058. DBG_871X_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
  2059. reason, GetAddr2Ptr(pframe));
  2060. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2061. if(psta)
  2062. {
  2063. u8 updated;
  2064. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2065. if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
  2066. {
  2067. rtw_list_delete(&psta->asoc_list);
  2068. pstapriv->asoc_list_cnt--;
  2069. updated = ap_free_sta(padapter, psta, _FALSE, reason);
  2070. }
  2071. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2072. associated_clients_update(padapter, updated);
  2073. }
  2074. return _SUCCESS;
  2075. }
  2076. else
  2077. #endif
  2078. {
  2079. DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
  2080. reason, GetAddr3Ptr(pframe));
  2081. receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
  2082. }
  2083. pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
  2084. return _SUCCESS;
  2085. }
  2086. unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
  2087. {
  2088. unsigned short reason;
  2089. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2090. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2091. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2092. u8 *pframe = precv_frame->u.hdr.rx_data;
  2093. #ifdef CONFIG_P2P
  2094. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  2095. #endif //CONFIG_P2P
  2096. //check A3
  2097. if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  2098. return _SUCCESS;
  2099. #ifdef CONFIG_P2P
  2100. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  2101. {
  2102. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  2103. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  2104. }
  2105. #endif //CONFIG_P2P
  2106. reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  2107. DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
  2108. #ifdef CONFIG_AP_MODE
  2109. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  2110. {
  2111. _irqL irqL;
  2112. struct sta_info *psta;
  2113. struct sta_priv *pstapriv = &padapter->stapriv;
  2114. //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2115. //rtw_free_stainfo(padapter, psta);
  2116. //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2117. DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
  2118. reason, GetAddr2Ptr(pframe));
  2119. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2120. if(psta)
  2121. {
  2122. u8 updated;
  2123. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2124. if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
  2125. {
  2126. rtw_list_delete(&psta->asoc_list);
  2127. pstapriv->asoc_list_cnt--;
  2128. updated = ap_free_sta(padapter, psta, _FALSE, reason);
  2129. }
  2130. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2131. associated_clients_update(padapter, updated);
  2132. }
  2133. return _SUCCESS;
  2134. }
  2135. else
  2136. #endif
  2137. {
  2138. DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
  2139. reason, GetAddr3Ptr(pframe));
  2140. receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
  2141. }
  2142. pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
  2143. return _SUCCESS;
  2144. }
  2145. unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
  2146. {
  2147. DBG_871X("%s\n", __FUNCTION__);
  2148. return _SUCCESS;
  2149. }
  2150. unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
  2151. {
  2152. unsigned int ret = _FAIL;
  2153. struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
  2154. struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
  2155. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
  2156. ret = _SUCCESS;
  2157. goto exit;
  2158. }
  2159. if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
  2160. int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
  2161. int ch_offset = -1;
  2162. u8 bwmode;
  2163. struct ieee80211_info_element *ie;
  2164. DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
  2165. FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
  2166. for_each_ie(ie, ies, ies_len) {
  2167. if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
  2168. ch_switch_mode = ie->data[0];
  2169. ch = ie->data[1];
  2170. ch_switch_cnt = ie->data[2];
  2171. DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
  2172. ch_switch_mode, ch, ch_switch_cnt);
  2173. }
  2174. else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
  2175. ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
  2176. DBG_871X("ch_offset:%d\n", ch_offset);
  2177. }
  2178. }
  2179. if (ch == -1)
  2180. return _SUCCESS;
  2181. if (ch_offset == -1)
  2182. bwmode = mlmeext->cur_bwmode;
  2183. else
  2184. bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
  2185. CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
  2186. ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
  2187. /* todo:
  2188. * 1. the decision of channel switching
  2189. * 2. things after channel switching
  2190. */
  2191. ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
  2192. }
  2193. exit:
  2194. return ret;
  2195. }
  2196. unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
  2197. {
  2198. unsigned int ret = _FAIL;
  2199. struct sta_info *psta = NULL;
  2200. struct sta_priv *pstapriv = &padapter->stapriv;
  2201. u8 *pframe = precv_frame->u.hdr.rx_data;
  2202. uint frame_len = precv_frame->u.hdr.len;
  2203. u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2204. u8 category;
  2205. u8 action;
  2206. DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
  2207. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2208. if (!psta)
  2209. goto exit;
  2210. category = frame_body[0];
  2211. if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
  2212. goto exit;
  2213. action = frame_body[1];
  2214. switch (action) {
  2215. case RTW_WLAN_ACTION_SPCT_MSR_REQ:
  2216. case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
  2217. case RTW_WLAN_ACTION_SPCT_TPC_REQ:
  2218. case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
  2219. break;
  2220. case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
  2221. #ifdef CONFIG_SPCT_CH_SWITCH
  2222. ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
  2223. frame_len-(frame_body-pframe)-2);
  2224. #endif
  2225. break;
  2226. default:
  2227. break;
  2228. }
  2229. exit:
  2230. return ret;
  2231. }
  2232. unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
  2233. {
  2234. return _SUCCESS;
  2235. }
  2236. unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
  2237. {
  2238. return _SUCCESS;
  2239. }
  2240. unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
  2241. {
  2242. u8 *addr;
  2243. struct sta_info *psta=NULL;
  2244. struct recv_reorder_ctrl *preorder_ctrl;
  2245. unsigned char *frame_body;
  2246. unsigned char category, action;
  2247. unsigned short tid, status, reason_code = 0;
  2248. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2249. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2250. u8 *pframe = precv_frame->u.hdr.rx_data;
  2251. struct sta_priv *pstapriv = &padapter->stapriv;
  2252. #ifdef CONFIG_80211N_HT
  2253. //check RA matches or not
  2254. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
  2255. return _SUCCESS;
  2256. /*
  2257. //check A1 matches or not
  2258. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  2259. return _SUCCESS;
  2260. */
  2261. DBG_871X("%s\n", __FUNCTION__);
  2262. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  2263. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  2264. return _SUCCESS;
  2265. addr = GetAddr2Ptr(pframe);
  2266. psta = rtw_get_stainfo(pstapriv, addr);
  2267. if(psta==NULL)
  2268. return _SUCCESS;
  2269. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2270. category = frame_body[0];
  2271. if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
  2272. {
  2273. #ifdef CONFIG_TDLS
  2274. if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
  2275. (psta->htpriv.ht_option==_TRUE) &&
  2276. (psta->htpriv.ampdu_enable==_TRUE) )
  2277. {
  2278. //do nothing; just don't want to return _SUCCESS;
  2279. }
  2280. else
  2281. #endif //CONFIG_TDLS
  2282. if (!pmlmeinfo->HT_enable)
  2283. {
  2284. return _SUCCESS;
  2285. }
  2286. action = frame_body[1];
  2287. DBG_871X("%s, action=%d\n", __FUNCTION__, action);
  2288. switch (action)
  2289. {
  2290. case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
  2291. _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
  2292. //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
  2293. process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
  2294. if(pmlmeinfo->bAcceptAddbaReq == _TRUE)
  2295. {
  2296. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
  2297. }
  2298. else
  2299. {
  2300. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);//reject ADDBA Req
  2301. }
  2302. break;
  2303. case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
  2304. //status = frame_body[3] | (frame_body[4] << 8); //endian issue
  2305. status = RTW_GET_LE16(&frame_body[3]);
  2306. tid = ((frame_body[5] >> 2) & 0x7);
  2307. if (status == 0)
  2308. { //successful
  2309. DBG_871X("agg_enable for TID=%d\n", tid);
  2310. psta->htpriv.agg_enable_bitmap |= 1 << tid;
  2311. psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
  2312. }
  2313. else
  2314. {
  2315. psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
  2316. }
  2317. //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
  2318. break;
  2319. case RTW_WLAN_ACTION_DELBA: //DELBA
  2320. if ((frame_body[3] & BIT(3)) == 0)
  2321. {
  2322. psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
  2323. psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
  2324. //reason_code = frame_body[4] | (frame_body[5] << 8);
  2325. reason_code = RTW_GET_LE16(&frame_body[4]);
  2326. }
  2327. else if((frame_body[3] & BIT(3)) == BIT(3))
  2328. {
  2329. tid = (frame_body[3] >> 4) & 0x0F;
  2330. preorder_ctrl = &psta->recvreorder_ctrl[tid];
  2331. preorder_ctrl->enable = _FALSE;
  2332. preorder_ctrl->indicate_seq = 0xffff;
  2333. #ifdef DBG_RX_SEQ
  2334. DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
  2335. preorder_ctrl->indicate_seq);
  2336. #endif
  2337. }
  2338. DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
  2339. //todo: how to notify the host while receiving DELETE BA
  2340. break;
  2341. default:
  2342. break;
  2343. }
  2344. }
  2345. #endif //CONFIG_80211N_HT
  2346. return _SUCCESS;
  2347. }
  2348. #ifdef CONFIG_P2P
  2349. static int get_reg_classes_full_count(struct p2p_channels channel_list) {
  2350. int cnt = 0;
  2351. int i;
  2352. for (i = 0; i < channel_list.reg_classes; i++) {
  2353. cnt += channel_list.reg_class[i].channels;
  2354. }
  2355. return cnt;
  2356. }
  2357. static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
  2358. {
  2359. int i = 0;
  2360. *p24g_cnt = 0;
  2361. *p5gl_cnt = 0;
  2362. *p5gh_cnt = 0;
  2363. for( i = 0; i < pmlmeext->max_chan_nums; i++ )
  2364. {
  2365. if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
  2366. {
  2367. (*p24g_cnt)++;
  2368. }
  2369. else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
  2370. {
  2371. // Just include the channel 36, 40, 44, 48 channels for 5G low
  2372. (*p5gl_cnt)++;
  2373. }
  2374. else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
  2375. {
  2376. // Just include the channel 149, 153, 157, 161 channels for 5G high
  2377. (*p5gh_cnt)++;
  2378. }
  2379. }
  2380. }
  2381. void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
  2382. {
  2383. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  2384. u8 action = P2P_PUB_ACTION_ACTION;
  2385. u32 p2poui = cpu_to_be32(P2POUI);
  2386. u8 oui_subtype = P2P_GO_NEGO_REQ;
  2387. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  2388. u8 wpsielen = 0, p2pielen = 0, i;
  2389. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  2390. u16 len_channellist_attr = 0;
  2391. #ifdef CONFIG_WFD
  2392. u32 wfdielen = 0;
  2393. #endif //CONFIG_WFD
  2394. struct xmit_frame *pmgntframe;
  2395. struct pkt_attrib *pattrib;
  2396. unsigned char *pframe;
  2397. struct rtw_ieee80211_hdr *pwlanhdr;
  2398. unsigned short *fctrl;
  2399. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  2400. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  2401. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2402. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  2403. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  2404. {
  2405. return;
  2406. }
  2407. DBG_871X( "[%s] In\n", __FUNCTION__ );
  2408. //update attribute
  2409. pattrib = &pmgntframe->attrib;
  2410. update_mgntframe_attrib(padapter, pattrib);
  2411. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  2412. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  2413. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  2414. fctrl = &(pwlanhdr->frame_ctl);
  2415. *(fctrl) = 0;
  2416. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  2417. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2418. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2419. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  2420. pmlmeext->mgnt_seq++;
  2421. SetFrameSubType(pframe, WIFI_ACTION);
  2422. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  2423. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  2424. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  2425. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  2426. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  2427. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  2428. pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
  2429. pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
  2430. // WPS Section
  2431. wpsielen = 0;
  2432. // WPS OUI
  2433. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  2434. wpsielen += 4;
  2435. // WPS version
  2436. // Type:
  2437. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  2438. wpsielen += 2;
  2439. // Length:
  2440. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  2441. wpsielen += 2;
  2442. // Value:
  2443. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  2444. // Device Password ID
  2445. // Type:
  2446. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  2447. wpsielen += 2;
  2448. // Length:
  2449. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  2450. wpsielen += 2;
  2451. // Value:
  2452. if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
  2453. {
  2454. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
  2455. }
  2456. else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
  2457. {
  2458. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
  2459. }
  2460. else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
  2461. {
  2462. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
  2463. }
  2464. wpsielen += 2;
  2465. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  2466. // P2P IE Section.
  2467. // P2P OUI
  2468. p2pielen = 0;
  2469. p2pie[ p2pielen++ ] = 0x50;
  2470. p2pie[ p2pielen++ ] = 0x6F;
  2471. p2pie[ p2pielen++ ] = 0x9A;
  2472. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  2473. // Commented by Albert 20110306
  2474. // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
  2475. // 1. P2P Capability
  2476. // 2. Group Owner Intent
  2477. // 3. Configuration Timeout
  2478. // 4. Listen Channel
  2479. // 5. Extended Listen Timing
  2480. // 6. Intended P2P Interface Address
  2481. // 7. Channel List
  2482. // 8. P2P Device Info
  2483. // 9. Operating Channel
  2484. // P2P Capability
  2485. // Type:
  2486. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  2487. // Length:
  2488. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2489. p2pielen += 2;
  2490. // Value:
  2491. // Device Capability Bitmap, 1 byte
  2492. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  2493. // Group Capability Bitmap, 1 byte
  2494. if ( pwdinfo->persistent_supported )
  2495. {
  2496. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  2497. }
  2498. else
  2499. {
  2500. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  2501. }
  2502. // Group Owner Intent
  2503. // Type:
  2504. p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
  2505. // Length:
  2506. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2507. p2pielen += 2;
  2508. // Value:
  2509. // Todo the tie breaker bit.
  2510. p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
  2511. // Configuration Timeout
  2512. // Type:
  2513. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  2514. // Length:
  2515. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2516. p2pielen += 2;
  2517. // Value:
  2518. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  2519. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  2520. // Listen Channel
  2521. // Type:
  2522. p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
  2523. // Length:
  2524. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2525. p2pielen += 2;
  2526. // Value:
  2527. // Country String
  2528. p2pie[ p2pielen++ ] = 'X';
  2529. p2pie[ p2pielen++ ] = 'X';
  2530. // The third byte should be set to 0x04.
  2531. // Described in the "Operating Channel Attribute" section.
  2532. p2pie[ p2pielen++ ] = 0x04;
  2533. // Operating Class
  2534. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  2535. // Channel Number
  2536. p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
  2537. // Extended Listen Timing ATTR
  2538. // Type:
  2539. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  2540. // Length:
  2541. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  2542. p2pielen += 2;
  2543. // Value:
  2544. // Availability Period
  2545. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  2546. p2pielen += 2;
  2547. // Availability Interval
  2548. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  2549. p2pielen += 2;
  2550. // Intended P2P Interface Address
  2551. // Type:
  2552. p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
  2553. // Length:
  2554. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  2555. p2pielen += 2;
  2556. // Value:
  2557. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2558. p2pielen += ETH_ALEN;
  2559. // Channel List
  2560. // Type:
  2561. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  2562. // Length:
  2563. // Country String(3)
  2564. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  2565. // + number of channels in all classes
  2566. len_channellist_attr = 3
  2567. + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
  2568. + get_reg_classes_full_count(pmlmeext->channel_list);
  2569. #ifdef CONFIG_CONCURRENT_MODE
  2570. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2571. {
  2572. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  2573. }
  2574. else
  2575. {
  2576. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2577. }
  2578. #else
  2579. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2580. #endif
  2581. p2pielen += 2;
  2582. // Value:
  2583. // Country String
  2584. p2pie[ p2pielen++ ] = 'X';
  2585. p2pie[ p2pielen++ ] = 'X';
  2586. // The third byte should be set to 0x04.
  2587. // Described in the "Operating Channel Attribute" section.
  2588. p2pie[ p2pielen++ ] = 0x04;
  2589. // Channel Entry List
  2590. #ifdef CONFIG_CONCURRENT_MODE
  2591. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2592. {
  2593. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2594. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2595. // Operating Class
  2596. if ( pbuddy_mlmeext->cur_channel > 14 )
  2597. {
  2598. if ( pbuddy_mlmeext->cur_channel >= 149 )
  2599. {
  2600. p2pie[ p2pielen++ ] = 0x7c;
  2601. }
  2602. else
  2603. {
  2604. p2pie[ p2pielen++ ] = 0x73;
  2605. }
  2606. }
  2607. else
  2608. {
  2609. p2pie[ p2pielen++ ] = 0x51;
  2610. }
  2611. // Number of Channels
  2612. // Just support 1 channel and this channel is AP's channel
  2613. p2pie[ p2pielen++ ] = 1;
  2614. // Channel List
  2615. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  2616. }
  2617. else
  2618. {
  2619. int i,j;
  2620. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  2621. // Operating Class
  2622. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  2623. // Number of Channels
  2624. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  2625. // Channel List
  2626. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  2627. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  2628. }
  2629. }
  2630. }
  2631. #else // CONFIG_CONCURRENT_MODE
  2632. {
  2633. int i,j;
  2634. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  2635. // Operating Class
  2636. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  2637. // Number of Channels
  2638. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  2639. // Channel List
  2640. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  2641. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  2642. }
  2643. }
  2644. }
  2645. #endif // CONFIG_CONCURRENT_MODE
  2646. // Device Info
  2647. // Type:
  2648. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  2649. // Length:
  2650. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  2651. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  2652. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  2653. p2pielen += 2;
  2654. // Value:
  2655. // P2P Device Address
  2656. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2657. p2pielen += ETH_ALEN;
  2658. // Config Method
  2659. // This field should be big endian. Noted by P2P specification.
  2660. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  2661. p2pielen += 2;
  2662. // Primary Device Type
  2663. // Category ID
  2664. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  2665. p2pielen += 2;
  2666. // OUI
  2667. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  2668. p2pielen += 4;
  2669. // Sub Category ID
  2670. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  2671. p2pielen += 2;
  2672. // Number of Secondary Device Types
  2673. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  2674. // Device Name
  2675. // Type:
  2676. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  2677. p2pielen += 2;
  2678. // Length:
  2679. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  2680. p2pielen += 2;
  2681. // Value:
  2682. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
  2683. p2pielen += pwdinfo->device_name_len;
  2684. // Operating Channel
  2685. // Type:
  2686. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  2687. // Length:
  2688. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2689. p2pielen += 2;
  2690. // Value:
  2691. // Country String
  2692. p2pie[ p2pielen++ ] = 'X';
  2693. p2pie[ p2pielen++ ] = 'X';
  2694. // The third byte should be set to 0x04.
  2695. // Described in the "Operating Channel Attribute" section.
  2696. p2pie[ p2pielen++ ] = 0x04;
  2697. // Operating Class
  2698. if ( pwdinfo->operating_channel <= 14 )
  2699. {
  2700. // Operating Class
  2701. p2pie[ p2pielen++ ] = 0x51;
  2702. }
  2703. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  2704. {
  2705. // Operating Class
  2706. p2pie[ p2pielen++ ] = 0x73;
  2707. }
  2708. else
  2709. {
  2710. // Operating Class
  2711. p2pie[ p2pielen++ ] = 0x7c;
  2712. }
  2713. // Channel Number
  2714. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  2715. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  2716. #ifdef CONFIG_WFD
  2717. wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
  2718. pframe += wfdielen;
  2719. pattrib->pktlen += wfdielen;
  2720. #endif //CONFIG_WFD
  2721. pattrib->last_txcmdsz = pattrib->pktlen;
  2722. dump_mgntframe(padapter, pmgntframe);
  2723. return;
  2724. }
  2725. void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
  2726. {
  2727. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  2728. u8 action = P2P_PUB_ACTION_ACTION;
  2729. u32 p2poui = cpu_to_be32(P2POUI);
  2730. u8 oui_subtype = P2P_GO_NEGO_RESP;
  2731. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  2732. u8 p2pielen = 0, i;
  2733. uint wpsielen = 0;
  2734. u16 wps_devicepassword_id = 0x0000;
  2735. uint wps_devicepassword_id_len = 0;
  2736. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
  2737. u16 len_channellist_attr = 0;
  2738. struct xmit_frame *pmgntframe;
  2739. struct pkt_attrib *pattrib;
  2740. unsigned char *pframe;
  2741. struct rtw_ieee80211_hdr *pwlanhdr;
  2742. unsigned short *fctrl;
  2743. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  2744. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  2745. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2746. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  2747. #ifdef CONFIG_WFD
  2748. u32 wfdielen = 0;
  2749. #endif //CONFIG_WFD
  2750. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  2751. {
  2752. return;
  2753. }
  2754. DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
  2755. //update attribute
  2756. pattrib = &pmgntframe->attrib;
  2757. update_mgntframe_attrib(padapter, pattrib);
  2758. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  2759. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  2760. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  2761. fctrl = &(pwlanhdr->frame_ctl);
  2762. *(fctrl) = 0;
  2763. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  2764. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2765. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2766. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  2767. pmlmeext->mgnt_seq++;
  2768. SetFrameSubType(pframe, WIFI_ACTION);
  2769. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  2770. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  2771. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  2772. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  2773. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  2774. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  2775. pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
  2776. pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
  2777. // Commented by Albert 20110328
  2778. // Try to get the device password ID from the WPS IE of group negotiation request frame
  2779. // WiFi Direct test plan 5.1.15
  2780. rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
  2781. rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
  2782. wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
  2783. _rtw_memset( wpsie, 0x00, 255 );
  2784. wpsielen = 0;
  2785. // WPS Section
  2786. wpsielen = 0;
  2787. // WPS OUI
  2788. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  2789. wpsielen += 4;
  2790. // WPS version
  2791. // Type:
  2792. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  2793. wpsielen += 2;
  2794. // Length:
  2795. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  2796. wpsielen += 2;
  2797. // Value:
  2798. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  2799. // Device Password ID
  2800. // Type:
  2801. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  2802. wpsielen += 2;
  2803. // Length:
  2804. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  2805. wpsielen += 2;
  2806. // Value:
  2807. if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
  2808. {
  2809. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
  2810. }
  2811. else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
  2812. {
  2813. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
  2814. }
  2815. else
  2816. {
  2817. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
  2818. }
  2819. wpsielen += 2;
  2820. // Commented by Kurt 20120113
  2821. // If some device wants to do p2p handshake without sending prov_disc_req
  2822. // We have to get peer_req_cm from here.
  2823. if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
  2824. {
  2825. if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
  2826. {
  2827. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
  2828. }
  2829. else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
  2830. {
  2831. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
  2832. }
  2833. else
  2834. {
  2835. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
  2836. }
  2837. }
  2838. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  2839. // P2P IE Section.
  2840. // P2P OUI
  2841. p2pielen = 0;
  2842. p2pie[ p2pielen++ ] = 0x50;
  2843. p2pie[ p2pielen++ ] = 0x6F;
  2844. p2pie[ p2pielen++ ] = 0x9A;
  2845. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  2846. // Commented by Albert 20100908
  2847. // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
  2848. // 1. Status
  2849. // 2. P2P Capability
  2850. // 3. Group Owner Intent
  2851. // 4. Configuration Timeout
  2852. // 5. Operating Channel
  2853. // 6. Intended P2P Interface Address
  2854. // 7. Channel List
  2855. // 8. Device Info
  2856. // 9. Group ID ( Only GO )
  2857. // ToDo:
  2858. // P2P Status
  2859. // Type:
  2860. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  2861. // Length:
  2862. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2863. p2pielen += 2;
  2864. // Value:
  2865. p2pie[ p2pielen++ ] = result;
  2866. // P2P Capability
  2867. // Type:
  2868. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  2869. // Length:
  2870. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2871. p2pielen += 2;
  2872. // Value:
  2873. // Device Capability Bitmap, 1 byte
  2874. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
  2875. {
  2876. // Commented by Albert 2011/03/08
  2877. // According to the P2P specification
  2878. // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
  2879. p2pie[ p2pielen++ ] = 0;
  2880. }
  2881. else
  2882. {
  2883. // Be group owner or meet the error case
  2884. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  2885. }
  2886. // Group Capability Bitmap, 1 byte
  2887. if ( pwdinfo->persistent_supported )
  2888. {
  2889. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  2890. }
  2891. else
  2892. {
  2893. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  2894. }
  2895. // Group Owner Intent
  2896. // Type:
  2897. p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
  2898. // Length:
  2899. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2900. p2pielen += 2;
  2901. // Value:
  2902. if ( pwdinfo->peer_intent & 0x01 )
  2903. {
  2904. // Peer's tie breaker bit is 1, our tie breaker bit should be 0
  2905. p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
  2906. }
  2907. else
  2908. {
  2909. // Peer's tie breaker bit is 0, our tie breaker bit should be 1
  2910. p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
  2911. }
  2912. // Configuration Timeout
  2913. // Type:
  2914. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  2915. // Length:
  2916. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2917. p2pielen += 2;
  2918. // Value:
  2919. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  2920. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  2921. // Operating Channel
  2922. // Type:
  2923. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  2924. // Length:
  2925. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2926. p2pielen += 2;
  2927. // Value:
  2928. // Country String
  2929. p2pie[ p2pielen++ ] = 'X';
  2930. p2pie[ p2pielen++ ] = 'X';
  2931. // The third byte should be set to 0x04.
  2932. // Described in the "Operating Channel Attribute" section.
  2933. p2pie[ p2pielen++ ] = 0x04;
  2934. // Operating Class
  2935. if ( pwdinfo->operating_channel <= 14 )
  2936. {
  2937. // Operating Class
  2938. p2pie[ p2pielen++ ] = 0x51;
  2939. }
  2940. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  2941. {
  2942. // Operating Class
  2943. p2pie[ p2pielen++ ] = 0x73;
  2944. }
  2945. else
  2946. {
  2947. // Operating Class
  2948. p2pie[ p2pielen++ ] = 0x7c;
  2949. }
  2950. // Channel Number
  2951. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  2952. // Intended P2P Interface Address
  2953. // Type:
  2954. p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
  2955. // Length:
  2956. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  2957. p2pielen += 2;
  2958. // Value:
  2959. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2960. p2pielen += ETH_ALEN;
  2961. // Channel List
  2962. // Type:
  2963. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  2964. // Country String(3)
  2965. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  2966. // + number of channels in all classes
  2967. len_channellist_attr = 3
  2968. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  2969. + get_reg_classes_full_count(pmlmeext->channel_list);
  2970. #ifdef CONFIG_CONCURRENT_MODE
  2971. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2972. {
  2973. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  2974. }
  2975. else
  2976. {
  2977. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2978. }
  2979. #else
  2980. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2981. #endif
  2982. p2pielen += 2;
  2983. // Value:
  2984. // Country String
  2985. p2pie[ p2pielen++ ] = 'X';
  2986. p2pie[ p2pielen++ ] = 'X';
  2987. // The third byte should be set to 0x04.
  2988. // Described in the "Operating Channel Attribute" section.
  2989. p2pie[ p2pielen++ ] = 0x04;
  2990. // Channel Entry List
  2991. #ifdef CONFIG_CONCURRENT_MODE
  2992. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2993. {
  2994. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2995. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2996. // Operating Class
  2997. if ( pbuddy_mlmeext->cur_channel > 14 )
  2998. {
  2999. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3000. {
  3001. p2pie[ p2pielen++ ] = 0x7c;
  3002. }
  3003. else
  3004. {
  3005. p2pie[ p2pielen++ ] = 0x73;
  3006. }
  3007. }
  3008. else
  3009. {
  3010. p2pie[ p2pielen++ ] = 0x51;
  3011. }
  3012. // Number of Channels
  3013. // Just support 1 channel and this channel is AP's channel
  3014. p2pie[ p2pielen++ ] = 1;
  3015. // Channel List
  3016. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3017. }
  3018. else
  3019. {
  3020. int i, j;
  3021. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3022. // Operating Class
  3023. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3024. // Number of Channels
  3025. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3026. // Channel List
  3027. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3028. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3029. }
  3030. }
  3031. }
  3032. #else // CONFIG_CONCURRENT_MODE
  3033. {
  3034. int i, j;
  3035. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3036. // Operating Class
  3037. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3038. // Number of Channels
  3039. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3040. // Channel List
  3041. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3042. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3043. }
  3044. }
  3045. }
  3046. #endif // CONFIG_CONCURRENT_MODE
  3047. // Device Info
  3048. // Type:
  3049. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  3050. // Length:
  3051. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  3052. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  3053. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  3054. p2pielen += 2;
  3055. // Value:
  3056. // P2P Device Address
  3057. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3058. p2pielen += ETH_ALEN;
  3059. // Config Method
  3060. // This field should be big endian. Noted by P2P specification.
  3061. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  3062. p2pielen += 2;
  3063. // Primary Device Type
  3064. // Category ID
  3065. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  3066. p2pielen += 2;
  3067. // OUI
  3068. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  3069. p2pielen += 4;
  3070. // Sub Category ID
  3071. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  3072. p2pielen += 2;
  3073. // Number of Secondary Device Types
  3074. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  3075. // Device Name
  3076. // Type:
  3077. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  3078. p2pielen += 2;
  3079. // Length:
  3080. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  3081. p2pielen += 2;
  3082. // Value:
  3083. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
  3084. p2pielen += pwdinfo->device_name_len;
  3085. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  3086. {
  3087. // Group ID Attribute
  3088. // Type:
  3089. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3090. // Length:
  3091. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
  3092. p2pielen += 2;
  3093. // Value:
  3094. // p2P Device Address
  3095. _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
  3096. p2pielen += ETH_ALEN;
  3097. // SSID
  3098. _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  3099. p2pielen += pwdinfo->nego_ssidlen;
  3100. }
  3101. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3102. #ifdef CONFIG_WFD
  3103. wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
  3104. pframe += wfdielen;
  3105. pattrib->pktlen += wfdielen;
  3106. #endif //CONFIG_WFD
  3107. pattrib->last_txcmdsz = pattrib->pktlen;
  3108. dump_mgntframe(padapter, pmgntframe);
  3109. return;
  3110. }
  3111. void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
  3112. {
  3113. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3114. u8 action = P2P_PUB_ACTION_ACTION;
  3115. u32 p2poui = cpu_to_be32(P2POUI);
  3116. u8 oui_subtype = P2P_GO_NEGO_CONF;
  3117. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  3118. u8 wpsielen = 0, p2pielen = 0;
  3119. struct xmit_frame *pmgntframe;
  3120. struct pkt_attrib *pattrib;
  3121. unsigned char *pframe;
  3122. struct rtw_ieee80211_hdr *pwlanhdr;
  3123. unsigned short *fctrl;
  3124. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3125. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3126. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3127. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3128. #ifdef CONFIG_WFD
  3129. u32 wfdielen = 0;
  3130. #endif //CONFIG_WFD
  3131. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3132. {
  3133. return;
  3134. }
  3135. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3136. //update attribute
  3137. pattrib = &pmgntframe->attrib;
  3138. update_mgntframe_attrib(padapter, pattrib);
  3139. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3140. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3141. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3142. fctrl = &(pwlanhdr->frame_ctl);
  3143. *(fctrl) = 0;
  3144. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3145. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3146. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3147. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3148. pmlmeext->mgnt_seq++;
  3149. SetFrameSubType(pframe, WIFI_ACTION);
  3150. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3151. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3152. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3153. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3154. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3155. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3156. pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
  3157. // P2P IE Section.
  3158. // P2P OUI
  3159. p2pielen = 0;
  3160. p2pie[ p2pielen++ ] = 0x50;
  3161. p2pie[ p2pielen++ ] = 0x6F;
  3162. p2pie[ p2pielen++ ] = 0x9A;
  3163. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3164. // Commented by Albert 20110306
  3165. // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
  3166. // 1. Status
  3167. // 2. P2P Capability
  3168. // 3. Operating Channel
  3169. // 4. Channel List
  3170. // 5. Group ID ( if this WiFi is GO )
  3171. // P2P Status
  3172. // Type:
  3173. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  3174. // Length:
  3175. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3176. p2pielen += 2;
  3177. // Value:
  3178. p2pie[ p2pielen++ ] = result;
  3179. // P2P Capability
  3180. // Type:
  3181. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  3182. // Length:
  3183. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3184. p2pielen += 2;
  3185. // Value:
  3186. // Device Capability Bitmap, 1 byte
  3187. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  3188. // Group Capability Bitmap, 1 byte
  3189. if ( pwdinfo->persistent_supported )
  3190. {
  3191. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  3192. }
  3193. else
  3194. {
  3195. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  3196. }
  3197. // Operating Channel
  3198. // Type:
  3199. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3200. // Length:
  3201. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3202. p2pielen += 2;
  3203. // Value:
  3204. // Country String
  3205. p2pie[ p2pielen++ ] = 'X';
  3206. p2pie[ p2pielen++ ] = 'X';
  3207. // The third byte should be set to 0x04.
  3208. // Described in the "Operating Channel Attribute" section.
  3209. p2pie[ p2pielen++ ] = 0x04;
  3210. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
  3211. {
  3212. if ( pwdinfo->peer_operating_ch <= 14 )
  3213. {
  3214. // Operating Class
  3215. p2pie[ p2pielen++ ] = 0x51;
  3216. }
  3217. else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
  3218. {
  3219. // Operating Class
  3220. p2pie[ p2pielen++ ] = 0x73;
  3221. }
  3222. else
  3223. {
  3224. // Operating Class
  3225. p2pie[ p2pielen++ ] = 0x7c;
  3226. }
  3227. p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
  3228. }
  3229. else
  3230. {
  3231. if ( pwdinfo->operating_channel <= 14 )
  3232. {
  3233. // Operating Class
  3234. p2pie[ p2pielen++ ] = 0x51;
  3235. }
  3236. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  3237. {
  3238. // Operating Class
  3239. p2pie[ p2pielen++ ] = 0x73;
  3240. }
  3241. else
  3242. {
  3243. // Operating Class
  3244. p2pie[ p2pielen++ ] = 0x7c;
  3245. }
  3246. // Channel Number
  3247. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
  3248. }
  3249. // Channel List
  3250. // Type:
  3251. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3252. // Length:
  3253. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( pwdinfo->channel_list_attr_len );
  3254. p2pielen += 2;
  3255. // Value:
  3256. _rtw_memcpy( p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len );
  3257. p2pielen += pwdinfo->channel_list_attr_len;
  3258. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  3259. {
  3260. // Group ID Attribute
  3261. // Type:
  3262. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3263. // Length:
  3264. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
  3265. p2pielen += 2;
  3266. // Value:
  3267. // p2P Device Address
  3268. _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
  3269. p2pielen += ETH_ALEN;
  3270. // SSID
  3271. _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  3272. p2pielen += pwdinfo->nego_ssidlen;
  3273. }
  3274. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3275. #ifdef CONFIG_WFD
  3276. wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
  3277. pframe += wfdielen;
  3278. pattrib->pktlen += wfdielen;
  3279. #endif //CONFIG_WFD
  3280. pattrib->last_txcmdsz = pattrib->pktlen;
  3281. dump_mgntframe(padapter, pmgntframe);
  3282. return;
  3283. }
  3284. void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
  3285. {
  3286. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3287. u8 action = P2P_PUB_ACTION_ACTION;
  3288. u32 p2poui = cpu_to_be32(P2POUI);
  3289. u8 oui_subtype = P2P_INVIT_REQ;
  3290. u8 p2pie[ 255 ] = { 0x00 };
  3291. u8 p2pielen = 0, i;
  3292. u8 dialogToken = 3;
  3293. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  3294. u16 len_channellist_attr = 0;
  3295. #ifdef CONFIG_WFD
  3296. u32 wfdielen = 0;
  3297. #endif //CONFIG_WFD
  3298. #ifdef CONFIG_CONCURRENT_MODE
  3299. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3300. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  3301. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  3302. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3303. #endif
  3304. struct xmit_frame *pmgntframe;
  3305. struct pkt_attrib *pattrib;
  3306. unsigned char *pframe;
  3307. struct rtw_ieee80211_hdr *pwlanhdr;
  3308. unsigned short *fctrl;
  3309. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3310. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3311. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3312. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3313. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3314. {
  3315. return;
  3316. }
  3317. //update attribute
  3318. pattrib = &pmgntframe->attrib;
  3319. update_mgntframe_attrib(padapter, pattrib);
  3320. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3321. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3322. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3323. fctrl = &(pwlanhdr->frame_ctl);
  3324. *(fctrl) = 0;
  3325. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3326. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3327. _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
  3328. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3329. pmlmeext->mgnt_seq++;
  3330. SetFrameSubType(pframe, WIFI_ACTION);
  3331. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3332. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3333. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3334. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3335. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3336. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3337. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3338. // P2P IE Section.
  3339. // P2P OUI
  3340. p2pielen = 0;
  3341. p2pie[ p2pielen++ ] = 0x50;
  3342. p2pie[ p2pielen++ ] = 0x6F;
  3343. p2pie[ p2pielen++ ] = 0x9A;
  3344. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3345. // Commented by Albert 20101011
  3346. // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
  3347. // 1. Configuration Timeout
  3348. // 2. Invitation Flags
  3349. // 3. Operating Channel ( Only GO )
  3350. // 4. P2P Group BSSID ( Should be included if I am the GO )
  3351. // 5. Channel List
  3352. // 6. P2P Group ID
  3353. // 7. P2P Device Info
  3354. // Configuration Timeout
  3355. // Type:
  3356. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  3357. // Length:
  3358. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3359. p2pielen += 2;
  3360. // Value:
  3361. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  3362. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  3363. // Invitation Flags
  3364. // Type:
  3365. p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
  3366. // Length:
  3367. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3368. p2pielen += 2;
  3369. // Value:
  3370. p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
  3371. // Operating Channel
  3372. // Type:
  3373. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3374. // Length:
  3375. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3376. p2pielen += 2;
  3377. // Value:
  3378. // Country String
  3379. p2pie[ p2pielen++ ] = 'X';
  3380. p2pie[ p2pielen++ ] = 'X';
  3381. // The third byte should be set to 0x04.
  3382. // Described in the "Operating Channel Attribute" section.
  3383. p2pie[ p2pielen++ ] = 0x04;
  3384. // Operating Class
  3385. if ( pwdinfo->invitereq_info.operating_ch <= 14 )
  3386. p2pie[ p2pielen++ ] = 0x51;
  3387. else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
  3388. p2pie[ p2pielen++ ] = 0x73;
  3389. else
  3390. p2pie[ p2pielen++ ] = 0x7c;
  3391. // Channel Number
  3392. p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
  3393. if ( _rtw_memcmp( myid( &padapter->eeprompriv ), pwdinfo->invitereq_info.go_bssid, ETH_ALEN ) )
  3394. {
  3395. // P2P Group BSSID
  3396. // Type:
  3397. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
  3398. // Length:
  3399. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  3400. p2pielen += 2;
  3401. // Value:
  3402. // P2P Device Address for GO
  3403. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
  3404. p2pielen += ETH_ALEN;
  3405. }
  3406. // Channel List
  3407. // Type:
  3408. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3409. // Length:
  3410. // Country String(3)
  3411. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  3412. // + number of channels in all classes
  3413. len_channellist_attr = 3
  3414. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  3415. + get_reg_classes_full_count(pmlmeext->channel_list);
  3416. #ifdef CONFIG_CONCURRENT_MODE
  3417. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3418. {
  3419. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  3420. }
  3421. else
  3422. {
  3423. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3424. }
  3425. #else
  3426. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3427. #endif
  3428. p2pielen += 2;
  3429. // Value:
  3430. // Country String
  3431. p2pie[ p2pielen++ ] = 'X';
  3432. p2pie[ p2pielen++ ] = 'X';
  3433. // The third byte should be set to 0x04.
  3434. // Described in the "Operating Channel Attribute" section.
  3435. p2pie[ p2pielen++ ] = 0x04;
  3436. // Channel Entry List
  3437. #ifdef CONFIG_CONCURRENT_MODE
  3438. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3439. {
  3440. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3441. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3442. // Operating Class
  3443. if ( pbuddy_mlmeext->cur_channel > 14 )
  3444. {
  3445. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3446. {
  3447. p2pie[ p2pielen++ ] = 0x7c;
  3448. }
  3449. else
  3450. {
  3451. p2pie[ p2pielen++ ] = 0x73;
  3452. }
  3453. }
  3454. else
  3455. {
  3456. p2pie[ p2pielen++ ] = 0x51;
  3457. }
  3458. // Number of Channels
  3459. // Just support 1 channel and this channel is AP's channel
  3460. p2pie[ p2pielen++ ] = 1;
  3461. // Channel List
  3462. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3463. }
  3464. else
  3465. {
  3466. int i, j;
  3467. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3468. // Operating Class
  3469. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3470. // Number of Channels
  3471. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3472. // Channel List
  3473. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3474. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3475. }
  3476. }
  3477. }
  3478. #else // CONFIG_CONCURRENT_MODE
  3479. {
  3480. int i, j;
  3481. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3482. // Operating Class
  3483. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3484. // Number of Channels
  3485. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3486. // Channel List
  3487. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3488. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3489. }
  3490. }
  3491. }
  3492. #endif // CONFIG_CONCURRENT_MODE
  3493. // P2P Group ID
  3494. // Type:
  3495. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3496. // Length:
  3497. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
  3498. p2pielen += 2;
  3499. // Value:
  3500. // P2P Device Address for GO
  3501. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
  3502. p2pielen += ETH_ALEN;
  3503. // SSID
  3504. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
  3505. p2pielen += pwdinfo->invitereq_info.ssidlen;
  3506. // Device Info
  3507. // Type:
  3508. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  3509. // Length:
  3510. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  3511. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  3512. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  3513. p2pielen += 2;
  3514. // Value:
  3515. // P2P Device Address
  3516. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3517. p2pielen += ETH_ALEN;
  3518. // Config Method
  3519. // This field should be big endian. Noted by P2P specification.
  3520. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
  3521. p2pielen += 2;
  3522. // Primary Device Type
  3523. // Category ID
  3524. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  3525. p2pielen += 2;
  3526. // OUI
  3527. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  3528. p2pielen += 4;
  3529. // Sub Category ID
  3530. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  3531. p2pielen += 2;
  3532. // Number of Secondary Device Types
  3533. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  3534. // Device Name
  3535. // Type:
  3536. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  3537. p2pielen += 2;
  3538. // Length:
  3539. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  3540. p2pielen += 2;
  3541. // Value:
  3542. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  3543. p2pielen += pwdinfo->device_name_len;
  3544. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3545. #ifdef CONFIG_WFD
  3546. wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
  3547. pframe += wfdielen;
  3548. pattrib->pktlen += wfdielen;
  3549. #endif //CONFIG_WFD
  3550. pattrib->last_txcmdsz = pattrib->pktlen;
  3551. dump_mgntframe(padapter, pmgntframe);
  3552. return;
  3553. }
  3554. void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
  3555. {
  3556. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3557. u8 action = P2P_PUB_ACTION_ACTION;
  3558. u32 p2poui = cpu_to_be32(P2POUI);
  3559. u8 oui_subtype = P2P_INVIT_RESP;
  3560. u8 p2pie[ 255 ] = { 0x00 };
  3561. u8 p2pielen = 0, i;
  3562. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  3563. u16 len_channellist_attr = 0;
  3564. #ifdef CONFIG_CONCURRENT_MODE
  3565. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3566. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  3567. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  3568. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3569. #endif
  3570. #ifdef CONFIG_WFD
  3571. u32 wfdielen = 0;
  3572. #endif //CONFIG_WFD
  3573. struct xmit_frame *pmgntframe;
  3574. struct pkt_attrib *pattrib;
  3575. unsigned char *pframe;
  3576. struct rtw_ieee80211_hdr *pwlanhdr;
  3577. unsigned short *fctrl;
  3578. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3579. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3580. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3581. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3582. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3583. {
  3584. return;
  3585. }
  3586. //update attribute
  3587. pattrib = &pmgntframe->attrib;
  3588. update_mgntframe_attrib(padapter, pattrib);
  3589. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3590. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3591. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3592. fctrl = &(pwlanhdr->frame_ctl);
  3593. *(fctrl) = 0;
  3594. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3595. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3596. _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
  3597. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3598. pmlmeext->mgnt_seq++;
  3599. SetFrameSubType(pframe, WIFI_ACTION);
  3600. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3601. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3602. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3603. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3604. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3605. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3606. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3607. // P2P IE Section.
  3608. // P2P OUI
  3609. p2pielen = 0;
  3610. p2pie[ p2pielen++ ] = 0x50;
  3611. p2pie[ p2pielen++ ] = 0x6F;
  3612. p2pie[ p2pielen++ ] = 0x9A;
  3613. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3614. // Commented by Albert 20101005
  3615. // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
  3616. // 1. Status
  3617. // 2. Configuration Timeout
  3618. // 3. Operating Channel ( Only GO )
  3619. // 4. P2P Group BSSID ( Only GO )
  3620. // 5. Channel List
  3621. // P2P Status
  3622. // Type:
  3623. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  3624. // Length:
  3625. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3626. p2pielen += 2;
  3627. // Value:
  3628. // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
  3629. // Sent the event receiving the P2P Invitation Req frame to DMP UI.
  3630. // DMP had to compare the MAC address to find out the profile.
  3631. // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
  3632. // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
  3633. // to NB to rebuild the persistent group.
  3634. p2pie[ p2pielen++ ] = status_code;
  3635. // Configuration Timeout
  3636. // Type:
  3637. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  3638. // Length:
  3639. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3640. p2pielen += 2;
  3641. // Value:
  3642. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  3643. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  3644. if( status_code == P2P_STATUS_SUCCESS )
  3645. {
  3646. if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
  3647. {
  3648. // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
  3649. // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
  3650. // First one is operating channel attribute.
  3651. // Second one is P2P Group BSSID attribute.
  3652. // Operating Channel
  3653. // Type:
  3654. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3655. // Length:
  3656. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3657. p2pielen += 2;
  3658. // Value:
  3659. // Country String
  3660. p2pie[ p2pielen++ ] = 'X';
  3661. p2pie[ p2pielen++ ] = 'X';
  3662. // The third byte should be set to 0x04.
  3663. // Described in the "Operating Channel Attribute" section.
  3664. p2pie[ p2pielen++ ] = 0x04;
  3665. // Operating Class
  3666. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  3667. // Channel Number
  3668. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  3669. // P2P Group BSSID
  3670. // Type:
  3671. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
  3672. // Length:
  3673. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  3674. p2pielen += 2;
  3675. // Value:
  3676. // P2P Device Address for GO
  3677. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3678. p2pielen += ETH_ALEN;
  3679. }
  3680. // Channel List
  3681. // Type:
  3682. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3683. // Length:
  3684. // Country String(3)
  3685. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  3686. // + number of channels in all classes
  3687. len_channellist_attr = 3
  3688. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  3689. + get_reg_classes_full_count(pmlmeext->channel_list);
  3690. #ifdef CONFIG_CONCURRENT_MODE
  3691. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3692. {
  3693. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  3694. }
  3695. else
  3696. {
  3697. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3698. }
  3699. #else
  3700. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3701. #endif
  3702. p2pielen += 2;
  3703. // Value:
  3704. // Country String
  3705. p2pie[ p2pielen++ ] = 'X';
  3706. p2pie[ p2pielen++ ] = 'X';
  3707. // The third byte should be set to 0x04.
  3708. // Described in the "Operating Channel Attribute" section.
  3709. p2pie[ p2pielen++ ] = 0x04;
  3710. // Channel Entry List
  3711. #ifdef CONFIG_CONCURRENT_MODE
  3712. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3713. {
  3714. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3715. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3716. // Operating Class
  3717. if ( pbuddy_mlmeext->cur_channel > 14 )
  3718. {
  3719. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3720. {
  3721. p2pie[ p2pielen++ ] = 0x7c;
  3722. }
  3723. else
  3724. {
  3725. p2pie[ p2pielen++ ] = 0x73;
  3726. }
  3727. }
  3728. else
  3729. {
  3730. p2pie[ p2pielen++ ] = 0x51;
  3731. }
  3732. // Number of Channels
  3733. // Just support 1 channel and this channel is AP's channel
  3734. p2pie[ p2pielen++ ] = 1;
  3735. // Channel List
  3736. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3737. }
  3738. else
  3739. {
  3740. int i, j;
  3741. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3742. // Operating Class
  3743. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3744. // Number of Channels
  3745. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3746. // Channel List
  3747. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3748. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3749. }
  3750. }
  3751. }
  3752. #else // CONFIG_CONCURRENT_MODE
  3753. {
  3754. int i, j;
  3755. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3756. // Operating Class
  3757. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3758. // Number of Channels
  3759. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3760. // Channel List
  3761. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3762. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3763. }
  3764. }
  3765. }
  3766. #endif // CONFIG_CONCURRENT_MODE
  3767. }
  3768. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3769. #ifdef CONFIG_WFD
  3770. wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
  3771. pframe += wfdielen;
  3772. pattrib->pktlen += wfdielen;
  3773. #endif //CONFIG_WFD
  3774. pattrib->last_txcmdsz = pattrib->pktlen;
  3775. dump_mgntframe(padapter, pmgntframe);
  3776. return;
  3777. }
  3778. void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
  3779. {
  3780. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3781. u8 action = P2P_PUB_ACTION_ACTION;
  3782. u8 dialogToken = 1;
  3783. u32 p2poui = cpu_to_be32(P2POUI);
  3784. u8 oui_subtype = P2P_PROVISION_DISC_REQ;
  3785. u8 wpsie[ 100 ] = { 0x00 };
  3786. u8 wpsielen = 0;
  3787. u32 p2pielen = 0;
  3788. #ifdef CONFIG_WFD
  3789. u32 wfdielen = 0;
  3790. #endif //CONFIG_WFD
  3791. struct xmit_frame *pmgntframe;
  3792. struct pkt_attrib *pattrib;
  3793. unsigned char *pframe;
  3794. struct rtw_ieee80211_hdr *pwlanhdr;
  3795. unsigned short *fctrl;
  3796. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3797. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3798. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3799. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  3800. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3801. {
  3802. return;
  3803. }
  3804. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3805. //update attribute
  3806. pattrib = &pmgntframe->attrib;
  3807. update_mgntframe_attrib(padapter, pattrib);
  3808. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3809. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3810. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3811. fctrl = &(pwlanhdr->frame_ctl);
  3812. *(fctrl) = 0;
  3813. _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
  3814. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3815. _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
  3816. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3817. pmlmeext->mgnt_seq++;
  3818. SetFrameSubType(pframe, WIFI_ACTION);
  3819. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3820. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3821. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3822. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3823. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3824. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3825. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3826. p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
  3827. pframe += p2pielen;
  3828. pattrib->pktlen += p2pielen;
  3829. wpsielen = 0;
  3830. // WPS OUI
  3831. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  3832. wpsielen += 4;
  3833. // WPS version
  3834. // Type:
  3835. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  3836. wpsielen += 2;
  3837. // Length:
  3838. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  3839. wpsielen += 2;
  3840. // Value:
  3841. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  3842. // Config Method
  3843. // Type:
  3844. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  3845. wpsielen += 2;
  3846. // Length:
  3847. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  3848. wpsielen += 2;
  3849. // Value:
  3850. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
  3851. wpsielen += 2;
  3852. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  3853. #ifdef CONFIG_WFD
  3854. wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
  3855. pframe += wfdielen;
  3856. pattrib->pktlen += wfdielen;
  3857. #endif //CONFIG_WFD
  3858. pattrib->last_txcmdsz = pattrib->pktlen;
  3859. dump_mgntframe(padapter, pmgntframe);
  3860. return;
  3861. }
  3862. u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
  3863. {
  3864. u8 i, match_result = 0;
  3865. DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  3866. peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
  3867. for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
  3868. {
  3869. DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  3870. profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
  3871. if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
  3872. {
  3873. match_result = 1;
  3874. DBG_871X( "[%s] Match!\n", __FUNCTION__ );
  3875. break;
  3876. }
  3877. }
  3878. return (match_result );
  3879. }
  3880. void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
  3881. {
  3882. struct xmit_frame *pmgntframe;
  3883. struct pkt_attrib *pattrib;
  3884. unsigned char *pframe;
  3885. struct rtw_ieee80211_hdr *pwlanhdr;
  3886. unsigned short *fctrl;
  3887. unsigned char *mac;
  3888. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3889. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3890. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3891. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  3892. //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  3893. u16 beacon_interval = 100;
  3894. u16 capInfo = 0;
  3895. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  3896. u8 wpsie[255] = { 0x00 };
  3897. u32 wpsielen = 0, p2pielen = 0;
  3898. #ifdef CONFIG_WFD
  3899. u32 wfdielen = 0;
  3900. #endif //CONFIG_WFD
  3901. #ifdef CONFIG_IOCTL_CFG80211
  3902. struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
  3903. struct ieee80211_channel *ieee_ch = &pcfg80211_wdinfo->remain_on_ch_channel;
  3904. u8 listen_channel = (u8) ieee80211_frequency_to_channel(ieee_ch->center_freq);
  3905. #endif //CONFIG_IOCTL_CFG80211
  3906. #ifdef CONFIG_INTEL_WIDI
  3907. u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
  3908. #endif //CONFIG_INTEL_WIDI
  3909. //DBG_871X("%s\n", __FUNCTION__);
  3910. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3911. {
  3912. return;
  3913. }
  3914. //update attribute
  3915. pattrib = &pmgntframe->attrib;
  3916. update_mgntframe_attrib(padapter, pattrib);
  3917. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3918. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3919. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3920. mac = myid(&(padapter->eeprompriv));
  3921. fctrl = &(pwlanhdr->frame_ctl);
  3922. *(fctrl) = 0;
  3923. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  3924. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  3925. // Use the device address for BSSID field.
  3926. _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
  3927. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3928. pmlmeext->mgnt_seq++;
  3929. SetFrameSubType(fctrl, WIFI_PROBERSP);
  3930. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3931. pattrib->pktlen = pattrib->hdrlen;
  3932. pframe += pattrib->hdrlen;
  3933. //timestamp will be inserted by hardware
  3934. pframe += 8;
  3935. pattrib->pktlen += 8;
  3936. // beacon interval: 2 bytes
  3937. _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
  3938. pframe += 2;
  3939. pattrib->pktlen += 2;
  3940. // capability info: 2 bytes
  3941. // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
  3942. capInfo |= cap_ShortPremble;
  3943. capInfo |= cap_ShortSlot;
  3944. _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
  3945. pframe += 2;
  3946. pattrib->pktlen += 2;
  3947. // SSID
  3948. pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
  3949. // supported rates...
  3950. // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
  3951. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
  3952. // DS parameter set
  3953. #ifdef CONFIG_IOCTL_CFG80211
  3954. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && listen_channel !=0 && pwdinfo->driver_interface == DRIVER_CFG80211 )
  3955. {
  3956. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&listen_channel, &pattrib->pktlen);
  3957. }
  3958. else
  3959. #endif //CONFIG_IOCTL_CFG80211
  3960. {
  3961. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
  3962. }
  3963. #ifdef CONFIG_IOCTL_CFG80211
  3964. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  3965. {
  3966. if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
  3967. {
  3968. //WPS IE
  3969. _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
  3970. pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
  3971. pframe += pmlmepriv->wps_probe_resp_ie_len;
  3972. //P2P IE
  3973. _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
  3974. pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
  3975. pframe += pmlmepriv->p2p_probe_resp_ie_len;
  3976. }
  3977. }
  3978. else
  3979. #endif //CONFIG_IOCTL_CFG80211
  3980. {
  3981. // Todo: WPS IE
  3982. // Noted by Albert 20100907
  3983. // According to the WPS specification, all the WPS attribute is presented by Big Endian.
  3984. wpsielen = 0;
  3985. // WPS OUI
  3986. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  3987. wpsielen += 4;
  3988. // WPS version
  3989. // Type:
  3990. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  3991. wpsielen += 2;
  3992. // Length:
  3993. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  3994. wpsielen += 2;
  3995. // Value:
  3996. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  3997. #ifdef CONFIG_INTEL_WIDI
  3998. // Commented by Kurt
  3999. // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
  4000. if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
  4001. {
  4002. //Sec dev type
  4003. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
  4004. wpsielen += 2;
  4005. // Length:
  4006. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4007. wpsielen += 2;
  4008. // Value:
  4009. // Category ID
  4010. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
  4011. wpsielen += 2;
  4012. // OUI
  4013. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
  4014. wpsielen += 4;
  4015. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
  4016. wpsielen += 2;
  4017. // Vendor Extension
  4018. _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
  4019. wpsielen += L2SDTA_SERVICE_VE_LEN;
  4020. }
  4021. #endif //CONFIG_INTEL_WIDI
  4022. // WiFi Simple Config State
  4023. // Type:
  4024. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
  4025. wpsielen += 2;
  4026. // Length:
  4027. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4028. wpsielen += 2;
  4029. // Value:
  4030. wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
  4031. // Response Type
  4032. // Type:
  4033. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
  4034. wpsielen += 2;
  4035. // Length:
  4036. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4037. wpsielen += 2;
  4038. // Value:
  4039. wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
  4040. // UUID-E
  4041. // Type:
  4042. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
  4043. wpsielen += 2;
  4044. // Length:
  4045. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
  4046. wpsielen += 2;
  4047. // Value:
  4048. _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  4049. wpsielen += 0x10;
  4050. // Manufacturer
  4051. // Type:
  4052. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
  4053. wpsielen += 2;
  4054. // Length:
  4055. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
  4056. wpsielen += 2;
  4057. // Value:
  4058. _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
  4059. wpsielen += 7;
  4060. // Model Name
  4061. // Type:
  4062. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
  4063. wpsielen += 2;
  4064. // Length:
  4065. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
  4066. wpsielen += 2;
  4067. // Value:
  4068. _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
  4069. wpsielen += 6;
  4070. // Model Number
  4071. // Type:
  4072. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
  4073. wpsielen += 2;
  4074. // Length:
  4075. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4076. wpsielen += 2;
  4077. // Value:
  4078. wpsie[ wpsielen++ ] = 0x31; // character 1
  4079. // Serial Number
  4080. // Type:
  4081. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
  4082. wpsielen += 2;
  4083. // Length:
  4084. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
  4085. wpsielen += 2;
  4086. // Value:
  4087. _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
  4088. wpsielen += ETH_ALEN;
  4089. // Primary Device Type
  4090. // Type:
  4091. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  4092. wpsielen += 2;
  4093. // Length:
  4094. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4095. wpsielen += 2;
  4096. // Value:
  4097. // Category ID
  4098. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  4099. wpsielen += 2;
  4100. // OUI
  4101. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
  4102. wpsielen += 4;
  4103. // Sub Category ID
  4104. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  4105. wpsielen += 2;
  4106. // Device Name
  4107. // Type:
  4108. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  4109. wpsielen += 2;
  4110. // Length:
  4111. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
  4112. wpsielen += 2;
  4113. // Value:
  4114. _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
  4115. wpsielen += pwdinfo->device_name_len;
  4116. // Config Method
  4117. // Type:
  4118. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  4119. wpsielen += 2;
  4120. // Length:
  4121. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4122. wpsielen += 2;
  4123. // Value:
  4124. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  4125. wpsielen += 2;
  4126. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  4127. p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
  4128. pframe += p2pielen;
  4129. pattrib->pktlen += p2pielen;
  4130. }
  4131. #ifdef CONFIG_WFD
  4132. #ifdef CONFIG_IOCTL_CFG80211
  4133. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  4134. #endif //CONFIG_IOCTL_CFG80211
  4135. {
  4136. wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
  4137. pframe += wfdielen;
  4138. pattrib->pktlen += wfdielen;
  4139. }
  4140. #ifdef CONFIG_IOCTL_CFG80211
  4141. else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
  4142. {
  4143. //WFD IE
  4144. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
  4145. pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
  4146. pframe += pmlmepriv->wfd_probe_resp_ie_len;
  4147. }
  4148. #endif //CONFIG_IOCTL_CFG80211
  4149. #endif //CONFIG_WFD
  4150. pattrib->last_txcmdsz = pattrib->pktlen;
  4151. dump_mgntframe(padapter, pmgntframe);
  4152. return;
  4153. }
  4154. int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
  4155. {
  4156. int ret = _FAIL;
  4157. struct xmit_frame *pmgntframe;
  4158. struct pkt_attrib *pattrib;
  4159. unsigned char *pframe;
  4160. struct rtw_ieee80211_hdr *pwlanhdr;
  4161. unsigned short *fctrl;
  4162. unsigned char *mac;
  4163. unsigned char bssrate[NumRates];
  4164. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  4165. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  4166. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  4167. int bssrate_len = 0;
  4168. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  4169. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  4170. u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  4171. u16 wpsielen = 0, p2pielen = 0;
  4172. #ifdef CONFIG_WFD
  4173. u32 wfdielen = 0;
  4174. #endif //CONFIG_WFD
  4175. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  4176. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  4177. {
  4178. goto exit;
  4179. }
  4180. //update attribute
  4181. pattrib = &pmgntframe->attrib;
  4182. update_mgntframe_attrib(padapter, pattrib);
  4183. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  4184. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  4185. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  4186. mac = myid(&(padapter->eeprompriv));
  4187. fctrl = &(pwlanhdr->frame_ctl);
  4188. *(fctrl) = 0;
  4189. if (da) {
  4190. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  4191. _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
  4192. } else {
  4193. if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
  4194. {
  4195. // This two flags will be set when this is only the P2P client mode.
  4196. _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
  4197. _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
  4198. }
  4199. else
  4200. {
  4201. // broadcast probe request frame
  4202. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  4203. _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
  4204. }
  4205. }
  4206. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  4207. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  4208. pmlmeext->mgnt_seq++;
  4209. SetFrameSubType(pframe, WIFI_PROBEREQ);
  4210. pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
  4211. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  4212. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  4213. {
  4214. pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
  4215. }
  4216. else
  4217. {
  4218. pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
  4219. }
  4220. // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
  4221. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
  4222. #ifdef CONFIG_IOCTL_CFG80211
  4223. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  4224. {
  4225. if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
  4226. {
  4227. //WPS IE
  4228. _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
  4229. pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
  4230. pframe += pmlmepriv->wps_probe_req_ie_len;
  4231. //P2P IE
  4232. _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
  4233. pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
  4234. pframe += pmlmepriv->p2p_probe_req_ie_len;
  4235. }
  4236. }
  4237. else
  4238. #endif //CONFIG_IOCTL_CFG80211
  4239. {
  4240. // WPS IE
  4241. // Noted by Albert 20110221
  4242. // According to the WPS specification, all the WPS attribute is presented by Big Endian.
  4243. wpsielen = 0;
  4244. // WPS OUI
  4245. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  4246. wpsielen += 4;
  4247. // WPS version
  4248. // Type:
  4249. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  4250. wpsielen += 2;
  4251. // Length:
  4252. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4253. wpsielen += 2;
  4254. // Value:
  4255. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  4256. if( pmlmepriv->wps_probe_req_ie == NULL )
  4257. {
  4258. // UUID-E
  4259. // Type:
  4260. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
  4261. wpsielen += 2;
  4262. // Length:
  4263. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
  4264. wpsielen += 2;
  4265. // Value:
  4266. _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  4267. wpsielen += 0x10;
  4268. // Config Method
  4269. // Type:
  4270. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  4271. wpsielen += 2;
  4272. // Length:
  4273. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4274. wpsielen += 2;
  4275. // Value:
  4276. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  4277. wpsielen += 2;
  4278. }
  4279. // Device Name
  4280. // Type:
  4281. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  4282. wpsielen += 2;
  4283. // Length:
  4284. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
  4285. wpsielen += 2;
  4286. // Value:
  4287. _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
  4288. wpsielen += pwdinfo->device_name_len;
  4289. // Primary Device Type
  4290. // Type:
  4291. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  4292. wpsielen += 2;
  4293. // Length:
  4294. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4295. wpsielen += 2;
  4296. // Value:
  4297. // Category ID
  4298. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
  4299. wpsielen += 2;
  4300. // OUI
  4301. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
  4302. wpsielen += 4;
  4303. // Sub Category ID
  4304. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
  4305. wpsielen += 2;
  4306. // Device Password ID
  4307. // Type:
  4308. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  4309. wpsielen += 2;
  4310. // Length:
  4311. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4312. wpsielen += 2;
  4313. // Value:
  4314. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
  4315. wpsielen += 2;
  4316. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  4317. // P2P OUI
  4318. p2pielen = 0;
  4319. p2pie[ p2pielen++ ] = 0x50;
  4320. p2pie[ p2pielen++ ] = 0x6F;
  4321. p2pie[ p2pielen++ ] = 0x9A;
  4322. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  4323. // Commented by Albert 20110221
  4324. // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
  4325. // 1. P2P Capability
  4326. // 2. P2P Device ID if this probe request wants to find the specific P2P device
  4327. // 3. Listen Channel
  4328. // 4. Extended Listen Timing
  4329. // 5. Operating Channel if this WiFi is working as the group owner now
  4330. // P2P Capability
  4331. // Type:
  4332. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  4333. // Length:
  4334. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  4335. p2pielen += 2;
  4336. // Value:
  4337. // Device Capability Bitmap, 1 byte
  4338. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  4339. // Group Capability Bitmap, 1 byte
  4340. if ( pwdinfo->persistent_supported )
  4341. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  4342. else
  4343. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  4344. // Listen Channel
  4345. // Type:
  4346. p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
  4347. // Length:
  4348. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  4349. p2pielen += 2;
  4350. // Value:
  4351. // Country String
  4352. p2pie[ p2pielen++ ] = 'X';
  4353. p2pie[ p2pielen++ ] = 'X';
  4354. // The third byte should be set to 0x04.
  4355. // Described in the "Operating Channel Attribute" section.
  4356. p2pie[ p2pielen++ ] = 0x04;
  4357. // Operating Class
  4358. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  4359. // Channel Number
  4360. p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
  4361. // Extended Listen Timing
  4362. // Type:
  4363. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  4364. // Length:
  4365. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  4366. p2pielen += 2;
  4367. // Value:
  4368. // Availability Period
  4369. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  4370. p2pielen += 2;
  4371. // Availability Interval
  4372. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  4373. p2pielen += 2;
  4374. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  4375. {
  4376. // Operating Channel (if this WiFi is working as the group owner now)
  4377. // Type:
  4378. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  4379. // Length:
  4380. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  4381. p2pielen += 2;
  4382. // Value:
  4383. // Country String
  4384. p2pie[ p2pielen++ ] = 'X';
  4385. p2pie[ p2pielen++ ] = 'X';
  4386. // The third byte should be set to 0x04.
  4387. // Described in the "Operating Channel Attribute" section.
  4388. p2pie[ p2pielen++ ] = 0x04;
  4389. // Operating Class
  4390. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  4391. // Channel Number
  4392. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  4393. }
  4394. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  4395. }
  4396. #ifdef CONFIG_WFD
  4397. #ifdef CONFIG_IOCTL_CFG80211
  4398. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  4399. #endif
  4400. {
  4401. wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
  4402. pframe += wfdielen;
  4403. pattrib->pktlen += wfdielen;
  4404. }
  4405. #ifdef CONFIG_IOCTL_CFG80211
  4406. else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
  4407. {
  4408. //WFD IE
  4409. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
  4410. pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
  4411. pframe += pmlmepriv->wfd_probe_req_ie_len;
  4412. }
  4413. #endif //CONFIG_IOCTL_CFG80211
  4414. #endif //CONFIG_WFD
  4415. pattrib->last_txcmdsz = pattrib->pktlen;
  4416. RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
  4417. if (wait_ack) {
  4418. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  4419. } else {
  4420. dump_mgntframe(padapter, pmgntframe);
  4421. ret = _SUCCESS;
  4422. }
  4423. exit:
  4424. return ret;
  4425. }
  4426. inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
  4427. {
  4428. _issue_probereq_p2p(adapter, da, _FALSE);
  4429. }
  4430. int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
  4431. {
  4432. int ret;
  4433. int i = 0;
  4434. u32 start = rtw_get_current_time();
  4435. do
  4436. {
  4437. ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
  4438. i++;
  4439. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  4440. break;
  4441. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  4442. rtw_msleep_os(wait_ms);
  4443. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  4444. if (ret != _FAIL) {
  4445. ret = _SUCCESS;
  4446. #ifndef DBG_XMIT_ACK
  4447. goto exit;
  4448. #endif
  4449. }
  4450. if (try_cnt && wait_ms) {
  4451. if (da)
  4452. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  4453. FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
  4454. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  4455. else
  4456. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  4457. FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
  4458. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  4459. }
  4460. exit:
  4461. return ret;
  4462. }
  4463. #endif //CONFIG_P2P
  4464. s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
  4465. {
  4466. _adapter *adapter = recv_frame->u.hdr.adapter;
  4467. struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
  4468. u8 *frame = recv_frame->u.hdr.rx_data;
  4469. u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
  4470. (recv_frame->u.hdr.attrib.frag_num & 0xf);
  4471. if (GetRetry(frame)) {
  4472. if (token >= 0) {
  4473. if ((seq_ctrl == mlmeext->action_public_rxseq)
  4474. && (token == mlmeext->action_public_dialog_token))
  4475. {
  4476. DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
  4477. FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
  4478. return _FAIL;
  4479. }
  4480. } else {
  4481. if (seq_ctrl == mlmeext->action_public_rxseq) {
  4482. DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
  4483. FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
  4484. return _FAIL;
  4485. }
  4486. }
  4487. }
  4488. mlmeext->action_public_rxseq = seq_ctrl;
  4489. if (token >= 0)
  4490. mlmeext->action_public_dialog_token = token;
  4491. return _SUCCESS;
  4492. }
  4493. unsigned int on_action_public_p2p(union recv_frame *precv_frame)
  4494. {
  4495. _adapter *padapter = precv_frame->u.hdr.adapter;
  4496. u8 *pframe = precv_frame->u.hdr.rx_data;
  4497. uint len = precv_frame->u.hdr.len;
  4498. u8 *frame_body;
  4499. u8 dialogToken=0;
  4500. #ifdef CONFIG_P2P
  4501. u8 *p2p_ie;
  4502. u32 p2p_ielen, wps_ielen;
  4503. struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
  4504. u8 result = P2P_STATUS_SUCCESS;
  4505. u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  4506. #endif //CONFIG_P2P
  4507. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4508. dialogToken = frame_body[7];
  4509. if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
  4510. return _FAIL;
  4511. #ifdef CONFIG_P2P
  4512. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  4513. #ifdef CONFIG_IOCTL_CFG80211
  4514. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
  4515. {
  4516. rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
  4517. }
  4518. else
  4519. #endif //CONFIG_IOCTL_CFG80211
  4520. {
  4521. // Do nothing if the driver doesn't enable the P2P function.
  4522. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  4523. return _SUCCESS;
  4524. len -= sizeof(struct rtw_ieee80211_hdr_3addr);
  4525. switch( frame_body[ 6 ] )//OUI Subtype
  4526. {
  4527. case P2P_GO_NEGO_REQ:
  4528. {
  4529. DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
  4530. _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
  4531. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
  4532. {
  4533. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  4534. }
  4535. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
  4536. {
  4537. // Commented by Albert 20110526
  4538. // In this case, this means the previous nego fail doesn't be reset yet.
  4539. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4540. // Restore the previous p2p state
  4541. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  4542. DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
  4543. }
  4544. #ifdef CONFIG_CONCURRENT_MODE
  4545. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  4546. {
  4547. _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
  4548. }
  4549. #endif // CONFIG_CONCURRENT_MODE
  4550. // Commented by Kurt 20110902
  4551. //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
  4552. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  4553. rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
  4554. // Commented by Kurt 20120113
  4555. // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
  4556. if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) );
  4557. _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
  4558. result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
  4559. issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
  4560. #ifdef CONFIG_INTEL_WIDI
  4561. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4562. {
  4563. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4564. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4565. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4566. }
  4567. #endif //CONFIG_INTEL_WIDI
  4568. // Commented by Albert 20110718
  4569. // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
  4570. #ifdef CONFIG_CONCURRENT_MODE
  4571. // Commented by Albert 20120107
  4572. _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
  4573. #else // CONFIG_CONCURRENT_MODE
  4574. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4575. #endif // CONFIG_CONCURRENT_MODE
  4576. break;
  4577. }
  4578. case P2P_GO_NEGO_RESP:
  4579. {
  4580. DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
  4581. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  4582. {
  4583. // Commented by Albert 20110425
  4584. // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
  4585. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4586. pwdinfo->nego_req_info.benable = _FALSE;
  4587. result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
  4588. issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
  4589. if ( P2P_STATUS_SUCCESS == result )
  4590. {
  4591. if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
  4592. {
  4593. pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
  4594. pwdinfo->p2p_info.scan_op_ch_only = 1;
  4595. _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
  4596. }
  4597. }
  4598. // Reset the dialog token for group negotiation frames.
  4599. pwdinfo->negotiation_dialog_token = 1;
  4600. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
  4601. {
  4602. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4603. }
  4604. }
  4605. else
  4606. {
  4607. DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
  4608. }
  4609. break;
  4610. }
  4611. case P2P_GO_NEGO_CONF:
  4612. {
  4613. DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
  4614. result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
  4615. if ( P2P_STATUS_SUCCESS == result )
  4616. {
  4617. if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
  4618. {
  4619. pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
  4620. pwdinfo->p2p_info.scan_op_ch_only = 1;
  4621. _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
  4622. }
  4623. }
  4624. break;
  4625. }
  4626. case P2P_INVIT_REQ:
  4627. {
  4628. // Added by Albert 2010/10/05
  4629. // Received the P2P Invite Request frame.
  4630. DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
  4631. if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
  4632. {
  4633. // Parse the necessary information from the P2P Invitation Request frame.
  4634. // For example: The MAC address of sending this P2P Invitation Request frame.
  4635. u32 attr_contentlen = 0;
  4636. u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4637. struct group_id_info group_id;
  4638. u8 invitation_flag = 0;
  4639. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
  4640. if ( attr_contentlen )
  4641. {
  4642. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
  4643. // Commented by Albert 20120510
  4644. // Copy to the pwdinfo->p2p_peer_interface_addr.
  4645. // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
  4646. // #> iwpriv wlan0 p2p_get peer_ifa
  4647. // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
  4648. if ( attr_contentlen )
  4649. {
  4650. DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  4651. pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
  4652. pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
  4653. pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
  4654. }
  4655. if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
  4656. {
  4657. // Re-invoke the persistent group.
  4658. _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
  4659. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
  4660. if ( attr_contentlen )
  4661. {
  4662. if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
  4663. {
  4664. // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
  4665. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
  4666. rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
  4667. status_code = P2P_STATUS_SUCCESS;
  4668. }
  4669. else
  4670. {
  4671. // The p2p device sending this p2p invitation request wants to be the persistent GO.
  4672. if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
  4673. {
  4674. u8 operatingch_info[5] = { 0x00 };
  4675. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
  4676. {
  4677. if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) )
  4678. {
  4679. // The operating channel is acceptable for this device.
  4680. pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
  4681. pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
  4682. _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
  4683. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
  4684. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4685. status_code = P2P_STATUS_SUCCESS;
  4686. }
  4687. else
  4688. {
  4689. // The operating channel isn't supported by this device.
  4690. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4691. rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
  4692. status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
  4693. _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
  4694. }
  4695. }
  4696. else
  4697. {
  4698. // Commented by Albert 20121130
  4699. // Intel will use the different P2P IE to store the operating channel information
  4700. // Workaround for Intel WiDi 3.5
  4701. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
  4702. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4703. status_code = P2P_STATUS_SUCCESS;
  4704. }
  4705. }
  4706. else
  4707. {
  4708. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4709. #ifdef CONFIG_INTEL_WIDI
  4710. _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
  4711. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4712. #endif //CONFIG_INTEL_WIDI
  4713. status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
  4714. }
  4715. }
  4716. }
  4717. else
  4718. {
  4719. DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
  4720. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4721. }
  4722. }
  4723. else
  4724. {
  4725. // Received the invitation to join a P2P group.
  4726. _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
  4727. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
  4728. if ( attr_contentlen )
  4729. {
  4730. if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
  4731. {
  4732. // In this case, the GO can't be myself.
  4733. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4734. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4735. }
  4736. else
  4737. {
  4738. // The p2p device sending this p2p invitation request wants to join an existing P2P group
  4739. // Commented by Albert 2012/06/28
  4740. // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
  4741. // The peer device address should be the destination address for the provisioning discovery request.
  4742. // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
  4743. // The peer interface address should be the address for WPS mac address
  4744. _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
  4745. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4746. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
  4747. status_code = P2P_STATUS_SUCCESS;
  4748. }
  4749. }
  4750. else
  4751. {
  4752. DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
  4753. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4754. }
  4755. }
  4756. }
  4757. else
  4758. {
  4759. DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
  4760. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4761. }
  4762. DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
  4763. pwdinfo->inviteresp_info.token = frame_body[ 7 ];
  4764. issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
  4765. }
  4766. #ifdef CONFIG_INTEL_WIDI
  4767. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4768. {
  4769. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4770. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4771. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4772. }
  4773. #endif //CONFIG_INTEL_WIDI
  4774. break;
  4775. }
  4776. case P2P_INVIT_RESP:
  4777. {
  4778. u8 attr_content = 0x00;
  4779. u32 attr_contentlen = 0;
  4780. DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
  4781. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4782. if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
  4783. {
  4784. rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
  4785. if ( attr_contentlen == 1 )
  4786. {
  4787. DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
  4788. pwdinfo->invitereq_info.benable = _FALSE;
  4789. if ( attr_content == P2P_STATUS_SUCCESS )
  4790. {
  4791. if ( _rtw_memcmp( pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv ), ETH_ALEN ))
  4792. {
  4793. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
  4794. }
  4795. else
  4796. {
  4797. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  4798. }
  4799. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
  4800. }
  4801. else
  4802. {
  4803. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4804. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4805. }
  4806. }
  4807. else
  4808. {
  4809. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4810. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4811. }
  4812. }
  4813. else
  4814. {
  4815. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4816. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4817. }
  4818. if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
  4819. {
  4820. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4821. }
  4822. break;
  4823. }
  4824. case P2P_DEVDISC_REQ:
  4825. process_p2p_devdisc_req(pwdinfo, pframe, len);
  4826. break;
  4827. case P2P_DEVDISC_RESP:
  4828. process_p2p_devdisc_resp(pwdinfo, pframe, len);
  4829. break;
  4830. case P2P_PROVISION_DISC_REQ:
  4831. DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
  4832. process_p2p_provdisc_req(pwdinfo, pframe, len);
  4833. _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
  4834. //20110902 Kurt
  4835. //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
  4836. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
  4837. rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
  4838. rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
  4839. _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
  4840. #ifdef CONFIG_INTEL_WIDI
  4841. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4842. {
  4843. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4844. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4845. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4846. }
  4847. #endif //CONFIG_INTEL_WIDI
  4848. break;
  4849. case P2P_PROVISION_DISC_RESP:
  4850. // Commented by Albert 20110707
  4851. // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
  4852. DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
  4853. // Commented by Albert 20110426
  4854. // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
  4855. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4856. rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
  4857. process_p2p_provdisc_resp(pwdinfo, pframe);
  4858. _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
  4859. break;
  4860. }
  4861. }
  4862. #endif //CONFIG_P2P
  4863. return _SUCCESS;
  4864. }
  4865. unsigned int on_action_public_vendor(union recv_frame *precv_frame)
  4866. {
  4867. unsigned int ret = _FAIL;
  4868. u8 *pframe = precv_frame->u.hdr.rx_data;
  4869. uint frame_len = precv_frame->u.hdr.len;
  4870. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4871. if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
  4872. ret = on_action_public_p2p(precv_frame);
  4873. }
  4874. return ret;
  4875. }
  4876. unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
  4877. {
  4878. unsigned int ret = _FAIL;
  4879. u8 *pframe = precv_frame->u.hdr.rx_data;
  4880. uint frame_len = precv_frame->u.hdr.len;
  4881. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4882. u8 token;
  4883. _adapter *adapter = precv_frame->u.hdr.adapter;
  4884. int cnt = 0;
  4885. char msg[64];
  4886. token = frame_body[2];
  4887. if (rtw_action_public_decache(precv_frame, token) == _FAIL)
  4888. goto exit;
  4889. #ifdef CONFIG_IOCTL_CFG80211
  4890. cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
  4891. rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
  4892. #endif
  4893. ret = _SUCCESS;
  4894. exit:
  4895. return ret;
  4896. }
  4897. unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
  4898. {
  4899. unsigned int ret = _FAIL;
  4900. u8 *pframe = precv_frame->u.hdr.rx_data;
  4901. uint frame_len = precv_frame->u.hdr.len;
  4902. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4903. u8 category, action;
  4904. /* check RA matches or not */
  4905. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
  4906. goto exit;
  4907. category = frame_body[0];
  4908. if(category != RTW_WLAN_CATEGORY_PUBLIC)
  4909. goto exit;
  4910. action = frame_body[1];
  4911. switch (action) {
  4912. case ACT_PUBLIC_VENDOR:
  4913. ret = on_action_public_vendor(precv_frame);
  4914. break;
  4915. default:
  4916. ret = on_action_public_default(precv_frame, action);
  4917. break;
  4918. }
  4919. exit:
  4920. return ret;
  4921. }
  4922. unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
  4923. {
  4924. return _SUCCESS;
  4925. }
  4926. unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
  4927. {
  4928. return _SUCCESS;
  4929. }
  4930. unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
  4931. {
  4932. #ifdef CONFIG_P2P
  4933. u8 *frame_body;
  4934. u8 category, OUI_Subtype, dialogToken=0;
  4935. u8 *pframe = precv_frame->u.hdr.rx_data;
  4936. uint len = precv_frame->u.hdr.len;
  4937. struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
  4938. DBG_871X("%s\n", __FUNCTION__);
  4939. //check RA matches or not
  4940. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
  4941. return _SUCCESS;
  4942. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4943. category = frame_body[0];
  4944. if(category != RTW_WLAN_CATEGORY_P2P)
  4945. return _SUCCESS;
  4946. if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
  4947. return _SUCCESS;
  4948. #ifdef CONFIG_IOCTL_CFG80211
  4949. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  4950. {
  4951. rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
  4952. return _SUCCESS;
  4953. }
  4954. else
  4955. #endif //CONFIG_IOCTL_CFG80211
  4956. {
  4957. len -= sizeof(struct rtw_ieee80211_hdr_3addr);
  4958. OUI_Subtype = frame_body[5];
  4959. dialogToken = frame_body[6];
  4960. switch(OUI_Subtype)
  4961. {
  4962. case P2P_NOTICE_OF_ABSENCE:
  4963. break;
  4964. case P2P_PRESENCE_REQUEST:
  4965. process_p2p_presence_req(pwdinfo, pframe, len);
  4966. break;
  4967. case P2P_PRESENCE_RESPONSE:
  4968. break;
  4969. case P2P_GO_DISC_REQUEST:
  4970. break;
  4971. default:
  4972. break;
  4973. }
  4974. }
  4975. #endif //CONFIG_P2P
  4976. return _SUCCESS;
  4977. }
  4978. unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
  4979. {
  4980. int i;
  4981. unsigned char category;
  4982. struct action_handler *ptable;
  4983. unsigned char *frame_body;
  4984. u8 *pframe = precv_frame->u.hdr.rx_data;
  4985. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4986. category = frame_body[0];
  4987. for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
  4988. {
  4989. ptable = &OnAction_tbl[i];
  4990. if(category == ptable->num)
  4991. ptable->func(padapter, precv_frame);
  4992. }
  4993. return _SUCCESS;
  4994. }
  4995. unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
  4996. {
  4997. //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
  4998. return _SUCCESS;
  4999. }
  5000. struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
  5001. {
  5002. struct xmit_frame *pmgntframe;
  5003. struct xmit_buf *pxmitbuf;
  5004. if (once)
  5005. pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
  5006. else
  5007. pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
  5008. if (pmgntframe == NULL) {
  5009. DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
  5010. goto exit;
  5011. }
  5012. if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
  5013. DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
  5014. rtw_free_xmitframe(pxmitpriv, pmgntframe);
  5015. pmgntframe = NULL;
  5016. goto exit;
  5017. }
  5018. pmgntframe->frame_tag = MGNT_FRAMETAG;
  5019. pmgntframe->pxmitbuf = pxmitbuf;
  5020. pmgntframe->buf_addr = pxmitbuf->pbuf;
  5021. pxmitbuf->priv_data = pmgntframe;
  5022. exit:
  5023. return pmgntframe;
  5024. }
  5025. inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
  5026. {
  5027. return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
  5028. }
  5029. inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
  5030. {
  5031. return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
  5032. }
  5033. /****************************************************************************
  5034. Following are some TX fuctions for WiFi MLME
  5035. *****************************************************************************/
  5036. void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
  5037. {
  5038. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5039. pmlmeext->tx_rate = rate;
  5040. //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
  5041. }
  5042. void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
  5043. {
  5044. u8 wireless_mode;
  5045. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5046. //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
  5047. pattrib->hdrlen = 24;
  5048. pattrib->nr_frags = 1;
  5049. pattrib->priority = 7;
  5050. pattrib->mac_id = 0;
  5051. pattrib->qsel = 0x12;
  5052. pattrib->pktlen = 0;
  5053. if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
  5054. wireless_mode = WIRELESS_11B;
  5055. else
  5056. wireless_mode = WIRELESS_11G;
  5057. pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
  5058. pattrib->encrypt = _NO_PRIVACY_;
  5059. pattrib->bswenc = _FALSE;
  5060. pattrib->qos_en = _FALSE;
  5061. pattrib->ht_en = _FALSE;
  5062. pattrib->bwmode = CHANNEL_WIDTH_20;
  5063. pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  5064. pattrib->sgi = _FALSE;
  5065. pattrib->seqnum = pmlmeext->mgnt_seq;
  5066. pattrib->retry_ctrl = _TRUE;
  5067. pattrib->mbssid = 0;
  5068. }
  5069. void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
  5070. {
  5071. u8 *pframe;
  5072. struct pkt_attrib *pattrib = &pmgntframe->attrib;
  5073. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5074. _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
  5075. _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
  5076. }
  5077. void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
  5078. {
  5079. if(padapter->bSurpriseRemoved == _TRUE ||
  5080. padapter->bDriverStopped == _TRUE)
  5081. return;
  5082. rtw_hal_mgnt_xmit(padapter, pmgntframe);
  5083. }
  5084. s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
  5085. {
  5086. s32 ret = _FAIL;
  5087. _irqL irqL;
  5088. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  5089. struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
  5090. struct submit_ctx sctx;
  5091. if(padapter->bSurpriseRemoved == _TRUE ||
  5092. padapter->bDriverStopped == _TRUE)
  5093. return ret;
  5094. rtw_sctx_init(&sctx, timeout_ms);
  5095. pxmitbuf->sctx = &sctx;
  5096. ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
  5097. if (ret == _SUCCESS)
  5098. ret = rtw_sctx_wait(&sctx);
  5099. _enter_critical(&pxmitpriv->lock_sctx, &irqL);
  5100. pxmitbuf->sctx = NULL;
  5101. _exit_critical(&pxmitpriv->lock_sctx, &irqL);
  5102. return ret;
  5103. }
  5104. s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
  5105. {
  5106. #ifdef CONFIG_XMIT_ACK
  5107. s32 ret = _FAIL;
  5108. u32 timeout_ms = 500;// 500ms
  5109. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  5110. #ifdef CONFIG_CONCURRENT_MODE
  5111. if (padapter->pbuddy_adapter && !padapter->isprimary)
  5112. pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
  5113. #endif
  5114. if(padapter->bSurpriseRemoved == _TRUE ||
  5115. padapter->bDriverStopped == _TRUE)
  5116. return -1;
  5117. _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
  5118. pxmitpriv->ack_tx = _TRUE;
  5119. pmgntframe->ack_report = 1;
  5120. if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
  5121. ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
  5122. }
  5123. pxmitpriv->ack_tx = _FALSE;
  5124. _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
  5125. return ret;
  5126. #else //!CONFIG_XMIT_ACK
  5127. dump_mgntframe(padapter, pmgntframe);
  5128. rtw_msleep_os(50);
  5129. return _SUCCESS;
  5130. #endif //!CONFIG_XMIT_ACK
  5131. }
  5132. int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
  5133. {
  5134. u8 *ssid_ie;
  5135. sint ssid_len_ori;
  5136. int len_diff = 0;
  5137. ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
  5138. //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
  5139. if(ssid_ie && ssid_len_ori>0)
  5140. {
  5141. switch(hidden_ssid_mode)
  5142. {
  5143. case 1:
  5144. {
  5145. u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
  5146. u32 remain_len = 0;
  5147. remain_len = ies_len -(next_ie-ies);
  5148. ssid_ie[1] = 0;
  5149. _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
  5150. len_diff -= ssid_len_ori;
  5151. break;
  5152. }
  5153. case 2:
  5154. _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
  5155. break;
  5156. default:
  5157. break;
  5158. }
  5159. }
  5160. return len_diff;
  5161. }
  5162. void issue_beacon(_adapter *padapter, int timeout_ms)
  5163. {
  5164. struct xmit_frame *pmgntframe;
  5165. struct pkt_attrib *pattrib;
  5166. unsigned char *pframe;
  5167. struct rtw_ieee80211_hdr *pwlanhdr;
  5168. unsigned short *fctrl;
  5169. unsigned int rate_len;
  5170. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5171. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5172. _irqL irqL;
  5173. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5174. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5175. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5176. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5177. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  5178. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  5179. #ifdef CONFIG_P2P
  5180. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5181. #endif //CONFIG_P2P
  5182. //DBG_871X("%s\n", __FUNCTION__);
  5183. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5184. {
  5185. DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
  5186. return;
  5187. }
  5188. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5189. _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5190. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5191. //update attribute
  5192. pattrib = &pmgntframe->attrib;
  5193. update_mgntframe_attrib(padapter, pattrib);
  5194. pattrib->qsel = 0x10;
  5195. #ifdef CONFIG_CONCURRENT_MODE
  5196. if(padapter->iface_type == IFACE_PORT1)
  5197. pattrib->mbssid = 1;
  5198. #endif
  5199. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5200. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5201. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5202. fctrl = &(pwlanhdr->frame_ctl);
  5203. *(fctrl) = 0;
  5204. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  5205. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5206. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
  5207. SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
  5208. //pmlmeext->mgnt_seq++;
  5209. SetFrameSubType(pframe, WIFI_BEACON);
  5210. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5211. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  5212. if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  5213. {
  5214. //DBG_871X("ie len=%d\n", cur_network->IELength);
  5215. #ifdef CONFIG_P2P
  5216. // for P2P : Primary Device Type & Device Name
  5217. u32 wpsielen=0, insert_len=0;
  5218. u8 *wpsie=NULL;
  5219. wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
  5220. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
  5221. {
  5222. uint wps_offset, remainder_ielen;
  5223. u8 *premainder_ie, *pframe_wscie;
  5224. wps_offset = (uint)(wpsie - cur_network->IEs);
  5225. premainder_ie = wpsie + wpsielen;
  5226. remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
  5227. #ifdef CONFIG_IOCTL_CFG80211
  5228. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5229. {
  5230. if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
  5231. {
  5232. _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
  5233. pframe += wps_offset;
  5234. pattrib->pktlen += wps_offset;
  5235. _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
  5236. pframe += pmlmepriv->wps_beacon_ie_len;
  5237. pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
  5238. //copy remainder_ie to pframe
  5239. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5240. pframe += remainder_ielen;
  5241. pattrib->pktlen += remainder_ielen;
  5242. }
  5243. else
  5244. {
  5245. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5246. pframe += cur_network->IELength;
  5247. pattrib->pktlen += cur_network->IELength;
  5248. }
  5249. }
  5250. else
  5251. #endif //CONFIG_IOCTL_CFG80211
  5252. {
  5253. pframe_wscie = pframe + wps_offset;
  5254. _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
  5255. pframe += (wps_offset + wpsielen);
  5256. pattrib->pktlen += (wps_offset + wpsielen);
  5257. //now pframe is end of wsc ie, insert Primary Device Type & Device Name
  5258. // Primary Device Type
  5259. // Type:
  5260. *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  5261. insert_len += 2;
  5262. // Length:
  5263. *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
  5264. insert_len += 2;
  5265. // Value:
  5266. // Category ID
  5267. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  5268. insert_len += 2;
  5269. // OUI
  5270. *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
  5271. insert_len += 4;
  5272. // Sub Category ID
  5273. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  5274. insert_len += 2;
  5275. // Device Name
  5276. // Type:
  5277. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  5278. insert_len += 2;
  5279. // Length:
  5280. *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
  5281. insert_len += 2;
  5282. // Value:
  5283. _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
  5284. insert_len += pwdinfo->device_name_len;
  5285. //update wsc ie length
  5286. *(pframe_wscie+1) = (wpsielen -2) + insert_len;
  5287. //pframe move to end
  5288. pframe+=insert_len;
  5289. pattrib->pktlen += insert_len;
  5290. //copy remainder_ie to pframe
  5291. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5292. pframe += remainder_ielen;
  5293. pattrib->pktlen += remainder_ielen;
  5294. }
  5295. }
  5296. else
  5297. #endif //CONFIG_P2P
  5298. {
  5299. int len_diff;
  5300. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5301. len_diff = update_hidden_ssid(
  5302. pframe+_BEACON_IE_OFFSET_
  5303. , cur_network->IELength-_BEACON_IE_OFFSET_
  5304. , pmlmeinfo->hidden_ssid_mode
  5305. );
  5306. pframe += (cur_network->IELength+len_diff);
  5307. pattrib->pktlen += (cur_network->IELength+len_diff);
  5308. }
  5309. {
  5310. u8 *wps_ie;
  5311. uint wps_ielen;
  5312. u8 sr = 0;
  5313. wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
  5314. pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
  5315. if (wps_ie && wps_ielen>0) {
  5316. rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
  5317. }
  5318. if (sr != 0)
  5319. set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
  5320. else
  5321. _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
  5322. }
  5323. #ifdef CONFIG_P2P
  5324. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  5325. {
  5326. u32 len;
  5327. #ifdef CONFIG_IOCTL_CFG80211
  5328. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5329. {
  5330. len = pmlmepriv->p2p_beacon_ie_len;
  5331. if(pmlmepriv->p2p_beacon_ie && len>0)
  5332. _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
  5333. }
  5334. else
  5335. #endif //CONFIG_IOCTL_CFG80211
  5336. {
  5337. len = build_beacon_p2p_ie(pwdinfo, pframe);
  5338. }
  5339. pframe += len;
  5340. pattrib->pktlen += len;
  5341. #ifdef CONFIG_WFD
  5342. #ifdef CONFIG_IOCTL_CFG80211
  5343. if(_TRUE == pwdinfo->wfd_info->wfd_enable)
  5344. #endif //CONFIG_IOCTL_CFG80211
  5345. {
  5346. len = build_beacon_wfd_ie( pwdinfo, pframe );
  5347. }
  5348. #ifdef CONFIG_IOCTL_CFG80211
  5349. else
  5350. {
  5351. len = 0;
  5352. if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
  5353. {
  5354. len = pmlmepriv->wfd_beacon_ie_len;
  5355. _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
  5356. }
  5357. }
  5358. #endif //CONFIG_IOCTL_CFG80211
  5359. pframe += len;
  5360. pattrib->pktlen += len;
  5361. #endif //CONFIG_WFD
  5362. }
  5363. #endif //CONFIG_P2P
  5364. goto _issue_bcn;
  5365. }
  5366. //below for ad-hoc mode
  5367. //timestamp will be inserted by hardware
  5368. pframe += 8;
  5369. pattrib->pktlen += 8;
  5370. // beacon interval: 2 bytes
  5371. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  5372. pframe += 2;
  5373. pattrib->pktlen += 2;
  5374. // capability info: 2 bytes
  5375. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  5376. pframe += 2;
  5377. pattrib->pktlen += 2;
  5378. // SSID
  5379. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
  5380. // supported rates...
  5381. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  5382. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
  5383. // DS parameter set
  5384. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
  5385. //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  5386. {
  5387. u8 erpinfo=0;
  5388. u32 ATIMWindow;
  5389. // IBSS Parameter Set...
  5390. //ATIMWindow = cur->Configuration.ATIMWindow;
  5391. ATIMWindow = 0;
  5392. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
  5393. //ERP IE
  5394. pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
  5395. }
  5396. // EXTERNDED SUPPORTED RATE
  5397. if (rate_len > 8)
  5398. {
  5399. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
  5400. }
  5401. //todo:HT for adhoc
  5402. _issue_bcn:
  5403. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5404. pmlmepriv->update_bcn = _FALSE;
  5405. _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5406. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5407. if ((pattrib->pktlen + TXDESC_SIZE) > 512)
  5408. {
  5409. DBG_871X("beacon frame too large\n");
  5410. return;
  5411. }
  5412. pattrib->last_txcmdsz = pattrib->pktlen;
  5413. //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
  5414. if(timeout_ms > 0)
  5415. dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
  5416. else
  5417. dump_mgntframe(padapter, pmgntframe);
  5418. }
  5419. void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
  5420. {
  5421. struct xmit_frame *pmgntframe;
  5422. struct pkt_attrib *pattrib;
  5423. unsigned char *pframe;
  5424. struct rtw_ieee80211_hdr *pwlanhdr;
  5425. unsigned short *fctrl;
  5426. unsigned char *mac, *bssid;
  5427. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5428. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5429. u8 *pwps_ie;
  5430. uint wps_ielen;
  5431. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  5432. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5433. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5434. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5435. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  5436. unsigned int rate_len;
  5437. #ifdef CONFIG_P2P
  5438. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5439. #ifdef CONFIG_WFD
  5440. u32 wfdielen = 0;
  5441. #endif //CONFIG_WFD
  5442. #endif //CONFIG_P2P
  5443. //DBG_871X("%s\n", __FUNCTION__);
  5444. if(da == NULL)
  5445. return;
  5446. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5447. {
  5448. DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
  5449. return;
  5450. }
  5451. //update attribute
  5452. pattrib = &pmgntframe->attrib;
  5453. update_mgntframe_attrib(padapter, pattrib);
  5454. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5455. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5456. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5457. mac = myid(&(padapter->eeprompriv));
  5458. bssid = cur_network->MacAddress;
  5459. fctrl = &(pwlanhdr->frame_ctl);
  5460. *(fctrl) = 0;
  5461. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  5462. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  5463. _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
  5464. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5465. pmlmeext->mgnt_seq++;
  5466. SetFrameSubType(fctrl, WIFI_PROBERSP);
  5467. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5468. pattrib->pktlen = pattrib->hdrlen;
  5469. pframe += pattrib->hdrlen;
  5470. if(cur_network->IELength>MAX_IE_SZ)
  5471. return;
  5472. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5473. if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  5474. {
  5475. pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
  5476. //inerset & update wps_probe_resp_ie
  5477. if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
  5478. {
  5479. uint wps_offset, remainder_ielen;
  5480. u8 *premainder_ie;
  5481. wps_offset = (uint)(pwps_ie - cur_network->IEs);
  5482. premainder_ie = pwps_ie + wps_ielen;
  5483. remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
  5484. _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
  5485. pframe += wps_offset;
  5486. pattrib->pktlen += wps_offset;
  5487. wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
  5488. if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
  5489. {
  5490. _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
  5491. pframe += wps_ielen+2;
  5492. pattrib->pktlen += wps_ielen+2;
  5493. }
  5494. if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
  5495. {
  5496. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5497. pframe += remainder_ielen;
  5498. pattrib->pktlen += remainder_ielen;
  5499. }
  5500. }
  5501. else
  5502. {
  5503. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5504. pframe += cur_network->IELength;
  5505. pattrib->pktlen += cur_network->IELength;
  5506. }
  5507. /* retrieve SSID IE from cur_network->Ssid */
  5508. {
  5509. u8 *ssid_ie;
  5510. sint ssid_ielen;
  5511. sint ssid_ielen_diff;
  5512. u8 buf[MAX_IE_SZ];
  5513. u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
  5514. ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
  5515. (pframe-ies)-_FIXED_IE_LENGTH_);
  5516. ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
  5517. if (ssid_ie && cur_network->Ssid.SsidLength) {
  5518. uint remainder_ielen;
  5519. u8 *remainder_ie;
  5520. remainder_ie = ssid_ie+2;
  5521. remainder_ielen = (pframe-remainder_ie);
  5522. DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
  5523. if (remainder_ielen > MAX_IE_SZ) {
  5524. remainder_ielen = MAX_IE_SZ;
  5525. }
  5526. _rtw_memcpy(buf, remainder_ie, remainder_ielen);
  5527. _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
  5528. *(ssid_ie+1) = cur_network->Ssid.SsidLength;
  5529. _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
  5530. pframe += ssid_ielen_diff;
  5531. pattrib->pktlen += ssid_ielen_diff;
  5532. }
  5533. }
  5534. }
  5535. else
  5536. #endif
  5537. {
  5538. //timestamp will be inserted by hardware
  5539. pframe += 8;
  5540. pattrib->pktlen += 8;
  5541. // beacon interval: 2 bytes
  5542. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  5543. pframe += 2;
  5544. pattrib->pktlen += 2;
  5545. // capability info: 2 bytes
  5546. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  5547. pframe += 2;
  5548. pattrib->pktlen += 2;
  5549. //below for ad-hoc mode
  5550. // SSID
  5551. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
  5552. // supported rates...
  5553. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  5554. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
  5555. // DS parameter set
  5556. pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
  5557. if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  5558. {
  5559. u8 erpinfo=0;
  5560. u32 ATIMWindow;
  5561. // IBSS Parameter Set...
  5562. //ATIMWindow = cur->Configuration.ATIMWindow;
  5563. ATIMWindow = 0;
  5564. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
  5565. //ERP IE
  5566. pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
  5567. }
  5568. // EXTERNDED SUPPORTED RATE
  5569. if (rate_len > 8)
  5570. {
  5571. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
  5572. }
  5573. //todo:HT for adhoc
  5574. }
  5575. #ifdef CONFIG_P2P
  5576. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq)
  5577. {
  5578. u32 len;
  5579. #ifdef CONFIG_IOCTL_CFG80211
  5580. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5581. {
  5582. //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
  5583. len = pmlmepriv->p2p_go_probe_resp_ie_len;
  5584. if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
  5585. _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
  5586. }
  5587. else
  5588. #endif //CONFIG_IOCTL_CFG80211
  5589. {
  5590. len = build_probe_resp_p2p_ie(pwdinfo, pframe);
  5591. }
  5592. pframe += len;
  5593. pattrib->pktlen += len;
  5594. #ifdef CONFIG_WFD
  5595. #ifdef CONFIG_IOCTL_CFG80211
  5596. if(_TRUE == pwdinfo->wfd_info->wfd_enable)
  5597. #endif //CONFIG_IOCTL_CFG80211
  5598. {
  5599. len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
  5600. }
  5601. #ifdef CONFIG_IOCTL_CFG80211
  5602. else
  5603. {
  5604. len = 0;
  5605. if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
  5606. {
  5607. len = pmlmepriv->wfd_probe_resp_ie_len;
  5608. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
  5609. }
  5610. }
  5611. #endif //CONFIG_IOCTL_CFG80211
  5612. pframe += len;
  5613. pattrib->pktlen += len;
  5614. #endif //CONFIG_WFD
  5615. }
  5616. #endif //CONFIG_P2P
  5617. #ifdef CONFIG_AUTO_AP_MODE
  5618. {
  5619. struct sta_info *psta;
  5620. struct sta_priv *pstapriv = &padapter->stapriv;
  5621. DBG_871X("(%s)\n", __FUNCTION__);
  5622. //check rc station
  5623. psta = rtw_get_stainfo(pstapriv, da);
  5624. if (psta && psta->isrc && psta->pid>0)
  5625. {
  5626. u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
  5627. u8 RC_INFO[14] = {0};
  5628. //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
  5629. u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
  5630. DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
  5631. psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
  5632. //append vendor specific ie
  5633. _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
  5634. _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
  5635. _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
  5636. _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
  5637. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
  5638. }
  5639. }
  5640. #endif //CONFIG_AUTO_AP_MODE
  5641. pattrib->last_txcmdsz = pattrib->pktlen;
  5642. dump_mgntframe(padapter, pmgntframe);
  5643. return;
  5644. }
  5645. int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack)
  5646. {
  5647. int ret = _FAIL;
  5648. struct xmit_frame *pmgntframe;
  5649. struct pkt_attrib *pattrib;
  5650. unsigned char *pframe;
  5651. struct rtw_ieee80211_hdr *pwlanhdr;
  5652. unsigned short *fctrl;
  5653. unsigned char *mac;
  5654. unsigned char bssrate[NumRates];
  5655. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5656. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5657. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5658. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5659. int bssrate_len = 0;
  5660. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  5661. RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
  5662. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5663. {
  5664. goto exit;
  5665. }
  5666. //update attribute
  5667. pattrib = &pmgntframe->attrib;
  5668. update_mgntframe_attrib(padapter, pattrib);
  5669. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5670. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5671. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5672. mac = myid(&(padapter->eeprompriv));
  5673. fctrl = &(pwlanhdr->frame_ctl);
  5674. *(fctrl) = 0;
  5675. if (da)
  5676. {
  5677. // unicast probe request frame
  5678. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  5679. _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
  5680. }
  5681. else
  5682. {
  5683. // broadcast probe request frame
  5684. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  5685. _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
  5686. }
  5687. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  5688. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5689. pmlmeext->mgnt_seq++;
  5690. SetFrameSubType(pframe, WIFI_PROBEREQ);
  5691. pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
  5692. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  5693. if(pssid)
  5694. pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
  5695. else
  5696. pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
  5697. get_rate_set(padapter, bssrate, &bssrate_len);
  5698. if (bssrate_len > 8)
  5699. {
  5700. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
  5701. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
  5702. }
  5703. else
  5704. {
  5705. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
  5706. }
  5707. #if 0
  5708. //add wps_ie for wps2.0
  5709. if(pmlmepriv->probereq_wpsie_len>0 && pmlmepriv->probereq_wpsie_len<MAX_WPS_IE_LEN)
  5710. {
  5711. _rtw_memcpy(pframe, pmlmepriv->probereq_wpsie, pmlmepriv->probereq_wpsie_len);
  5712. pframe += pmlmepriv->probereq_wpsie_len;
  5713. pattrib->pktlen += pmlmepriv->probereq_wpsie_len;
  5714. //pmlmepriv->probereq_wpsie_len = 0 ;//reset to zero
  5715. }
  5716. #else
  5717. //add wps_ie for wps2.0
  5718. if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
  5719. {
  5720. _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
  5721. pframe += pmlmepriv->wps_probe_req_ie_len;
  5722. pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
  5723. //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
  5724. }
  5725. #endif
  5726. pattrib->last_txcmdsz = pattrib->pktlen;
  5727. RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
  5728. if (wait_ack) {
  5729. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  5730. } else {
  5731. dump_mgntframe(padapter, pmgntframe);
  5732. ret = _SUCCESS;
  5733. }
  5734. exit:
  5735. return ret;
  5736. }
  5737. inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
  5738. {
  5739. _issue_probereq(padapter, pssid, da, _FALSE);
  5740. }
  5741. int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da,
  5742. int try_cnt, int wait_ms)
  5743. {
  5744. int ret;
  5745. int i = 0;
  5746. u32 start = rtw_get_current_time();
  5747. do
  5748. {
  5749. ret = _issue_probereq(padapter, pssid, da, wait_ms>0?_TRUE:_FALSE);
  5750. i++;
  5751. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  5752. break;
  5753. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  5754. rtw_msleep_os(wait_ms);
  5755. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  5756. if (ret != _FAIL) {
  5757. ret = _SUCCESS;
  5758. #ifndef DBG_XMIT_ACK
  5759. goto exit;
  5760. #endif
  5761. }
  5762. if (try_cnt && wait_ms) {
  5763. if (da)
  5764. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  5765. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  5766. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  5767. else
  5768. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  5769. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  5770. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  5771. }
  5772. exit:
  5773. return ret;
  5774. }
  5775. // if psta == NULL, indiate we are station(client) now...
  5776. void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
  5777. {
  5778. struct xmit_frame *pmgntframe;
  5779. struct pkt_attrib *pattrib;
  5780. unsigned char *pframe;
  5781. struct rtw_ieee80211_hdr *pwlanhdr;
  5782. unsigned short *fctrl;
  5783. unsigned int val32;
  5784. unsigned short val16;
  5785. int use_shared_key = 0;
  5786. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5787. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5788. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5789. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5790. {
  5791. return;
  5792. }
  5793. //update attribute
  5794. pattrib = &pmgntframe->attrib;
  5795. update_mgntframe_attrib(padapter, pattrib);
  5796. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5797. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5798. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5799. fctrl = &(pwlanhdr->frame_ctl);
  5800. *(fctrl) = 0;
  5801. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5802. pmlmeext->mgnt_seq++;
  5803. SetFrameSubType(pframe, WIFI_AUTH);
  5804. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5805. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5806. if(psta)// for AP mode
  5807. {
  5808. #ifdef CONFIG_NATIVEAP_MLME
  5809. _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
  5810. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5811. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5812. // setting auth algo number
  5813. val16 = (u16)psta->authalg;
  5814. if(status != _STATS_SUCCESSFUL_)
  5815. val16 = 0;
  5816. if (val16) {
  5817. val16 = cpu_to_le16(val16);
  5818. use_shared_key = 1;
  5819. }
  5820. pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5821. // setting auth seq number
  5822. val16 =(u16)psta->auth_seq;
  5823. val16 = cpu_to_le16(val16);
  5824. pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5825. // setting status code...
  5826. val16 = status;
  5827. val16 = cpu_to_le16(val16);
  5828. pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
  5829. // added challenging text...
  5830. if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5831. {
  5832. pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
  5833. }
  5834. #endif
  5835. }
  5836. else
  5837. {
  5838. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
  5839. _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
  5840. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
  5841. // setting auth algo number
  5842. val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
  5843. if (val16) {
  5844. val16 = cpu_to_le16(val16);
  5845. use_shared_key = 1;
  5846. }
  5847. //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
  5848. //setting IV for auth seq #3
  5849. if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5850. {
  5851. //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
  5852. val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
  5853. val32 = cpu_to_le32(val32);
  5854. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
  5855. pattrib->iv_len = 4;
  5856. }
  5857. pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5858. // setting auth seq number
  5859. val16 = pmlmeinfo->auth_seq;
  5860. val16 = cpu_to_le16(val16);
  5861. pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5862. // setting status code...
  5863. val16 = status;
  5864. val16 = cpu_to_le16(val16);
  5865. pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
  5866. // then checking to see if sending challenging text...
  5867. if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5868. {
  5869. pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
  5870. SetPrivacy(fctrl);
  5871. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5872. pattrib->encrypt = _WEP40_;
  5873. pattrib->icv_len = 4;
  5874. pattrib->pktlen += pattrib->icv_len;
  5875. }
  5876. }
  5877. pattrib->last_txcmdsz = pattrib->pktlen;
  5878. rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
  5879. DBG_871X("%s\n", __FUNCTION__);
  5880. dump_mgntframe(padapter, pmgntframe);
  5881. return;
  5882. }
  5883. void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
  5884. {
  5885. #ifdef CONFIG_AP_MODE
  5886. struct xmit_frame *pmgntframe;
  5887. struct rtw_ieee80211_hdr *pwlanhdr;
  5888. struct pkt_attrib *pattrib;
  5889. unsigned char *pbuf, *pframe;
  5890. unsigned short val;
  5891. unsigned short *fctrl;
  5892. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5893. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5894. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  5895. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5896. WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
  5897. u8 *ie = pnetwork->IEs;
  5898. #ifdef CONFIG_P2P
  5899. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5900. #ifdef CONFIG_WFD
  5901. u32 wfdielen = 0;
  5902. #endif //CONFIG_WFD
  5903. #endif //CONFIG_P2P
  5904. DBG_871X("%s\n", __FUNCTION__);
  5905. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5906. {
  5907. return;
  5908. }
  5909. //update attribute
  5910. pattrib = &pmgntframe->attrib;
  5911. update_mgntframe_attrib(padapter, pattrib);
  5912. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5913. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5914. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5915. fctrl = &(pwlanhdr->frame_ctl);
  5916. *(fctrl) = 0;
  5917. _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
  5918. _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
  5919. _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  5920. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5921. pmlmeext->mgnt_seq++;
  5922. if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
  5923. SetFrameSubType(pwlanhdr, pkt_type);
  5924. else
  5925. return;
  5926. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5927. pattrib->pktlen += pattrib->hdrlen;
  5928. pframe += pattrib->hdrlen;
  5929. //capability
  5930. val = *(unsigned short *)rtw_get_capability_from_ie(ie);
  5931. pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
  5932. status = cpu_to_le16(status);
  5933. pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
  5934. val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
  5935. pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
  5936. if (pstat->bssratelen <= 8)
  5937. {
  5938. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
  5939. }
  5940. else
  5941. {
  5942. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
  5943. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
  5944. }
  5945. #ifdef CONFIG_80211N_HT
  5946. if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
  5947. {
  5948. uint ie_len=0;
  5949. //FILL HT CAP INFO IE
  5950. //p = hostapd_eid_ht_capabilities_info(hapd, p);
  5951. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5952. if(pbuf && ie_len>0)
  5953. {
  5954. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5955. pframe += (ie_len+2);
  5956. pattrib->pktlen +=(ie_len+2);
  5957. }
  5958. //FILL HT ADD INFO IE
  5959. //p = hostapd_eid_ht_operation(hapd, p);
  5960. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5961. if(pbuf && ie_len>0)
  5962. {
  5963. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5964. pframe += (ie_len+2);
  5965. pattrib->pktlen +=(ie_len+2);
  5966. }
  5967. }
  5968. #endif
  5969. #ifdef CONFIG_80211AC_VHT
  5970. if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option))
  5971. {
  5972. u32 ie_len=0;
  5973. //FILL VHT CAP IE
  5974. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5975. if(pbuf && ie_len>0)
  5976. {
  5977. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5978. pframe += (ie_len+2);
  5979. pattrib->pktlen +=(ie_len+2);
  5980. }
  5981. //FILL VHT OPERATION IE
  5982. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5983. if(pbuf && ie_len>0)
  5984. {
  5985. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5986. pframe += (ie_len+2);
  5987. pattrib->pktlen +=(ie_len+2);
  5988. }
  5989. }
  5990. #endif //CONFIG_80211AC_VHT
  5991. //FILL WMM IE
  5992. if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
  5993. {
  5994. uint ie_len=0;
  5995. unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
  5996. for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
  5997. {
  5998. pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
  5999. if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
  6000. {
  6001. _rtw_memcpy(pframe, pbuf, ie_len+2);
  6002. pframe += (ie_len+2);
  6003. pattrib->pktlen +=(ie_len+2);
  6004. break;
  6005. }
  6006. if ((pbuf == NULL) || (ie_len == 0))
  6007. {
  6008. break;
  6009. }
  6010. }
  6011. }
  6012. if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
  6013. {
  6014. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
  6015. }
  6016. //add WPS IE ie for wps 2.0
  6017. if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
  6018. {
  6019. _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
  6020. pframe += pmlmepriv->wps_assoc_resp_ie_len;
  6021. pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
  6022. }
  6023. #ifdef CONFIG_P2P
  6024. if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
  6025. {
  6026. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
  6027. {
  6028. u32 len;
  6029. len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
  6030. pframe += len;
  6031. pattrib->pktlen += len;
  6032. }
  6033. }
  6034. #ifdef CONFIG_WFD
  6035. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
  6036. #ifdef CONFIG_IOCTL_CFG80211
  6037. && (_TRUE == pwdinfo->wfd_info->wfd_enable)
  6038. #endif //CONFIG_IOCTL_CFG80211
  6039. )
  6040. {
  6041. wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
  6042. pframe += wfdielen;
  6043. pattrib->pktlen += wfdielen;
  6044. }
  6045. #endif //CONFIG_WFD
  6046. #endif //CONFIG_P2P
  6047. pattrib->last_txcmdsz = pattrib->pktlen;
  6048. dump_mgntframe(padapter, pmgntframe);
  6049. #endif
  6050. }
  6051. void issue_assocreq(_adapter *padapter)
  6052. {
  6053. int ret = _FAIL;
  6054. struct xmit_frame *pmgntframe;
  6055. struct pkt_attrib *pattrib;
  6056. unsigned char *pframe, *p;
  6057. struct rtw_ieee80211_hdr *pwlanhdr;
  6058. unsigned short *fctrl;
  6059. unsigned short val16;
  6060. unsigned int i, j, ie_len, index=0;
  6061. unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
  6062. PNDIS_802_11_VARIABLE_IEs pIE;
  6063. struct registry_priv *pregpriv = &padapter->registrypriv;
  6064. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6065. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  6066. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6067. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6068. int bssrate_len = 0, sta_bssrate_len = 0;
  6069. u8 cbw40_enable = 0;
  6070. #ifdef CONFIG_P2P
  6071. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  6072. u8 p2pie[ 255 ] = { 0x00 };
  6073. u16 p2pielen = 0;
  6074. #ifdef CONFIG_WFD
  6075. u32 wfdielen = 0;
  6076. #endif //CONFIG_WFD
  6077. #endif //CONFIG_P2P
  6078. #ifdef CONFIG_DFS
  6079. u16 cap;
  6080. #endif //CONFIG_DFS
  6081. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6082. goto exit;
  6083. //update attribute
  6084. pattrib = &pmgntframe->attrib;
  6085. update_mgntframe_attrib(padapter, pattrib);
  6086. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6087. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6088. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6089. fctrl = &(pwlanhdr->frame_ctl);
  6090. *(fctrl) = 0;
  6091. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6092. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6093. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6094. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6095. pmlmeext->mgnt_seq++;
  6096. SetFrameSubType(pframe, WIFI_ASSOCREQ);
  6097. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6098. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6099. //caps
  6100. #ifdef CONFIG_DFS
  6101. _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
  6102. cap |= BIT(8);
  6103. _rtw_memcpy(pframe, &cap, 2);
  6104. #else
  6105. _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
  6106. #endif //CONFIG_DFS
  6107. pframe += 2;
  6108. pattrib->pktlen += 2;
  6109. //listen interval
  6110. //todo: listen interval for power saving
  6111. val16 = cpu_to_le16(3);
  6112. _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
  6113. pframe += 2;
  6114. pattrib->pktlen += 2;
  6115. //SSID
  6116. pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
  6117. //supported rate & extended supported rate
  6118. #if 1 // Check if the AP's supported rates are also supported by STA.
  6119. get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
  6120. //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
  6121. if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
  6122. {
  6123. sta_bssrate_len = 4;
  6124. }
  6125. //for (i = 0; i < sta_bssrate_len; i++) {
  6126. // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
  6127. //}
  6128. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  6129. if (pmlmeinfo->network.SupportedRates[i] == 0) break;
  6130. DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
  6131. }
  6132. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  6133. if (pmlmeinfo->network.SupportedRates[i] == 0) break;
  6134. // Check if the AP's supported rates are also supported by STA.
  6135. for (j=0; j < sta_bssrate_len; j++) {
  6136. // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
  6137. if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
  6138. == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
  6139. //DBG_871X("match i = %d, j=%d\n", i, j);
  6140. break;
  6141. } else {
  6142. //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
  6143. }
  6144. }
  6145. if (j == sta_bssrate_len) {
  6146. // the rate is not supported by STA
  6147. DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
  6148. } else {
  6149. // the rate is supported by STA
  6150. bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
  6151. }
  6152. }
  6153. bssrate_len = index;
  6154. DBG_871X("bssrate_len = %d\n", bssrate_len);
  6155. #else // Check if the AP's supported rates are also supported by STA.
  6156. #if 0
  6157. get_rate_set(padapter, bssrate, &bssrate_len);
  6158. #else
  6159. for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
  6160. if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
  6161. if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
  6162. break;
  6163. bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
  6164. }
  6165. #endif
  6166. #endif // Check if the AP's supported rates are also supported by STA.
  6167. if (bssrate_len == 0) {
  6168. rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
  6169. rtw_free_xmitframe(pxmitpriv, pmgntframe);
  6170. goto exit; //don't connect to AP if no joint supported rate
  6171. }
  6172. if (bssrate_len > 8)
  6173. {
  6174. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
  6175. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
  6176. }
  6177. else
  6178. {
  6179. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
  6180. }
  6181. //RSN
  6182. p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  6183. if (p != NULL)
  6184. {
  6185. pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
  6186. }
  6187. #ifdef CONFIG_80211N_HT
  6188. //HT caps
  6189. if(padapter->mlmepriv.htpriv.ht_option==_TRUE)
  6190. {
  6191. p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  6192. if ((p != NULL) && (!(is_ap_in_tkip(padapter))))
  6193. {
  6194. _rtw_memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
  6195. //to disable 40M Hz support while gd_bw_40MHz_en = 0
  6196. if (pmlmeext->cur_channel > 14) {
  6197. if ((pregpriv->bw_mode & 0xf0) > 0)
  6198. cbw40_enable = 1;
  6199. } else {
  6200. if ((pregpriv->bw_mode & 0x0f) > 0)
  6201. cbw40_enable = 1;
  6202. }
  6203. if (cbw40_enable == 0)
  6204. {
  6205. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
  6206. }
  6207. else
  6208. {
  6209. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
  6210. }
  6211. //todo: disable SM power save mode
  6212. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c;
  6213. rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  6214. //switch (pregpriv->rf_config)
  6215. switch(rf_type)
  6216. {
  6217. case RF_1T1R:
  6218. if(pregpriv->rx_stbc)
  6219. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
  6220. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
  6221. break;
  6222. case RF_2T2R:
  6223. case RF_1T2R:
  6224. default:
  6225. if((pregpriv->rx_stbc == 0x3) ||//enable for 2.4/5 GHz
  6226. ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || //enable for 2.4GHz
  6227. ((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || //enable for 5GHz
  6228. (pregpriv->wifi_spec==1))
  6229. {
  6230. DBG_871X("declare supporting RX STBC\n");
  6231. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);//RX STBC two spatial stream
  6232. }
  6233. #ifdef CONFIG_DISABLE_MCS13TO15
  6234. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1))
  6235. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16);
  6236. else
  6237. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
  6238. #else //CONFIG_DISABLE_MCS13TO15
  6239. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
  6240. #endif //CONFIG_DISABLE_MCS13TO15
  6241. break;
  6242. }
  6243. #ifdef RTL8192C_RECONFIG_TO_1T1R
  6244. {
  6245. if(pregpriv->rx_stbc)
  6246. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
  6247. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
  6248. }
  6249. #endif
  6250. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
  6251. #ifdef CONFIG_BT_COEXIST
  6252. if (BT_1Ant(padapter) == _TRUE)
  6253. {
  6254. // set to 8K
  6255. pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_CAP_AMPDU_FACTOR;
  6256. // pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K
  6257. }
  6258. #endif
  6259. pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
  6260. }
  6261. }
  6262. #endif
  6263. //vendor specific IE, such as WPA, WMM, WPS
  6264. for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
  6265. {
  6266. pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
  6267. switch (pIE->ElementID)
  6268. {
  6269. case _VENDOR_SPECIFIC_IE_:
  6270. if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
  6271. (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
  6272. (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
  6273. {
  6274. if(!padapter->registrypriv.wifi_spec)
  6275. {
  6276. //Commented by Kurt 20110629
  6277. //In some older APs, WPS handshake
  6278. //would be fail if we append vender extensions informations to AP
  6279. if(_rtw_memcmp(pIE->data, WPS_OUI, 4)){
  6280. pIE->Length=14;
  6281. }
  6282. }
  6283. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
  6284. }
  6285. break;
  6286. #ifdef CONFIG_80211AC_VHT
  6287. case EID_VHTCapability:
  6288. if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
  6289. pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
  6290. }
  6291. break;
  6292. case EID_OpModeNotification:
  6293. if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
  6294. pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
  6295. }
  6296. break;
  6297. #endif // CONFIG_80211AC_VHT
  6298. default:
  6299. break;
  6300. }
  6301. i += (pIE->Length + 2);
  6302. }
  6303. if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
  6304. {
  6305. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
  6306. }
  6307. #ifdef CONFIG_WAPI_SUPPORT
  6308. rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
  6309. #endif
  6310. #ifdef CONFIG_P2P
  6311. #ifdef CONFIG_IOCTL_CFG80211
  6312. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  6313. {
  6314. if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
  6315. {
  6316. _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
  6317. pframe += pmlmepriv->p2p_assoc_req_ie_len;
  6318. pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
  6319. }
  6320. }
  6321. else
  6322. #endif //CONFIG_IOCTL_CFG80211
  6323. {
  6324. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  6325. {
  6326. // Should add the P2P IE in the association request frame.
  6327. // P2P OUI
  6328. p2pielen = 0;
  6329. p2pie[ p2pielen++ ] = 0x50;
  6330. p2pie[ p2pielen++ ] = 0x6F;
  6331. p2pie[ p2pielen++ ] = 0x9A;
  6332. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  6333. // Commented by Albert 20101109
  6334. // According to the P2P Specification, the association request frame should contain 3 P2P attributes
  6335. // 1. P2P Capability
  6336. // 2. Extended Listen Timing
  6337. // 3. Device Info
  6338. // Commented by Albert 20110516
  6339. // 4. P2P Interface
  6340. // P2P Capability
  6341. // Type:
  6342. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  6343. // Length:
  6344. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  6345. p2pielen += 2;
  6346. // Value:
  6347. // Device Capability Bitmap, 1 byte
  6348. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  6349. // Group Capability Bitmap, 1 byte
  6350. if ( pwdinfo->persistent_supported )
  6351. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  6352. else
  6353. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  6354. // Extended Listen Timing
  6355. // Type:
  6356. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  6357. // Length:
  6358. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  6359. p2pielen += 2;
  6360. // Value:
  6361. // Availability Period
  6362. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  6363. p2pielen += 2;
  6364. // Availability Interval
  6365. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  6366. p2pielen += 2;
  6367. // Device Info
  6368. // Type:
  6369. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  6370. // Length:
  6371. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  6372. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  6373. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  6374. p2pielen += 2;
  6375. // Value:
  6376. // P2P Device Address
  6377. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  6378. p2pielen += ETH_ALEN;
  6379. // Config Method
  6380. // This field should be big endian. Noted by P2P specification.
  6381. if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
  6382. ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
  6383. {
  6384. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
  6385. }
  6386. else
  6387. {
  6388. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
  6389. }
  6390. p2pielen += 2;
  6391. // Primary Device Type
  6392. // Category ID
  6393. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  6394. p2pielen += 2;
  6395. // OUI
  6396. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  6397. p2pielen += 4;
  6398. // Sub Category ID
  6399. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  6400. p2pielen += 2;
  6401. // Number of Secondary Device Types
  6402. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  6403. // Device Name
  6404. // Type:
  6405. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  6406. p2pielen += 2;
  6407. // Length:
  6408. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  6409. p2pielen += 2;
  6410. // Value:
  6411. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  6412. p2pielen += pwdinfo->device_name_len;
  6413. // P2P Interface
  6414. // Type:
  6415. p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
  6416. // Length:
  6417. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
  6418. p2pielen += 2;
  6419. // Value:
  6420. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
  6421. p2pielen += ETH_ALEN;
  6422. p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
  6423. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
  6424. p2pielen += ETH_ALEN;
  6425. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  6426. #ifdef CONFIG_WFD
  6427. //wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
  6428. //pframe += wfdielen;
  6429. //pattrib->pktlen += wfdielen;
  6430. #endif //CONFIG_WFD
  6431. }
  6432. }
  6433. #endif //CONFIG_P2P
  6434. #ifdef CONFIG_WFD
  6435. #ifdef CONFIG_IOCTL_CFG80211
  6436. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  6437. #endif //CONFIG_IOCTL_CFG80211
  6438. {
  6439. wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
  6440. pframe += wfdielen;
  6441. pattrib->pktlen += wfdielen;
  6442. }
  6443. #ifdef CONFIG_IOCTL_CFG80211
  6444. else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
  6445. {
  6446. //WFD IE
  6447. _rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
  6448. pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
  6449. pframe += pmlmepriv->wfd_assoc_req_ie_len;
  6450. }
  6451. #endif //CONFIG_IOCTL_CFG80211
  6452. #endif //CONFIG_WFD
  6453. pattrib->last_txcmdsz = pattrib->pktlen;
  6454. dump_mgntframe(padapter, pmgntframe);
  6455. ret = _SUCCESS;
  6456. exit:
  6457. if (ret == _SUCCESS)
  6458. rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
  6459. else
  6460. rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
  6461. return;
  6462. }
  6463. //when wait_ack is ture, this function shoule be called at process context
  6464. static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
  6465. {
  6466. int ret = _FAIL;
  6467. struct xmit_frame *pmgntframe;
  6468. struct pkt_attrib *pattrib;
  6469. unsigned char *pframe;
  6470. struct rtw_ieee80211_hdr *pwlanhdr;
  6471. unsigned short *fctrl;
  6472. struct xmit_priv *pxmitpriv;
  6473. struct mlme_ext_priv *pmlmeext;
  6474. struct mlme_ext_info *pmlmeinfo;
  6475. //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
  6476. if(!padapter)
  6477. goto exit;
  6478. pxmitpriv = &(padapter->xmitpriv);
  6479. pmlmeext = &(padapter->mlmeextpriv);
  6480. pmlmeinfo = &(pmlmeext->mlmext_info);
  6481. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6482. {
  6483. goto exit;
  6484. }
  6485. //update attribute
  6486. pattrib = &pmgntframe->attrib;
  6487. update_mgntframe_attrib(padapter, pattrib);
  6488. pattrib->retry_ctrl = _FALSE;
  6489. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6490. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6491. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6492. fctrl = &(pwlanhdr->frame_ctl);
  6493. *(fctrl) = 0;
  6494. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  6495. {
  6496. SetFrDs(fctrl);
  6497. }
  6498. else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  6499. {
  6500. SetToDs(fctrl);
  6501. }
  6502. if (power_mode)
  6503. {
  6504. SetPwrMgt(fctrl);
  6505. }
  6506. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6507. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6508. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6509. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6510. pmlmeext->mgnt_seq++;
  6511. SetFrameSubType(pframe, WIFI_DATA_NULL);
  6512. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6513. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6514. pattrib->last_txcmdsz = pattrib->pktlen;
  6515. if(wait_ack)
  6516. {
  6517. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6518. }
  6519. else
  6520. {
  6521. dump_mgntframe(padapter, pmgntframe);
  6522. ret = _SUCCESS;
  6523. }
  6524. exit:
  6525. return ret;
  6526. }
  6527. //when wait_ms >0 , this function shoule be called at process context
  6528. //da == NULL for station mode
  6529. int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
  6530. {
  6531. int ret;
  6532. int i = 0;
  6533. u32 start = rtw_get_current_time();
  6534. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6535. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6536. /* da == NULL, assum it's null data for sta to ap*/
  6537. if (da == NULL)
  6538. da = get_my_bssid(&(pmlmeinfo->network));
  6539. do
  6540. {
  6541. ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
  6542. i++;
  6543. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6544. break;
  6545. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6546. rtw_msleep_os(wait_ms);
  6547. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6548. if (ret != _FAIL) {
  6549. ret = _SUCCESS;
  6550. #ifndef DBG_XMIT_ACK
  6551. goto exit;
  6552. #endif
  6553. }
  6554. if (try_cnt && wait_ms) {
  6555. if (da)
  6556. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6557. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6558. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6559. else
  6560. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6561. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6562. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6563. }
  6564. exit:
  6565. return ret;
  6566. }
  6567. //when wait_ack is ture, this function shoule be called at process context
  6568. static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
  6569. {
  6570. int ret = _FAIL;
  6571. struct xmit_frame *pmgntframe;
  6572. struct pkt_attrib *pattrib;
  6573. unsigned char *pframe;
  6574. struct rtw_ieee80211_hdr *pwlanhdr;
  6575. unsigned short *fctrl, *qc;
  6576. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6577. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6578. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6579. DBG_871X("%s\n", __FUNCTION__);
  6580. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6581. {
  6582. goto exit;
  6583. }
  6584. //update attribute
  6585. pattrib = &pmgntframe->attrib;
  6586. update_mgntframe_attrib(padapter, pattrib);
  6587. pattrib->hdrlen +=2;
  6588. pattrib->qos_en = _TRUE;
  6589. pattrib->eosp = 1;
  6590. pattrib->ack_policy = 0;
  6591. pattrib->mdata = 0;
  6592. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6593. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6594. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6595. fctrl = &(pwlanhdr->frame_ctl);
  6596. *(fctrl) = 0;
  6597. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  6598. {
  6599. SetFrDs(fctrl);
  6600. }
  6601. else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  6602. {
  6603. SetToDs(fctrl);
  6604. }
  6605. if(pattrib->mdata)
  6606. SetMData(fctrl);
  6607. qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
  6608. SetPriority(qc, tid);
  6609. SetEOSP(qc, pattrib->eosp);
  6610. SetAckpolicy(qc, pattrib->ack_policy);
  6611. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6612. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6613. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6614. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6615. pmlmeext->mgnt_seq++;
  6616. SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
  6617. pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
  6618. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
  6619. pattrib->last_txcmdsz = pattrib->pktlen;
  6620. if(wait_ack)
  6621. {
  6622. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6623. }
  6624. else
  6625. {
  6626. dump_mgntframe(padapter, pmgntframe);
  6627. ret = _SUCCESS;
  6628. }
  6629. exit:
  6630. return ret;
  6631. }
  6632. //when wait_ms >0 , this function shoule be called at process context
  6633. //da == NULL for station mode
  6634. int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
  6635. {
  6636. int ret;
  6637. int i = 0;
  6638. u32 start = rtw_get_current_time();
  6639. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6640. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6641. /* da == NULL, assum it's null data for sta to ap*/
  6642. if (da == NULL)
  6643. da = get_my_bssid(&(pmlmeinfo->network));
  6644. do
  6645. {
  6646. ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
  6647. i++;
  6648. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6649. break;
  6650. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6651. rtw_msleep_os(wait_ms);
  6652. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6653. if (ret != _FAIL) {
  6654. ret = _SUCCESS;
  6655. #ifndef DBG_XMIT_ACK
  6656. goto exit;
  6657. #endif
  6658. }
  6659. if (try_cnt && wait_ms) {
  6660. if (da)
  6661. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6662. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6663. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6664. else
  6665. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6666. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6667. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6668. }
  6669. exit:
  6670. return ret;
  6671. }
  6672. static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
  6673. {
  6674. struct xmit_frame *pmgntframe;
  6675. struct pkt_attrib *pattrib;
  6676. unsigned char *pframe;
  6677. struct rtw_ieee80211_hdr *pwlanhdr;
  6678. unsigned short *fctrl;
  6679. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6680. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6681. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6682. int ret = _FAIL;
  6683. #ifdef CONFIG_P2P
  6684. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  6685. #endif //CONFIG_P2P
  6686. //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
  6687. #ifdef CONFIG_P2P
  6688. if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
  6689. {
  6690. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  6691. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  6692. }
  6693. #endif //CONFIG_P2P
  6694. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6695. {
  6696. goto exit;
  6697. }
  6698. //update attribute
  6699. pattrib = &pmgntframe->attrib;
  6700. update_mgntframe_attrib(padapter, pattrib);
  6701. pattrib->retry_ctrl = _FALSE;
  6702. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6703. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6704. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6705. fctrl = &(pwlanhdr->frame_ctl);
  6706. *(fctrl) = 0;
  6707. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6708. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6709. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6710. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6711. pmlmeext->mgnt_seq++;
  6712. SetFrameSubType(pframe, WIFI_DEAUTH);
  6713. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6714. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6715. reason = cpu_to_le16(reason);
  6716. pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
  6717. pattrib->last_txcmdsz = pattrib->pktlen;
  6718. if(wait_ack)
  6719. {
  6720. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6721. }
  6722. else
  6723. {
  6724. dump_mgntframe(padapter, pmgntframe);
  6725. ret = _SUCCESS;
  6726. }
  6727. exit:
  6728. return ret;
  6729. }
  6730. int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
  6731. {
  6732. DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
  6733. return _issue_deauth(padapter, da, reason, _FALSE);
  6734. }
  6735. int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
  6736. int wait_ms)
  6737. {
  6738. int ret;
  6739. int i = 0;
  6740. u32 start = rtw_get_current_time();
  6741. do
  6742. {
  6743. ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
  6744. i++;
  6745. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6746. break;
  6747. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6748. rtw_msleep_os(wait_ms);
  6749. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6750. if (ret != _FAIL) {
  6751. ret = _SUCCESS;
  6752. #ifndef DBG_XMIT_ACK
  6753. goto exit;
  6754. #endif
  6755. }
  6756. if (try_cnt && wait_ms) {
  6757. if (da)
  6758. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6759. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6760. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6761. else
  6762. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6763. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6764. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6765. }
  6766. exit:
  6767. return ret;
  6768. }
  6769. void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
  6770. {
  6771. _irqL irqL;
  6772. _list *plist, *phead;
  6773. struct xmit_frame *pmgntframe;
  6774. struct pkt_attrib *pattrib;
  6775. unsigned char *pframe;
  6776. struct rtw_ieee80211_hdr *pwlanhdr;
  6777. unsigned short *fctrl;
  6778. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6779. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6780. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6781. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6782. DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
  6783. FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
  6784. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6785. return;
  6786. //update attribute
  6787. pattrib = &pmgntframe->attrib;
  6788. update_mgntframe_attrib(padapter, pattrib);
  6789. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6790. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6791. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6792. fctrl = &(pwlanhdr->frame_ctl);
  6793. *(fctrl) = 0;
  6794. _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
  6795. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
  6796. _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
  6797. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6798. pmlmeext->mgnt_seq++;
  6799. SetFrameSubType(pframe, WIFI_ACTION);
  6800. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6801. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6802. /* category, action */
  6803. {
  6804. u8 category, action;
  6805. category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
  6806. action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
  6807. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  6808. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  6809. }
  6810. pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
  6811. pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
  6812. hal_ch_offset_to_secondary_ch_offset(ch_offset));
  6813. pattrib->last_txcmdsz = pattrib->pktlen;
  6814. dump_mgntframe(padapter, pmgntframe);
  6815. }
  6816. void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
  6817. {
  6818. u8 category = RTW_WLAN_CATEGORY_BACK;
  6819. u16 start_seq;
  6820. u16 BA_para_set;
  6821. u16 reason_code;
  6822. u16 BA_timeout_value;
  6823. u16 BA_starting_seqctrl;
  6824. HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
  6825. struct xmit_frame *pmgntframe;
  6826. struct pkt_attrib *pattrib;
  6827. u8 *pframe;
  6828. struct rtw_ieee80211_hdr *pwlanhdr;
  6829. u16 *fctrl;
  6830. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6831. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6832. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6833. struct sta_info *psta;
  6834. struct sta_priv *pstapriv = &padapter->stapriv;
  6835. struct registry_priv *pregpriv = &padapter->registrypriv;
  6836. #ifdef CONFIG_BT_COEXIST
  6837. u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
  6838. #endif
  6839. #ifdef CONFIG_80211N_HT
  6840. DBG_871X("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status);
  6841. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6842. {
  6843. return;
  6844. }
  6845. //update attribute
  6846. pattrib = &pmgntframe->attrib;
  6847. update_mgntframe_attrib(padapter, pattrib);
  6848. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6849. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6850. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6851. fctrl = &(pwlanhdr->frame_ctl);
  6852. *(fctrl) = 0;
  6853. //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6854. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  6855. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6856. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6857. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6858. pmlmeext->mgnt_seq++;
  6859. SetFrameSubType(pframe, WIFI_ACTION);
  6860. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6861. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6862. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  6863. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  6864. status = cpu_to_le16(status);
  6865. if (category == 3)
  6866. {
  6867. switch (action)
  6868. {
  6869. case 0: //ADDBA req
  6870. do {
  6871. pmlmeinfo->dialogToken++;
  6872. } while (pmlmeinfo->dialogToken == 0);
  6873. pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
  6874. #ifdef CONFIG_BT_COEXIST
  6875. if ((BT_1Ant(padapter) == _TRUE) &&
  6876. ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
  6877. (_rtw_memcmp(raddr, tendaAPMac, 3) == _FALSE)))
  6878. {
  6879. // A-MSDU NOT Supported
  6880. BA_para_set = 0;
  6881. // immediate Block Ack
  6882. BA_para_set |= (1 << 1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
  6883. // TID
  6884. BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
  6885. // max buffer size is 8 MSDU
  6886. BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6887. }
  6888. else
  6889. #endif
  6890. {
  6891. #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
  6892. BA_para_set = (0x0802 | ((status & 0xf) << 2)); //immediate ack & 16 buffer size
  6893. #else
  6894. BA_para_set = (0x1002 | ((status & 0xf) << 2)); //immediate ack & 64 buffer size
  6895. #endif
  6896. }
  6897. //sys_mib.BA_para_set = 0x0802; //immediate ack & 32 buffer size
  6898. BA_para_set = cpu_to_le16(BA_para_set);
  6899. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6900. //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
  6901. BA_timeout_value = 5000;//~ 5ms
  6902. BA_timeout_value = cpu_to_le16(BA_timeout_value);
  6903. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
  6904. //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  6905. if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
  6906. {
  6907. start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
  6908. DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07);
  6909. psta->BA_starting_seqctrl[status & 0x07] = start_seq;
  6910. BA_starting_seqctrl = start_seq << 4;
  6911. }
  6912. BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
  6913. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
  6914. break;
  6915. case 1: //ADDBA rsp
  6916. pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
  6917. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
  6918. /*
  6919. //BA_para_set = cpu_to_le16((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6920. #if defined(CONFIG_RTL8188E )&& defined (CONFIG_SDIO_HCI)
  6921. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); //32buffer size
  6922. #else
  6923. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6924. #endif
  6925. */
  6926. rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
  6927. if(MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
  6928. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6929. else if(MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
  6930. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); //32 buffer size
  6931. else if(MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
  6932. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); //16 buffer size
  6933. else if(MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
  6934. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); //8 buffer size
  6935. else
  6936. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6937. #ifdef CONFIG_BT_COEXIST
  6938. if ((BT_1Ant(padapter) == _TRUE) &&
  6939. ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
  6940. (_rtw_memcmp(raddr, tendaAPMac, 3) == _FALSE)))
  6941. {
  6942. // max buffer size is 8 MSDU
  6943. BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6944. BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6945. }
  6946. #endif
  6947. if(pregpriv->ampdu_amsdu==0)//disabled
  6948. BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
  6949. else if(pregpriv->ampdu_amsdu==1)//enabled
  6950. BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
  6951. else //auto
  6952. BA_para_set = cpu_to_le16(BA_para_set);
  6953. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6954. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
  6955. break;
  6956. case 2://DELBA
  6957. BA_para_set = (status & 0x1F) << 3;
  6958. BA_para_set = cpu_to_le16(BA_para_set);
  6959. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6960. reason_code = 37;//Requested from peer STA as it does not want to use the mechanism
  6961. reason_code = cpu_to_le16(reason_code);
  6962. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen));
  6963. break;
  6964. default:
  6965. break;
  6966. }
  6967. }
  6968. pattrib->last_txcmdsz = pattrib->pktlen;
  6969. dump_mgntframe(padapter, pmgntframe);
  6970. #endif //CONFIG_80211N_HT
  6971. }
  6972. static void issue_action_BSSCoexistPacket(_adapter *padapter)
  6973. {
  6974. _irqL irqL;
  6975. _list *plist, *phead;
  6976. unsigned char category, action;
  6977. struct xmit_frame *pmgntframe;
  6978. struct pkt_attrib *pattrib;
  6979. unsigned char *pframe;
  6980. struct rtw_ieee80211_hdr *pwlanhdr;
  6981. unsigned short *fctrl;
  6982. struct wlan_network *pnetwork = NULL;
  6983. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6984. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6985. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6986. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6987. _queue *queue = &(pmlmepriv->scanned_queue);
  6988. u8 InfoContent[16] = {0};
  6989. u8 ICS[8][15];
  6990. #ifdef CONFIG_80211N_HT
  6991. if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
  6992. return;
  6993. if(_TRUE == pmlmeinfo->bwmode_updated)
  6994. return;
  6995. DBG_871X("%s\n", __FUNCTION__);
  6996. category = RTW_WLAN_CATEGORY_PUBLIC;
  6997. action = ACT_PUBLIC_BSSCOEXIST;
  6998. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6999. {
  7000. return;
  7001. }
  7002. //update attribute
  7003. pattrib = &pmgntframe->attrib;
  7004. update_mgntframe_attrib(padapter, pattrib);
  7005. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  7006. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  7007. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  7008. fctrl = &(pwlanhdr->frame_ctl);
  7009. *(fctrl) = 0;
  7010. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  7011. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  7012. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  7013. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  7014. pmlmeext->mgnt_seq++;
  7015. SetFrameSubType(pframe, WIFI_ACTION);
  7016. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  7017. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  7018. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  7019. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  7020. //
  7021. if(pmlmepriv->num_FortyMHzIntolerant>0)
  7022. {
  7023. u8 iedata=0;
  7024. iedata |= BIT(2);//20 MHz BSS Width Request
  7025. pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
  7026. }
  7027. //
  7028. _rtw_memset(ICS, 0, sizeof(ICS));
  7029. if(pmlmepriv->num_sta_no_ht>0)
  7030. {
  7031. int i;
  7032. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  7033. phead = get_list_head(queue);
  7034. plist = get_next(phead);
  7035. while(1)
  7036. {
  7037. int len;
  7038. u8 *p;
  7039. WLAN_BSSID_EX *pbss_network;
  7040. if (rtw_end_of_queue_search(phead,plist)== _TRUE)
  7041. break;
  7042. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  7043. plist = get_next(plist);
  7044. pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
  7045. p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
  7046. if((p==NULL) || (len==0))//non-HT
  7047. {
  7048. if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
  7049. continue;
  7050. ICS[0][pbss_network->Configuration.DSConfig]=1;
  7051. if(ICS[0][0] == 0)
  7052. ICS[0][0] = 1;
  7053. }
  7054. }
  7055. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  7056. for(i= 0;i<8;i++)
  7057. {
  7058. if(ICS[i][0] == 1)
  7059. {
  7060. int j, k = 0;
  7061. InfoContent[k] = i;
  7062. //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
  7063. k++;
  7064. for(j=1;j<=14;j++)
  7065. {
  7066. if(ICS[i][j]==1)
  7067. {
  7068. if(k<16)
  7069. {
  7070. InfoContent[k] = j; //channel number
  7071. //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
  7072. k++;
  7073. }
  7074. }
  7075. }
  7076. pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
  7077. }
  7078. }
  7079. }
  7080. pattrib->last_txcmdsz = pattrib->pktlen;
  7081. dump_mgntframe(padapter, pmgntframe);
  7082. #endif //CONFIG_80211N_HT
  7083. }
  7084. unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
  7085. {
  7086. struct sta_priv *pstapriv = &padapter->stapriv;
  7087. struct sta_info *psta = NULL;
  7088. //struct recv_reorder_ctrl *preorder_ctrl;
  7089. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7090. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7091. u16 tid;
  7092. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  7093. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  7094. return _SUCCESS;
  7095. psta = rtw_get_stainfo(pstapriv, addr);
  7096. if(psta==NULL)
  7097. return _SUCCESS;
  7098. //DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR");
  7099. if(initiator==0) // recipient
  7100. {
  7101. for(tid = 0;tid<MAXTID;tid++)
  7102. {
  7103. if(psta->recvreorder_ctrl[tid].enable == _TRUE)
  7104. {
  7105. DBG_871X("rx agg disable tid(%d)\n",tid);
  7106. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
  7107. psta->recvreorder_ctrl[tid].enable = _FALSE;
  7108. psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
  7109. #ifdef DBG_RX_SEQ
  7110. DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
  7111. psta->recvreorder_ctrl[tid].indicate_seq);
  7112. #endif
  7113. }
  7114. }
  7115. }
  7116. else if(initiator == 1)// originator
  7117. {
  7118. #ifdef CONFIG_80211N_HT
  7119. //DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
  7120. for(tid = 0;tid<MAXTID;tid++)
  7121. {
  7122. if(psta->htpriv.agg_enable_bitmap & BIT(tid))
  7123. {
  7124. DBG_871X("tx agg disable tid(%d)\n",tid);
  7125. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) );
  7126. psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
  7127. psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
  7128. }
  7129. }
  7130. #endif //CONFIG_80211N_HT
  7131. }
  7132. return _SUCCESS;
  7133. }
  7134. unsigned int send_beacon(_adapter *padapter)
  7135. {
  7136. u8 bxmitok = _FALSE;
  7137. int issue=0;
  7138. int poll = 0;
  7139. //#ifdef CONFIG_CONCURRENT_MODE
  7140. //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  7141. //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7142. //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  7143. //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  7144. //#endif
  7145. #ifdef CONFIG_PCI_HCI
  7146. //DBG_871X("%s\n", __FUNCTION__);
  7147. issue_beacon(padapter, 0);
  7148. return _SUCCESS;
  7149. #endif
  7150. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  7151. u32 start = rtw_get_current_time();
  7152. rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
  7153. rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
  7154. do{
  7155. issue_beacon(padapter, 100);
  7156. issue++;
  7157. do {
  7158. rtw_yield_os();
  7159. rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
  7160. poll++;
  7161. }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
  7162. }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
  7163. if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
  7164. {
  7165. return _FAIL;
  7166. }
  7167. if(_FALSE == bxmitok)
  7168. {
  7169. DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
  7170. return _FAIL;
  7171. }
  7172. else
  7173. {
  7174. u32 passing_time = rtw_get_passing_time_ms(start);
  7175. if(passing_time > 100 || issue > 3)
  7176. DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
  7177. //else
  7178. // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
  7179. return _SUCCESS;
  7180. }
  7181. #endif
  7182. }
  7183. /****************************************************************************
  7184. Following are some utitity fuctions for WiFi MLME
  7185. *****************************************************************************/
  7186. BOOLEAN IsLegal5GChannel(
  7187. IN PADAPTER Adapter,
  7188. IN u8 channel)
  7189. {
  7190. int i=0;
  7191. u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
  7192. 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
  7193. 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
  7194. 161,163,165};
  7195. for(i=0;i<sizeof(Channel_5G);i++)
  7196. if(channel == Channel_5G[i])
  7197. return _TRUE;
  7198. return _FALSE;
  7199. }
  7200. void site_survey(_adapter *padapter)
  7201. {
  7202. unsigned char survey_channel = 0, val8;
  7203. RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
  7204. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7205. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7206. u32 initialgain = 0;
  7207. #ifdef CONFIG_P2P
  7208. #ifdef CONFIG_CONCURRENT_MODE
  7209. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7210. u8 stay_buddy_ch = 0;
  7211. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7212. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  7213. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  7214. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  7215. #endif //CONFIG_CONCURRENT_MODE
  7216. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  7217. static unsigned char prev_survey_channel = 0;
  7218. static unsigned int p2p_scan_count = 0;
  7219. if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
  7220. {
  7221. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  7222. {
  7223. survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
  7224. }
  7225. else
  7226. {
  7227. survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
  7228. }
  7229. ScanType = SCAN_ACTIVE;
  7230. }
  7231. else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
  7232. {
  7233. // Commented by Albert 2011/06/03
  7234. // The driver is in the find phase, it should go through the social channel.
  7235. int ch_set_idx;
  7236. survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
  7237. ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
  7238. if (ch_set_idx >= 0)
  7239. ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
  7240. else
  7241. ScanType = SCAN_ACTIVE;
  7242. }
  7243. else
  7244. #endif //CONFIG_P2P
  7245. {
  7246. struct rtw_ieee80211_channel *ch;
  7247. if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
  7248. ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
  7249. survey_channel = ch->hw_value;
  7250. ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
  7251. }
  7252. }
  7253. if (0){
  7254. DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
  7255. , FUNC_ADPT_ARG(padapter)
  7256. , survey_channel
  7257. , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
  7258. , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
  7259. , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
  7260. , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
  7261. );
  7262. #ifdef DBG_FIXED_CHAN
  7263. DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
  7264. #endif
  7265. }
  7266. if(survey_channel != 0)
  7267. {
  7268. //PAUSE 4-AC Queue when site_survey
  7269. //rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7270. //val8 |= 0x0f;
  7271. //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7272. #ifdef CONFIG_CONCURRENT_MODE
  7273. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7274. if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
  7275. {
  7276. if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH )
  7277. {
  7278. pmlmeinfo->scan_cnt = 0;
  7279. survey_channel = pbuddy_mlmeext->cur_channel;
  7280. ScanType = SCAN_ACTIVE;
  7281. stay_buddy_ch = 1;
  7282. }
  7283. else
  7284. {
  7285. if( pmlmeinfo->scan_cnt == 0 )
  7286. stay_buddy_ch = 2;
  7287. pmlmeinfo->scan_cnt++;
  7288. }
  7289. }
  7290. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7291. #endif //CONFIG_CONCURRENT_MODE
  7292. if(pmlmeext->sitesurvey_res.channel_idx == 0)
  7293. {
  7294. #ifdef DBG_FIXED_CHAN
  7295. if(pmlmeext->fixed_chan !=0xff)
  7296. set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7297. else
  7298. #endif
  7299. set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7300. }
  7301. else
  7302. {
  7303. #ifdef DBG_FIXED_CHAN
  7304. if(pmlmeext->fixed_chan!=0xff)
  7305. SelectChannel(padapter, pmlmeext->fixed_chan);
  7306. else
  7307. #endif
  7308. SelectChannel(padapter, survey_channel);
  7309. }
  7310. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7311. if( stay_buddy_ch == 1 )
  7312. {
  7313. val8 = 0; //survey done
  7314. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7315. if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
  7316. check_buddy_fwstate(padapter, _FW_LINKED))
  7317. {
  7318. update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
  7319. }
  7320. }
  7321. else if( stay_buddy_ch == 2 )
  7322. {
  7323. val8 = 1; //under site survey
  7324. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7325. }
  7326. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7327. if(ScanType == SCAN_ACTIVE) //obey the channel plan setting...
  7328. {
  7329. #ifdef CONFIG_P2P
  7330. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
  7331. rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
  7332. )
  7333. {
  7334. issue_probereq_p2p(padapter, NULL);
  7335. issue_probereq_p2p(padapter, NULL);
  7336. issue_probereq_p2p(padapter, NULL);
  7337. }
  7338. else
  7339. #endif //CONFIG_P2P
  7340. {
  7341. int i;
  7342. for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
  7343. if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
  7344. //todo: to issue two probe req???
  7345. issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
  7346. //rtw_msleep_os(SURVEY_TO>>1);
  7347. issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
  7348. }
  7349. }
  7350. if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
  7351. //todo: to issue two probe req???
  7352. issue_probereq(padapter, NULL, NULL);
  7353. //rtw_msleep_os(SURVEY_TO>>1);
  7354. issue_probereq(padapter, NULL, NULL);
  7355. }
  7356. }
  7357. }
  7358. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7359. if( stay_buddy_ch == 1 )
  7360. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND );
  7361. else
  7362. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7363. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
  7364. }
  7365. else
  7366. {
  7367. // channel number is 0 or this channel is not valid.
  7368. #ifdef CONFIG_CONCURRENT_MODE
  7369. u8 cur_channel;
  7370. u8 cur_bwmode;
  7371. u8 cur_ch_offset;
  7372. if(check_fwstate(pmlmepriv, _FW_LINKED))
  7373. {
  7374. cur_channel = pmlmeext->cur_channel;
  7375. cur_bwmode = pmlmeext->cur_bwmode;
  7376. cur_ch_offset = pmlmeext->cur_ch_offset;
  7377. }
  7378. //else if((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  7379. else if(check_buddy_fwstate(padapter, _FW_LINKED)) // for AP or STA
  7380. {
  7381. cur_channel = pbuddy_mlmeext->cur_channel;
  7382. cur_bwmode = pbuddy_mlmeext->cur_bwmode;
  7383. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  7384. }
  7385. else
  7386. {
  7387. cur_channel = pmlmeext->cur_channel;
  7388. cur_bwmode = pmlmeext->cur_bwmode;
  7389. cur_ch_offset = pmlmeext->cur_ch_offset;
  7390. }
  7391. #endif
  7392. #ifdef CONFIG_P2P
  7393. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
  7394. {
  7395. if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
  7396. {
  7397. // Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT.
  7398. // This will let the following flow to run the scanning end.
  7399. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
  7400. }
  7401. #ifdef CONFIG_DBG_P2P
  7402. DBG_871X( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
  7403. #endif
  7404. }
  7405. if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
  7406. {
  7407. // Set the P2P State to the listen state of find phase and set the current channel to the listen channel
  7408. set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7409. rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
  7410. pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
  7411. initialgain = 0xff; //restore RX GAIN
  7412. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  7413. //turn on dynamic functions
  7414. Restore_DM_Func_Flag(padapter);
  7415. //Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
  7416. _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
  7417. }
  7418. else
  7419. #endif //CONFIG_P2P
  7420. {
  7421. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7422. pmlmeinfo->scan_cnt = 0;
  7423. #endif //CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE
  7424. #ifdef CONFIG_ANTENNA_DIVERSITY
  7425. // 20100721:Interrupt scan operation here.
  7426. // For SW antenna diversity before link, it needs to switch to another antenna and scan again.
  7427. // It compares the scan result and select beter one to do connection.
  7428. if(rtw_hal_antdiv_before_linked(padapter))
  7429. {
  7430. pmlmeext->sitesurvey_res.bss_cnt = 0;
  7431. pmlmeext->sitesurvey_res.channel_idx = -1;
  7432. pmlmeext->chan_scan_time = SURVEY_TO /2;
  7433. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
  7434. return;
  7435. }
  7436. #endif
  7437. #ifdef CONFIG_P2P
  7438. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
  7439. {
  7440. #ifdef CONFIG_CONCURRENT_MODE
  7441. if( pwdinfo->driver_interface == DRIVER_WEXT )
  7442. {
  7443. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  7444. {
  7445. _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
  7446. }
  7447. }
  7448. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  7449. #else
  7450. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  7451. #endif
  7452. }
  7453. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
  7454. #endif //CONFIG_P2P
  7455. pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
  7456. //switch back to the original channel
  7457. //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
  7458. {
  7459. #ifdef CONFIG_CONCURRENT_MODE
  7460. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  7461. #else
  7462. #ifdef CONFIG_DUALMAC_CONCURRENT
  7463. dc_set_channel_bwmode_survey_done(padapter);
  7464. #else
  7465. if( pwdinfo->driver_interface == DRIVER_WEXT )
  7466. {
  7467. if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
  7468. {
  7469. set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7470. }
  7471. else
  7472. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7473. }
  7474. else if( pwdinfo->driver_interface == DRIVER_CFG80211 )
  7475. {
  7476. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7477. }
  7478. #endif //CONFIG_DUALMAC_CONCURRENT
  7479. #endif //CONFIG_CONCURRENT_MODE
  7480. }
  7481. //flush 4-AC Queue after site_survey
  7482. //val8 = 0;
  7483. //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7484. //config MSR
  7485. Set_MSR(padapter, (pmlmeinfo->state & 0x3));
  7486. initialgain = 0xff; //restore RX GAIN
  7487. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  7488. //turn on dynamic functions
  7489. Restore_DM_Func_Flag(padapter);
  7490. //Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
  7491. if (is_client_associated_to_ap(padapter) == _TRUE)
  7492. {
  7493. issue_nulldata(padapter, NULL, 0, 3, 500);
  7494. #ifdef CONFIG_CONCURRENT_MODE
  7495. if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  7496. {
  7497. DBG_871X("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
  7498. issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
  7499. }
  7500. #endif
  7501. }
  7502. #ifdef CONFIG_CONCURRENT_MODE
  7503. else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  7504. {
  7505. issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
  7506. }
  7507. #endif
  7508. val8 = 0; //survey done
  7509. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7510. report_surveydone_event(padapter);
  7511. pmlmeext->chan_scan_time = SURVEY_TO;
  7512. pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
  7513. issue_action_BSSCoexistPacket(padapter);
  7514. issue_action_BSSCoexistPacket(padapter);
  7515. issue_action_BSSCoexistPacket(padapter);
  7516. }
  7517. #ifdef CONFIG_CONCURRENT_MODE
  7518. if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
  7519. check_buddy_fwstate(padapter, _FW_LINKED))
  7520. {
  7521. DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  7522. DBG_871X("restart pbuddy_adapter's beacon\n");
  7523. update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
  7524. }
  7525. #endif
  7526. }
  7527. return;
  7528. }
  7529. //collect bss info from Beacon and Probe response frames.
  7530. u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
  7531. {
  7532. int i;
  7533. u32 len;
  7534. u8 *p;
  7535. u16 val16, subtype;
  7536. u8 *pframe = precv_frame->u.hdr.rx_data;
  7537. u32 packet_len = precv_frame->u.hdr.len;
  7538. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  7539. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7540. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7541. len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
  7542. if (len > MAX_IE_SZ)
  7543. {
  7544. //DBG_871X("IE too long for survey event\n");
  7545. return _FAIL;
  7546. }
  7547. _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
  7548. subtype = GetFrameSubType(pframe);
  7549. if(subtype==WIFI_BEACON)
  7550. bssid->Reserved[0] = 1;
  7551. else
  7552. bssid->Reserved[0] = 0;
  7553. bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
  7554. //below is to copy the information element
  7555. bssid->IELength = len;
  7556. _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
  7557. //get the signal strength
  7558. //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
  7559. bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
  7560. bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
  7561. bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
  7562. #ifdef CONFIG_ANTENNA_DIVERSITY
  7563. //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
  7564. rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
  7565. #endif
  7566. // checking SSID
  7567. if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL)
  7568. {
  7569. DBG_871X("marc: cannot find SSID for survey event\n");
  7570. return _FAIL;
  7571. }
  7572. if (*(p + 1))
  7573. {
  7574. if (len > NDIS_802_11_LENGTH_SSID)
  7575. {
  7576. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7577. return _FAIL;
  7578. }
  7579. _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
  7580. bssid->Ssid.SsidLength = *(p + 1);
  7581. }
  7582. else
  7583. {
  7584. bssid->Ssid.SsidLength = 0;
  7585. }
  7586. _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
  7587. //checking rate info...
  7588. i = 0;
  7589. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7590. if (p != NULL)
  7591. {
  7592. if (len > NDIS_802_11_LENGTH_RATES_EX)
  7593. {
  7594. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7595. return _FAIL;
  7596. }
  7597. _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
  7598. i = len;
  7599. }
  7600. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7601. if (p != NULL)
  7602. {
  7603. if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
  7604. {
  7605. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7606. return _FAIL;
  7607. }
  7608. _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
  7609. }
  7610. //todo:
  7611. #if 0
  7612. if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
  7613. {
  7614. bssid->NetworkTypeInUse = Ndis802_11DS;
  7615. }
  7616. else
  7617. #endif
  7618. {
  7619. bssid->NetworkTypeInUse = Ndis802_11OFDM24;
  7620. }
  7621. if (bssid->IELength < 12)
  7622. return _FAIL;
  7623. // Checking for DSConfig
  7624. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7625. bssid->Configuration.DSConfig = 0;
  7626. bssid->Configuration.Length = 0;
  7627. if (p)
  7628. {
  7629. bssid->Configuration.DSConfig = *(p + 2);
  7630. }
  7631. else
  7632. {// In 5G, some ap do not have DSSET IE
  7633. // checking HT info for channel
  7634. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7635. if(p)
  7636. {
  7637. struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
  7638. bssid->Configuration.DSConfig = HT_info->primary_channel;
  7639. }
  7640. else
  7641. { // use current channel
  7642. bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
  7643. }
  7644. }
  7645. _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
  7646. bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
  7647. val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
  7648. if (val16 & BIT(0))
  7649. {
  7650. bssid->InfrastructureMode = Ndis802_11Infrastructure;
  7651. _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
  7652. }
  7653. else
  7654. {
  7655. bssid->InfrastructureMode = Ndis802_11IBSS;
  7656. _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
  7657. }
  7658. if (val16 & BIT(4))
  7659. bssid->Privacy = 1;
  7660. else
  7661. bssid->Privacy = 0;
  7662. bssid->Configuration.ATIMWindow = 0;
  7663. //20/40 BSS Coexistence check
  7664. if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
  7665. {
  7666. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  7667. #ifdef CONFIG_80211N_HT
  7668. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7669. if(p && len>0)
  7670. {
  7671. struct HT_caps_element *pHT_caps;
  7672. pHT_caps = (struct HT_caps_element *)(p + 2);
  7673. if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
  7674. {
  7675. pmlmepriv->num_FortyMHzIntolerant++;
  7676. }
  7677. }
  7678. else
  7679. {
  7680. pmlmepriv->num_sta_no_ht++;
  7681. }
  7682. #endif //CONFIG_80211N_HT
  7683. }
  7684. #ifdef CONFIG_INTEL_WIDI
  7685. //process_intel_widi_query_or_tigger(padapter, bssid);
  7686. if(process_intel_widi_query_or_tigger(padapter, bssid))
  7687. {
  7688. return _FAIL;
  7689. }
  7690. #endif // CONFIG_INTEL_WIDI
  7691. #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) & 1
  7692. if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
  7693. DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
  7694. , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
  7695. , rtw_get_oper_ch(padapter)
  7696. , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
  7697. );
  7698. }
  7699. #endif
  7700. // mark bss info receving from nearby channel as SignalQuality 101
  7701. if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
  7702. {
  7703. bssid->PhyInfo.SignalQuality= 101;
  7704. }
  7705. return _SUCCESS;
  7706. }
  7707. void start_create_ibss(_adapter* padapter)
  7708. {
  7709. unsigned short caps;
  7710. u8 val8;
  7711. u8 join_type;
  7712. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7713. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7714. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  7715. pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
  7716. pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
  7717. //update wireless mode
  7718. update_wireless_mode(padapter);
  7719. //udpate capability
  7720. caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
  7721. update_capinfo(padapter, caps);
  7722. if(caps&cap_IBSS)//adhoc master
  7723. {
  7724. //set_opmode_cmd(padapter, adhoc);//removed
  7725. val8 = 0xcf;
  7726. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7727. //switch channel
  7728. //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
  7729. set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7730. beacon_timing_control(padapter);
  7731. //set msr to WIFI_FW_ADHOC_STATE
  7732. pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
  7733. Set_MSR(padapter, (pmlmeinfo->state & 0x3));
  7734. //issue beacon
  7735. if(send_beacon(padapter)==_FAIL)
  7736. {
  7737. RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
  7738. report_join_res(padapter, -1);
  7739. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7740. }
  7741. else
  7742. {
  7743. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
  7744. join_type = 0;
  7745. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  7746. report_join_res(padapter, 1);
  7747. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  7748. }
  7749. }
  7750. else
  7751. {
  7752. DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
  7753. return;
  7754. }
  7755. }
  7756. void start_clnt_join(_adapter* padapter)
  7757. {
  7758. unsigned short caps;
  7759. u8 val8;
  7760. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7761. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7762. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  7763. int beacon_timeout;
  7764. pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
  7765. pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
  7766. #ifdef CONFIG_DUALMAC_CONCURRENT
  7767. if(dc_handle_join_request(padapter) == _FAIL)
  7768. {
  7769. DBG_871X("dc_handle_join_request fail !!!\n");
  7770. return;
  7771. }
  7772. //switch channel
  7773. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7774. #elif defined (CONFIG_CONCURRENT_MODE)
  7775. if(concurrent_chk_start_clnt_join(padapter) == _FAIL)
  7776. return;
  7777. #else //NON CONCURRENT_MODE
  7778. //switch channel
  7779. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7780. #endif
  7781. //update wireless mode
  7782. update_wireless_mode(padapter);
  7783. //udpate capability
  7784. caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
  7785. update_capinfo(padapter, caps);
  7786. if (caps&cap_ESS)
  7787. {
  7788. Set_MSR(padapter, WIFI_FW_STATION_STATE);
  7789. val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
  7790. #ifdef CONFIG_WAPI_SUPPORT
  7791. if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
  7792. {
  7793. //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
  7794. val8 = 0x4c;
  7795. }
  7796. #endif
  7797. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7798. //switch channel
  7799. //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7800. //here wait for receiving the beacon to start auth
  7801. //and enable a timer
  7802. beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
  7803. set_link_timer(pmlmeext, beacon_timeout);
  7804. _set_timer( &padapter->mlmepriv.assoc_timer,
  7805. (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
  7806. pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
  7807. }
  7808. else if (caps&cap_IBSS) //adhoc client
  7809. {
  7810. Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
  7811. val8 = 0xcf;
  7812. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7813. //switch channel
  7814. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7815. beacon_timing_control(padapter);
  7816. pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
  7817. report_join_res(padapter, 1);
  7818. }
  7819. else
  7820. {
  7821. //DBG_871X("marc: invalid cap:%x\n", caps);
  7822. return;
  7823. }
  7824. }
  7825. void start_clnt_auth(_adapter* padapter)
  7826. {
  7827. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7828. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7829. _cancel_timer_ex(&pmlmeext->link_timer);
  7830. pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
  7831. pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
  7832. pmlmeinfo->auth_seq = 1;
  7833. pmlmeinfo->reauth_count = 0;
  7834. pmlmeinfo->reassoc_count = 0;
  7835. pmlmeinfo->link_count = 0;
  7836. pmlmeext->retry = 0;
  7837. // Because of AP's not receiving deauth before
  7838. // AP may: 1)not response auth or 2)deauth us after link is complete
  7839. // issue deauth before issuing auth to deal with the situation
  7840. #ifndef CONFIG_PLATFORM_RTK_DMP
  7841. // Commented by Albert 2012/07/21
  7842. // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
  7843. issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
  7844. #endif
  7845. DBG_871X_LEVEL(_drv_always_, "start auth\n");
  7846. issue_auth(padapter, NULL, 0);
  7847. set_link_timer(pmlmeext, REAUTH_TO);
  7848. }
  7849. void start_clnt_assoc(_adapter* padapter)
  7850. {
  7851. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7852. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7853. _cancel_timer_ex(&pmlmeext->link_timer);
  7854. pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
  7855. pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
  7856. issue_assocreq(padapter);
  7857. set_link_timer(pmlmeext, REASSOC_TO);
  7858. }
  7859. unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
  7860. {
  7861. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7862. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7863. //check A3
  7864. if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  7865. return _SUCCESS;
  7866. DBG_871X("%s\n", __FUNCTION__);
  7867. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  7868. {
  7869. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  7870. {
  7871. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7872. report_del_sta_event(padapter, MacAddr, reason);
  7873. }
  7874. else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
  7875. {
  7876. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7877. report_join_res(padapter, -2);
  7878. }
  7879. }
  7880. return _SUCCESS;
  7881. }
  7882. #ifdef CONFIG_80211D
  7883. static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
  7884. {
  7885. struct registry_priv *pregistrypriv;
  7886. struct mlme_ext_priv *pmlmeext;
  7887. RT_CHANNEL_INFO *chplan_new;
  7888. u8 channel;
  7889. u8 i;
  7890. pregistrypriv = &padapter->registrypriv;
  7891. pmlmeext = &padapter->mlmeextpriv;
  7892. // Adjust channel plan by AP Country IE
  7893. if (pregistrypriv->enable80211d &&
  7894. (!pmlmeext->update_channel_plan_by_ap_done))
  7895. {
  7896. u8 *ie, *p;
  7897. u32 len;
  7898. RT_CHANNEL_PLAN chplan_ap;
  7899. RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
  7900. u8 country[4];
  7901. u8 fcn; // first channel number
  7902. u8 noc; // number of channel
  7903. u8 j, k;
  7904. ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7905. if (!ie) return;
  7906. if (len < 6) return;
  7907. ie += 2;
  7908. p = ie;
  7909. ie += len;
  7910. _rtw_memset(country, 0, 4);
  7911. _rtw_memcpy(country, p, 3);
  7912. p += 3;
  7913. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  7914. ("%s: 802.11d country=%s\n", __FUNCTION__, country));
  7915. i = 0;
  7916. while ((ie - p) >= 3)
  7917. {
  7918. fcn = *(p++);
  7919. noc = *(p++);
  7920. p++;
  7921. for (j = 0; j < noc; j++)
  7922. {
  7923. if (fcn <= 14) channel = fcn + j; // 2.4 GHz
  7924. else channel = fcn + j*4; // 5 GHz
  7925. chplan_ap.Channel[i++] = channel;
  7926. }
  7927. }
  7928. chplan_ap.Len = i;
  7929. #ifdef CONFIG_DEBUG_RTL871X
  7930. i = 0;
  7931. DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
  7932. while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
  7933. {
  7934. DBG_8192C("%02d,", chplan_ap.Channel[i]);
  7935. i++;
  7936. }
  7937. DBG_871X("}\n");
  7938. #endif
  7939. _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
  7940. #ifdef CONFIG_DEBUG_RTL871X
  7941. i = 0;
  7942. DBG_871X("%s: STA channel plan {", __FUNCTION__);
  7943. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  7944. {
  7945. DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
  7946. i++;
  7947. }
  7948. DBG_871X("}\n");
  7949. #endif
  7950. _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
  7951. chplan_new = pmlmeext->channel_set;
  7952. i = j = k = 0;
  7953. if (pregistrypriv->wireless_mode & WIRELESS_11G)
  7954. {
  7955. do {
  7956. if ((i == MAX_CHANNEL_NUM) ||
  7957. (chplan_sta[i].ChannelNum == 0) ||
  7958. (chplan_sta[i].ChannelNum > 14))
  7959. break;
  7960. if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
  7961. break;
  7962. if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
  7963. {
  7964. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  7965. chplan_new[k].ScanType = SCAN_ACTIVE;
  7966. i++;
  7967. j++;
  7968. k++;
  7969. }
  7970. else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
  7971. {
  7972. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  7973. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  7974. chplan_new[k].ScanType = SCAN_PASSIVE;
  7975. i++;
  7976. k++;
  7977. }
  7978. else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
  7979. {
  7980. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  7981. chplan_new[k].ScanType = SCAN_ACTIVE;
  7982. j++;
  7983. k++;
  7984. }
  7985. } while (1);
  7986. // change AP not support channel to Passive scan
  7987. while ((i < MAX_CHANNEL_NUM) &&
  7988. (chplan_sta[i].ChannelNum != 0) &&
  7989. (chplan_sta[i].ChannelNum <= 14))
  7990. {
  7991. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  7992. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  7993. chplan_new[k].ScanType = SCAN_PASSIVE;
  7994. i++;
  7995. k++;
  7996. }
  7997. // add channel AP supported
  7998. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
  7999. {
  8000. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8001. chplan_new[k].ScanType = SCAN_ACTIVE;
  8002. j++;
  8003. k++;
  8004. }
  8005. }
  8006. else
  8007. {
  8008. // keep original STA 2.4G channel plan
  8009. while ((i < MAX_CHANNEL_NUM) &&
  8010. (chplan_sta[i].ChannelNum != 0) &&
  8011. (chplan_sta[i].ChannelNum <= 14))
  8012. {
  8013. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8014. chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8015. i++;
  8016. k++;
  8017. }
  8018. // skip AP 2.4G channel plan
  8019. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
  8020. {
  8021. j++;
  8022. }
  8023. }
  8024. if (pregistrypriv->wireless_mode & WIRELESS_11A)
  8025. {
  8026. do {
  8027. if ((i == MAX_CHANNEL_NUM) ||
  8028. (chplan_sta[i].ChannelNum == 0))
  8029. break;
  8030. if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
  8031. break;
  8032. if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
  8033. {
  8034. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8035. chplan_new[k].ScanType = SCAN_ACTIVE;
  8036. i++;
  8037. j++;
  8038. k++;
  8039. }
  8040. else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
  8041. {
  8042. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8043. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8044. chplan_new[k].ScanType = SCAN_PASSIVE;
  8045. i++;
  8046. k++;
  8047. }
  8048. else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
  8049. {
  8050. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8051. chplan_new[k].ScanType = SCAN_ACTIVE;
  8052. j++;
  8053. k++;
  8054. }
  8055. } while (1);
  8056. // change AP not support channel to Passive scan
  8057. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  8058. {
  8059. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8060. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8061. chplan_new[k].ScanType = SCAN_PASSIVE;
  8062. i++;
  8063. k++;
  8064. }
  8065. // add channel AP supported
  8066. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
  8067. {
  8068. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8069. chplan_new[k].ScanType = SCAN_ACTIVE;
  8070. j++;
  8071. k++;
  8072. }
  8073. }
  8074. else
  8075. {
  8076. // keep original STA 5G channel plan
  8077. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  8078. {
  8079. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8080. chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8081. i++;
  8082. k++;
  8083. }
  8084. }
  8085. pmlmeext->update_channel_plan_by_ap_done = 1;
  8086. #ifdef CONFIG_DEBUG_RTL871X
  8087. k = 0;
  8088. DBG_871X("%s: new STA channel plan {", __FUNCTION__);
  8089. while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
  8090. {
  8091. DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
  8092. k++;
  8093. }
  8094. DBG_871X("}\n");
  8095. #endif
  8096. #if 0
  8097. // recover the right channel index
  8098. channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
  8099. k = 0;
  8100. while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
  8101. {
  8102. if (chplan_new[k].ChannelNum == channel) {
  8103. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  8104. ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
  8105. __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
  8106. pmlmeext->sitesurvey_res.channel_idx = k;
  8107. break;
  8108. }
  8109. k++;
  8110. }
  8111. #endif
  8112. }
  8113. // If channel is used by AP, set channel scan type to active
  8114. channel = bssid->Configuration.DSConfig;
  8115. chplan_new = pmlmeext->channel_set;
  8116. i = 0;
  8117. while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
  8118. {
  8119. if (chplan_new[i].ChannelNum == channel)
  8120. {
  8121. if (chplan_new[i].ScanType == SCAN_PASSIVE)
  8122. {
  8123. //5G Bnad 2, 3 (DFS) doesn't change to active scan
  8124. if(channel >= 52 && channel <= 144)
  8125. break;
  8126. chplan_new[i].ScanType = SCAN_ACTIVE;
  8127. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  8128. ("%s: change channel %d scan type from passive to active\n",
  8129. __FUNCTION__, channel));
  8130. }
  8131. break;
  8132. }
  8133. i++;
  8134. }
  8135. }
  8136. #endif
  8137. /****************************************************************************
  8138. Following are the functions to report events
  8139. *****************************************************************************/
  8140. void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  8141. {
  8142. struct cmd_obj *pcmd_obj;
  8143. u8 *pevtcmd;
  8144. u32 cmdsz;
  8145. struct survey_event *psurvey_evt;
  8146. struct C2HEvent_Header *pc2h_evt_hdr;
  8147. struct mlme_ext_priv *pmlmeext;
  8148. struct cmd_priv *pcmdpriv;
  8149. //u8 *pframe = precv_frame->u.hdr.rx_data;
  8150. //uint len = precv_frame->u.hdr.len;
  8151. if(!padapter)
  8152. return;
  8153. pmlmeext = &padapter->mlmeextpriv;
  8154. pcmdpriv = &padapter->cmdpriv;
  8155. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8156. {
  8157. return;
  8158. }
  8159. cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
  8160. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8161. {
  8162. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8163. return;
  8164. }
  8165. _rtw_init_listhead(&pcmd_obj->list);
  8166. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8167. pcmd_obj->cmdsz = cmdsz;
  8168. pcmd_obj->parmbuf = pevtcmd;
  8169. pcmd_obj->rsp = NULL;
  8170. pcmd_obj->rspsz = 0;
  8171. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8172. pc2h_evt_hdr->len = sizeof(struct survey_event);
  8173. pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
  8174. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8175. psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8176. if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
  8177. {
  8178. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8179. rtw_mfree((u8 *)pevtcmd, cmdsz);
  8180. return;
  8181. }
  8182. #ifdef CONFIG_80211D
  8183. process_80211d(padapter, &psurvey_evt->bss);
  8184. #endif
  8185. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8186. pmlmeext->sitesurvey_res.bss_cnt++;
  8187. return;
  8188. }
  8189. void report_surveydone_event(_adapter *padapter)
  8190. {
  8191. struct cmd_obj *pcmd_obj;
  8192. u8 *pevtcmd;
  8193. u32 cmdsz;
  8194. struct surveydone_event *psurveydone_evt;
  8195. struct C2HEvent_Header *pc2h_evt_hdr;
  8196. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8197. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8198. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8199. {
  8200. return;
  8201. }
  8202. cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
  8203. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8204. {
  8205. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8206. return;
  8207. }
  8208. _rtw_init_listhead(&pcmd_obj->list);
  8209. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8210. pcmd_obj->cmdsz = cmdsz;
  8211. pcmd_obj->parmbuf = pevtcmd;
  8212. pcmd_obj->rsp = NULL;
  8213. pcmd_obj->rspsz = 0;
  8214. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8215. pc2h_evt_hdr->len = sizeof(struct surveydone_event);
  8216. pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
  8217. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8218. psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8219. psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
  8220. DBG_871X("survey done event(%x)\n", psurveydone_evt->bss_cnt);
  8221. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8222. return;
  8223. }
  8224. void report_join_res(_adapter *padapter, int res)
  8225. {
  8226. struct cmd_obj *pcmd_obj;
  8227. u8 *pevtcmd;
  8228. u32 cmdsz;
  8229. struct joinbss_event *pjoinbss_evt;
  8230. struct C2HEvent_Header *pc2h_evt_hdr;
  8231. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8232. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8233. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8234. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8235. {
  8236. return;
  8237. }
  8238. cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
  8239. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8240. {
  8241. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8242. return;
  8243. }
  8244. _rtw_init_listhead(&pcmd_obj->list);
  8245. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8246. pcmd_obj->cmdsz = cmdsz;
  8247. pcmd_obj->parmbuf = pevtcmd;
  8248. pcmd_obj->rsp = NULL;
  8249. pcmd_obj->rspsz = 0;
  8250. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8251. pc2h_evt_hdr->len = sizeof(struct joinbss_event);
  8252. pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
  8253. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8254. pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8255. _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
  8256. pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
  8257. DBG_871X("report_join_res(%d)\n", res);
  8258. rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
  8259. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8260. return;
  8261. }
  8262. void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
  8263. {
  8264. struct cmd_obj *pcmd_obj;
  8265. u8 *pevtcmd;
  8266. u32 cmdsz;
  8267. struct sta_info *psta;
  8268. int mac_id;
  8269. struct stadel_event *pdel_sta_evt;
  8270. struct C2HEvent_Header *pc2h_evt_hdr;
  8271. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8272. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8273. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8274. {
  8275. return;
  8276. }
  8277. cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
  8278. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8279. {
  8280. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8281. return;
  8282. }
  8283. _rtw_init_listhead(&pcmd_obj->list);
  8284. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8285. pcmd_obj->cmdsz = cmdsz;
  8286. pcmd_obj->parmbuf = pevtcmd;
  8287. pcmd_obj->rsp = NULL;
  8288. pcmd_obj->rspsz = 0;
  8289. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8290. pc2h_evt_hdr->len = sizeof(struct stadel_event);
  8291. pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
  8292. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8293. pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8294. _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
  8295. _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
  8296. psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
  8297. if(psta)
  8298. mac_id = (int)psta->mac_id;
  8299. else
  8300. mac_id = (-1);
  8301. pdel_sta_evt->mac_id = mac_id;
  8302. DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
  8303. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8304. return;
  8305. }
  8306. void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
  8307. {
  8308. struct cmd_obj *pcmd_obj;
  8309. u8 *pevtcmd;
  8310. u32 cmdsz;
  8311. struct stassoc_event *padd_sta_evt;
  8312. struct C2HEvent_Header *pc2h_evt_hdr;
  8313. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8314. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8315. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8316. {
  8317. return;
  8318. }
  8319. cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
  8320. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8321. {
  8322. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8323. return;
  8324. }
  8325. _rtw_init_listhead(&pcmd_obj->list);
  8326. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8327. pcmd_obj->cmdsz = cmdsz;
  8328. pcmd_obj->parmbuf = pevtcmd;
  8329. pcmd_obj->rsp = NULL;
  8330. pcmd_obj->rspsz = 0;
  8331. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8332. pc2h_evt_hdr->len = sizeof(struct stassoc_event);
  8333. pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
  8334. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8335. padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8336. _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
  8337. padd_sta_evt->cam_id = cam_idx;
  8338. DBG_871X("report_add_sta_event: add STA\n");
  8339. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8340. return;
  8341. }
  8342. /****************************************************************************
  8343. Following are the event callback functions
  8344. *****************************************************************************/
  8345. //for sta/adhoc mode
  8346. void update_sta_info(_adapter *padapter, struct sta_info *psta)
  8347. {
  8348. _irqL irqL;
  8349. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  8350. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8351. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8352. //ERP
  8353. VCS_update(padapter, psta);
  8354. #ifdef CONFIG_80211N_HT
  8355. //HT
  8356. if(pmlmepriv->htpriv.ht_option)
  8357. {
  8358. psta->htpriv.ht_option = _TRUE;
  8359. psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
  8360. if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
  8361. psta->htpriv.sgi = _TRUE;
  8362. psta->qos_option = _TRUE;
  8363. }
  8364. else
  8365. #endif //CONFIG_80211N_HT
  8366. {
  8367. #ifdef CONFIG_80211N_HT
  8368. psta->htpriv.ht_option = _FALSE;
  8369. psta->htpriv.ampdu_enable = _FALSE;
  8370. psta->htpriv.sgi = _FALSE;
  8371. #endif //CONFIG_80211N_HT
  8372. psta->qos_option = _FALSE;
  8373. }
  8374. #ifdef CONFIG_80211N_HT
  8375. psta->htpriv.bwmode = pmlmeext->cur_bwmode;
  8376. psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
  8377. psta->htpriv.agg_enable_bitmap = 0x0;//reset
  8378. psta->htpriv.candidate_tid_bitmap = 0x0;//reset
  8379. #endif //CONFIG_80211N_HT
  8380. //QoS
  8381. if(pmlmepriv->qospriv.qos_option)
  8382. psta->qos_option = _TRUE;
  8383. #ifdef CONFIG_80211AC_VHT
  8384. if (pmlmepriv->vhtpriv.bwmode < CHANNEL_WIDTH_80)
  8385. pmlmepriv->vhtpriv.sgi = psta->htpriv.sgi;
  8386. _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
  8387. #endif //CONFIG_80211AC_VHT
  8388. _enter_critical_bh(&psta->lock, &irqL);
  8389. psta->state = _FW_LINKED;
  8390. _exit_critical_bh(&psta->lock, &irqL);
  8391. }
  8392. void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
  8393. {
  8394. struct sta_info *psta, *psta_bmc;
  8395. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8396. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8397. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  8398. struct sta_priv *pstapriv = &padapter->stapriv;
  8399. u8 join_type;
  8400. u16 media_status;
  8401. if(join_res < 0)
  8402. {
  8403. join_type = 1;
  8404. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8405. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  8406. goto exit_mlmeext_joinbss_event_callback;
  8407. }
  8408. if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  8409. {
  8410. //for bc/mc
  8411. psta_bmc = rtw_get_bcmc_stainfo(padapter);
  8412. if(psta_bmc)
  8413. {
  8414. pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
  8415. update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
  8416. Update_RA_Entry(padapter, psta_bmc);
  8417. }
  8418. }
  8419. //turn on dynamic functions
  8420. Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
  8421. // update IOT-releated issue
  8422. update_IOT_info(padapter);
  8423. rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
  8424. //BCN interval
  8425. rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
  8426. //udpate capability
  8427. update_capinfo(padapter, pmlmeinfo->capability);
  8428. //WMM, Update EDCA param
  8429. WMMOnAssocRsp(padapter);
  8430. //HT
  8431. HTOnAssocRsp(padapter);
  8432. #ifdef CONFIG_80211AC_VHT
  8433. //VHT
  8434. VHTOnAssocRsp(padapter);
  8435. #endif
  8436. #ifndef CONFIG_CONCURRENT_MODE
  8437. // Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined.
  8438. //Set cur_channel&cur_bwmode&cur_ch_offset
  8439. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  8440. #endif
  8441. psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
  8442. if (psta) //only for infra. mode
  8443. {
  8444. pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
  8445. //DBG_871X("set_sta_rate\n");
  8446. psta->wireless_mode = pmlmeext->cur_wireless_mode;
  8447. //set per sta rate after updating HT cap.
  8448. set_sta_rate(padapter, psta);
  8449. #if (RATE_ADAPTIVE_SUPPORT==1) //for 88E RA
  8450. rtw_hal_set_hwreg(padapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&psta->mac_id);
  8451. #endif
  8452. media_status = (psta->mac_id<<8)|1; // MACID|OPMODE: 1 means connect
  8453. rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
  8454. }
  8455. join_type = 2;
  8456. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8457. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  8458. {
  8459. // correcting TSF
  8460. correct_TSF(padapter, pmlmeext);
  8461. //set_link_timer(pmlmeext, DISCONNECT_TO);
  8462. }
  8463. #ifdef CONFIG_LPS
  8464. #ifdef CONFIG_CONCURRENT_MODE
  8465. if(padapter->iface_type == IFACE_PORT0)
  8466. #endif
  8467. rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
  8468. #endif
  8469. exit_mlmeext_joinbss_event_callback:
  8470. #ifdef CONFIG_DUALMAC_CONCURRENT
  8471. dc_handle_join_done(padapter, join_res);
  8472. #endif
  8473. #ifdef CONFIG_CONCURRENT_MODE
  8474. concurrent_chk_joinbss_done(padapter, join_res);
  8475. #endif
  8476. DBG_871X("=>%s\n", __FUNCTION__);
  8477. }
  8478. //currently only adhoc mode will go here
  8479. void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
  8480. {
  8481. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  8482. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8483. u8 join_type;
  8484. DBG_871X("%s\n", __FUNCTION__);
  8485. if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  8486. {
  8487. if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
  8488. {
  8489. //nothing to do
  8490. }
  8491. else//adhoc client
  8492. {
  8493. //update TSF Value
  8494. //update_TSF(pmlmeext, pframe, len);
  8495. // correcting TSF
  8496. correct_TSF(padapter, pmlmeext);
  8497. //start beacon
  8498. if(send_beacon(padapter)==_FAIL)
  8499. {
  8500. pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
  8501. pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
  8502. return;
  8503. }
  8504. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  8505. }
  8506. join_type = 2;
  8507. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8508. }
  8509. pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
  8510. //rate radaptive
  8511. Update_RA_Entry(padapter, psta);
  8512. //update adhoc sta_info
  8513. update_sta_info(padapter, psta);
  8514. }
  8515. void mlmeext_sta_del_event_callback(_adapter *padapter)
  8516. {
  8517. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8518. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8519. if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
  8520. {
  8521. //set_opmode_cmd(padapter, infra_client_with_mlme);
  8522. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  8523. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  8524. #ifdef CONFIG_DUALMAC_CONCURRENT
  8525. dc_set_channel_bwmode_disconnect(padapter);
  8526. #else
  8527. #ifdef CONFIG_CONCURRENT_MODE
  8528. if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
  8529. {
  8530. #endif //CONFIG_CONCURRENT_MODE
  8531. //switch to the 20M Hz mode after disconnect
  8532. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  8533. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  8534. //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
  8535. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  8536. #ifdef CONFIG_CONCURRENT_MODE
  8537. }
  8538. #endif //CONFIG_CONCURRENT_MODE
  8539. #endif //CONFIG_DUALMAC_CONCURRENT
  8540. flush_all_cam_entry(padapter);
  8541. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8542. //set MSR to no link state -> infra. mode
  8543. Set_MSR(padapter, _HW_STATE_STATION_);
  8544. _cancel_timer_ex(&pmlmeext->link_timer);
  8545. }
  8546. }
  8547. /****************************************************************************
  8548. Following are the functions for the timer handlers
  8549. *****************************************************************************/
  8550. void _linked_info_dump(_adapter *padapter);
  8551. void _linked_info_dump(_adapter *padapter)
  8552. {
  8553. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8554. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8555. u8 mac_id;
  8556. int UndecoratedSmoothedPWDB;
  8557. #if 0
  8558. DBG_871X("============ linked status check ===================\n");
  8559. DBG_871X("pathA Rx SNRdb:%d, pathB Rx SNRdb:%d\n",padapter->recvpriv.RxSNRdB[0], padapter->recvpriv.RxSNRdB[1]);
  8560. DBG_871X("pathA Rx PWDB:%d\n",padapter->recvpriv.rxpwdb);
  8561. rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
  8562. DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
  8563. DBG_871X("Rx RSSI:%d\n",padapter->recvpriv.rssi);
  8564. DBG_871X("Rx Signal_strength:%d\n",padapter->recvpriv.signal_strength);
  8565. DBG_871X("Rx Signal_qual:%d \n",padapter->recvpriv.signal_qual);
  8566. if ( check_fwstate( &padapter->mlmepriv, _FW_LINKED ) )
  8567. {
  8568. DBG_871X("bw mode: %d, channel: %d\n", padapter->mlmeextpriv.cur_bwmode, padapter->mlmeextpriv.cur_channel );
  8569. DBG_871X("received bytes = %d\n", (u32) (padapter->recvpriv.rx_bytes - padapter->recvpriv.last_rx_bytes ) );
  8570. }
  8571. DBG_871X("============ linked status check ===================\n");
  8572. DBG_871X("============ RX GAIN / FALSE ALARM ===================\n");
  8573. DBG_871X(" DIG PATH-A(0x%02x), PATH-B(0x%02x)\n",rtw_read8(padapter,0xc50),rtw_read8(padapter,0xc58));
  8574. DBG_871X(" OFDM -Alarm DA2(0x%04x),DA4(0x%04x),DA6(0x%04x),DA8(0x%04x)\n",
  8575. rtw_read16(padapter,0xDA2),rtw_read16(padapter,0xDA4),rtw_read16(padapter,0xDA6),rtw_read16(padapter,0xDA8));
  8576. DBG_871X(" CCK -Alarm A5B(0x%02x),A5C(0x%02x)\n",rtw_read8(padapter,0xA5B),rtw_read8(padapter,0xA5C));
  8577. #endif
  8578. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  8579. {
  8580. mac_id=0;
  8581. }
  8582. else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
  8583. {
  8584. mac_id=2;
  8585. }
  8586. if(padapter->bLinkInfoDump){
  8587. DBG_871X("\n============ linked status check ===================\n");
  8588. rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
  8589. DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
  8590. }
  8591. //============ tx info ============
  8592. rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
  8593. //============ rx info ============
  8594. rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP,&mac_id);
  8595. }
  8596. u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
  8597. {
  8598. u8 ret = _FALSE;
  8599. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8600. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8601. #ifdef DBG_EXPIRATION_CHK
  8602. DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
  8603. /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
  8604. ", retry:%u\n"
  8605. , FUNC_ADPT_ARG(padapter)
  8606. , STA_RX_PKTS_DIFF_ARG(psta)
  8607. , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
  8608. , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
  8609. /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
  8610. , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
  8611. , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
  8612. , pmlmeinfo->bcn_interval*/
  8613. , pmlmeext->retry
  8614. );
  8615. DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
  8616. , padapter->xmitpriv.tx_pkts
  8617. , pmlmeinfo->link_count
  8618. );
  8619. #endif
  8620. if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
  8621. && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
  8622. && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
  8623. )
  8624. {
  8625. ret = _FALSE;
  8626. }
  8627. else
  8628. {
  8629. ret = _TRUE;
  8630. }
  8631. sta_update_last_rx_pkts(psta);
  8632. return ret;
  8633. }
  8634. void linked_status_chk(_adapter *padapter)
  8635. {
  8636. u32 i;
  8637. struct sta_info *psta;
  8638. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  8639. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8640. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8641. struct sta_priv *pstapriv = &padapter->stapriv;
  8642. _linked_info_dump(padapter);
  8643. #ifdef DBG_CONFIG_ERROR_DETECT
  8644. rtw_hal_sreset_linked_status_check(padapter);
  8645. #endif
  8646. if (is_client_associated_to_ap(padapter))
  8647. {
  8648. //linked infrastructure client mode
  8649. int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
  8650. int rx_chk_limit;
  8651. #if defined(DBG_ROAMING_TEST)
  8652. rx_chk_limit = 1;
  8653. #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
  8654. rx_chk_limit = 4;
  8655. #else
  8656. rx_chk_limit = 8;
  8657. #endif
  8658. #ifdef CONFIG_INTEL_WIDI
  8659. if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
  8660. rx_chk_limit = 1;
  8661. #endif
  8662. if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  8663. {
  8664. bool is_p2p_enable = _FALSE;
  8665. #ifdef CONFIG_P2P
  8666. is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
  8667. #endif
  8668. if (chk_ap_is_alive(padapter, psta) == _FALSE)
  8669. rx_chk = _FAIL;
  8670. if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
  8671. tx_chk = _FAIL;
  8672. #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
  8673. if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
  8674. u8 backup_oper_channel=0;
  8675. /* switch to correct channel of current network before issue keep-alive frames */
  8676. if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
  8677. backup_oper_channel = rtw_get_oper_ch(padapter);
  8678. SelectChannel(padapter, pmlmeext->cur_channel);
  8679. }
  8680. if (rx_chk != _SUCCESS)
  8681. issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
  8682. if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
  8683. tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
  8684. /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
  8685. if (tx_chk == _SUCCESS && !is_p2p_enable)
  8686. rx_chk = _SUCCESS;
  8687. }
  8688. /* back to the original operation channel */
  8689. if(backup_oper_channel>0)
  8690. SelectChannel(padapter, backup_oper_channel);
  8691. }
  8692. else
  8693. #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
  8694. {
  8695. if (rx_chk != _SUCCESS) {
  8696. if (pmlmeext->retry == 0) {
  8697. #ifdef DBG_EXPIRATION_CHK
  8698. DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
  8699. #endif
  8700. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8701. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8702. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8703. }
  8704. }
  8705. if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
  8706. #ifdef DBG_EXPIRATION_CHK
  8707. DBG_871X("%s issue_nulldata 0\n", __FUNCTION__);
  8708. #endif
  8709. tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
  8710. }
  8711. }
  8712. if (rx_chk == _FAIL) {
  8713. pmlmeext->retry++;
  8714. if (pmlmeext->retry > rx_chk_limit) {
  8715. DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
  8716. FUNC_ADPT_ARG(padapter));
  8717. receive_disconnect(padapter, pmlmeinfo->network.MacAddress
  8718. , WLAN_REASON_EXPIRATION_CHK);
  8719. return;
  8720. }
  8721. } else {
  8722. pmlmeext->retry = 0;
  8723. }
  8724. if (tx_chk == _FAIL) {
  8725. pmlmeinfo->link_count &= 0xf;
  8726. } else {
  8727. pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
  8728. pmlmeinfo->link_count = 0;
  8729. }
  8730. } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
  8731. }
  8732. else if (is_client_associated_to_ibss(padapter))
  8733. {
  8734. //linked IBSS mode
  8735. //for each assoc list entry to check the rx pkt counter
  8736. for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
  8737. {
  8738. if (pmlmeinfo->FW_sta_info[i].status == 1)
  8739. {
  8740. psta = pmlmeinfo->FW_sta_info[i].psta;
  8741. if(NULL==psta) continue;
  8742. if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
  8743. {
  8744. if(pmlmeinfo->FW_sta_info[i].retry<3)
  8745. {
  8746. pmlmeinfo->FW_sta_info[i].retry++;
  8747. }
  8748. else
  8749. {
  8750. pmlmeinfo->FW_sta_info[i].retry = 0;
  8751. pmlmeinfo->FW_sta_info[i].status = 0;
  8752. report_del_sta_event(padapter, psta->hwaddr
  8753. , 65535// indicate disconnect caused by no rx
  8754. );
  8755. }
  8756. }
  8757. else
  8758. {
  8759. pmlmeinfo->FW_sta_info[i].retry = 0;
  8760. pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
  8761. }
  8762. }
  8763. }
  8764. //set_link_timer(pmlmeext, DISCONNECT_TO);
  8765. }
  8766. }
  8767. void survey_timer_hdl(_adapter *padapter)
  8768. {
  8769. struct cmd_obj *ph2c;
  8770. struct sitesurvey_parm *psurveyPara;
  8771. struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
  8772. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8773. #ifdef CONFIG_P2P
  8774. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  8775. #endif
  8776. //DBG_871X("marc: survey timer\n");
  8777. //issue rtw_sitesurvey_cmd
  8778. if (pmlmeext->sitesurvey_res.state > SCAN_START)
  8779. {
  8780. if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  8781. {
  8782. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  8783. if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH )
  8784. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  8785. pmlmeext->sitesurvey_res.channel_idx++;
  8786. }
  8787. if(pmlmeext->scan_abort == _TRUE)
  8788. {
  8789. #ifdef CONFIG_P2P
  8790. if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
  8791. {
  8792. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
  8793. pmlmeext->sitesurvey_res.channel_idx = 3;
  8794. DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
  8795. , pmlmeext->sitesurvey_res.channel_idx
  8796. , pwdinfo->find_phase_state_exchange_cnt
  8797. );
  8798. }
  8799. else
  8800. #endif
  8801. {
  8802. pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
  8803. DBG_871X("%s idx:%d\n", __FUNCTION__
  8804. , pmlmeext->sitesurvey_res.channel_idx
  8805. );
  8806. }
  8807. pmlmeext->scan_abort = _FALSE;//reset
  8808. }
  8809. if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8810. {
  8811. goto exit_survey_timer_hdl;
  8812. }
  8813. if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL)
  8814. {
  8815. rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
  8816. goto exit_survey_timer_hdl;
  8817. }
  8818. init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
  8819. rtw_enqueue_cmd(pcmdpriv, ph2c);
  8820. }
  8821. exit_survey_timer_hdl:
  8822. return;
  8823. }
  8824. void link_timer_hdl(_adapter *padapter)
  8825. {
  8826. //static unsigned int rx_pkt = 0;
  8827. //static u64 tx_cnt = 0;
  8828. //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  8829. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8830. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8831. //struct sta_priv *pstapriv = &padapter->stapriv;
  8832. if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
  8833. {
  8834. DBG_871X("link_timer_hdl:no beacon while connecting\n");
  8835. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8836. report_join_res(padapter, -3);
  8837. }
  8838. else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
  8839. {
  8840. //re-auth timer
  8841. if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
  8842. {
  8843. //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
  8844. //{
  8845. pmlmeinfo->state = 0;
  8846. report_join_res(padapter, -1);
  8847. return;
  8848. //}
  8849. //else
  8850. //{
  8851. // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
  8852. // pmlmeinfo->reauth_count = 0;
  8853. //}
  8854. }
  8855. DBG_871X("link_timer_hdl: auth timeout and try again\n");
  8856. pmlmeinfo->auth_seq = 1;
  8857. issue_auth(padapter, NULL, 0);
  8858. set_link_timer(pmlmeext, REAUTH_TO);
  8859. }
  8860. else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
  8861. {
  8862. //re-assoc timer
  8863. if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
  8864. {
  8865. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8866. report_join_res(padapter, -2);
  8867. return;
  8868. }
  8869. DBG_871X("link_timer_hdl: assoc timeout and try again\n");
  8870. issue_assocreq(padapter);
  8871. set_link_timer(pmlmeext, REASSOC_TO);
  8872. }
  8873. #if 0
  8874. else if (is_client_associated_to_ap(padapter))
  8875. {
  8876. //linked infrastructure client mode
  8877. if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  8878. {
  8879. /*to monitor whether the AP is alive or not*/
  8880. if (rx_pkt == psta->sta_stats.rx_pkts)
  8881. {
  8882. receive_disconnect(padapter, pmlmeinfo->network.MacAddress);
  8883. return;
  8884. }
  8885. else
  8886. {
  8887. rx_pkt = psta->sta_stats.rx_pkts;
  8888. set_link_timer(pmlmeext, DISCONNECT_TO);
  8889. }
  8890. //update the EDCA paramter according to the Tx/RX mode
  8891. update_EDCA_param(padapter);
  8892. /*to send the AP a nulldata if no frame is xmitted in order to keep alive*/
  8893. if (pmlmeinfo->link_count++ == 0)
  8894. {
  8895. tx_cnt = pxmitpriv->tx_pkts;
  8896. }
  8897. else if ((pmlmeinfo->link_count & 0xf) == 0)
  8898. {
  8899. if (tx_cnt == pxmitpriv->tx_pkts)
  8900. {
  8901. issue_nulldata(padapter, NULL, 0, 0, 0);
  8902. }
  8903. tx_cnt = pxmitpriv->tx_pkts;
  8904. }
  8905. } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
  8906. }
  8907. else if (is_client_associated_to_ibss(padapter))
  8908. {
  8909. //linked IBSS mode
  8910. //for each assoc list entry to check the rx pkt counter
  8911. for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
  8912. {
  8913. if (pmlmeinfo->FW_sta_info[i].status == 1)
  8914. {
  8915. psta = pmlmeinfo->FW_sta_info[i].psta;
  8916. if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts)
  8917. {
  8918. pmlmeinfo->FW_sta_info[i].status = 0;
  8919. report_del_sta_event(padapter, psta->hwaddr);
  8920. }
  8921. else
  8922. {
  8923. pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts;
  8924. }
  8925. }
  8926. }
  8927. set_link_timer(pmlmeext, DISCONNECT_TO);
  8928. }
  8929. #endif
  8930. return;
  8931. }
  8932. void addba_timer_hdl(struct sta_info *psta)
  8933. {
  8934. #ifdef CONFIG_80211N_HT
  8935. struct ht_priv *phtpriv;
  8936. if(!psta)
  8937. return;
  8938. phtpriv = &psta->htpriv;
  8939. if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
  8940. {
  8941. if(phtpriv->candidate_tid_bitmap)
  8942. phtpriv->candidate_tid_bitmap=0x0;
  8943. }
  8944. #endif //CONFIG_80211N_HT
  8945. }
  8946. u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
  8947. {
  8948. return H2C_SUCCESS;
  8949. }
  8950. #ifdef CONFIG_AUTO_AP_MODE
  8951. void rtw_start_auto_ap(_adapter *adapter)
  8952. {
  8953. DBG_871X("%s\n", __FUNCTION__);
  8954. rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
  8955. rtw_setopmode_cmd(adapter, Ndis802_11APMode);
  8956. }
  8957. static int rtw_auto_ap_start_beacon(_adapter *adapter)
  8958. {
  8959. int ret=0;
  8960. u8 *pbuf = NULL;
  8961. uint len;
  8962. u8 supportRate[16];
  8963. int sz = 0, rateLen;
  8964. u8 * ie;
  8965. u8 wireless_mode, oper_channel;
  8966. u8 ssid[3] = {0}; //hidden ssid
  8967. u32 ssid_len = sizeof(ssid);
  8968. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  8969. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
  8970. return -EINVAL;
  8971. len = 128;
  8972. pbuf = rtw_zmalloc(len);
  8973. if(!pbuf)
  8974. return -ENOMEM;
  8975. //generate beacon
  8976. ie = pbuf;
  8977. //timestamp will be inserted by hardware
  8978. sz += 8;
  8979. ie += sz;
  8980. //beacon interval : 2bytes
  8981. *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
  8982. sz += 2;
  8983. ie += 2;
  8984. //capability info
  8985. *(u16*)ie = 0;
  8986. *(u16*)ie |= cpu_to_le16(cap_ESS);
  8987. *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
  8988. //*(u16*)ie |= cpu_to_le16(cap_Privacy);
  8989. sz += 2;
  8990. ie += 2;
  8991. //SSID
  8992. ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
  8993. //supported rates
  8994. wireless_mode = WIRELESS_11BG_24N;
  8995. rtw_set_supported_rate(supportRate, wireless_mode) ;
  8996. rateLen = rtw_get_rateset_len(supportRate);
  8997. if (rateLen > 8)
  8998. {
  8999. ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
  9000. }
  9001. else
  9002. {
  9003. ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
  9004. }
  9005. //DS parameter set
  9006. if(check_buddy_fwstate(adapter, _FW_LINKED) &&
  9007. check_buddy_fwstate(adapter, WIFI_STATION_STATE))
  9008. {
  9009. PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
  9010. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9011. oper_channel = pbuddy_mlmeext->cur_channel;
  9012. }
  9013. else
  9014. {
  9015. oper_channel = adapter_to_dvobj(adapter)->oper_channel;
  9016. }
  9017. ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
  9018. //ext supported rates
  9019. if (rateLen > 8)
  9020. {
  9021. ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
  9022. }
  9023. DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
  9024. //lunch ap mode & start to issue beacon
  9025. if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
  9026. {
  9027. }
  9028. else
  9029. {
  9030. ret = -EINVAL;
  9031. }
  9032. rtw_mfree(pbuf, len);
  9033. return ret;
  9034. }
  9035. #endif//CONFIG_AUTO_AP_MODE
  9036. u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
  9037. {
  9038. u8 type;
  9039. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9040. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9041. struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
  9042. if(psetop->mode == Ndis802_11APMode)
  9043. {
  9044. pmlmeinfo->state = WIFI_FW_AP_STATE;
  9045. type = _HW_STATE_AP_;
  9046. #ifdef CONFIG_NATIVEAP_MLME
  9047. //start_ap_mode(padapter);
  9048. #endif
  9049. }
  9050. else if(psetop->mode == Ndis802_11Infrastructure)
  9051. {
  9052. pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
  9053. pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
  9054. type = _HW_STATE_STATION_;
  9055. }
  9056. else if(psetop->mode == Ndis802_11IBSS)
  9057. {
  9058. type = _HW_STATE_ADHOC_;
  9059. }
  9060. else
  9061. {
  9062. type = _HW_STATE_NOLINK_;
  9063. }
  9064. rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
  9065. //Set_NETYPE0_MSR(padapter, type);
  9066. #ifdef CONFIG_AUTO_AP_MODE
  9067. if(psetop->mode == Ndis802_11APMode)
  9068. rtw_auto_ap_start_beacon(padapter);
  9069. #endif
  9070. return H2C_SUCCESS;
  9071. }
  9072. u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
  9073. {
  9074. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9075. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9076. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9077. struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
  9078. //u32 initialgain;
  9079. if(pparm->network.InfrastructureMode == Ndis802_11APMode)
  9080. {
  9081. #ifdef CONFIG_AP_MODE
  9082. if(pmlmeinfo->state == WIFI_FW_AP_STATE)
  9083. {
  9084. //todo:
  9085. return H2C_SUCCESS;
  9086. }
  9087. #endif
  9088. }
  9089. //below is for ad-hoc master
  9090. if(pparm->network.InfrastructureMode == Ndis802_11IBSS)
  9091. {
  9092. rtw_joinbss_reset(padapter);
  9093. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9094. pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9095. pmlmeinfo->ERP_enable = 0;
  9096. pmlmeinfo->WMM_enable = 0;
  9097. pmlmeinfo->HT_enable = 0;
  9098. pmlmeinfo->HT_caps_enable = 0;
  9099. pmlmeinfo->HT_info_enable = 0;
  9100. pmlmeinfo->agg_enable_bitmap = 0;
  9101. pmlmeinfo->candidate_tid_bitmap = 0;
  9102. //disable dynamic functions, such as high power, DIG
  9103. Save_DM_Func_Flag(padapter);
  9104. Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9105. //config the initial gain under linking, need to write the BB registers
  9106. //initialgain = 0x1E;
  9107. //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9108. //cancel link timer
  9109. _cancel_timer_ex(&pmlmeext->link_timer);
  9110. //clear CAM
  9111. flush_all_cam_entry(padapter);
  9112. _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
  9113. pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
  9114. if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
  9115. return H2C_PARAMETERS_ERROR;
  9116. _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
  9117. start_create_ibss(padapter);
  9118. }
  9119. return H2C_SUCCESS;
  9120. }
  9121. u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
  9122. {
  9123. u8 join_type;
  9124. PNDIS_802_11_VARIABLE_IEs pIE;
  9125. struct registry_priv *pregpriv = &padapter->registrypriv;
  9126. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9127. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9128. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9129. #ifdef CONFIG_ANTENNA_DIVERSITY
  9130. struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
  9131. #endif //CONFIG_ANTENNA_DIVERSITY
  9132. u32 i;
  9133. u8 cbw40_enable=0;
  9134. //u32 initialgain;
  9135. //u32 acparm;
  9136. //check already connecting to AP or not
  9137. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  9138. {
  9139. if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
  9140. {
  9141. issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
  9142. }
  9143. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9144. //clear CAM
  9145. flush_all_cam_entry(padapter);
  9146. _cancel_timer_ex(&pmlmeext->link_timer);
  9147. //set MSR to nolink -> infra. mode
  9148. //Set_MSR(padapter, _HW_STATE_NOLINK_);
  9149. Set_MSR(padapter, _HW_STATE_STATION_);
  9150. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  9151. }
  9152. #ifdef CONFIG_ANTENNA_DIVERSITY
  9153. rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
  9154. #endif
  9155. #ifdef CONFIG_WAPI_SUPPORT
  9156. rtw_wapi_clear_all_cam_entry(padapter);
  9157. #endif
  9158. rtw_joinbss_reset(padapter);
  9159. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9160. pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9161. pmlmeinfo->ERP_enable = 0;
  9162. pmlmeinfo->WMM_enable = 0;
  9163. pmlmeinfo->HT_enable = 0;
  9164. pmlmeinfo->HT_caps_enable = 0;
  9165. pmlmeinfo->HT_info_enable = 0;
  9166. pmlmeinfo->agg_enable_bitmap = 0;
  9167. pmlmeinfo->candidate_tid_bitmap = 0;
  9168. pmlmeinfo->bwmode_updated = _FALSE;
  9169. //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
  9170. pmlmeinfo->VHT_enable = 0;
  9171. _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
  9172. pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
  9173. if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
  9174. return H2C_PARAMETERS_ERROR;
  9175. _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
  9176. //Check AP vendor to move rtw_joinbss_cmd()
  9177. //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
  9178. //sizeof(NDIS_802_11_FIXED_IEs)
  9179. for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;)
  9180. {
  9181. pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
  9182. switch (pIE->ElementID)
  9183. {
  9184. case _VENDOR_SPECIFIC_IE_://Get WMM IE.
  9185. if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
  9186. {
  9187. WMM_param_handler(padapter, pIE);
  9188. }
  9189. break;
  9190. case _HT_CAPABILITY_IE_: //Get HT Cap IE.
  9191. pmlmeinfo->HT_caps_enable = 1;
  9192. break;
  9193. case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
  9194. #ifdef CONFIG_80211N_HT
  9195. pmlmeinfo->HT_info_enable = 1;
  9196. //spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz
  9197. //#if !defined(CONFIG_CONCURRENT_MODE) && !defined(CONFIG_DUALMAC_CONCURRENT)
  9198. // if(pmlmeinfo->assoc_AP_vendor == ciscoAP)
  9199. //#endif
  9200. {
  9201. struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
  9202. if (pnetwork->Configuration.DSConfig > 14) {
  9203. if ((pregpriv->bw_mode & 0xf0) > CHANNEL_WIDTH_20)
  9204. cbw40_enable = 1;
  9205. } else {
  9206. if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
  9207. cbw40_enable = 1;
  9208. }
  9209. if ((cbw40_enable) && (pht_info->infos[0] & BIT(2)))
  9210. {
  9211. //switch to the 40M Hz mode according to the AP
  9212. pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  9213. switch (pht_info->infos[0] & 0x3)
  9214. {
  9215. case 1:
  9216. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  9217. break;
  9218. case 3:
  9219. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  9220. break;
  9221. default:
  9222. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9223. break;
  9224. }
  9225. DBG_871X("set HT ch/bw before connected\n");
  9226. }
  9227. }
  9228. #endif //CONFIG_80211N_HT
  9229. break;
  9230. #ifdef CONFIG_80211AC_VHT
  9231. case EID_VHTCapability://Get VHT Cap IE.
  9232. pmlmeinfo->VHT_enable = 1;
  9233. break;
  9234. case EID_VHTOperation://Get VHT Operation IE.
  9235. if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) {
  9236. if((GET_VHT_OPERATION_ELE_CHL_WIDTH(pIE->data) >= 1)
  9237. && ((pregpriv->bw_mode & 0xf0) >= CHANNEL_WIDTH_80)) {
  9238. pmlmeext->cur_bwmode = CHANNEL_WIDTH_80;
  9239. DBG_871X("VHT center ch = %d\n", GET_VHT_OPERATION_ELE_CENTER_FREQ1(pIE->data));
  9240. DBG_871X("set VHT ch/bw before connected\n");
  9241. }
  9242. }
  9243. break;
  9244. #endif
  9245. default:
  9246. break;
  9247. }
  9248. i += (pIE->Length + 2);
  9249. }
  9250. #if 0
  9251. if (padapter->registrypriv.wifi_spec) {
  9252. // for WiFi test, follow WMM test plan spec
  9253. acparm = 0x002F431C; // VO
  9254. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
  9255. acparm = 0x005E541C; // VI
  9256. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
  9257. acparm = 0x0000A525; // BE
  9258. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9259. acparm = 0x0000A549; // BK
  9260. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
  9261. // for WiFi test, mixed mode with intel STA under bg mode throughput issue
  9262. if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
  9263. acparm = 0x00004320;
  9264. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9265. }
  9266. }
  9267. else {
  9268. acparm = 0x002F3217; // VO
  9269. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
  9270. acparm = 0x005E4317; // VI
  9271. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
  9272. acparm = 0x00105320; // BE
  9273. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9274. acparm = 0x0000A444; // BK
  9275. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
  9276. }
  9277. #endif
  9278. //disable dynamic functions, such as high power, DIG
  9279. //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9280. //config the initial gain under linking, need to write the BB registers
  9281. //initialgain = 0x1E;
  9282. //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9283. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
  9284. join_type = 0;
  9285. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  9286. //cancel link timer
  9287. _cancel_timer_ex(&pmlmeext->link_timer);
  9288. start_clnt_join(padapter);
  9289. return H2C_SUCCESS;
  9290. }
  9291. u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
  9292. {
  9293. struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
  9294. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9295. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9296. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9297. u8 val8;
  9298. if (is_client_associated_to_ap(padapter))
  9299. {
  9300. issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
  9301. }
  9302. //set_opmode_cmd(padapter, infra_client_with_mlme);
  9303. //pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9304. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  9305. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  9306. if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
  9307. {
  9308. //Stop BCN
  9309. val8 = 0;
  9310. rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
  9311. }
  9312. //set MSR to no link state -> infra. mode
  9313. Set_MSR(padapter, _HW_STATE_STATION_);
  9314. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9315. #ifdef CONFIG_DUALMAC_CONCURRENT
  9316. dc_set_channel_bwmode_disconnect(padapter);
  9317. #else
  9318. #ifdef CONFIG_CONCURRENT_MODE
  9319. if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
  9320. {
  9321. #endif //CONFIG_CONCURRENT_MODE
  9322. //switch to the 20M Hz mode after disconnect
  9323. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9324. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9325. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9326. #ifdef CONFIG_CONCURRENT_MODE
  9327. }
  9328. #endif //CONFIG_CONCURRENT_MODE
  9329. #endif //CONFIG_DUALMAC_CONCURRENT
  9330. flush_all_cam_entry(padapter);
  9331. _cancel_timer_ex(&pmlmeext->link_timer);
  9332. rtw_free_uc_swdec_pending_queue(padapter);
  9333. return H2C_SUCCESS;
  9334. }
  9335. int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
  9336. u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
  9337. {
  9338. int i, j;
  9339. int scan_ch_num = 0;
  9340. int set_idx;
  9341. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9342. /* clear out first */
  9343. _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
  9344. /* acquire channels from in */
  9345. j = 0;
  9346. for (i=0;i<in_num;i++) {
  9347. if (0)
  9348. DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
  9349. if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
  9350. && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
  9351. )
  9352. {
  9353. _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
  9354. if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
  9355. out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
  9356. j++;
  9357. }
  9358. if(j>=out_num)
  9359. break;
  9360. }
  9361. /* if out is empty, use channel_set as default */
  9362. if(j == 0) {
  9363. for (i=0;i<pmlmeext->max_chan_nums;i++) {
  9364. out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
  9365. if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
  9366. out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
  9367. j++;
  9368. }
  9369. }
  9370. if (padapter->setband == GHZ_24) { // 2.4G
  9371. for (i=0; i < j ; i++) {
  9372. if (out[i].hw_value > 35)
  9373. _rtw_memset(&out[i], 0 , sizeof(struct rtw_ieee80211_channel));
  9374. else
  9375. scan_ch_num++;
  9376. }
  9377. j = scan_ch_num;
  9378. } else if (padapter->setband == GHZ_50) { // 5G
  9379. for (i=0; i < j ; i++) {
  9380. if (out[i].hw_value > 35) {
  9381. _rtw_memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
  9382. }
  9383. }
  9384. j = scan_ch_num;
  9385. } else
  9386. {}
  9387. return j;
  9388. }
  9389. u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
  9390. {
  9391. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9392. struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
  9393. u8 bdelayscan = _FALSE;
  9394. u8 val8;
  9395. u32 initialgain;
  9396. u32 i;
  9397. #ifdef CONFIG_P2P
  9398. struct wifidirect_info* pwdinfo = &padapter->wdinfo;
  9399. #endif
  9400. if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
  9401. {
  9402. #ifdef CONFIG_CONCURRENT_MODE
  9403. //for first time sitesurvey_cmd
  9404. rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  9405. #endif //CONFIG_CONCURRENT_MODE
  9406. pmlmeext->sitesurvey_res.state = SCAN_START;
  9407. pmlmeext->sitesurvey_res.bss_cnt = 0;
  9408. pmlmeext->sitesurvey_res.channel_idx = 0;
  9409. for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
  9410. if(pparm->ssid[i].SsidLength) {
  9411. _rtw_memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
  9412. pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength;
  9413. } else {
  9414. pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0;
  9415. }
  9416. }
  9417. pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
  9418. , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
  9419. , pparm->ch, pparm->ch_num
  9420. );
  9421. pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
  9422. #ifdef CONFIG_DUALMAC_CONCURRENT
  9423. bdelayscan = dc_handle_site_survey(padapter);
  9424. #endif
  9425. //issue null data if associating to the AP
  9426. if (is_client_associated_to_ap(padapter) == _TRUE)
  9427. {
  9428. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  9429. issue_nulldata(padapter, NULL, 1, 3, 500);
  9430. #ifdef CONFIG_CONCURRENT_MODE
  9431. if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  9432. {
  9433. DBG_871X("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n");
  9434. issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
  9435. }
  9436. #endif
  9437. bdelayscan = _TRUE;
  9438. }
  9439. #ifdef CONFIG_CONCURRENT_MODE
  9440. else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  9441. {
  9442. #ifdef CONFIG_TDLS
  9443. if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1)
  9444. {
  9445. issue_tunneled_probe_req(padapter->pbuddy_adapter);
  9446. }
  9447. #endif //CONFIG_TDLS
  9448. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  9449. issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
  9450. bdelayscan = _TRUE;
  9451. }
  9452. #endif
  9453. if(bdelayscan)
  9454. {
  9455. //delay 50ms to protect nulldata(1).
  9456. set_survey_timer(pmlmeext, 50);
  9457. return H2C_SUCCESS;
  9458. }
  9459. }
  9460. if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL))
  9461. {
  9462. #ifdef CONFIG_FIND_BEST_CHANNEL
  9463. #if 0
  9464. for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
  9465. pmlmeext->channel_set[i].rx_count = 0;
  9466. }
  9467. #endif
  9468. #endif /* CONFIG_FIND_BEST_CHANNEL */
  9469. //disable dynamic functions, such as high power, DIG
  9470. Save_DM_Func_Flag(padapter);
  9471. Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9472. //config the initial gain under scaning, need to write the BB registers
  9473. #ifdef CONFIG_P2P
  9474. #ifdef CONFIG_IOCTL_CFG80211
  9475. if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211 )
  9476. initialgain = 0x30;
  9477. else
  9478. #endif //CONFIG_IOCTL_CFG80211
  9479. if ( !rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
  9480. initialgain = 0x28;
  9481. else
  9482. #endif //CONFIG_P2P
  9483. initialgain = 0x1e;
  9484. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9485. //set MSR to no link state
  9486. Set_MSR(padapter, _HW_STATE_NOLINK_);
  9487. val8 = 1; //under site survey
  9488. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  9489. pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
  9490. }
  9491. site_survey(padapter);
  9492. return H2C_SUCCESS;
  9493. }
  9494. u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
  9495. {
  9496. struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
  9497. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9498. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9499. if (pparm->mode < 4)
  9500. {
  9501. pmlmeinfo->auth_algo = pparm->mode;
  9502. }
  9503. return H2C_SUCCESS;
  9504. }
  9505. u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
  9506. {
  9507. unsigned short ctrl;
  9508. struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
  9509. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9510. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9511. unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  9512. //main tx key for wep.
  9513. if(pparm->set_tx)
  9514. pmlmeinfo->key_index = pparm->keyid;
  9515. //write cam
  9516. ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
  9517. DBG_871X_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
  9518. "keyid:%d\n", pparm->algorithm, pparm->keyid);
  9519. write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
  9520. //allow multicast packets to driver
  9521. padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
  9522. return H2C_SUCCESS;
  9523. }
  9524. u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
  9525. {
  9526. u16 ctrl=0;
  9527. u8 cam_id = 0;//cam_entry
  9528. u8 ret = H2C_SUCCESS;
  9529. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9530. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9531. struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
  9532. struct sta_priv *pstapriv = &padapter->stapriv;
  9533. struct sta_info *psta;
  9534. #ifdef CONFIG_TDLS
  9535. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  9536. #endif //CONFIG_TDLS
  9537. //cam_entry:
  9538. //0~3 for default key
  9539. //for concurrent mode (ap+sta, sta+sta):
  9540. //default key is disable, using sw encrypt/decrypt
  9541. //camid 0, 1, 2, 3 is default entry for default key/group key
  9542. //macid = 1 is for bc/mc stainfo, no mapping to camid
  9543. //macid = 0 mapping to camid 4
  9544. //for macid >=2, camid = macid+3;
  9545. if(pparm->algorithm == _NO_PRIVACY_) // clear cam entry
  9546. {
  9547. clear_cam_entry(padapter, pparm->id);
  9548. ret = H2C_SUCCESS;
  9549. goto exit_set_stakey_hdl;
  9550. }
  9551. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  9552. {
  9553. psta = rtw_get_stainfo(pstapriv, pparm->addr);
  9554. if(psta)
  9555. {
  9556. ctrl = (BIT(15) | ((pparm->algorithm) << 2));
  9557. DBG_871X("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
  9558. if((psta->mac_id == 1) || (psta->mac_id>(NUM_STA-4)))
  9559. {
  9560. DBG_871X("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
  9561. ret = H2C_REJECTED;
  9562. goto exit_set_stakey_hdl;
  9563. }
  9564. cam_id = (u8)rtw_get_camid(psta->mac_id);//0~3 for default key, cmd_id=macid + 3;
  9565. DBG_871X("Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
  9566. pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
  9567. pparm->addr[5], cam_id);
  9568. write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
  9569. ret = H2C_SUCCESS_RSP;
  9570. goto exit_set_stakey_hdl;
  9571. }
  9572. else
  9573. {
  9574. DBG_871X("r871x_set_stakey_hdl(): sta has been free\n");
  9575. ret = H2C_REJECTED;
  9576. goto exit_set_stakey_hdl;
  9577. }
  9578. }
  9579. //below for sta mode
  9580. if((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)))
  9581. cam_id = (u8)rtw_get_camid(psta->mac_id);
  9582. else
  9583. cam_id = 4;
  9584. ctrl = BIT(15) | ((pparm->algorithm) << 2);
  9585. #ifdef CONFIG_TDLS
  9586. if(ptdlsinfo->clear_cam!=0){
  9587. clear_cam_entry(padapter, ptdlsinfo->clear_cam);
  9588. ptdlsinfo->clear_cam=0;
  9589. ret = H2C_SUCCESS;
  9590. goto exit_set_stakey_hdl;
  9591. }
  9592. psta = rtw_get_stainfo(pstapriv, pparm->addr);//Get TDLS Peer STA
  9593. if( psta->tdls_sta_state&TDLS_LINKED_STATE ){
  9594. write_cam(padapter, psta->mac_id, ctrl, pparm->addr, pparm->key);
  9595. }
  9596. else
  9597. #endif //CONFIG_TDLS
  9598. write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
  9599. pmlmeinfo->enc_algo = pparm->algorithm;
  9600. exit_set_stakey_hdl:
  9601. DBG_871X_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
  9602. pparm->algorithm, cam_id);
  9603. return ret;
  9604. }
  9605. u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
  9606. {
  9607. struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
  9608. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9609. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9610. struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
  9611. if(!psta)
  9612. return H2C_SUCCESS;
  9613. #ifdef CONFIG_80211N_HT
  9614. if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
  9615. ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
  9616. {
  9617. //pmlmeinfo->ADDBA_retry_count = 0;
  9618. //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
  9619. //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
  9620. issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
  9621. //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
  9622. _set_timer(&psta->addba_retry_timer, ADDBA_TO);
  9623. }
  9624. #ifdef CONFIG_TDLS
  9625. else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
  9626. (psta->htpriv.ht_option==_TRUE) &&
  9627. (psta->htpriv.ampdu_enable==_TRUE) )
  9628. {
  9629. issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
  9630. //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
  9631. _set_timer(&psta->addba_retry_timer, ADDBA_TO);
  9632. }
  9633. #endif //CONFIG
  9634. else
  9635. {
  9636. psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
  9637. }
  9638. #endif //CONFIG_80211N_HT
  9639. return H2C_SUCCESS;
  9640. }
  9641. u8 set_tx_beacon_cmd(_adapter* padapter)
  9642. {
  9643. struct cmd_obj *ph2c;
  9644. struct Tx_Beacon_param *ptxBeacon_parm;
  9645. struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
  9646. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9647. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9648. u8 res = _SUCCESS;
  9649. int len_diff = 0;
  9650. _func_enter_;
  9651. if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  9652. {
  9653. res= _FAIL;
  9654. goto exit;
  9655. }
  9656. if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
  9657. {
  9658. rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
  9659. res= _FAIL;
  9660. goto exit;
  9661. }
  9662. _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
  9663. len_diff = update_hidden_ssid(
  9664. ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
  9665. , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
  9666. , pmlmeinfo->hidden_ssid_mode
  9667. );
  9668. ptxBeacon_parm->network.IELength += len_diff;
  9669. init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
  9670. res = rtw_enqueue_cmd(pcmdpriv, ph2c);
  9671. exit:
  9672. _func_exit_;
  9673. return res;
  9674. }
  9675. u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
  9676. {
  9677. u8 evt_code, evt_seq;
  9678. u16 evt_sz;
  9679. uint *peventbuf;
  9680. void (*event_callback)(_adapter *dev, u8 *pbuf);
  9681. struct evt_priv *pevt_priv = &(padapter->evtpriv);
  9682. peventbuf = (uint*)pbuf;
  9683. evt_sz = (u16)(*peventbuf&0xffff);
  9684. evt_seq = (u8)((*peventbuf>>24)&0x7f);
  9685. evt_code = (u8)((*peventbuf>>16)&0xff);
  9686. #ifdef CHECK_EVENT_SEQ
  9687. // checking event sequence...
  9688. if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
  9689. {
  9690. RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)));
  9691. pevt_priv->event_seq = (evt_seq+1)&0x7f;
  9692. goto _abort_event_;
  9693. }
  9694. #endif
  9695. // checking if event code is valid
  9696. if (evt_code >= MAX_C2HEVT)
  9697. {
  9698. RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
  9699. goto _abort_event_;
  9700. }
  9701. // checking if event size match the event parm size
  9702. if ((wlanevents[evt_code].parmsize != 0) &&
  9703. (wlanevents[evt_code].parmsize != evt_sz))
  9704. {
  9705. RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
  9706. evt_code, wlanevents[evt_code].parmsize, evt_sz));
  9707. goto _abort_event_;
  9708. }
  9709. ATOMIC_INC(&pevt_priv->event_seq);
  9710. peventbuf += 2;
  9711. if(peventbuf)
  9712. {
  9713. event_callback = wlanevents[evt_code].event_callback;
  9714. event_callback(padapter, (u8*)peventbuf);
  9715. pevt_priv->evt_done_cnt++;
  9716. }
  9717. _abort_event_:
  9718. return H2C_SUCCESS;
  9719. }
  9720. u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
  9721. {
  9722. if(!pbuf)
  9723. return H2C_PARAMETERS_ERROR;
  9724. return H2C_SUCCESS;
  9725. }
  9726. u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
  9727. {
  9728. if(send_beacon(padapter)==_FAIL)
  9729. {
  9730. DBG_871X("issue_beacon, fail!\n");
  9731. return H2C_PARAMETERS_ERROR;
  9732. }
  9733. #ifdef CONFIG_AP_MODE
  9734. else //tx bc/mc frames after update TIM
  9735. {
  9736. _irqL irqL;
  9737. struct sta_info *psta_bmc;
  9738. _list *xmitframe_plist, *xmitframe_phead;
  9739. struct xmit_frame *pxmitframe=NULL;
  9740. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  9741. struct sta_priv *pstapriv = &padapter->stapriv;
  9742. //for BC/MC Frames
  9743. psta_bmc = rtw_get_bcmc_stainfo(padapter);
  9744. if(!psta_bmc)
  9745. return H2C_SUCCESS;
  9746. if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
  9747. {
  9748. #ifndef CONFIG_PCI_HCI
  9749. rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
  9750. #endif
  9751. //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9752. _enter_critical_bh(&pxmitpriv->lock, &irqL);
  9753. xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
  9754. xmitframe_plist = get_next(xmitframe_phead);
  9755. while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
  9756. {
  9757. pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
  9758. xmitframe_plist = get_next(xmitframe_plist);
  9759. rtw_list_delete(&pxmitframe->list);
  9760. psta_bmc->sleepq_len--;
  9761. if(psta_bmc->sleepq_len>0)
  9762. pxmitframe->attrib.mdata = 1;
  9763. else
  9764. pxmitframe->attrib.mdata = 0;
  9765. pxmitframe->attrib.triggered=1;
  9766. pxmitframe->attrib.qsel = 0x11;//HIQ
  9767. #if 0
  9768. _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9769. if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
  9770. {
  9771. rtw_os_xmit_complete(padapter, pxmitframe);
  9772. }
  9773. _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9774. #endif
  9775. rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
  9776. //pstapriv->tim_bitmap &= ~BIT(0);
  9777. }
  9778. //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9779. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  9780. //#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  9781. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  9782. rtw_chk_hi_queue_cmd(padapter);
  9783. #endif
  9784. }
  9785. }
  9786. #endif
  9787. return H2C_SUCCESS;
  9788. }
  9789. void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
  9790. {
  9791. u8 network_type,rate_len, total_rate_len,remainder_rate_len;
  9792. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  9793. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9794. u8 erpinfo=0x4;
  9795. //DBG_871X("%s\n", __FUNCTION__);
  9796. if(pmlmeext->cur_channel >= 36)
  9797. {
  9798. network_type = WIRELESS_11A;
  9799. total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
  9800. DBG_871X("%s(): change to 5G Band\n",__FUNCTION__);
  9801. rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
  9802. }
  9803. else
  9804. {
  9805. network_type = WIRELESS_11BG;
  9806. total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
  9807. DBG_871X("%s(): change to 2.4G Band\n",__FUNCTION__);
  9808. rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
  9809. }
  9810. rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
  9811. UpdateBrateTbl(padapter, pnetwork->SupportedRates);
  9812. rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
  9813. if(total_rate_len > 8)
  9814. {
  9815. rate_len = 8;
  9816. remainder_rate_len = total_rate_len - 8;
  9817. }
  9818. else
  9819. {
  9820. rate_len = total_rate_len;
  9821. remainder_rate_len = 0;
  9822. }
  9823. rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
  9824. if(remainder_rate_len)
  9825. {
  9826. rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
  9827. }
  9828. else
  9829. {
  9830. rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
  9831. }
  9832. }
  9833. #ifdef CONFIG_DUALMAC_CONCURRENT
  9834. void dc_SelectChannel(_adapter *padapter, unsigned char channel)
  9835. {
  9836. PADAPTER ptarget_adapter;
  9837. if( (padapter->pbuddy_adapter != NULL) &&
  9838. (padapter->DualMacConcurrent == _TRUE) &&
  9839. (padapter->adapter_type == SECONDARY_ADAPTER))
  9840. {
  9841. // only mac0 could control BB&RF
  9842. ptarget_adapter = padapter->pbuddy_adapter;
  9843. }
  9844. else
  9845. {
  9846. ptarget_adapter = padapter;
  9847. }
  9848. _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
  9849. rtw_hal_set_chan(ptarget_adapter, channel);
  9850. _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
  9851. }
  9852. void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
  9853. {
  9854. PADAPTER ptarget_adapter;
  9855. if( (padapter->pbuddy_adapter != NULL) &&
  9856. (padapter->DualMacConcurrent == _TRUE) &&
  9857. (padapter->adapter_type == SECONDARY_ADAPTER))
  9858. {
  9859. // only mac0 could control BB&RF
  9860. ptarget_adapter = padapter->pbuddy_adapter;
  9861. }
  9862. else
  9863. {
  9864. ptarget_adapter = padapter;
  9865. }
  9866. _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
  9867. rtw_hal_set_bwmode(ptarget_adapter, (CHANNEL_WIDTH)bwmode, channel_offset);
  9868. _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
  9869. }
  9870. void dc_set_channel_bwmode_disconnect(_adapter *padapter)
  9871. {
  9872. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9873. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9874. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9875. if(pbuddy_adapter != NULL &&
  9876. padapter->DualMacConcurrent == _TRUE)
  9877. {
  9878. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9879. if((check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) != _TRUE)
  9880. {
  9881. //switch to the 20M Hz mode after disconnect
  9882. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9883. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9884. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9885. }
  9886. }
  9887. else
  9888. {
  9889. //switch to the 20M Hz mode after disconnect
  9890. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9891. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9892. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9893. }
  9894. }
  9895. u8 dc_handle_join_request(_adapter *padapter)
  9896. {
  9897. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9898. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9899. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9900. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9901. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  9902. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9903. u8 ret = _SUCCESS;
  9904. if(pbuddy_adapter != NULL &&
  9905. padapter->DualMacConcurrent == _TRUE)
  9906. {
  9907. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9908. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9909. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel ||
  9910. pmlmeext->cur_bwmode != pbuddy_mlmeext->cur_bwmode ||
  9911. pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
  9912. {
  9913. if((check_fwstate(pbuddy_mlmepriv, WIFI_AP_STATE)) == _TRUE)
  9914. {
  9915. //issue deauth to all stas if if2 is at ap mode
  9916. rtw_sta_flush(pbuddy_adapter);
  9917. //rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  9918. rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_CHECK_TXBUF, 0);
  9919. }
  9920. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE)
  9921. {
  9922. if(pmlmeext->cur_channel == pbuddy_mlmeext->cur_channel)
  9923. {
  9924. // CHANNEL_WIDTH_40 or CHANNEL_WIDTH_20 but channel offset is different
  9925. if((pmlmeext->cur_bwmode == pbuddy_mlmeext->cur_bwmode) &&
  9926. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) )
  9927. {
  9928. report_join_res(padapter, -4);
  9929. ret = _FAIL;
  9930. }
  9931. }
  9932. else
  9933. {
  9934. report_join_res(padapter, -4);
  9935. ret = _FAIL;
  9936. }
  9937. }
  9938. }
  9939. else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  9940. {
  9941. issue_nulldata(pbuddy_adapter, NULL, 1, 0, 0);
  9942. }
  9943. }
  9944. return ret;
  9945. }
  9946. void dc_handle_join_done(_adapter *padapter, u8 join_res)
  9947. {
  9948. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9949. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9950. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9951. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9952. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  9953. struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
  9954. WLAN_BSSID_EX *pbuddy_network_mlmeext = NULL;
  9955. u8 change_band = _FALSE;
  9956. if(pbuddy_adapter != NULL &&
  9957. padapter->DualMacConcurrent == _TRUE)
  9958. {
  9959. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9960. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9961. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  9962. pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
  9963. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  9964. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  9965. {
  9966. //restart and update beacon
  9967. DBG_871X("after join, current adapter, CH=%d, BW=%d, offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
  9968. if(join_res >= 0)
  9969. {
  9970. u8 *p;
  9971. int ie_len;
  9972. struct HT_info_element *pht_info=NULL;
  9973. if((pbuddy_mlmeext->cur_channel <= 14 && pmlmeext->cur_channel >= 36) ||
  9974. (pbuddy_mlmeext->cur_channel >= 36 && pmlmeext->cur_channel <= 14))
  9975. {
  9976. change_band = _TRUE;
  9977. }
  9978. //sync channel/bwmode/ch_offset with another adapter
  9979. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  9980. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  9981. {
  9982. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  9983. if( p && ie_len)
  9984. {
  9985. pht_info = (struct HT_info_element *)(p+2);
  9986. pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present
  9987. }
  9988. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  9989. {
  9990. pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
  9991. //to update cur_ch_offset value in beacon
  9992. if( pht_info )
  9993. {
  9994. switch(pmlmeext->cur_ch_offset)
  9995. {
  9996. case HAL_PRIME_CHNL_OFFSET_LOWER:
  9997. pht_info->infos[0] |= 0x1;
  9998. break;
  9999. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10000. pht_info->infos[0] |= 0x3;
  10001. break;
  10002. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10003. default:
  10004. break;
  10005. }
  10006. }
  10007. }
  10008. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10009. {
  10010. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  10011. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10012. if(pmlmeext->cur_channel>0 && pmlmeext->cur_channel<5)
  10013. {
  10014. if(pht_info)
  10015. pht_info->infos[0] |= 0x1;
  10016. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10017. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10018. }
  10019. if(pmlmeext->cur_channel>7 && pmlmeext->cur_channel<(14+1))
  10020. {
  10021. if(pht_info)
  10022. pht_info->infos[0] |= 0x3;
  10023. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10024. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10025. }
  10026. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10027. }
  10028. }
  10029. // to update channel value in beacon
  10030. pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
  10031. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10032. if(p && ie_len>0)
  10033. *(p + 2) = pmlmeext->cur_channel;
  10034. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10035. if( p && ie_len)
  10036. {
  10037. pht_info = (struct HT_info_element *)(p+2);
  10038. pht_info->primary_channel = pmlmeext->cur_channel;
  10039. }
  10040. // update mlmepriv's cur_network
  10041. _rtw_memcpy(&pbuddy_mlmepriv->cur_network.network, pbuddy_network_mlmeext, pbuddy_network_mlmeext->Length);
  10042. }
  10043. else
  10044. {
  10045. // switch back to original channel/bwmode/ch_offset;
  10046. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10047. }
  10048. DBG_871X("after join, another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10049. if(change_band == _TRUE)
  10050. change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext);
  10051. DBG_871X("update pbuddy_adapter's beacon\n");
  10052. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10053. }
  10054. else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10055. {
  10056. if((pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10057. (pmlmeext->cur_bwmode == CHANNEL_WIDTH_20))
  10058. {
  10059. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10060. }
  10061. issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
  10062. }
  10063. }
  10064. }
  10065. sint dc_check_fwstate(_adapter *padapter, sint fw_state)
  10066. {
  10067. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10068. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10069. if(padapter->pbuddy_adapter != NULL &&
  10070. padapter->DualMacConcurrent == _TRUE)
  10071. {
  10072. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10073. return check_fwstate(pbuddy_mlmepriv, fw_state);
  10074. }
  10075. return _FALSE;
  10076. }
  10077. u8 dc_handle_site_survey(_adapter *padapter)
  10078. {
  10079. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10080. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  10081. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10082. // only mac0 can do scan request, help issue nulldata(1) for mac1
  10083. if(pbuddy_adapter != NULL &&
  10084. padapter->DualMacConcurrent == _TRUE)
  10085. {
  10086. if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10087. {
  10088. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  10089. issue_nulldata(pbuddy_adapter, NULL, 1, 2, 0);
  10090. return _TRUE;
  10091. }
  10092. }
  10093. return _FALSE;
  10094. }
  10095. void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  10096. {
  10097. if(padapter->pbuddy_adapter != NULL &&
  10098. padapter->DualMacConcurrent == _TRUE)
  10099. {
  10100. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  10101. }
  10102. }
  10103. void dc_set_channel_bwmode_survey_done(_adapter *padapter)
  10104. {
  10105. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10106. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10107. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10108. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10109. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  10110. struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
  10111. u8 cur_channel;
  10112. u8 cur_bwmode;
  10113. u8 cur_ch_offset;
  10114. if(pbuddy_adapter != NULL &&
  10115. padapter->DualMacConcurrent == _TRUE)
  10116. {
  10117. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10118. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10119. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10120. if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10121. {
  10122. if(check_fwstate(pmlmepriv, _FW_LINKED) &&
  10123. (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40))
  10124. {
  10125. cur_channel = pmlmeext->cur_channel;
  10126. cur_bwmode = pmlmeext->cur_bwmode;
  10127. cur_ch_offset = pmlmeext->cur_ch_offset;
  10128. }
  10129. else
  10130. {
  10131. cur_channel = pbuddy_mlmeext->cur_channel;
  10132. cur_bwmode = pbuddy_mlmeext->cur_bwmode;
  10133. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10134. }
  10135. }
  10136. else
  10137. {
  10138. cur_channel = pmlmeext->cur_channel;
  10139. cur_bwmode = pmlmeext->cur_bwmode;
  10140. cur_ch_offset = pmlmeext->cur_ch_offset;
  10141. }
  10142. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10143. if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10144. {
  10145. //issue null data
  10146. issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
  10147. }
  10148. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  10149. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10150. {
  10151. DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10152. DBG_871X("restart pbuddy_adapter's beacon\n");
  10153. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10154. }
  10155. }
  10156. else
  10157. {
  10158. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10159. }
  10160. }
  10161. void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)
  10162. {
  10163. u8 *p;
  10164. u8 val8, cur_channel, cur_bwmode, cur_ch_offset, change_band;
  10165. int ie_len;
  10166. struct registry_priv *pregpriv = &padapter->registrypriv;
  10167. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10168. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
  10169. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  10170. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  10171. struct HT_info_element *pht_info=NULL;
  10172. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  10173. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10174. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  10175. DBG_871X("dualmac_concurrent_ap_set_channel_bwmode ==>\n");
  10176. cur_channel = channel;
  10177. cur_bwmode = bwmode;
  10178. cur_ch_offset = channel_offset;
  10179. change_band = _FALSE;
  10180. p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10181. if( p && ie_len)
  10182. {
  10183. pht_info = (struct HT_info_element *)(p+2);
  10184. }
  10185. if(pbuddy_adapter != NULL &&
  10186. padapter->DualMacConcurrent == _TRUE)
  10187. {
  10188. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10189. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10190. if(!check_fwstate(pbuddy_mlmepriv, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  10191. {
  10192. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10193. }
  10194. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)==_TRUE)
  10195. {
  10196. //To sync cur_channel/cur_bwmode/cur_ch_offset with another adapter
  10197. DBG_871X("Another iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
  10198. DBG_871X("Another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10199. DBG_871X("Current adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10200. cur_channel = pbuddy_mlmeext->cur_channel;
  10201. if(cur_bwmode == CHANNEL_WIDTH_40)
  10202. {
  10203. if(pht_info)
  10204. pht_info->infos[0] &= ~(BIT(0)|BIT(1));
  10205. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10206. {
  10207. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10208. //to update cur_ch_offset value in beacon
  10209. if(pht_info)
  10210. {
  10211. switch(cur_ch_offset)
  10212. {
  10213. case HAL_PRIME_CHNL_OFFSET_LOWER:
  10214. pht_info->infos[0] |= 0x1;
  10215. break;
  10216. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10217. pht_info->infos[0] |= 0x3;
  10218. break;
  10219. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10220. default:
  10221. break;
  10222. }
  10223. }
  10224. }
  10225. else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10226. {
  10227. cur_bwmode = CHANNEL_WIDTH_20;
  10228. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10229. if(cur_channel>0 && cur_channel<5)
  10230. {
  10231. if(pht_info)
  10232. pht_info->infos[0] |= 0x1;
  10233. cur_bwmode = CHANNEL_WIDTH_40;
  10234. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10235. }
  10236. if(cur_channel>7 && cur_channel<(14+1))
  10237. {
  10238. if(pht_info)
  10239. pht_info->infos[0] |= 0x3;
  10240. cur_bwmode = CHANNEL_WIDTH_40;
  10241. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10242. }
  10243. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10244. }
  10245. }
  10246. // to update channel value in beacon
  10247. pnetwork->Configuration.DSConfig = cur_channel;
  10248. p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10249. if(p && ie_len>0)
  10250. *(p + 2) = cur_channel;
  10251. if(pht_info)
  10252. pht_info->primary_channel = cur_channel;
  10253. }
  10254. }
  10255. else
  10256. {
  10257. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10258. }
  10259. DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10260. if((channel <= 14 && cur_channel >= 36) ||
  10261. (channel >= 36 && cur_channel <= 14))
  10262. {
  10263. change_band = _TRUE;
  10264. }
  10265. pmlmeext->cur_channel = cur_channel;
  10266. pmlmeext->cur_bwmode = cur_bwmode;
  10267. pmlmeext->cur_ch_offset = cur_ch_offset;
  10268. if(change_band == _TRUE)
  10269. change_band_update_ie(padapter, pnetwork);
  10270. DBG_871X("dualmac_concurrent_ap_set_channel_bwmode <==\n");
  10271. }
  10272. void dc_resume_xmit(_adapter *padapter)
  10273. {
  10274. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10275. if(pbuddy_adapter != NULL &&
  10276. padapter->DualMacConcurrent == _TRUE)
  10277. {
  10278. DBG_871X("dc_resume_xmit, resume pbuddy_adapter Tx\n");
  10279. rtw_os_xmit_schedule(pbuddy_adapter);
  10280. }
  10281. }
  10282. u8 dc_check_xmit(_adapter *padapter)
  10283. {
  10284. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10285. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10286. if(pbuddy_adapter != NULL &&
  10287. padapter->DualMacConcurrent == _TRUE)
  10288. {
  10289. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10290. if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
  10291. {
  10292. DBG_871X("dc_check_xmit pbuddy_adapter is under survey or under linking\n");
  10293. return _FALSE;
  10294. }
  10295. }
  10296. return _TRUE;
  10297. }
  10298. #endif
  10299. #ifdef CONFIG_CONCURRENT_MODE
  10300. sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
  10301. {
  10302. PADAPTER pbuddy_adapter;
  10303. struct mlme_ext_priv *pbuddy_mlmeext;
  10304. struct mlme_ext_info *pbuddy_mlmeinfo;
  10305. if(padapter == NULL)
  10306. return _FALSE;
  10307. pbuddy_adapter = padapter->pbuddy_adapter;
  10308. if(pbuddy_adapter == NULL)
  10309. return _FALSE;
  10310. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10311. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10312. if((pbuddy_mlmeinfo->state&0x03) == state)
  10313. return _TRUE;
  10314. return _FALSE;
  10315. }
  10316. int concurrent_chk_start_clnt_join(_adapter *padapter)
  10317. {
  10318. int ret = _FAIL;
  10319. PADAPTER pbuddy_adapter;
  10320. struct mlme_ext_priv *pbuddy_mlmeext;
  10321. struct mlme_ext_info *pbuddy_pmlmeinfo;
  10322. struct mlme_priv *pbuddy_mlmepriv;
  10323. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10324. unsigned char cur_ch = pmlmeext->cur_channel;
  10325. unsigned char cur_bw = pmlmeext->cur_bwmode;
  10326. unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
  10327. if(!rtw_buddy_adapter_up(padapter))
  10328. {
  10329. goto start_join_set_ch_bw;
  10330. }
  10331. pbuddy_adapter = padapter->pbuddy_adapter;
  10332. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10333. pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10334. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10335. if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE
  10336. {
  10337. bool inform_ch_switch = _FALSE;
  10338. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
  10339. {
  10340. inform_ch_switch = _TRUE;
  10341. }
  10342. else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10343. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10344. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
  10345. {
  10346. inform_ch_switch = _TRUE;
  10347. }
  10348. else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_20) &&
  10349. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40))
  10350. {
  10351. inform_ch_switch = _FALSE;
  10352. cur_ch = pmlmeext->cur_channel;
  10353. cur_bw = pbuddy_mlmeext->cur_bwmode;
  10354. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10355. }
  10356. if (inform_ch_switch) {
  10357. #ifdef CONFIG_SPCT_CH_SWITCH
  10358. if (1) {
  10359. rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
  10360. } else
  10361. #endif
  10362. {
  10363. //issue deauth to all stas if if2 is at ap mode
  10364. rtw_sta_flush(pbuddy_adapter);
  10365. }
  10366. rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  10367. }
  10368. }
  10369. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
  10370. check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client
  10371. {
  10372. #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
  10373. struct wifidirect_info *pbuddy_wdinfo = &(pbuddy_adapter->wdinfo);
  10374. if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE) && pbuddy_wdinfo->driver_interface == DRIVER_CFG80211 )
  10375. {
  10376. goto start_join_set_ch_bw;//wlan0-sta mode has higher priority than p2p0-p2p client
  10377. }
  10378. #endif //CONFIG_P2P && CONFIG_IOCTL_CFG80211
  10379. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
  10380. {
  10381. DBG_871X("start_clnt_join(ch=%d), but channel mismatch with buddy(ch=%d) interface\n",
  10382. pmlmeext->cur_channel, pbuddy_mlmeext->cur_channel);
  10383. report_join_res(padapter, (-4));
  10384. return ret;
  10385. }
  10386. if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10387. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10388. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
  10389. {
  10390. DBG_871X("start_clnt_join(bwmode=%d, ch_offset=%d), but bwmode & ch_offset mismatch with buddy(bwmode=%d, ch_offset=%d) interface\n",
  10391. pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10392. report_join_res(padapter, (-4));
  10393. return ret;
  10394. }
  10395. }
  10396. start_join_set_ch_bw:
  10397. set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
  10398. return _SUCCESS;
  10399. }
  10400. void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
  10401. {
  10402. struct mlme_ext_priv *pmlmeext;
  10403. struct mlme_ext_info *pmlmeinfo;
  10404. PADAPTER pbuddy_adapter;
  10405. struct mlme_priv *pbuddy_mlmepriv;
  10406. struct mlme_ext_priv *pbuddy_mlmeext;
  10407. struct mlme_ext_info *pbuddy_mlmeinfo;
  10408. WLAN_BSSID_EX *pbuddy_network_mlmeext;
  10409. pmlmeext = &padapter->mlmeextpriv;
  10410. pmlmeinfo = &(pmlmeext->mlmext_info);
  10411. if(!rtw_buddy_adapter_up(padapter))
  10412. {
  10413. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10414. return;
  10415. }
  10416. pbuddy_adapter = padapter->pbuddy_adapter;
  10417. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10418. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10419. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10420. pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
  10421. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  10422. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10423. {
  10424. //restart and update beacon
  10425. DBG_871X("after join,primary adapter, CH=%d, BW=%d, offset=%d\n"
  10426. , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
  10427. if(join_res >= 0)
  10428. {
  10429. u8 *p;
  10430. int ie_len;
  10431. u8 change_band = _FALSE;
  10432. struct HT_info_element *pht_info=NULL;
  10433. if((pmlmeext->cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||
  10434. (pmlmeext->cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))
  10435. change_band = _TRUE;
  10436. //sync channel/bwmode/ch_offset with primary adapter
  10437. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  10438. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10439. {
  10440. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10441. if( p && ie_len)
  10442. {
  10443. pht_info = (struct HT_info_element *)(p+2);
  10444. pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present
  10445. }
  10446. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10447. {
  10448. pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
  10449. //to update cur_ch_offset value in beacon
  10450. if( pht_info )
  10451. {
  10452. switch(pmlmeext->cur_ch_offset)
  10453. {
  10454. case HAL_PRIME_CHNL_OFFSET_LOWER:
  10455. pht_info->infos[0] |= 0x1;
  10456. break;
  10457. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10458. pht_info->infos[0] |= 0x3;
  10459. break;
  10460. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10461. default:
  10462. break;
  10463. }
  10464. }
  10465. }
  10466. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10467. {
  10468. if(pmlmeext->cur_channel>=1 && pmlmeext->cur_channel<=4)
  10469. {
  10470. if(pht_info)
  10471. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
  10472. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10473. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10474. }
  10475. else if(pmlmeext->cur_channel>=5 && pmlmeext->cur_channel<=14)
  10476. {
  10477. if(pht_info)
  10478. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10479. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10480. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10481. }
  10482. else
  10483. {
  10484. switch(pmlmeext->cur_channel)
  10485. {
  10486. case 36:
  10487. case 44:
  10488. case 52:
  10489. case 60:
  10490. case 100:
  10491. case 108:
  10492. case 116:
  10493. case 124:
  10494. case 132:
  10495. case 149:
  10496. case 157:
  10497. {
  10498. if(pht_info)
  10499. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
  10500. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10501. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10502. break;
  10503. }
  10504. case 40:
  10505. case 48:
  10506. case 56:
  10507. case 64:
  10508. case 104:
  10509. case 112:
  10510. case 120:
  10511. case 128:
  10512. case 136:
  10513. case 153:
  10514. case 161:
  10515. {
  10516. if(pht_info)
  10517. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10518. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10519. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10520. break;
  10521. }
  10522. default:
  10523. if(pht_info)
  10524. pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10525. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  10526. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10527. break;
  10528. }
  10529. }
  10530. }
  10531. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10532. }
  10533. else
  10534. {
  10535. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10536. }
  10537. // to update channel value in beacon
  10538. pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
  10539. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10540. if(p && ie_len>0)
  10541. *(p + 2) = pmlmeext->cur_channel;
  10542. p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10543. if( p && ie_len)
  10544. {
  10545. pht_info = (struct HT_info_element *)(p+2);
  10546. pht_info->primary_channel = pmlmeext->cur_channel;
  10547. }
  10548. //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE
  10549. if(change_band == _TRUE)
  10550. change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext);
  10551. }
  10552. else
  10553. {
  10554. // switch back to original channel/bwmode/ch_offset;
  10555. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10556. }
  10557. DBG_871X("after join, second adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10558. DBG_871X("update pbuddy_adapter's beacon\n");
  10559. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10560. }
  10561. else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
  10562. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10563. {
  10564. if(join_res >= 0)
  10565. {
  10566. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  10567. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10568. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10569. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10570. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10571. else
  10572. set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  10573. }
  10574. else
  10575. {
  10576. // switch back to original channel/bwmode/ch_offset;
  10577. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10578. }
  10579. }
  10580. else
  10581. {
  10582. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10583. }
  10584. }
  10585. #endif //CONFIG_CONCURRENT_MODE
  10586. u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
  10587. {
  10588. struct set_ch_parm *set_ch_parm;
  10589. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10590. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10591. if(!pbuf)
  10592. return H2C_PARAMETERS_ERROR;
  10593. set_ch_parm = (struct set_ch_parm *)pbuf;
  10594. DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
  10595. FUNC_NDEV_ARG(padapter->pnetdev),
  10596. set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
  10597. pmlmeext->cur_channel = set_ch_parm->ch;
  10598. pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
  10599. pmlmeext->cur_bwmode = set_ch_parm->bw;
  10600. set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
  10601. return H2C_SUCCESS;
  10602. }
  10603. u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
  10604. {
  10605. struct SetChannelPlan_param *setChannelPlan_param;
  10606. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10607. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10608. if(!pbuf)
  10609. return H2C_PARAMETERS_ERROR;
  10610. setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
  10611. pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
  10612. init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
  10613. return H2C_SUCCESS;
  10614. }
  10615. u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
  10616. {
  10617. struct LedBlink_param *ledBlink_param;
  10618. if(!pbuf)
  10619. return H2C_PARAMETERS_ERROR;
  10620. ledBlink_param = (struct LedBlink_param *)pbuf;
  10621. #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
  10622. BlinkHandler((PLED_DATA)ledBlink_param->pLed);
  10623. #endif
  10624. return H2C_SUCCESS;
  10625. }
  10626. u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
  10627. {
  10628. #ifdef CONFIG_DFS
  10629. struct SetChannelSwitch_param *setChannelSwitch_param;
  10630. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10631. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10632. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  10633. u8 new_ch_no;
  10634. u8 gval8 = 0x00, sval8 = 0xff;
  10635. if(!pbuf)
  10636. return H2C_PARAMETERS_ERROR;
  10637. setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
  10638. new_ch_no = setChannelSwitch_param->new_ch_no;
  10639. rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
  10640. rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
  10641. DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
  10642. SelectChannel(padapter, new_ch_no);
  10643. rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
  10644. rtw_free_network_queue(padapter, _TRUE);
  10645. rtw_indicate_disconnect(padapter);
  10646. if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
  10647. DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
  10648. }
  10649. return H2C_SUCCESS;
  10650. #else
  10651. return H2C_REJECTED;
  10652. #endif //CONFIG_DFS
  10653. }
  10654. // TDLS_WRCR : write RCR DATA BIT
  10655. // TDLS_SD_PTI : issue peer traffic indication
  10656. // TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure
  10657. // TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame
  10658. // TDLS_DONE_CH_SEN: channel sensing and report candidate channel
  10659. // TDLS_OFF_CH : first time set channel to off channel
  10660. // TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel
  10661. // TDLS_P_OFF_CH : periodically go to off channel
  10662. // TDLS_P_BASE_CH : periodically go back to base channel
  10663. // TDLS_RS_RCR : restore RCR
  10664. // TDLS_CKALV_PH1 : check alive timer phase1
  10665. // TDLS_CKALV_PH2 : check alive timer phase2
  10666. // TDLS_FREE_STA : free tdls sta
  10667. u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
  10668. {
  10669. #ifdef CONFIG_TDLS
  10670. _irqL irqL;
  10671. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  10672. struct TDLSoption_param *TDLSoption;
  10673. struct sta_info *ptdls_sta;
  10674. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10675. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  10676. u8 survey_channel, i, min, option;
  10677. if(!pbuf)
  10678. return H2C_PARAMETERS_ERROR;
  10679. TDLSoption = (struct TDLSoption_param *)pbuf;
  10680. ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
  10681. option = TDLSoption->option;
  10682. if( ptdls_sta == NULL )
  10683. {
  10684. if( option != TDLS_RS_RCR )
  10685. return H2C_REJECTED;
  10686. }
  10687. //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
  10688. DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
  10689. switch(option){
  10690. case TDLS_WRCR:
  10691. //As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0
  10692. //such we can receive all kinds of data frames.
  10693. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
  10694. DBG_871X("TDLS with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
  10695. pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
  10696. //set TDLS sta rate.
  10697. set_sta_rate(padapter, ptdls_sta);
  10698. break;
  10699. case TDLS_SD_PTI:
  10700. issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
  10701. break;
  10702. case TDLS_CS_OFF:
  10703. _cancel_timer_ex(&ptdls_sta->base_ch_timer);
  10704. _cancel_timer_ex(&ptdls_sta->off_ch_timer);
  10705. SelectChannel(padapter, pmlmeext->cur_channel);
  10706. ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
  10707. TDLS_PEER_AT_OFF_STATE |
  10708. TDLS_AT_OFF_CH_STATE);
  10709. DBG_871X("go back to base channel\n ");
  10710. issue_nulldata(padapter, NULL, 0, 0, 0);
  10711. break;
  10712. case TDLS_INIT_CH_SEN:
  10713. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_INIT_CH_SEN, 0);
  10714. pmlmeext->sitesurvey_res.channel_idx = 0;
  10715. ptdls_sta->option = TDLS_DONE_CH_SEN;
  10716. rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
  10717. break;
  10718. case TDLS_DONE_CH_SEN:
  10719. survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
  10720. if(survey_channel){
  10721. SelectChannel(padapter, survey_channel);
  10722. ptdlsinfo->cur_channel = survey_channel;
  10723. pmlmeext->sitesurvey_res.channel_idx++;
  10724. _set_timer(&ptdls_sta->option_timer, SURVEY_TO);
  10725. }else{
  10726. SelectChannel(padapter, pmlmeext->cur_channel);
  10727. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_DONE_CH_SEN, 0);
  10728. if(ptdlsinfo->ch_sensing==1){
  10729. ptdlsinfo->ch_sensing=0;
  10730. ptdlsinfo->cur_channel=1;
  10731. min=ptdlsinfo->collect_pkt_num[0];
  10732. for(i=1; i<MAX_CHANNEL_NUM-1; i++){
  10733. if(min > ptdlsinfo->collect_pkt_num[i]){
  10734. ptdlsinfo->cur_channel=i+1;
  10735. min=ptdlsinfo->collect_pkt_num[i];
  10736. }
  10737. ptdlsinfo->collect_pkt_num[i]=0;
  10738. }
  10739. ptdlsinfo->collect_pkt_num[0]=0;
  10740. ptdlsinfo->candidate_ch=ptdlsinfo->cur_channel;
  10741. DBG_871X("TDLS channel sensing done, candidate channel: %02x\n", ptdlsinfo->candidate_ch);
  10742. ptdlsinfo->cur_channel=0;
  10743. }
  10744. if(ptdls_sta->tdls_sta_state & TDLS_PEER_SLEEP_STATE){
  10745. ptdls_sta->tdls_sta_state |= TDLS_APSD_CHSW_STATE;
  10746. }else{
  10747. //send null data with pwrbit==1 before send ch_switching_req to peer STA.
  10748. issue_nulldata(padapter, NULL, 1, 0, 0);
  10749. ptdls_sta->tdls_sta_state |= TDLS_CH_SW_INITIATOR_STATE;
  10750. issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr);
  10751. DBG_871X("issue tdls ch switch req\n");
  10752. }
  10753. }
  10754. break;
  10755. case TDLS_OFF_CH:
  10756. issue_nulldata(padapter, NULL, 1, 0, 0);
  10757. SelectChannel(padapter, ptdls_sta->off_ch);
  10758. DBG_871X("change channel to tar ch:%02x\n", ptdls_sta->off_ch);
  10759. ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
  10760. ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE);
  10761. _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
  10762. break;
  10763. case TDLS_BASE_CH:
  10764. _cancel_timer_ex(&ptdls_sta->base_ch_timer);
  10765. _cancel_timer_ex(&ptdls_sta->off_ch_timer);
  10766. SelectChannel(padapter, pmlmeext->cur_channel);
  10767. ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
  10768. TDLS_PEER_AT_OFF_STATE |
  10769. TDLS_AT_OFF_CH_STATE);
  10770. DBG_871X("go back to base channel\n ");
  10771. issue_nulldata(padapter, NULL, 0, 0, 0);
  10772. _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
  10773. break;
  10774. case TDLS_P_OFF_CH:
  10775. SelectChannel(padapter, pmlmeext->cur_channel);
  10776. issue_nulldata(padapter, NULL, 0, 0, 0);
  10777. DBG_871X("change channel to base ch:%02x\n", pmlmeext->cur_channel);
  10778. ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE| TDLS_AT_OFF_CH_STATE);
  10779. _set_timer(&ptdls_sta->off_ch_timer, TDLS_STAY_TIME);
  10780. break;
  10781. case TDLS_P_BASE_CH:
  10782. issue_nulldata(ptdls_sta->padapter, NULL, 1, 0, 0);
  10783. SelectChannel(padapter, ptdls_sta->off_ch);
  10784. DBG_871X("change channel to off ch:%02x\n", ptdls_sta->off_ch);
  10785. ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
  10786. if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE){
  10787. issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
  10788. }
  10789. _set_timer(&ptdls_sta->base_ch_timer, TDLS_STAY_TIME);
  10790. break;
  10791. case TDLS_RS_RCR:
  10792. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
  10793. DBG_871X("wirte REG_RCR, set bit6 on\n");
  10794. break;
  10795. case TDLS_CKALV_PH1:
  10796. _set_timer(&ptdls_sta->alive_timer2, TDLS_ALIVE_TIMER_PH2);
  10797. break;
  10798. case TDLS_CKALV_PH2:
  10799. _set_timer(&ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
  10800. break;
  10801. case TDLS_FREE_STA:
  10802. free_tdls_sta(padapter, ptdls_sta);
  10803. break;
  10804. }
  10805. //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
  10806. return H2C_SUCCESS;
  10807. #else
  10808. return H2C_REJECTED;
  10809. #endif //CONFIG_TDLS
  10810. }