rtw_mlme_ext.c 373 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336
  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. #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
  611. __attribute__ ((fallthrough));
  612. #else
  613. __attribute__ ((__fallthrough__));
  614. #endif
  615. case WIFI_ASSOCREQ:
  616. case WIFI_REASSOCREQ:
  617. _mgt_dispatcher(padapter, ptable, precv_frame);
  618. #ifdef CONFIG_HOSTAPD_MLME
  619. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  620. rtw_hostapd_mlme_rx(padapter, precv_frame);
  621. #endif
  622. break;
  623. case WIFI_PROBEREQ:
  624. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  625. {
  626. #ifdef CONFIG_HOSTAPD_MLME
  627. rtw_hostapd_mlme_rx(padapter, precv_frame);
  628. #else
  629. _mgt_dispatcher(padapter, ptable, precv_frame);
  630. #endif
  631. }
  632. else
  633. _mgt_dispatcher(padapter, ptable, precv_frame);
  634. break;
  635. case WIFI_BEACON:
  636. _mgt_dispatcher(padapter, ptable, precv_frame);
  637. break;
  638. case WIFI_ACTION:
  639. //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  640. _mgt_dispatcher(padapter, ptable, precv_frame);
  641. break;
  642. default:
  643. _mgt_dispatcher(padapter, ptable, precv_frame);
  644. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  645. rtw_hostapd_mlme_rx(padapter, precv_frame);
  646. break;
  647. }
  648. #else
  649. _mgt_dispatcher(padapter, ptable, precv_frame);
  650. #endif
  651. }
  652. #ifdef CONFIG_P2P
  653. u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
  654. {
  655. bool response = _TRUE;
  656. #ifdef CONFIG_IOCTL_CFG80211
  657. if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
  658. {
  659. if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
  660. || padapter->mlmepriv.wps_probe_resp_ie == NULL
  661. || padapter->mlmepriv.p2p_probe_resp_ie == NULL
  662. )
  663. {
  664. DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
  665. wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
  666. padapter->mlmepriv.wps_probe_resp_ie,
  667. padapter->mlmepriv.p2p_probe_resp_ie);
  668. response = _FALSE;
  669. }
  670. }
  671. else
  672. #endif //CONFIG_IOCTL_CFG80211
  673. if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
  674. {
  675. // do nothing if the device name is empty
  676. if ( !padapter->wdinfo.device_name_len )
  677. {
  678. response = _FALSE;
  679. }
  680. }
  681. if (response == _TRUE)
  682. issue_probersp_p2p( padapter, da);
  683. return _SUCCESS;
  684. }
  685. #endif //CONFIG_P2P
  686. /****************************************************************************
  687. Following are the callback functions for each subtype of the management frames
  688. *****************************************************************************/
  689. unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
  690. {
  691. unsigned int ielen;
  692. unsigned char *p;
  693. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  694. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  695. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  696. WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
  697. u8 *pframe = precv_frame->u.hdr.rx_data;
  698. uint len = precv_frame->u.hdr.len;
  699. u8 is_valid_p2p_probereq = _FALSE;
  700. #ifdef CONFIG_P2P
  701. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  702. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  703. u8 wifi_test_chk_rate = 1;
  704. if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
  705. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
  706. !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
  707. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
  708. !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
  709. )
  710. {
  711. // Commented by Albert 2011/03/17
  712. // mcs_rate = 0 -> CCK 1M rate
  713. // mcs_rate = 1 -> CCK 2M rate
  714. // mcs_rate = 2 -> CCK 5.5M rate
  715. // mcs_rate = 3 -> CCK 11M rate
  716. // In the P2P mode, the driver should not support the CCK rate
  717. // Commented by Kurt 2012/10/16
  718. // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
  719. #ifdef CONFIG_WIFI_TEST
  720. if ( pattrib->mcs_rate <= 3 )
  721. {
  722. wifi_test_chk_rate = 0;
  723. }
  724. #endif //CONFIG_WIFI_TEST
  725. if( wifi_test_chk_rate == 1 )
  726. {
  727. if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
  728. {
  729. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
  730. {
  731. p2p_listen_state_process( padapter, get_sa(pframe));
  732. return _SUCCESS;
  733. }
  734. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  735. {
  736. goto _continue;
  737. }
  738. }
  739. }
  740. }
  741. _continue:
  742. #endif //CONFIG_P2P
  743. if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  744. {
  745. return _SUCCESS;
  746. }
  747. if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
  748. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
  749. {
  750. return _SUCCESS;
  751. }
  752. //DBG_871X("+OnProbeReq\n");
  753. #ifdef CONFIG_AUTO_AP_MODE
  754. if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
  755. pmlmepriv->cur_network.join_res == _TRUE)
  756. {
  757. _irqL irqL;
  758. struct sta_info *psta;
  759. u8 *mac_addr, *peer_addr;
  760. struct sta_priv *pstapriv = &padapter->stapriv;
  761. u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
  762. //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
  763. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
  764. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  765. if(!p || ielen !=14)
  766. goto _non_rc_device;
  767. if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
  768. goto _non_rc_device;
  769. if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
  770. {
  771. DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
  772. MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
  773. goto _non_rc_device;
  774. }
  775. DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
  776. //new a station
  777. psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
  778. if (psta == NULL)
  779. {
  780. // allocate a new one
  781. DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
  782. psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
  783. if (psta == NULL)
  784. {
  785. //TODO:
  786. DBG_871X(" Exceed the upper limit of supported clients...\n");
  787. return _SUCCESS;
  788. }
  789. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  790. if (rtw_is_list_empty(&psta->asoc_list))
  791. {
  792. psta->expire_to = pstapriv->expire_to;
  793. rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
  794. pstapriv->asoc_list_cnt++;
  795. }
  796. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  797. //generate pairing ID
  798. mac_addr = myid(&(padapter->eeprompriv));
  799. peer_addr = psta->hwaddr;
  800. psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
  801. //update peer stainfo
  802. psta->isrc = _TRUE;
  803. //psta->aid = 0;
  804. //psta->mac_id = 2;
  805. /* get a unique AID */
  806. if (psta->aid > 0) {
  807. DBG_871X("old AID %d\n", psta->aid);
  808. } else {
  809. for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
  810. if (pstapriv->sta_aid[psta->aid - 1] == NULL)
  811. break;
  812. if (psta->aid > pstapriv->max_num_sta) {
  813. psta->aid = 0;
  814. DBG_871X("no room for more AIDs\n");
  815. return _SUCCESS;
  816. } else {
  817. pstapriv->sta_aid[psta->aid - 1] = psta;
  818. DBG_871X("allocate new AID = (%d)\n", psta->aid);
  819. }
  820. }
  821. psta->qos_option = 1;
  822. psta->htpriv.ht_option = _TRUE;
  823. psta->ieee8021x_blocked = _FALSE;
  824. psta->htpriv.ampdu_enable = _FALSE;
  825. psta->htpriv.sgi = _FALSE;
  826. psta->htpriv.bwmode = CHANNEL_WIDTH_20;
  827. psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  828. rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
  829. psta->htpriv.agg_enable_bitmap = 0x0;//reset
  830. psta->htpriv.candidate_tid_bitmap = 0x0;//reset
  831. _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
  832. _enter_critical_bh(&psta->lock, &irqL);
  833. psta->state |= _FW_LINKED;
  834. _exit_critical_bh(&psta->lock, &irqL);
  835. report_add_sta_event(padapter, psta->hwaddr, psta->aid);
  836. }
  837. issue_probersp(padapter, get_sa(pframe), _FALSE);
  838. return _SUCCESS;
  839. }
  840. _non_rc_device:
  841. return _SUCCESS;
  842. #endif //CONFIG_AUTO_AP_MODE
  843. #ifdef CONFIG_CONCURRENT_MODE
  844. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  845. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  846. {
  847. //don't process probe req
  848. return _SUCCESS;
  849. }
  850. #endif
  851. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
  852. len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
  853. //check (wildcard) SSID
  854. if (p != NULL)
  855. {
  856. if(is_valid_p2p_probereq == _TRUE)
  857. {
  858. goto _issue_probersp;
  859. }
  860. if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
  861. || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
  862. )
  863. {
  864. return _SUCCESS;
  865. }
  866. _issue_probersp:
  867. if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
  868. pmlmepriv->cur_network.join_res == _TRUE)
  869. {
  870. //DBG_871X("+issue_probersp during ap mode\n");
  871. issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
  872. }
  873. }
  874. return _SUCCESS;
  875. }
  876. unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
  877. {
  878. struct sta_info *psta;
  879. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  880. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  881. struct sta_priv *pstapriv = &padapter->stapriv;
  882. u8 *pframe = precv_frame->u.hdr.rx_data;
  883. #ifdef CONFIG_P2P
  884. struct wifidirect_info *pwdinfo = &padapter->wdinfo;
  885. #endif
  886. #ifdef CONFIG_P2P
  887. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  888. {
  889. if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
  890. {
  891. if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  892. {
  893. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
  894. {
  895. pwdinfo->tx_prov_disc_info.benable = _FALSE;
  896. issue_p2p_provision_request( padapter,
  897. pwdinfo->tx_prov_disc_info.ssid.Ssid,
  898. pwdinfo->tx_prov_disc_info.ssid.SsidLength,
  899. pwdinfo->tx_prov_disc_info.peerDevAddr );
  900. }
  901. else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  902. {
  903. pwdinfo->tx_prov_disc_info.benable = _FALSE;
  904. issue_p2p_provision_request( padapter,
  905. NULL,
  906. 0,
  907. pwdinfo->tx_prov_disc_info.peerDevAddr );
  908. }
  909. }
  910. }
  911. return _SUCCESS;
  912. }
  913. else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  914. {
  915. if ( _TRUE == pwdinfo->nego_req_info.benable )
  916. {
  917. DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
  918. if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  919. {
  920. pwdinfo->nego_req_info.benable = _FALSE;
  921. issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
  922. }
  923. }
  924. }
  925. else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
  926. {
  927. if ( _TRUE == pwdinfo->invitereq_info.benable )
  928. {
  929. DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
  930. if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
  931. {
  932. pwdinfo->invitereq_info.benable = _FALSE;
  933. issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
  934. }
  935. }
  936. }
  937. #endif
  938. if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  939. {
  940. report_survey_event(padapter, precv_frame);
  941. #ifdef CONFIG_CONCURRENT_MODE
  942. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  943. #endif
  944. #ifdef CONFIG_DUALMAC_CONCURRENT
  945. dc_report_survey_event(padapter, precv_frame);
  946. #endif
  947. return _SUCCESS;
  948. }
  949. #if 0 //move to validate_recv_mgnt_frame
  950. if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
  951. {
  952. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  953. {
  954. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  955. {
  956. psta->sta_stats.rx_mgnt_pkts++;
  957. }
  958. }
  959. }
  960. #endif
  961. return _SUCCESS;
  962. }
  963. unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
  964. {
  965. int cam_idx;
  966. struct sta_info *psta;
  967. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  968. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  969. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  970. struct sta_priv *pstapriv = &padapter->stapriv;
  971. u8 *pframe = precv_frame->u.hdr.rx_data;
  972. uint len = precv_frame->u.hdr.len;
  973. WLAN_BSSID_EX *pbss;
  974. int ret = _SUCCESS;
  975. u8 *p = NULL;
  976. u32 ielen = 0;
  977. #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
  978. 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_);
  979. if ((p != NULL) && (ielen > 0))
  980. {
  981. if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
  982. {
  983. /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
  984. 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)));
  985. *(p + 1) = ielen - 1;
  986. }
  987. }
  988. #endif
  989. if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  990. {
  991. report_survey_event(padapter, precv_frame);
  992. #ifdef CONFIG_CONCURRENT_MODE
  993. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  994. #endif
  995. #ifdef CONFIG_DUALMAC_CONCURRENT
  996. dc_report_survey_event(padapter, precv_frame);
  997. #endif
  998. return _SUCCESS;
  999. }
  1000. if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
  1001. {
  1002. if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
  1003. {
  1004. //we should update current network before auth, or some IE is wrong
  1005. pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
  1006. if (pbss) {
  1007. if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
  1008. update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
  1009. rtw_get_bcn_info(&(pmlmepriv->cur_network));
  1010. }
  1011. rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
  1012. }
  1013. //check the vendor of the assoc AP
  1014. pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
  1015. //update TSF Value
  1016. update_TSF(pmlmeext, pframe, len);
  1017. //start auth
  1018. start_clnt_auth(padapter);
  1019. return _SUCCESS;
  1020. }
  1021. if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  1022. {
  1023. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  1024. {
  1025. #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
  1026. //Merge from 8712 FW code
  1027. if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
  1028. { // join wrong channel, deauth and reconnect
  1029. issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
  1030. report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
  1031. pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
  1032. return _SUCCESS;
  1033. }
  1034. #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
  1035. ret = rtw_check_bcn_info(padapter, pframe, len);
  1036. if (!ret) {
  1037. DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
  1038. receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
  1039. return _SUCCESS;
  1040. }
  1041. //update WMM, ERP in the beacon
  1042. //todo: the timer is used instead of the number of the beacon received
  1043. if ((sta_rx_pkts(psta) & 0xf) == 0)
  1044. {
  1045. //DBG_871X("update_bcn_info\n");
  1046. update_beacon_info(padapter, pframe, len, psta);
  1047. }
  1048. #ifdef CONFIG_DFS
  1049. process_csa_ie(padapter, pframe, len); //channel switch announcement
  1050. #endif //CONFIG_DFS
  1051. #ifdef CONFIG_P2P_PS
  1052. process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
  1053. #endif //CONFIG_P2P_PS
  1054. #if 0 //move to validate_recv_mgnt_frame
  1055. psta->sta_stats.rx_mgnt_pkts++;
  1056. #endif
  1057. }
  1058. }
  1059. else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  1060. {
  1061. if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
  1062. {
  1063. //update WMM, ERP in the beacon
  1064. //todo: the timer is used instead of the number of the beacon received
  1065. if ((sta_rx_pkts(psta) & 0xf) == 0)
  1066. {
  1067. //DBG_871X("update_bcn_info\n");
  1068. update_beacon_info(padapter, pframe, len, psta);
  1069. }
  1070. #if 0 //move to validate_recv_mgnt_frame
  1071. psta->sta_stats.rx_mgnt_pkts++;
  1072. #endif
  1073. }
  1074. else
  1075. {
  1076. //allocate a new CAM entry for IBSS station
  1077. if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
  1078. {
  1079. goto _END_ONBEACON_;
  1080. }
  1081. //get supported rate
  1082. 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)
  1083. {
  1084. pmlmeinfo->FW_sta_info[cam_idx].status = 0;
  1085. goto _END_ONBEACON_;
  1086. }
  1087. //update TSF Value
  1088. update_TSF(pmlmeext, pframe, len);
  1089. //report sta add event
  1090. report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
  1091. }
  1092. }
  1093. }
  1094. _END_ONBEACON_:
  1095. return _SUCCESS;
  1096. }
  1097. unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
  1098. {
  1099. #ifdef CONFIG_AP_MODE
  1100. _irqL irqL;
  1101. unsigned int auth_mode, seq, ie_len;
  1102. unsigned char *sa, *p;
  1103. u16 algorithm;
  1104. int status;
  1105. static struct sta_info stat;
  1106. struct sta_info *pstat=NULL;
  1107. struct sta_priv *pstapriv = &padapter->stapriv;
  1108. struct security_priv *psecuritypriv = &padapter->securitypriv;
  1109. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1110. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1111. u8 *pframe = precv_frame->u.hdr.rx_data;
  1112. uint len = precv_frame->u.hdr.len;
  1113. u8 offset = 0;
  1114. #ifdef CONFIG_CONCURRENT_MODE
  1115. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  1116. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  1117. {
  1118. //don't process auth request;
  1119. return _SUCCESS;
  1120. }
  1121. #endif //CONFIG_CONCURRENT_MODE
  1122. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  1123. return _FAIL;
  1124. DBG_871X("+OnAuth\n");
  1125. sa = GetAddr2Ptr(pframe);
  1126. auth_mode = psecuritypriv->dot11AuthAlgrthm;
  1127. if (GetPrivacy(pframe))
  1128. {
  1129. u8 *iv;
  1130. struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
  1131. prxattrib->hdrlen = WLAN_HDR_A3_LEN;
  1132. prxattrib->encrypt = _WEP40_;
  1133. iv = pframe+prxattrib->hdrlen;
  1134. prxattrib->key_index = ((iv[3]>>6)&0x3);
  1135. prxattrib->iv_len = 4;
  1136. prxattrib->icv_len = 4;
  1137. rtw_wep_decrypt(padapter, (u8 *)precv_frame);
  1138. offset = 4;
  1139. }
  1140. algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
  1141. seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
  1142. DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
  1143. if (auth_mode == 2 &&
  1144. psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
  1145. psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
  1146. auth_mode = 0;
  1147. if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
  1148. (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
  1149. {
  1150. DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
  1151. algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
  1152. status = _STATS_NO_SUPP_ALG_;
  1153. goto auth_fail;
  1154. }
  1155. #if 0 //ACL control
  1156. phead = &priv->wlan_acl_list;
  1157. plist = phead->next;
  1158. //check sa
  1159. if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
  1160. res = FAIL;
  1161. else
  1162. res = SUCCESS;
  1163. while(plist != phead)
  1164. {
  1165. paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
  1166. plist = plist->next;
  1167. if (!memcmp((void *)sa, paclnode->addr, 6)) {
  1168. if (paclnode->mode & 2) { // deny
  1169. res = FAIL;
  1170. break;
  1171. }
  1172. else {
  1173. res = SUCCESS;
  1174. break;
  1175. }
  1176. }
  1177. }
  1178. if (res != SUCCESS) {
  1179. RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
  1180. return FAIL;
  1181. }
  1182. #else
  1183. if(rtw_access_ctrl(padapter, sa) == _FALSE)
  1184. {
  1185. status = _STATS_UNABLE_HANDLE_STA_;
  1186. goto auth_fail;
  1187. }
  1188. #endif
  1189. pstat = rtw_get_stainfo(pstapriv, sa);
  1190. if (pstat == NULL)
  1191. {
  1192. // allocate a new one
  1193. DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
  1194. pstat = rtw_alloc_stainfo(pstapriv, sa);
  1195. if (pstat == NULL)
  1196. {
  1197. DBG_871X(" Exceed the upper limit of supported clients...\n");
  1198. status = _STATS_UNABLE_HANDLE_STA_;
  1199. goto auth_fail;
  1200. }
  1201. pstat->state = WIFI_FW_AUTH_NULL;
  1202. pstat->auth_seq = 0;
  1203. //pstat->flags = 0;
  1204. //pstat->capability = 0;
  1205. }
  1206. else
  1207. {
  1208. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1209. if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
  1210. {
  1211. rtw_list_delete(&pstat->asoc_list);
  1212. pstapriv->asoc_list_cnt--;
  1213. if (pstat->expire_to > 0)
  1214. {
  1215. //TODO: STA re_auth within expire_to
  1216. }
  1217. }
  1218. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1219. if (seq==1) {
  1220. //TODO: STA re_auth and auth timeout
  1221. }
  1222. }
  1223. _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1224. if (rtw_is_list_empty(&pstat->auth_list))
  1225. {
  1226. rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
  1227. pstapriv->auth_list_cnt++;
  1228. }
  1229. _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1230. if (pstat->auth_seq == 0)
  1231. pstat->expire_to = pstapriv->auth_to;
  1232. if ((pstat->auth_seq + 1) != seq)
  1233. {
  1234. DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1235. seq, pstat->auth_seq+1);
  1236. status = _STATS_OUT_OF_AUTH_SEQ_;
  1237. goto auth_fail;
  1238. }
  1239. if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
  1240. {
  1241. if (seq == 1)
  1242. {
  1243. pstat->state &= ~WIFI_FW_AUTH_NULL;
  1244. pstat->state |= WIFI_FW_AUTH_SUCCESS;
  1245. pstat->expire_to = pstapriv->assoc_to;
  1246. pstat->authalg = algorithm;
  1247. }
  1248. else
  1249. {
  1250. DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1251. seq, pstat->auth_seq+1);
  1252. status = _STATS_OUT_OF_AUTH_SEQ_;
  1253. goto auth_fail;
  1254. }
  1255. }
  1256. else // shared system or auto authentication
  1257. {
  1258. if (seq == 1)
  1259. {
  1260. //prepare for the challenging txt...
  1261. //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
  1262. _rtw_memset((void *)pstat->chg_txt, 78, 128);
  1263. pstat->state &= ~WIFI_FW_AUTH_NULL;
  1264. pstat->state |= WIFI_FW_AUTH_STATE;
  1265. pstat->authalg = algorithm;
  1266. pstat->auth_seq = 2;
  1267. }
  1268. else if (seq == 3)
  1269. {
  1270. //checking for challenging txt...
  1271. DBG_871X("checking for challenging txt...\n");
  1272. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
  1273. len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
  1274. if((p==NULL) || (ie_len<=0))
  1275. {
  1276. DBG_871X("auth rejected because challenge failure!(1)\n");
  1277. status = _STATS_CHALLENGE_FAIL_;
  1278. goto auth_fail;
  1279. }
  1280. if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
  1281. {
  1282. pstat->state &= (~WIFI_FW_AUTH_STATE);
  1283. pstat->state |= WIFI_FW_AUTH_SUCCESS;
  1284. // challenging txt is correct...
  1285. pstat->expire_to = pstapriv->assoc_to;
  1286. }
  1287. else
  1288. {
  1289. DBG_871X("auth rejected because challenge failure!\n");
  1290. status = _STATS_CHALLENGE_FAIL_;
  1291. goto auth_fail;
  1292. }
  1293. }
  1294. else
  1295. {
  1296. DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
  1297. seq, pstat->auth_seq+1);
  1298. status = _STATS_OUT_OF_AUTH_SEQ_;
  1299. goto auth_fail;
  1300. }
  1301. }
  1302. // Now, we are going to issue_auth...
  1303. pstat->auth_seq = seq + 1;
  1304. #ifdef CONFIG_NATIVEAP_MLME
  1305. issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
  1306. #endif
  1307. if (pstat->state & WIFI_FW_AUTH_SUCCESS)
  1308. pstat->auth_seq = 0;
  1309. return _SUCCESS;
  1310. auth_fail:
  1311. if(pstat)
  1312. rtw_free_stainfo(padapter , pstat);
  1313. pstat = &stat;
  1314. _rtw_memset((char *)pstat, '\0', sizeof(stat));
  1315. pstat->auth_seq = 2;
  1316. _rtw_memcpy(pstat->hwaddr, sa, 6);
  1317. #ifdef CONFIG_NATIVEAP_MLME
  1318. issue_auth(padapter, pstat, (unsigned short)status);
  1319. #endif
  1320. #endif
  1321. return _FAIL;
  1322. }
  1323. unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
  1324. {
  1325. unsigned int seq, len, status, algthm, offset;
  1326. unsigned char *p;
  1327. unsigned int go2asoc = 0;
  1328. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1329. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1330. u8 *pframe = precv_frame->u.hdr.rx_data;
  1331. uint pkt_len = precv_frame->u.hdr.len;
  1332. DBG_871X("%s\n", __FUNCTION__);
  1333. //check A1 matches or not
  1334. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  1335. return _SUCCESS;
  1336. if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
  1337. return _SUCCESS;
  1338. offset = (GetPrivacy(pframe))? 4: 0;
  1339. algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
  1340. seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
  1341. status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
  1342. if (status != 0)
  1343. {
  1344. DBG_871X("clnt auth fail, status: %d\n", status);
  1345. if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
  1346. {
  1347. if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1348. pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
  1349. else
  1350. pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
  1351. //pmlmeinfo->reauth_count = 0;
  1352. }
  1353. set_link_timer(pmlmeext, 1);
  1354. goto authclnt_fail;
  1355. }
  1356. if (seq == 2)
  1357. {
  1358. if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1359. {
  1360. // legendary shared system
  1361. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
  1362. pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
  1363. if (p == NULL)
  1364. {
  1365. //DBG_871X("marc: no challenge text?\n");
  1366. goto authclnt_fail;
  1367. }
  1368. _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
  1369. pmlmeinfo->auth_seq = 3;
  1370. issue_auth(padapter, NULL, 0);
  1371. set_link_timer(pmlmeext, REAUTH_TO);
  1372. return _SUCCESS;
  1373. }
  1374. else
  1375. {
  1376. // open system
  1377. go2asoc = 1;
  1378. }
  1379. }
  1380. else if (seq == 4)
  1381. {
  1382. if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
  1383. {
  1384. go2asoc = 1;
  1385. }
  1386. else
  1387. {
  1388. goto authclnt_fail;
  1389. }
  1390. }
  1391. else
  1392. {
  1393. // this is also illegal
  1394. //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
  1395. goto authclnt_fail;
  1396. }
  1397. if (go2asoc)
  1398. {
  1399. DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
  1400. start_clnt_assoc(padapter);
  1401. return _SUCCESS;
  1402. }
  1403. authclnt_fail:
  1404. //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
  1405. return _FAIL;
  1406. }
  1407. unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
  1408. {
  1409. #ifdef CONFIG_AP_MODE
  1410. _irqL irqL;
  1411. u16 capab_info, listen_interval;
  1412. struct rtw_ieee802_11_elems elems;
  1413. struct sta_info *pstat;
  1414. unsigned char reassoc, *p, *pos, *wpa_ie;
  1415. unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
  1416. int i, ie_len, wpa_ie_len, left;
  1417. unsigned char supportRate[16];
  1418. int supportRateNum;
  1419. unsigned short status = _STATS_SUCCESSFUL_;
  1420. unsigned short frame_type, ie_offset=0;
  1421. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1422. struct security_priv *psecuritypriv = &padapter->securitypriv;
  1423. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1424. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1425. WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
  1426. struct sta_priv *pstapriv = &padapter->stapriv;
  1427. u8 *pframe = precv_frame->u.hdr.rx_data;
  1428. uint pkt_len = precv_frame->u.hdr.len;
  1429. #ifdef CONFIG_P2P
  1430. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  1431. u8 p2p_status_code = P2P_STATUS_SUCCESS;
  1432. u8 *p2pie;
  1433. u32 p2pielen = 0;
  1434. #ifdef CONFIG_WFD
  1435. u8 wfd_ie[ 128 ] = { 0x00 };
  1436. u32 wfd_ielen = 0;
  1437. #endif // CONFIG_WFD
  1438. #endif //CONFIG_P2P
  1439. #ifdef CONFIG_CONCURRENT_MODE
  1440. if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  1441. check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  1442. {
  1443. //don't process assoc request;
  1444. return _SUCCESS;
  1445. }
  1446. #endif //CONFIG_CONCURRENT_MODE
  1447. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  1448. return _FAIL;
  1449. frame_type = GetFrameSubType(pframe);
  1450. if (frame_type == WIFI_ASSOCREQ)
  1451. {
  1452. reassoc = 0;
  1453. ie_offset = _ASOCREQ_IE_OFFSET_;
  1454. }
  1455. else // WIFI_REASSOCREQ
  1456. {
  1457. reassoc = 1;
  1458. ie_offset = _REASOCREQ_IE_OFFSET_;
  1459. }
  1460. if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
  1461. DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
  1462. "\n", reassoc, (unsigned long)pkt_len);
  1463. return _FAIL;
  1464. }
  1465. pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  1466. if (pstat == (struct sta_info *)NULL)
  1467. {
  1468. status = _RSON_CLS2_;
  1469. goto asoc_class2_error;
  1470. }
  1471. capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
  1472. //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  1473. //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
  1474. listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
  1475. left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
  1476. pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
  1477. DBG_871X("%s\n", __FUNCTION__);
  1478. // check if this stat has been successfully authenticated/assocated
  1479. if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
  1480. {
  1481. if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
  1482. {
  1483. status = _RSON_CLS2_;
  1484. goto asoc_class2_error;
  1485. }
  1486. else
  1487. {
  1488. pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
  1489. pstat->state |= WIFI_FW_ASSOC_STATE;
  1490. }
  1491. }
  1492. else
  1493. {
  1494. pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
  1495. pstat->state |= WIFI_FW_ASSOC_STATE;
  1496. }
  1497. #if 0// todo:tkip_countermeasures
  1498. if (hapd->tkip_countermeasures) {
  1499. resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
  1500. goto fail;
  1501. }
  1502. #endif
  1503. pstat->capability = capab_info;
  1504. #if 0//todo:
  1505. //check listen_interval
  1506. if (listen_interval > hapd->conf->max_listen_interval) {
  1507. hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
  1508. HOSTAPD_LEVEL_DEBUG,
  1509. "Too large Listen Interval (%d)",
  1510. listen_interval);
  1511. resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
  1512. goto fail;
  1513. }
  1514. pstat->listen_interval = listen_interval;
  1515. #endif
  1516. //now parse all ieee802_11 ie to point to elems
  1517. if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
  1518. !elems.ssid) {
  1519. DBG_871X("STA " MAC_FMT " sent invalid association request\n",
  1520. MAC_ARG(pstat->hwaddr));
  1521. status = _STATS_FAILURE_;
  1522. goto OnAssocReqFail;
  1523. }
  1524. // now we should check all the fields...
  1525. // checking SSID
  1526. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
  1527. pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1528. if (p == NULL)
  1529. {
  1530. status = _STATS_FAILURE_;
  1531. }
  1532. if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
  1533. status = _STATS_FAILURE_;
  1534. else
  1535. {
  1536. // check if ssid match
  1537. if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
  1538. status = _STATS_FAILURE_;
  1539. if (ie_len != cur->Ssid.SsidLength)
  1540. status = _STATS_FAILURE_;
  1541. }
  1542. if(_STATS_SUCCESSFUL_ != status)
  1543. goto OnAssocReqFail;
  1544. // check if the supported rate is ok
  1545. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1546. if (p == NULL) {
  1547. DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
  1548. // use our own rate set as statoin used
  1549. //_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
  1550. //supportRateNum = AP_BSSRATE_LEN;
  1551. status = _STATS_FAILURE_;
  1552. goto OnAssocReqFail;
  1553. }
  1554. else {
  1555. _rtw_memcpy(supportRate, p+2, ie_len);
  1556. supportRateNum = ie_len;
  1557. p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
  1558. pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1559. if (p != NULL) {
  1560. if(supportRateNum<=sizeof(supportRate))
  1561. {
  1562. _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
  1563. supportRateNum += ie_len;
  1564. }
  1565. }
  1566. }
  1567. //todo: mask supportRate between AP & STA -> move to update raid
  1568. //get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
  1569. //update station supportRate
  1570. pstat->bssratelen = supportRateNum;
  1571. _rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
  1572. UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
  1573. //check RSN/WPA/WPS
  1574. pstat->dot8021xalg = 0;
  1575. pstat->wpa_psk = 0;
  1576. pstat->wpa_group_cipher = 0;
  1577. pstat->wpa2_group_cipher = 0;
  1578. pstat->wpa_pairwise_cipher = 0;
  1579. pstat->wpa2_pairwise_cipher = 0;
  1580. _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
  1581. if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
  1582. int group_cipher=0, pairwise_cipher=0;
  1583. wpa_ie = elems.rsn_ie;
  1584. wpa_ie_len = elems.rsn_ie_len;
  1585. if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
  1586. {
  1587. pstat->dot8021xalg = 1;//psk, todo:802.1x
  1588. pstat->wpa_psk |= BIT(1);
  1589. pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
  1590. pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
  1591. if(!pstat->wpa2_group_cipher)
  1592. status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
  1593. if(!pstat->wpa2_pairwise_cipher)
  1594. status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
  1595. }
  1596. else
  1597. {
  1598. status = WLAN_STATUS_INVALID_IE;
  1599. }
  1600. } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
  1601. int group_cipher=0, pairwise_cipher=0;
  1602. wpa_ie = elems.wpa_ie;
  1603. wpa_ie_len = elems.wpa_ie_len;
  1604. if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
  1605. {
  1606. pstat->dot8021xalg = 1;//psk, todo:802.1x
  1607. pstat->wpa_psk |= BIT(0);
  1608. pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
  1609. pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
  1610. if(!pstat->wpa_group_cipher)
  1611. status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
  1612. if(!pstat->wpa_pairwise_cipher)
  1613. status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
  1614. }
  1615. else
  1616. {
  1617. status = WLAN_STATUS_INVALID_IE;
  1618. }
  1619. } else {
  1620. wpa_ie = NULL;
  1621. wpa_ie_len = 0;
  1622. }
  1623. if(_STATS_SUCCESSFUL_ != status)
  1624. goto OnAssocReqFail;
  1625. pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
  1626. //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
  1627. if(wpa_ie == NULL) {
  1628. if (elems.wps_ie) {
  1629. DBG_871X("STA included WPS IE in "
  1630. "(Re)Association Request - assume WPS is "
  1631. "used\n");
  1632. pstat->flags |= WLAN_STA_WPS;
  1633. //wpabuf_free(sta->wps_ie);
  1634. //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
  1635. // elems.wps_ie_len - 4);
  1636. } else {
  1637. DBG_871X("STA did not include WPA/RSN IE "
  1638. "in (Re)Association Request - possible WPS "
  1639. "use\n");
  1640. pstat->flags |= WLAN_STA_MAYBE_WPS;
  1641. }
  1642. // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
  1643. // that the selected registrar of AP is _FLASE
  1644. if((psecuritypriv->wpa_psk >0)
  1645. && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
  1646. {
  1647. if(pmlmepriv->wps_beacon_ie)
  1648. {
  1649. u8 selected_registrar = 0;
  1650. rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
  1651. if(!selected_registrar)
  1652. {
  1653. DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
  1654. status = _STATS_UNABLE_HANDLE_STA_;
  1655. goto OnAssocReqFail;
  1656. }
  1657. }
  1658. }
  1659. }
  1660. else
  1661. {
  1662. int copy_len;
  1663. if(psecuritypriv->wpa_psk == 0)
  1664. {
  1665. DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
  1666. "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
  1667. status = WLAN_STATUS_INVALID_IE;
  1668. goto OnAssocReqFail;
  1669. }
  1670. if (elems.wps_ie) {
  1671. DBG_871X("STA included WPS IE in "
  1672. "(Re)Association Request - WPS is "
  1673. "used\n");
  1674. pstat->flags |= WLAN_STA_WPS;
  1675. copy_len=0;
  1676. }
  1677. else
  1678. {
  1679. copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
  1680. }
  1681. if(copy_len>0)
  1682. _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
  1683. }
  1684. // check if there is WMM IE & support WWM-PS
  1685. pstat->flags &= ~WLAN_STA_WME;
  1686. pstat->qos_option = 0;
  1687. pstat->qos_info = 0;
  1688. pstat->has_legacy_ac = _TRUE;
  1689. pstat->uapsd_vo = 0;
  1690. pstat->uapsd_vi = 0;
  1691. pstat->uapsd_be = 0;
  1692. pstat->uapsd_bk = 0;
  1693. if (pmlmepriv->qospriv.qos_option)
  1694. {
  1695. p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
  1696. for (;;)
  1697. {
  1698. p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  1699. if (p != NULL) {
  1700. if (_rtw_memcmp(p+2, WMM_IE, 6)) {
  1701. pstat->flags |= WLAN_STA_WME;
  1702. pstat->qos_option = 1;
  1703. pstat->qos_info = *(p+8);
  1704. pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
  1705. if((pstat->qos_info&0xf) !=0xf)
  1706. pstat->has_legacy_ac = _TRUE;
  1707. else
  1708. pstat->has_legacy_ac = _FALSE;
  1709. if(pstat->qos_info&0xf)
  1710. {
  1711. if(pstat->qos_info&BIT(0))
  1712. pstat->uapsd_vo = BIT(0)|BIT(1);
  1713. else
  1714. pstat->uapsd_vo = 0;
  1715. if(pstat->qos_info&BIT(1))
  1716. pstat->uapsd_vi = BIT(0)|BIT(1);
  1717. else
  1718. pstat->uapsd_vi = 0;
  1719. if(pstat->qos_info&BIT(2))
  1720. pstat->uapsd_bk = BIT(0)|BIT(1);
  1721. else
  1722. pstat->uapsd_bk = 0;
  1723. if(pstat->qos_info&BIT(3))
  1724. pstat->uapsd_be = BIT(0)|BIT(1);
  1725. else
  1726. pstat->uapsd_be = 0;
  1727. }
  1728. break;
  1729. }
  1730. }
  1731. else {
  1732. break;
  1733. }
  1734. p = p + ie_len + 2;
  1735. }
  1736. }
  1737. #ifdef CONFIG_80211N_HT
  1738. /* save HT capabilities in the sta object */
  1739. _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
  1740. if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
  1741. {
  1742. pstat->flags |= WLAN_STA_HT;
  1743. pstat->flags |= WLAN_STA_WME;
  1744. _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
  1745. } else
  1746. pstat->flags &= ~WLAN_STA_HT;
  1747. if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
  1748. {
  1749. status = _STATS_FAILURE_;
  1750. goto OnAssocReqFail;
  1751. }
  1752. if ((pstat->flags & WLAN_STA_HT) &&
  1753. ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
  1754. (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
  1755. {
  1756. DBG_871X("HT: " MAC_FMT " tried to "
  1757. "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
  1758. //status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
  1759. //goto OnAssocReqFail;
  1760. }
  1761. #endif /* CONFIG_80211N_HT */
  1762. #ifdef CONFIG_80211AC_VHT
  1763. _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
  1764. if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
  1765. pstat->flags |= WLAN_STA_VHT;
  1766. _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
  1767. if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
  1768. pstat->vhtpriv.bwmode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(elems.vht_op_mode_notify);
  1769. }
  1770. }
  1771. else {
  1772. pstat->flags &= ~WLAN_STA_HT;
  1773. }
  1774. if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
  1775. {
  1776. status = _STATS_FAILURE_;
  1777. goto OnAssocReqFail;
  1778. }
  1779. #endif /* CONFIG_80211AC_VHT */
  1780. //
  1781. //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
  1782. pstat->flags |= WLAN_STA_NONERP;
  1783. for (i = 0; i < pstat->bssratelen; i++) {
  1784. if ((pstat->bssrateset[i] & 0x7f) > 22) {
  1785. pstat->flags &= ~WLAN_STA_NONERP;
  1786. break;
  1787. }
  1788. }
  1789. if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
  1790. pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
  1791. else
  1792. pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
  1793. if (status != _STATS_SUCCESSFUL_)
  1794. goto OnAssocReqFail;
  1795. #ifdef CONFIG_P2P
  1796. pstat->is_p2p_device = _FALSE;
  1797. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  1798. {
  1799. if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
  1800. {
  1801. pstat->is_p2p_device = _TRUE;
  1802. if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
  1803. {
  1804. pstat->p2p_status_code = p2p_status_code;
  1805. status = _STATS_CAP_FAIL_;
  1806. goto OnAssocReqFail;
  1807. }
  1808. }
  1809. #ifdef CONFIG_WFD
  1810. if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
  1811. {
  1812. u8 attr_content[ 10 ] = { 0x00 };
  1813. u32 attr_contentlen = 0;
  1814. DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
  1815. rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
  1816. if ( attr_contentlen )
  1817. {
  1818. pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
  1819. DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
  1820. }
  1821. }
  1822. #endif
  1823. }
  1824. pstat->p2p_status_code = p2p_status_code;
  1825. #endif //CONFIG_P2P
  1826. //TODO: identify_proprietary_vendor_ie();
  1827. // Realtek proprietary IE
  1828. // identify if this is Broadcom sta
  1829. // identify if this is ralink sta
  1830. // Customer proprietary IE
  1831. /* get a unique AID */
  1832. if (pstat->aid > 0) {
  1833. DBG_871X(" old AID %d\n", pstat->aid);
  1834. } else {
  1835. for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
  1836. if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
  1837. break;
  1838. //if (pstat->aid > NUM_STA) {
  1839. if (pstat->aid > pstapriv->max_num_sta) {
  1840. pstat->aid = 0;
  1841. DBG_871X(" no room for more AIDs\n");
  1842. status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
  1843. goto OnAssocReqFail;
  1844. } else {
  1845. pstapriv->sta_aid[pstat->aid - 1] = pstat;
  1846. DBG_871X("allocate new AID = (%d)\n", pstat->aid);
  1847. }
  1848. }
  1849. pstat->state &= (~WIFI_FW_ASSOC_STATE);
  1850. pstat->state |= WIFI_FW_ASSOC_SUCCESS;
  1851. _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1852. if (!rtw_is_list_empty(&pstat->auth_list))
  1853. {
  1854. rtw_list_delete(&pstat->auth_list);
  1855. pstapriv->auth_list_cnt--;
  1856. }
  1857. _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
  1858. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1859. if (rtw_is_list_empty(&pstat->asoc_list))
  1860. {
  1861. pstat->expire_to = pstapriv->expire_to;
  1862. rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
  1863. pstapriv->asoc_list_cnt++;
  1864. }
  1865. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  1866. // now the station is qualified to join our BSS...
  1867. if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
  1868. {
  1869. #ifdef CONFIG_NATIVEAP_MLME
  1870. //.1 bss_cap_update & sta_info_update
  1871. bss_cap_update_on_sta_join(padapter, pstat);
  1872. sta_info_update(padapter, pstat);
  1873. //issue assoc rsp before notify station join event.
  1874. if (frame_type == WIFI_ASSOCREQ)
  1875. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1876. else
  1877. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1878. //.2 - report to upper layer
  1879. DBG_871X("indicate_sta_join_event to upper layer - hostapd\n");
  1880. #ifdef CONFIG_IOCTL_CFG80211
  1881. #ifdef COMPAT_KERNEL_RELEASE
  1882. rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
  1883. #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1884. rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
  1885. #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1886. _enter_critical_bh(&pstat->lock, &irqL);
  1887. if(pstat->passoc_req)
  1888. {
  1889. rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
  1890. pstat->passoc_req = NULL;
  1891. pstat->assoc_req_len = 0;
  1892. }
  1893. pstat->passoc_req = rtw_zmalloc(pkt_len);
  1894. if(pstat->passoc_req)
  1895. {
  1896. _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
  1897. pstat->assoc_req_len = pkt_len;
  1898. }
  1899. _exit_critical_bh(&pstat->lock, &irqL);
  1900. #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
  1901. #else
  1902. rtw_indicate_sta_assoc_event(padapter, pstat);
  1903. #endif //CONFIG_IOCTL_CFG80211
  1904. //.3-(1) report sta add event
  1905. report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
  1906. /*
  1907. //issue assoc rsp before notify station join event.
  1908. if (frame_type == WIFI_ASSOCREQ)
  1909. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1910. else
  1911. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1912. */
  1913. #endif
  1914. }
  1915. return _SUCCESS;
  1916. asoc_class2_error:
  1917. #ifdef CONFIG_NATIVEAP_MLME
  1918. issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
  1919. #endif
  1920. return _FAIL;
  1921. OnAssocReqFail:
  1922. #ifdef CONFIG_NATIVEAP_MLME
  1923. pstat->aid = 0;
  1924. if (frame_type == WIFI_ASSOCREQ)
  1925. issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
  1926. else
  1927. issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
  1928. #endif
  1929. #endif /* CONFIG_AP_MODE */
  1930. return _FAIL;
  1931. }
  1932. unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
  1933. {
  1934. uint i;
  1935. int res;
  1936. unsigned short status;
  1937. PNDIS_802_11_VARIABLE_IEs pIE;
  1938. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  1939. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  1940. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  1941. //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  1942. u8 *pframe = precv_frame->u.hdr.rx_data;
  1943. uint pkt_len = precv_frame->u.hdr.len;
  1944. PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
  1945. DBG_871X("%s\n", __FUNCTION__);
  1946. //check A1 matches or not
  1947. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  1948. return _SUCCESS;
  1949. if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
  1950. return _SUCCESS;
  1951. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  1952. return _SUCCESS;
  1953. _cancel_timer_ex(&pmlmeext->link_timer);
  1954. //status
  1955. if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
  1956. {
  1957. DBG_871X("assoc reject, status code: %d\n", status);
  1958. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  1959. res = -4;
  1960. goto report_assoc_result;
  1961. }
  1962. //get capabilities
  1963. pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  1964. //set slot time
  1965. pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
  1966. //AID
  1967. res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
  1968. //following are moved to join event callback function
  1969. //to handle HT, WMM, rate adaptive, update MAC reg
  1970. //for not to handle the synchronous IO in the tasklet
  1971. for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
  1972. {
  1973. pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
  1974. switch (pIE->ElementID)
  1975. {
  1976. case _VENDOR_SPECIFIC_IE_:
  1977. if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
  1978. {
  1979. WMM_param_handler(padapter, pIE);
  1980. }
  1981. #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
  1982. else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
  1983. {
  1984. DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
  1985. WFD_info_handler( padapter, pIE );
  1986. }
  1987. #endif
  1988. break;
  1989. #ifdef CONFIG_WAPI_SUPPORT
  1990. case _WAPI_IE_:
  1991. pWapiIE = pIE;
  1992. break;
  1993. #endif
  1994. case _HT_CAPABILITY_IE_: //HT caps
  1995. HT_caps_handler(padapter, pIE);
  1996. break;
  1997. case _HT_EXTRA_INFO_IE_: //HT info
  1998. HT_info_handler(padapter, pIE);
  1999. break;
  2000. #ifdef CONFIG_80211AC_VHT
  2001. case EID_VHTCapability:
  2002. VHT_caps_handler(padapter, pIE);
  2003. break;
  2004. case EID_VHTOperation:
  2005. VHT_operation_handler(padapter, pIE);
  2006. break;
  2007. #endif
  2008. case _ERPINFO_IE_:
  2009. ERP_IE_handler(padapter, pIE);
  2010. default:
  2011. break;
  2012. }
  2013. i += (pIE->Length + 2);
  2014. }
  2015. #ifdef CONFIG_WAPI_SUPPORT
  2016. rtw_wapi_on_assoc_ok(padapter, pIE);
  2017. #endif
  2018. pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
  2019. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  2020. //Update Basic Rate Table for spec, 2010-12-28 , by thomas
  2021. UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
  2022. report_assoc_result:
  2023. if (res > 0) {
  2024. rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
  2025. } else {
  2026. rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
  2027. }
  2028. report_join_res(padapter, res);
  2029. return _SUCCESS;
  2030. }
  2031. unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
  2032. {
  2033. unsigned short reason;
  2034. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2035. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2036. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2037. u8 *pframe = precv_frame->u.hdr.rx_data;
  2038. #ifdef CONFIG_P2P
  2039. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  2040. #endif //CONFIG_P2P
  2041. //check A3
  2042. if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  2043. return _SUCCESS;
  2044. #ifdef CONFIG_P2P
  2045. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  2046. {
  2047. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  2048. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  2049. }
  2050. #endif //CONFIG_P2P
  2051. reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  2052. DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
  2053. #ifdef CONFIG_AP_MODE
  2054. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  2055. {
  2056. _irqL irqL;
  2057. struct sta_info *psta;
  2058. struct sta_priv *pstapriv = &padapter->stapriv;
  2059. //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2060. //rtw_free_stainfo(padapter, psta);
  2061. //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2062. DBG_871X_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
  2063. reason, GetAddr2Ptr(pframe));
  2064. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2065. if(psta)
  2066. {
  2067. u8 updated;
  2068. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2069. if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
  2070. {
  2071. rtw_list_delete(&psta->asoc_list);
  2072. pstapriv->asoc_list_cnt--;
  2073. updated = ap_free_sta(padapter, psta, _FALSE, reason);
  2074. }
  2075. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2076. associated_clients_update(padapter, updated);
  2077. }
  2078. return _SUCCESS;
  2079. }
  2080. else
  2081. #endif
  2082. {
  2083. DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
  2084. reason, GetAddr3Ptr(pframe));
  2085. receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
  2086. }
  2087. pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
  2088. return _SUCCESS;
  2089. }
  2090. unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
  2091. {
  2092. unsigned short reason;
  2093. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  2094. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2095. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2096. u8 *pframe = precv_frame->u.hdr.rx_data;
  2097. #ifdef CONFIG_P2P
  2098. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  2099. #endif //CONFIG_P2P
  2100. //check A3
  2101. if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  2102. return _SUCCESS;
  2103. #ifdef CONFIG_P2P
  2104. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  2105. {
  2106. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  2107. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  2108. }
  2109. #endif //CONFIG_P2P
  2110. reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
  2111. DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
  2112. #ifdef CONFIG_AP_MODE
  2113. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
  2114. {
  2115. _irqL irqL;
  2116. struct sta_info *psta;
  2117. struct sta_priv *pstapriv = &padapter->stapriv;
  2118. //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2119. //rtw_free_stainfo(padapter, psta);
  2120. //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
  2121. DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
  2122. reason, GetAddr2Ptr(pframe));
  2123. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2124. if(psta)
  2125. {
  2126. u8 updated;
  2127. _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2128. if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
  2129. {
  2130. rtw_list_delete(&psta->asoc_list);
  2131. pstapriv->asoc_list_cnt--;
  2132. updated = ap_free_sta(padapter, psta, _FALSE, reason);
  2133. }
  2134. _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
  2135. associated_clients_update(padapter, updated);
  2136. }
  2137. return _SUCCESS;
  2138. }
  2139. else
  2140. #endif
  2141. {
  2142. DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
  2143. reason, GetAddr3Ptr(pframe));
  2144. receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
  2145. }
  2146. pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
  2147. return _SUCCESS;
  2148. }
  2149. unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
  2150. {
  2151. DBG_871X("%s\n", __FUNCTION__);
  2152. return _SUCCESS;
  2153. }
  2154. unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
  2155. {
  2156. unsigned int ret = _FAIL;
  2157. struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
  2158. struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
  2159. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
  2160. ret = _SUCCESS;
  2161. goto exit;
  2162. }
  2163. if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
  2164. int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
  2165. int ch_offset = -1;
  2166. u8 bwmode;
  2167. struct ieee80211_info_element *ie;
  2168. DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
  2169. FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
  2170. for_each_ie(ie, ies, ies_len) {
  2171. if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
  2172. ch_switch_mode = ie->data[0];
  2173. ch = ie->data[1];
  2174. ch_switch_cnt = ie->data[2];
  2175. DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
  2176. ch_switch_mode, ch, ch_switch_cnt);
  2177. }
  2178. else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
  2179. ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
  2180. DBG_871X("ch_offset:%d\n", ch_offset);
  2181. }
  2182. }
  2183. if (ch == -1)
  2184. return _SUCCESS;
  2185. if (ch_offset == -1)
  2186. bwmode = mlmeext->cur_bwmode;
  2187. else
  2188. bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
  2189. CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
  2190. ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
  2191. /* todo:
  2192. * 1. the decision of channel switching
  2193. * 2. things after channel switching
  2194. */
  2195. ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
  2196. }
  2197. exit:
  2198. return ret;
  2199. }
  2200. unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
  2201. {
  2202. unsigned int ret = _FAIL;
  2203. struct sta_info *psta = NULL;
  2204. struct sta_priv *pstapriv = &padapter->stapriv;
  2205. u8 *pframe = precv_frame->u.hdr.rx_data;
  2206. uint frame_len = precv_frame->u.hdr.len;
  2207. u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2208. u8 category;
  2209. u8 action;
  2210. DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
  2211. psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
  2212. if (!psta)
  2213. goto exit;
  2214. category = frame_body[0];
  2215. if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
  2216. goto exit;
  2217. action = frame_body[1];
  2218. switch (action) {
  2219. case RTW_WLAN_ACTION_SPCT_MSR_REQ:
  2220. case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
  2221. case RTW_WLAN_ACTION_SPCT_TPC_REQ:
  2222. case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
  2223. break;
  2224. case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
  2225. #ifdef CONFIG_SPCT_CH_SWITCH
  2226. ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
  2227. frame_len-(frame_body-pframe)-2);
  2228. #endif
  2229. break;
  2230. default:
  2231. break;
  2232. }
  2233. exit:
  2234. return ret;
  2235. }
  2236. unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
  2237. {
  2238. return _SUCCESS;
  2239. }
  2240. unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
  2241. {
  2242. return _SUCCESS;
  2243. }
  2244. unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
  2245. {
  2246. u8 *addr;
  2247. struct sta_info *psta=NULL;
  2248. struct recv_reorder_ctrl *preorder_ctrl;
  2249. unsigned char *frame_body;
  2250. unsigned char category, action;
  2251. unsigned short tid, status, reason_code = 0;
  2252. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  2253. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2254. u8 *pframe = precv_frame->u.hdr.rx_data;
  2255. struct sta_priv *pstapriv = &padapter->stapriv;
  2256. #ifdef CONFIG_80211N_HT
  2257. //check RA matches or not
  2258. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
  2259. return _SUCCESS;
  2260. /*
  2261. //check A1 matches or not
  2262. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
  2263. return _SUCCESS;
  2264. */
  2265. DBG_871X("%s\n", __FUNCTION__);
  2266. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  2267. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  2268. return _SUCCESS;
  2269. addr = GetAddr2Ptr(pframe);
  2270. psta = rtw_get_stainfo(pstapriv, addr);
  2271. if(psta==NULL)
  2272. return _SUCCESS;
  2273. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  2274. category = frame_body[0];
  2275. if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
  2276. {
  2277. #ifdef CONFIG_TDLS
  2278. if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
  2279. (psta->htpriv.ht_option==_TRUE) &&
  2280. (psta->htpriv.ampdu_enable==_TRUE) )
  2281. {
  2282. //do nothing; just don't want to return _SUCCESS;
  2283. }
  2284. else
  2285. #endif //CONFIG_TDLS
  2286. if (!pmlmeinfo->HT_enable)
  2287. {
  2288. return _SUCCESS;
  2289. }
  2290. action = frame_body[1];
  2291. DBG_871X("%s, action=%d\n", __FUNCTION__, action);
  2292. switch (action)
  2293. {
  2294. case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
  2295. _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
  2296. //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
  2297. process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
  2298. if(pmlmeinfo->bAcceptAddbaReq == _TRUE)
  2299. {
  2300. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
  2301. }
  2302. else
  2303. {
  2304. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);//reject ADDBA Req
  2305. }
  2306. break;
  2307. case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
  2308. //status = frame_body[3] | (frame_body[4] << 8); //endian issue
  2309. status = RTW_GET_LE16(&frame_body[3]);
  2310. tid = ((frame_body[5] >> 2) & 0x7);
  2311. if (status == 0)
  2312. { //successful
  2313. DBG_871X("agg_enable for TID=%d\n", tid);
  2314. psta->htpriv.agg_enable_bitmap |= 1 << tid;
  2315. psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
  2316. }
  2317. else
  2318. {
  2319. psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
  2320. }
  2321. //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
  2322. break;
  2323. case RTW_WLAN_ACTION_DELBA: //DELBA
  2324. if ((frame_body[3] & BIT(3)) == 0)
  2325. {
  2326. psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
  2327. psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
  2328. //reason_code = frame_body[4] | (frame_body[5] << 8);
  2329. reason_code = RTW_GET_LE16(&frame_body[4]);
  2330. }
  2331. else if((frame_body[3] & BIT(3)) == BIT(3))
  2332. {
  2333. tid = (frame_body[3] >> 4) & 0x0F;
  2334. preorder_ctrl = &psta->recvreorder_ctrl[tid];
  2335. preorder_ctrl->enable = _FALSE;
  2336. preorder_ctrl->indicate_seq = 0xffff;
  2337. #ifdef DBG_RX_SEQ
  2338. DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
  2339. preorder_ctrl->indicate_seq);
  2340. #endif
  2341. }
  2342. DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
  2343. //todo: how to notify the host while receiving DELETE BA
  2344. break;
  2345. default:
  2346. break;
  2347. }
  2348. }
  2349. #endif //CONFIG_80211N_HT
  2350. return _SUCCESS;
  2351. }
  2352. #ifdef CONFIG_P2P
  2353. static int get_reg_classes_full_count(struct p2p_channels channel_list) {
  2354. int cnt = 0;
  2355. int i;
  2356. for (i = 0; i < channel_list.reg_classes; i++) {
  2357. cnt += channel_list.reg_class[i].channels;
  2358. }
  2359. return cnt;
  2360. }
  2361. static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
  2362. {
  2363. int i = 0;
  2364. *p24g_cnt = 0;
  2365. *p5gl_cnt = 0;
  2366. *p5gh_cnt = 0;
  2367. for( i = 0; i < pmlmeext->max_chan_nums; i++ )
  2368. {
  2369. if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
  2370. {
  2371. (*p24g_cnt)++;
  2372. }
  2373. else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
  2374. {
  2375. // Just include the channel 36, 40, 44, 48 channels for 5G low
  2376. (*p5gl_cnt)++;
  2377. }
  2378. else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
  2379. {
  2380. // Just include the channel 149, 153, 157, 161 channels for 5G high
  2381. (*p5gh_cnt)++;
  2382. }
  2383. }
  2384. }
  2385. void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
  2386. {
  2387. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  2388. u8 action = P2P_PUB_ACTION_ACTION;
  2389. u32 p2poui = cpu_to_be32(P2POUI);
  2390. u8 oui_subtype = P2P_GO_NEGO_REQ;
  2391. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  2392. u8 wpsielen = 0, p2pielen = 0, i;
  2393. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  2394. u16 len_channellist_attr = 0;
  2395. #ifdef CONFIG_WFD
  2396. u32 wfdielen = 0;
  2397. #endif //CONFIG_WFD
  2398. struct xmit_frame *pmgntframe;
  2399. struct pkt_attrib *pattrib;
  2400. unsigned char *pframe;
  2401. struct rtw_ieee80211_hdr *pwlanhdr;
  2402. unsigned short *fctrl;
  2403. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  2404. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  2405. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2406. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  2407. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  2408. {
  2409. return;
  2410. }
  2411. DBG_871X( "[%s] In\n", __FUNCTION__ );
  2412. //update attribute
  2413. pattrib = &pmgntframe->attrib;
  2414. update_mgntframe_attrib(padapter, pattrib);
  2415. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  2416. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  2417. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  2418. fctrl = &(pwlanhdr->frame_ctl);
  2419. *(fctrl) = 0;
  2420. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  2421. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2422. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2423. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  2424. pmlmeext->mgnt_seq++;
  2425. SetFrameSubType(pframe, WIFI_ACTION);
  2426. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  2427. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  2428. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  2429. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  2430. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  2431. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  2432. pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
  2433. pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
  2434. // WPS Section
  2435. wpsielen = 0;
  2436. // WPS OUI
  2437. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  2438. wpsielen += 4;
  2439. // WPS version
  2440. // Type:
  2441. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  2442. wpsielen += 2;
  2443. // Length:
  2444. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  2445. wpsielen += 2;
  2446. // Value:
  2447. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  2448. // Device Password ID
  2449. // Type:
  2450. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  2451. wpsielen += 2;
  2452. // Length:
  2453. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  2454. wpsielen += 2;
  2455. // Value:
  2456. if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
  2457. {
  2458. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
  2459. }
  2460. else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
  2461. {
  2462. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
  2463. }
  2464. else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
  2465. {
  2466. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
  2467. }
  2468. wpsielen += 2;
  2469. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  2470. // P2P IE Section.
  2471. // P2P OUI
  2472. p2pielen = 0;
  2473. p2pie[ p2pielen++ ] = 0x50;
  2474. p2pie[ p2pielen++ ] = 0x6F;
  2475. p2pie[ p2pielen++ ] = 0x9A;
  2476. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  2477. // Commented by Albert 20110306
  2478. // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
  2479. // 1. P2P Capability
  2480. // 2. Group Owner Intent
  2481. // 3. Configuration Timeout
  2482. // 4. Listen Channel
  2483. // 5. Extended Listen Timing
  2484. // 6. Intended P2P Interface Address
  2485. // 7. Channel List
  2486. // 8. P2P Device Info
  2487. // 9. Operating Channel
  2488. // P2P Capability
  2489. // Type:
  2490. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  2491. // Length:
  2492. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2493. p2pielen += 2;
  2494. // Value:
  2495. // Device Capability Bitmap, 1 byte
  2496. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  2497. // Group Capability Bitmap, 1 byte
  2498. if ( pwdinfo->persistent_supported )
  2499. {
  2500. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  2501. }
  2502. else
  2503. {
  2504. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  2505. }
  2506. // Group Owner Intent
  2507. // Type:
  2508. p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
  2509. // Length:
  2510. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2511. p2pielen += 2;
  2512. // Value:
  2513. // Todo the tie breaker bit.
  2514. p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
  2515. // Configuration Timeout
  2516. // Type:
  2517. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  2518. // Length:
  2519. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2520. p2pielen += 2;
  2521. // Value:
  2522. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  2523. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  2524. // Listen Channel
  2525. // Type:
  2526. p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
  2527. // Length:
  2528. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2529. p2pielen += 2;
  2530. // Value:
  2531. // Country String
  2532. p2pie[ p2pielen++ ] = 'X';
  2533. p2pie[ p2pielen++ ] = 'X';
  2534. // The third byte should be set to 0x04.
  2535. // Described in the "Operating Channel Attribute" section.
  2536. p2pie[ p2pielen++ ] = 0x04;
  2537. // Operating Class
  2538. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  2539. // Channel Number
  2540. p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
  2541. // Extended Listen Timing ATTR
  2542. // Type:
  2543. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  2544. // Length:
  2545. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  2546. p2pielen += 2;
  2547. // Value:
  2548. // Availability Period
  2549. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  2550. p2pielen += 2;
  2551. // Availability Interval
  2552. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  2553. p2pielen += 2;
  2554. // Intended P2P Interface Address
  2555. // Type:
  2556. p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
  2557. // Length:
  2558. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  2559. p2pielen += 2;
  2560. // Value:
  2561. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2562. p2pielen += ETH_ALEN;
  2563. // Channel List
  2564. // Type:
  2565. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  2566. // Length:
  2567. // Country String(3)
  2568. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  2569. // + number of channels in all classes
  2570. len_channellist_attr = 3
  2571. + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
  2572. + get_reg_classes_full_count(pmlmeext->channel_list);
  2573. #ifdef CONFIG_CONCURRENT_MODE
  2574. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2575. {
  2576. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  2577. }
  2578. else
  2579. {
  2580. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2581. }
  2582. #else
  2583. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2584. #endif
  2585. p2pielen += 2;
  2586. // Value:
  2587. // Country String
  2588. p2pie[ p2pielen++ ] = 'X';
  2589. p2pie[ p2pielen++ ] = 'X';
  2590. // The third byte should be set to 0x04.
  2591. // Described in the "Operating Channel Attribute" section.
  2592. p2pie[ p2pielen++ ] = 0x04;
  2593. // Channel Entry List
  2594. #ifdef CONFIG_CONCURRENT_MODE
  2595. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2596. {
  2597. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2598. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  2599. // Operating Class
  2600. if ( pbuddy_mlmeext->cur_channel > 14 )
  2601. {
  2602. if ( pbuddy_mlmeext->cur_channel >= 149 )
  2603. {
  2604. p2pie[ p2pielen++ ] = 0x7c;
  2605. }
  2606. else
  2607. {
  2608. p2pie[ p2pielen++ ] = 0x73;
  2609. }
  2610. }
  2611. else
  2612. {
  2613. p2pie[ p2pielen++ ] = 0x51;
  2614. }
  2615. // Number of Channels
  2616. // Just support 1 channel and this channel is AP's channel
  2617. p2pie[ p2pielen++ ] = 1;
  2618. // Channel List
  2619. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  2620. }
  2621. else
  2622. {
  2623. int i,j;
  2624. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  2625. // Operating Class
  2626. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  2627. // Number of Channels
  2628. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  2629. // Channel List
  2630. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  2631. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  2632. }
  2633. }
  2634. }
  2635. #else // CONFIG_CONCURRENT_MODE
  2636. {
  2637. int i,j;
  2638. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  2639. // Operating Class
  2640. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  2641. // Number of Channels
  2642. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  2643. // Channel List
  2644. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  2645. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  2646. }
  2647. }
  2648. }
  2649. #endif // CONFIG_CONCURRENT_MODE
  2650. // Device Info
  2651. // Type:
  2652. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  2653. // Length:
  2654. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  2655. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  2656. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  2657. p2pielen += 2;
  2658. // Value:
  2659. // P2P Device Address
  2660. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2661. p2pielen += ETH_ALEN;
  2662. // Config Method
  2663. // This field should be big endian. Noted by P2P specification.
  2664. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  2665. p2pielen += 2;
  2666. // Primary Device Type
  2667. // Category ID
  2668. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  2669. p2pielen += 2;
  2670. // OUI
  2671. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  2672. p2pielen += 4;
  2673. // Sub Category ID
  2674. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  2675. p2pielen += 2;
  2676. // Number of Secondary Device Types
  2677. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  2678. // Device Name
  2679. // Type:
  2680. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  2681. p2pielen += 2;
  2682. // Length:
  2683. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  2684. p2pielen += 2;
  2685. // Value:
  2686. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
  2687. p2pielen += pwdinfo->device_name_len;
  2688. // Operating Channel
  2689. // Type:
  2690. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  2691. // Length:
  2692. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2693. p2pielen += 2;
  2694. // Value:
  2695. // Country String
  2696. p2pie[ p2pielen++ ] = 'X';
  2697. p2pie[ p2pielen++ ] = 'X';
  2698. // The third byte should be set to 0x04.
  2699. // Described in the "Operating Channel Attribute" section.
  2700. p2pie[ p2pielen++ ] = 0x04;
  2701. // Operating Class
  2702. if ( pwdinfo->operating_channel <= 14 )
  2703. {
  2704. // Operating Class
  2705. p2pie[ p2pielen++ ] = 0x51;
  2706. }
  2707. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  2708. {
  2709. // Operating Class
  2710. p2pie[ p2pielen++ ] = 0x73;
  2711. }
  2712. else
  2713. {
  2714. // Operating Class
  2715. p2pie[ p2pielen++ ] = 0x7c;
  2716. }
  2717. // Channel Number
  2718. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  2719. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  2720. #ifdef CONFIG_WFD
  2721. wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
  2722. pframe += wfdielen;
  2723. pattrib->pktlen += wfdielen;
  2724. #endif //CONFIG_WFD
  2725. pattrib->last_txcmdsz = pattrib->pktlen;
  2726. dump_mgntframe(padapter, pmgntframe);
  2727. return;
  2728. }
  2729. void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
  2730. {
  2731. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  2732. u8 action = P2P_PUB_ACTION_ACTION;
  2733. u32 p2poui = cpu_to_be32(P2POUI);
  2734. u8 oui_subtype = P2P_GO_NEGO_RESP;
  2735. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  2736. u8 p2pielen = 0, i;
  2737. uint wpsielen = 0;
  2738. u16 wps_devicepassword_id = 0x0000;
  2739. uint wps_devicepassword_id_len = 0;
  2740. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
  2741. u16 len_channellist_attr = 0;
  2742. struct xmit_frame *pmgntframe;
  2743. struct pkt_attrib *pattrib;
  2744. unsigned char *pframe;
  2745. struct rtw_ieee80211_hdr *pwlanhdr;
  2746. unsigned short *fctrl;
  2747. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  2748. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  2749. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  2750. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  2751. #ifdef CONFIG_WFD
  2752. u32 wfdielen = 0;
  2753. #endif //CONFIG_WFD
  2754. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  2755. {
  2756. return;
  2757. }
  2758. DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
  2759. //update attribute
  2760. pattrib = &pmgntframe->attrib;
  2761. update_mgntframe_attrib(padapter, pattrib);
  2762. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  2763. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  2764. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  2765. fctrl = &(pwlanhdr->frame_ctl);
  2766. *(fctrl) = 0;
  2767. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  2768. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2769. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  2770. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  2771. pmlmeext->mgnt_seq++;
  2772. SetFrameSubType(pframe, WIFI_ACTION);
  2773. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  2774. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  2775. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  2776. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  2777. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  2778. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  2779. pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
  2780. pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
  2781. // Commented by Albert 20110328
  2782. // Try to get the device password ID from the WPS IE of group negotiation request frame
  2783. // WiFi Direct test plan 5.1.15
  2784. rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
  2785. rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
  2786. wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
  2787. _rtw_memset( wpsie, 0x00, 255 );
  2788. wpsielen = 0;
  2789. // WPS Section
  2790. wpsielen = 0;
  2791. // WPS OUI
  2792. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  2793. wpsielen += 4;
  2794. // WPS version
  2795. // Type:
  2796. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  2797. wpsielen += 2;
  2798. // Length:
  2799. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  2800. wpsielen += 2;
  2801. // Value:
  2802. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  2803. // Device Password ID
  2804. // Type:
  2805. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  2806. wpsielen += 2;
  2807. // Length:
  2808. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  2809. wpsielen += 2;
  2810. // Value:
  2811. if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
  2812. {
  2813. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
  2814. }
  2815. else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
  2816. {
  2817. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
  2818. }
  2819. else
  2820. {
  2821. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
  2822. }
  2823. wpsielen += 2;
  2824. // Commented by Kurt 20120113
  2825. // If some device wants to do p2p handshake without sending prov_disc_req
  2826. // We have to get peer_req_cm from here.
  2827. if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
  2828. {
  2829. if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
  2830. {
  2831. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
  2832. }
  2833. else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
  2834. {
  2835. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
  2836. }
  2837. else
  2838. {
  2839. _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
  2840. }
  2841. }
  2842. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  2843. // P2P IE Section.
  2844. // P2P OUI
  2845. p2pielen = 0;
  2846. p2pie[ p2pielen++ ] = 0x50;
  2847. p2pie[ p2pielen++ ] = 0x6F;
  2848. p2pie[ p2pielen++ ] = 0x9A;
  2849. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  2850. // Commented by Albert 20100908
  2851. // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
  2852. // 1. Status
  2853. // 2. P2P Capability
  2854. // 3. Group Owner Intent
  2855. // 4. Configuration Timeout
  2856. // 5. Operating Channel
  2857. // 6. Intended P2P Interface Address
  2858. // 7. Channel List
  2859. // 8. Device Info
  2860. // 9. Group ID ( Only GO )
  2861. // ToDo:
  2862. // P2P Status
  2863. // Type:
  2864. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  2865. // Length:
  2866. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2867. p2pielen += 2;
  2868. // Value:
  2869. p2pie[ p2pielen++ ] = result;
  2870. // P2P Capability
  2871. // Type:
  2872. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  2873. // Length:
  2874. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2875. p2pielen += 2;
  2876. // Value:
  2877. // Device Capability Bitmap, 1 byte
  2878. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
  2879. {
  2880. // Commented by Albert 2011/03/08
  2881. // According to the P2P specification
  2882. // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
  2883. p2pie[ p2pielen++ ] = 0;
  2884. }
  2885. else
  2886. {
  2887. // Be group owner or meet the error case
  2888. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  2889. }
  2890. // Group Capability Bitmap, 1 byte
  2891. if ( pwdinfo->persistent_supported )
  2892. {
  2893. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  2894. }
  2895. else
  2896. {
  2897. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  2898. }
  2899. // Group Owner Intent
  2900. // Type:
  2901. p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
  2902. // Length:
  2903. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  2904. p2pielen += 2;
  2905. // Value:
  2906. if ( pwdinfo->peer_intent & 0x01 )
  2907. {
  2908. // Peer's tie breaker bit is 1, our tie breaker bit should be 0
  2909. p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
  2910. }
  2911. else
  2912. {
  2913. // Peer's tie breaker bit is 0, our tie breaker bit should be 1
  2914. p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
  2915. }
  2916. // Configuration Timeout
  2917. // Type:
  2918. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  2919. // Length:
  2920. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  2921. p2pielen += 2;
  2922. // Value:
  2923. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  2924. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  2925. // Operating Channel
  2926. // Type:
  2927. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  2928. // Length:
  2929. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  2930. p2pielen += 2;
  2931. // Value:
  2932. // Country String
  2933. p2pie[ p2pielen++ ] = 'X';
  2934. p2pie[ p2pielen++ ] = 'X';
  2935. // The third byte should be set to 0x04.
  2936. // Described in the "Operating Channel Attribute" section.
  2937. p2pie[ p2pielen++ ] = 0x04;
  2938. // Operating Class
  2939. if ( pwdinfo->operating_channel <= 14 )
  2940. {
  2941. // Operating Class
  2942. p2pie[ p2pielen++ ] = 0x51;
  2943. }
  2944. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  2945. {
  2946. // Operating Class
  2947. p2pie[ p2pielen++ ] = 0x73;
  2948. }
  2949. else
  2950. {
  2951. // Operating Class
  2952. p2pie[ p2pielen++ ] = 0x7c;
  2953. }
  2954. // Channel Number
  2955. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  2956. // Intended P2P Interface Address
  2957. // Type:
  2958. p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
  2959. // Length:
  2960. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  2961. p2pielen += 2;
  2962. // Value:
  2963. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  2964. p2pielen += ETH_ALEN;
  2965. // Channel List
  2966. // Type:
  2967. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  2968. // Country String(3)
  2969. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  2970. // + number of channels in all classes
  2971. len_channellist_attr = 3
  2972. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  2973. + get_reg_classes_full_count(pmlmeext->channel_list);
  2974. #ifdef CONFIG_CONCURRENT_MODE
  2975. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2976. {
  2977. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  2978. }
  2979. else
  2980. {
  2981. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2982. }
  2983. #else
  2984. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  2985. #endif
  2986. p2pielen += 2;
  2987. // Value:
  2988. // Country String
  2989. p2pie[ p2pielen++ ] = 'X';
  2990. p2pie[ p2pielen++ ] = 'X';
  2991. // The third byte should be set to 0x04.
  2992. // Described in the "Operating Channel Attribute" section.
  2993. p2pie[ p2pielen++ ] = 0x04;
  2994. // Channel Entry List
  2995. #ifdef CONFIG_CONCURRENT_MODE
  2996. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  2997. {
  2998. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  2999. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3000. // Operating Class
  3001. if ( pbuddy_mlmeext->cur_channel > 14 )
  3002. {
  3003. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3004. {
  3005. p2pie[ p2pielen++ ] = 0x7c;
  3006. }
  3007. else
  3008. {
  3009. p2pie[ p2pielen++ ] = 0x73;
  3010. }
  3011. }
  3012. else
  3013. {
  3014. p2pie[ p2pielen++ ] = 0x51;
  3015. }
  3016. // Number of Channels
  3017. // Just support 1 channel and this channel is AP's channel
  3018. p2pie[ p2pielen++ ] = 1;
  3019. // Channel List
  3020. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3021. }
  3022. else
  3023. {
  3024. int i, j;
  3025. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3026. // Operating Class
  3027. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3028. // Number of Channels
  3029. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3030. // Channel List
  3031. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3032. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3033. }
  3034. }
  3035. }
  3036. #else // CONFIG_CONCURRENT_MODE
  3037. {
  3038. int i, j;
  3039. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3040. // Operating Class
  3041. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3042. // Number of Channels
  3043. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3044. // Channel List
  3045. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3046. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3047. }
  3048. }
  3049. }
  3050. #endif // CONFIG_CONCURRENT_MODE
  3051. // Device Info
  3052. // Type:
  3053. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  3054. // Length:
  3055. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  3056. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  3057. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  3058. p2pielen += 2;
  3059. // Value:
  3060. // P2P Device Address
  3061. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3062. p2pielen += ETH_ALEN;
  3063. // Config Method
  3064. // This field should be big endian. Noted by P2P specification.
  3065. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  3066. p2pielen += 2;
  3067. // Primary Device Type
  3068. // Category ID
  3069. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  3070. p2pielen += 2;
  3071. // OUI
  3072. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  3073. p2pielen += 4;
  3074. // Sub Category ID
  3075. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  3076. p2pielen += 2;
  3077. // Number of Secondary Device Types
  3078. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  3079. // Device Name
  3080. // Type:
  3081. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  3082. p2pielen += 2;
  3083. // Length:
  3084. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  3085. p2pielen += 2;
  3086. // Value:
  3087. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
  3088. p2pielen += pwdinfo->device_name_len;
  3089. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  3090. {
  3091. // Group ID Attribute
  3092. // Type:
  3093. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3094. // Length:
  3095. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
  3096. p2pielen += 2;
  3097. // Value:
  3098. // p2P Device Address
  3099. _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
  3100. p2pielen += ETH_ALEN;
  3101. // SSID
  3102. _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  3103. p2pielen += pwdinfo->nego_ssidlen;
  3104. }
  3105. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3106. #ifdef CONFIG_WFD
  3107. wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
  3108. pframe += wfdielen;
  3109. pattrib->pktlen += wfdielen;
  3110. #endif //CONFIG_WFD
  3111. pattrib->last_txcmdsz = pattrib->pktlen;
  3112. dump_mgntframe(padapter, pmgntframe);
  3113. return;
  3114. }
  3115. void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
  3116. {
  3117. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3118. u8 action = P2P_PUB_ACTION_ACTION;
  3119. u32 p2poui = cpu_to_be32(P2POUI);
  3120. u8 oui_subtype = P2P_GO_NEGO_CONF;
  3121. u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  3122. u8 wpsielen = 0, p2pielen = 0;
  3123. struct xmit_frame *pmgntframe;
  3124. struct pkt_attrib *pattrib;
  3125. unsigned char *pframe;
  3126. struct rtw_ieee80211_hdr *pwlanhdr;
  3127. unsigned short *fctrl;
  3128. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3129. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3130. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3131. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3132. #ifdef CONFIG_WFD
  3133. u32 wfdielen = 0;
  3134. #endif //CONFIG_WFD
  3135. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3136. {
  3137. return;
  3138. }
  3139. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3140. //update attribute
  3141. pattrib = &pmgntframe->attrib;
  3142. update_mgntframe_attrib(padapter, pattrib);
  3143. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3144. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3145. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3146. fctrl = &(pwlanhdr->frame_ctl);
  3147. *(fctrl) = 0;
  3148. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3149. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3150. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3151. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3152. pmlmeext->mgnt_seq++;
  3153. SetFrameSubType(pframe, WIFI_ACTION);
  3154. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3155. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3156. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3157. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3158. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3159. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3160. pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
  3161. // P2P IE Section.
  3162. // P2P OUI
  3163. p2pielen = 0;
  3164. p2pie[ p2pielen++ ] = 0x50;
  3165. p2pie[ p2pielen++ ] = 0x6F;
  3166. p2pie[ p2pielen++ ] = 0x9A;
  3167. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3168. // Commented by Albert 20110306
  3169. // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
  3170. // 1. Status
  3171. // 2. P2P Capability
  3172. // 3. Operating Channel
  3173. // 4. Channel List
  3174. // 5. Group ID ( if this WiFi is GO )
  3175. // P2P Status
  3176. // Type:
  3177. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  3178. // Length:
  3179. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3180. p2pielen += 2;
  3181. // Value:
  3182. p2pie[ p2pielen++ ] = result;
  3183. // P2P Capability
  3184. // Type:
  3185. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  3186. // Length:
  3187. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3188. p2pielen += 2;
  3189. // Value:
  3190. // Device Capability Bitmap, 1 byte
  3191. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  3192. // Group Capability Bitmap, 1 byte
  3193. if ( pwdinfo->persistent_supported )
  3194. {
  3195. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
  3196. }
  3197. else
  3198. {
  3199. p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
  3200. }
  3201. // Operating Channel
  3202. // Type:
  3203. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3204. // Length:
  3205. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3206. p2pielen += 2;
  3207. // Value:
  3208. // Country String
  3209. p2pie[ p2pielen++ ] = 'X';
  3210. p2pie[ p2pielen++ ] = 'X';
  3211. // The third byte should be set to 0x04.
  3212. // Described in the "Operating Channel Attribute" section.
  3213. p2pie[ p2pielen++ ] = 0x04;
  3214. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
  3215. {
  3216. if ( pwdinfo->peer_operating_ch <= 14 )
  3217. {
  3218. // Operating Class
  3219. p2pie[ p2pielen++ ] = 0x51;
  3220. }
  3221. else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
  3222. {
  3223. // Operating Class
  3224. p2pie[ p2pielen++ ] = 0x73;
  3225. }
  3226. else
  3227. {
  3228. // Operating Class
  3229. p2pie[ p2pielen++ ] = 0x7c;
  3230. }
  3231. p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
  3232. }
  3233. else
  3234. {
  3235. if ( pwdinfo->operating_channel <= 14 )
  3236. {
  3237. // Operating Class
  3238. p2pie[ p2pielen++ ] = 0x51;
  3239. }
  3240. else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
  3241. {
  3242. // Operating Class
  3243. p2pie[ p2pielen++ ] = 0x73;
  3244. }
  3245. else
  3246. {
  3247. // Operating Class
  3248. p2pie[ p2pielen++ ] = 0x7c;
  3249. }
  3250. // Channel Number
  3251. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
  3252. }
  3253. // Channel List
  3254. // Type:
  3255. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3256. // Length:
  3257. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( pwdinfo->channel_list_attr_len );
  3258. p2pielen += 2;
  3259. // Value:
  3260. _rtw_memcpy( p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len );
  3261. p2pielen += pwdinfo->channel_list_attr_len;
  3262. if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  3263. {
  3264. // Group ID Attribute
  3265. // Type:
  3266. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3267. // Length:
  3268. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
  3269. p2pielen += 2;
  3270. // Value:
  3271. // p2P Device Address
  3272. _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
  3273. p2pielen += ETH_ALEN;
  3274. // SSID
  3275. _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
  3276. p2pielen += pwdinfo->nego_ssidlen;
  3277. }
  3278. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3279. #ifdef CONFIG_WFD
  3280. wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
  3281. pframe += wfdielen;
  3282. pattrib->pktlen += wfdielen;
  3283. #endif //CONFIG_WFD
  3284. pattrib->last_txcmdsz = pattrib->pktlen;
  3285. dump_mgntframe(padapter, pmgntframe);
  3286. return;
  3287. }
  3288. void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
  3289. {
  3290. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3291. u8 action = P2P_PUB_ACTION_ACTION;
  3292. u32 p2poui = cpu_to_be32(P2POUI);
  3293. u8 oui_subtype = P2P_INVIT_REQ;
  3294. u8 p2pie[ 255 ] = { 0x00 };
  3295. u8 p2pielen = 0, i;
  3296. u8 dialogToken = 3;
  3297. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  3298. u16 len_channellist_attr = 0;
  3299. #ifdef CONFIG_WFD
  3300. u32 wfdielen = 0;
  3301. #endif //CONFIG_WFD
  3302. #ifdef CONFIG_CONCURRENT_MODE
  3303. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3304. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  3305. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  3306. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3307. #endif
  3308. struct xmit_frame *pmgntframe;
  3309. struct pkt_attrib *pattrib;
  3310. unsigned char *pframe;
  3311. struct rtw_ieee80211_hdr *pwlanhdr;
  3312. unsigned short *fctrl;
  3313. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3314. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3315. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3316. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3317. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3318. {
  3319. return;
  3320. }
  3321. //update attribute
  3322. pattrib = &pmgntframe->attrib;
  3323. update_mgntframe_attrib(padapter, pattrib);
  3324. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3325. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3326. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3327. fctrl = &(pwlanhdr->frame_ctl);
  3328. *(fctrl) = 0;
  3329. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3330. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3331. _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
  3332. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3333. pmlmeext->mgnt_seq++;
  3334. SetFrameSubType(pframe, WIFI_ACTION);
  3335. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3336. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3337. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3338. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3339. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3340. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3341. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3342. // P2P IE Section.
  3343. // P2P OUI
  3344. p2pielen = 0;
  3345. p2pie[ p2pielen++ ] = 0x50;
  3346. p2pie[ p2pielen++ ] = 0x6F;
  3347. p2pie[ p2pielen++ ] = 0x9A;
  3348. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3349. // Commented by Albert 20101011
  3350. // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
  3351. // 1. Configuration Timeout
  3352. // 2. Invitation Flags
  3353. // 3. Operating Channel ( Only GO )
  3354. // 4. P2P Group BSSID ( Should be included if I am the GO )
  3355. // 5. Channel List
  3356. // 6. P2P Group ID
  3357. // 7. P2P Device Info
  3358. // Configuration Timeout
  3359. // Type:
  3360. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  3361. // Length:
  3362. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3363. p2pielen += 2;
  3364. // Value:
  3365. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  3366. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  3367. // Invitation Flags
  3368. // Type:
  3369. p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
  3370. // Length:
  3371. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3372. p2pielen += 2;
  3373. // Value:
  3374. p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
  3375. // Operating Channel
  3376. // Type:
  3377. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3378. // Length:
  3379. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3380. p2pielen += 2;
  3381. // Value:
  3382. // Country String
  3383. p2pie[ p2pielen++ ] = 'X';
  3384. p2pie[ p2pielen++ ] = 'X';
  3385. // The third byte should be set to 0x04.
  3386. // Described in the "Operating Channel Attribute" section.
  3387. p2pie[ p2pielen++ ] = 0x04;
  3388. // Operating Class
  3389. if ( pwdinfo->invitereq_info.operating_ch <= 14 )
  3390. p2pie[ p2pielen++ ] = 0x51;
  3391. else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
  3392. p2pie[ p2pielen++ ] = 0x73;
  3393. else
  3394. p2pie[ p2pielen++ ] = 0x7c;
  3395. // Channel Number
  3396. p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
  3397. if ( _rtw_memcmp( myid( &padapter->eeprompriv ), pwdinfo->invitereq_info.go_bssid, ETH_ALEN ) )
  3398. {
  3399. // P2P Group BSSID
  3400. // Type:
  3401. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
  3402. // Length:
  3403. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  3404. p2pielen += 2;
  3405. // Value:
  3406. // P2P Device Address for GO
  3407. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
  3408. p2pielen += ETH_ALEN;
  3409. }
  3410. // Channel List
  3411. // Type:
  3412. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3413. // Length:
  3414. // Country String(3)
  3415. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  3416. // + number of channels in all classes
  3417. len_channellist_attr = 3
  3418. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  3419. + get_reg_classes_full_count(pmlmeext->channel_list);
  3420. #ifdef CONFIG_CONCURRENT_MODE
  3421. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3422. {
  3423. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  3424. }
  3425. else
  3426. {
  3427. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3428. }
  3429. #else
  3430. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3431. #endif
  3432. p2pielen += 2;
  3433. // Value:
  3434. // Country String
  3435. p2pie[ p2pielen++ ] = 'X';
  3436. p2pie[ p2pielen++ ] = 'X';
  3437. // The third byte should be set to 0x04.
  3438. // Described in the "Operating Channel Attribute" section.
  3439. p2pie[ p2pielen++ ] = 0x04;
  3440. // Channel Entry List
  3441. #ifdef CONFIG_CONCURRENT_MODE
  3442. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3443. {
  3444. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3445. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3446. // Operating Class
  3447. if ( pbuddy_mlmeext->cur_channel > 14 )
  3448. {
  3449. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3450. {
  3451. p2pie[ p2pielen++ ] = 0x7c;
  3452. }
  3453. else
  3454. {
  3455. p2pie[ p2pielen++ ] = 0x73;
  3456. }
  3457. }
  3458. else
  3459. {
  3460. p2pie[ p2pielen++ ] = 0x51;
  3461. }
  3462. // Number of Channels
  3463. // Just support 1 channel and this channel is AP's channel
  3464. p2pie[ p2pielen++ ] = 1;
  3465. // Channel List
  3466. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3467. }
  3468. else
  3469. {
  3470. int i, j;
  3471. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3472. // Operating Class
  3473. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3474. // Number of Channels
  3475. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3476. // Channel List
  3477. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3478. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3479. }
  3480. }
  3481. }
  3482. #else // CONFIG_CONCURRENT_MODE
  3483. {
  3484. int i, j;
  3485. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3486. // Operating Class
  3487. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3488. // Number of Channels
  3489. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3490. // Channel List
  3491. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3492. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3493. }
  3494. }
  3495. }
  3496. #endif // CONFIG_CONCURRENT_MODE
  3497. // P2P Group ID
  3498. // Type:
  3499. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
  3500. // Length:
  3501. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
  3502. p2pielen += 2;
  3503. // Value:
  3504. // P2P Device Address for GO
  3505. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
  3506. p2pielen += ETH_ALEN;
  3507. // SSID
  3508. _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
  3509. p2pielen += pwdinfo->invitereq_info.ssidlen;
  3510. // Device Info
  3511. // Type:
  3512. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  3513. // Length:
  3514. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  3515. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  3516. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  3517. p2pielen += 2;
  3518. // Value:
  3519. // P2P Device Address
  3520. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3521. p2pielen += ETH_ALEN;
  3522. // Config Method
  3523. // This field should be big endian. Noted by P2P specification.
  3524. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
  3525. p2pielen += 2;
  3526. // Primary Device Type
  3527. // Category ID
  3528. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  3529. p2pielen += 2;
  3530. // OUI
  3531. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  3532. p2pielen += 4;
  3533. // Sub Category ID
  3534. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  3535. p2pielen += 2;
  3536. // Number of Secondary Device Types
  3537. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  3538. // Device Name
  3539. // Type:
  3540. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  3541. p2pielen += 2;
  3542. // Length:
  3543. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  3544. p2pielen += 2;
  3545. // Value:
  3546. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  3547. p2pielen += pwdinfo->device_name_len;
  3548. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3549. #ifdef CONFIG_WFD
  3550. wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
  3551. pframe += wfdielen;
  3552. pattrib->pktlen += wfdielen;
  3553. #endif //CONFIG_WFD
  3554. pattrib->last_txcmdsz = pattrib->pktlen;
  3555. dump_mgntframe(padapter, pmgntframe);
  3556. return;
  3557. }
  3558. void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
  3559. {
  3560. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3561. u8 action = P2P_PUB_ACTION_ACTION;
  3562. u32 p2poui = cpu_to_be32(P2POUI);
  3563. u8 oui_subtype = P2P_INVIT_RESP;
  3564. u8 p2pie[ 255 ] = { 0x00 };
  3565. u8 p2pielen = 0, i;
  3566. u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
  3567. u16 len_channellist_attr = 0;
  3568. #ifdef CONFIG_CONCURRENT_MODE
  3569. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3570. struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
  3571. struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
  3572. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3573. #endif
  3574. #ifdef CONFIG_WFD
  3575. u32 wfdielen = 0;
  3576. #endif //CONFIG_WFD
  3577. struct xmit_frame *pmgntframe;
  3578. struct pkt_attrib *pattrib;
  3579. unsigned char *pframe;
  3580. struct rtw_ieee80211_hdr *pwlanhdr;
  3581. unsigned short *fctrl;
  3582. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3583. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3584. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3585. struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
  3586. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3587. {
  3588. return;
  3589. }
  3590. //update attribute
  3591. pattrib = &pmgntframe->attrib;
  3592. update_mgntframe_attrib(padapter, pattrib);
  3593. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3594. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3595. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3596. fctrl = &(pwlanhdr->frame_ctl);
  3597. *(fctrl) = 0;
  3598. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  3599. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3600. _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
  3601. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3602. pmlmeext->mgnt_seq++;
  3603. SetFrameSubType(pframe, WIFI_ACTION);
  3604. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3605. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3606. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3607. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3608. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3609. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3610. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3611. // P2P IE Section.
  3612. // P2P OUI
  3613. p2pielen = 0;
  3614. p2pie[ p2pielen++ ] = 0x50;
  3615. p2pie[ p2pielen++ ] = 0x6F;
  3616. p2pie[ p2pielen++ ] = 0x9A;
  3617. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  3618. // Commented by Albert 20101005
  3619. // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
  3620. // 1. Status
  3621. // 2. Configuration Timeout
  3622. // 3. Operating Channel ( Only GO )
  3623. // 4. P2P Group BSSID ( Only GO )
  3624. // 5. Channel List
  3625. // P2P Status
  3626. // Type:
  3627. p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
  3628. // Length:
  3629. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
  3630. p2pielen += 2;
  3631. // Value:
  3632. // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
  3633. // Sent the event receiving the P2P Invitation Req frame to DMP UI.
  3634. // DMP had to compare the MAC address to find out the profile.
  3635. // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
  3636. // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
  3637. // to NB to rebuild the persistent group.
  3638. p2pie[ p2pielen++ ] = status_code;
  3639. // Configuration Timeout
  3640. // Type:
  3641. p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
  3642. // Length:
  3643. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  3644. p2pielen += 2;
  3645. // Value:
  3646. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
  3647. p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
  3648. if( status_code == P2P_STATUS_SUCCESS )
  3649. {
  3650. if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
  3651. {
  3652. // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
  3653. // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
  3654. // First one is operating channel attribute.
  3655. // Second one is P2P Group BSSID attribute.
  3656. // Operating Channel
  3657. // Type:
  3658. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  3659. // Length:
  3660. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  3661. p2pielen += 2;
  3662. // Value:
  3663. // Country String
  3664. p2pie[ p2pielen++ ] = 'X';
  3665. p2pie[ p2pielen++ ] = 'X';
  3666. // The third byte should be set to 0x04.
  3667. // Described in the "Operating Channel Attribute" section.
  3668. p2pie[ p2pielen++ ] = 0x04;
  3669. // Operating Class
  3670. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  3671. // Channel Number
  3672. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  3673. // P2P Group BSSID
  3674. // Type:
  3675. p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
  3676. // Length:
  3677. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
  3678. p2pielen += 2;
  3679. // Value:
  3680. // P2P Device Address for GO
  3681. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  3682. p2pielen += ETH_ALEN;
  3683. }
  3684. // Channel List
  3685. // Type:
  3686. p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
  3687. // Length:
  3688. // Country String(3)
  3689. // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
  3690. // + number of channels in all classes
  3691. len_channellist_attr = 3
  3692. + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
  3693. + get_reg_classes_full_count(pmlmeext->channel_list);
  3694. #ifdef CONFIG_CONCURRENT_MODE
  3695. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3696. {
  3697. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
  3698. }
  3699. else
  3700. {
  3701. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3702. }
  3703. #else
  3704. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
  3705. #endif
  3706. p2pielen += 2;
  3707. // Value:
  3708. // Country String
  3709. p2pie[ p2pielen++ ] = 'X';
  3710. p2pie[ p2pielen++ ] = 'X';
  3711. // The third byte should be set to 0x04.
  3712. // Described in the "Operating Channel Attribute" section.
  3713. p2pie[ p2pielen++ ] = 0x04;
  3714. // Channel Entry List
  3715. #ifdef CONFIG_CONCURRENT_MODE
  3716. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  3717. {
  3718. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  3719. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  3720. // Operating Class
  3721. if ( pbuddy_mlmeext->cur_channel > 14 )
  3722. {
  3723. if ( pbuddy_mlmeext->cur_channel >= 149 )
  3724. {
  3725. p2pie[ p2pielen++ ] = 0x7c;
  3726. }
  3727. else
  3728. {
  3729. p2pie[ p2pielen++ ] = 0x73;
  3730. }
  3731. }
  3732. else
  3733. {
  3734. p2pie[ p2pielen++ ] = 0x51;
  3735. }
  3736. // Number of Channels
  3737. // Just support 1 channel and this channel is AP's channel
  3738. p2pie[ p2pielen++ ] = 1;
  3739. // Channel List
  3740. p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
  3741. }
  3742. else
  3743. {
  3744. int i, j;
  3745. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3746. // Operating Class
  3747. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3748. // Number of Channels
  3749. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3750. // Channel List
  3751. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3752. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3753. }
  3754. }
  3755. }
  3756. #else // CONFIG_CONCURRENT_MODE
  3757. {
  3758. int i, j;
  3759. for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
  3760. // Operating Class
  3761. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
  3762. // Number of Channels
  3763. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
  3764. // Channel List
  3765. for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
  3766. p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
  3767. }
  3768. }
  3769. }
  3770. #endif // CONFIG_CONCURRENT_MODE
  3771. }
  3772. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  3773. #ifdef CONFIG_WFD
  3774. wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
  3775. pframe += wfdielen;
  3776. pattrib->pktlen += wfdielen;
  3777. #endif //CONFIG_WFD
  3778. pattrib->last_txcmdsz = pattrib->pktlen;
  3779. dump_mgntframe(padapter, pmgntframe);
  3780. return;
  3781. }
  3782. void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
  3783. {
  3784. unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
  3785. u8 action = P2P_PUB_ACTION_ACTION;
  3786. u8 dialogToken = 1;
  3787. u32 p2poui = cpu_to_be32(P2POUI);
  3788. u8 oui_subtype = P2P_PROVISION_DISC_REQ;
  3789. u8 wpsie[ 100 ] = { 0x00 };
  3790. u8 wpsielen = 0;
  3791. u32 p2pielen = 0;
  3792. #ifdef CONFIG_WFD
  3793. u32 wfdielen = 0;
  3794. #endif //CONFIG_WFD
  3795. struct xmit_frame *pmgntframe;
  3796. struct pkt_attrib *pattrib;
  3797. unsigned char *pframe;
  3798. struct rtw_ieee80211_hdr *pwlanhdr;
  3799. unsigned short *fctrl;
  3800. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3801. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3802. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3803. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  3804. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3805. {
  3806. return;
  3807. }
  3808. DBG_871X( "[%s] In\n", __FUNCTION__ );
  3809. //update attribute
  3810. pattrib = &pmgntframe->attrib;
  3811. update_mgntframe_attrib(padapter, pattrib);
  3812. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3813. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3814. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3815. fctrl = &(pwlanhdr->frame_ctl);
  3816. *(fctrl) = 0;
  3817. _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
  3818. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  3819. _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
  3820. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3821. pmlmeext->mgnt_seq++;
  3822. SetFrameSubType(pframe, WIFI_ACTION);
  3823. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  3824. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3825. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  3826. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  3827. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
  3828. pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
  3829. pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
  3830. p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
  3831. pframe += p2pielen;
  3832. pattrib->pktlen += p2pielen;
  3833. wpsielen = 0;
  3834. // WPS OUI
  3835. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  3836. wpsielen += 4;
  3837. // WPS version
  3838. // Type:
  3839. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  3840. wpsielen += 2;
  3841. // Length:
  3842. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  3843. wpsielen += 2;
  3844. // Value:
  3845. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  3846. // Config Method
  3847. // Type:
  3848. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  3849. wpsielen += 2;
  3850. // Length:
  3851. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  3852. wpsielen += 2;
  3853. // Value:
  3854. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
  3855. wpsielen += 2;
  3856. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  3857. #ifdef CONFIG_WFD
  3858. wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
  3859. pframe += wfdielen;
  3860. pattrib->pktlen += wfdielen;
  3861. #endif //CONFIG_WFD
  3862. pattrib->last_txcmdsz = pattrib->pktlen;
  3863. dump_mgntframe(padapter, pmgntframe);
  3864. return;
  3865. }
  3866. u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
  3867. {
  3868. u8 i, match_result = 0;
  3869. DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  3870. peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
  3871. for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
  3872. {
  3873. DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  3874. profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
  3875. if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
  3876. {
  3877. match_result = 1;
  3878. DBG_871X( "[%s] Match!\n", __FUNCTION__ );
  3879. break;
  3880. }
  3881. }
  3882. return (match_result );
  3883. }
  3884. void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
  3885. {
  3886. struct xmit_frame *pmgntframe;
  3887. struct pkt_attrib *pattrib;
  3888. unsigned char *pframe;
  3889. struct rtw_ieee80211_hdr *pwlanhdr;
  3890. unsigned short *fctrl;
  3891. unsigned char *mac;
  3892. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  3893. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  3894. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  3895. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  3896. //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  3897. u16 beacon_interval = 100;
  3898. u16 capInfo = 0;
  3899. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  3900. u8 wpsie[255] = { 0x00 };
  3901. u32 wpsielen = 0, p2pielen = 0;
  3902. #ifdef CONFIG_WFD
  3903. u32 wfdielen = 0;
  3904. #endif //CONFIG_WFD
  3905. #ifdef CONFIG_IOCTL_CFG80211
  3906. struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
  3907. struct ieee80211_channel *ieee_ch = &pcfg80211_wdinfo->remain_on_ch_channel;
  3908. u8 listen_channel = (u8) ieee80211_frequency_to_channel(ieee_ch->center_freq);
  3909. #endif //CONFIG_IOCTL_CFG80211
  3910. #ifdef CONFIG_INTEL_WIDI
  3911. u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
  3912. #endif //CONFIG_INTEL_WIDI
  3913. //DBG_871X("%s\n", __FUNCTION__);
  3914. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  3915. {
  3916. return;
  3917. }
  3918. //update attribute
  3919. pattrib = &pmgntframe->attrib;
  3920. update_mgntframe_attrib(padapter, pattrib);
  3921. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  3922. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  3923. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  3924. mac = myid(&(padapter->eeprompriv));
  3925. fctrl = &(pwlanhdr->frame_ctl);
  3926. *(fctrl) = 0;
  3927. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  3928. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  3929. // Use the device address for BSSID field.
  3930. _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
  3931. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  3932. pmlmeext->mgnt_seq++;
  3933. SetFrameSubType(fctrl, WIFI_PROBERSP);
  3934. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  3935. pattrib->pktlen = pattrib->hdrlen;
  3936. pframe += pattrib->hdrlen;
  3937. //timestamp will be inserted by hardware
  3938. pframe += 8;
  3939. pattrib->pktlen += 8;
  3940. // beacon interval: 2 bytes
  3941. _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
  3942. pframe += 2;
  3943. pattrib->pktlen += 2;
  3944. // capability info: 2 bytes
  3945. // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
  3946. capInfo |= cap_ShortPremble;
  3947. capInfo |= cap_ShortSlot;
  3948. _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
  3949. pframe += 2;
  3950. pattrib->pktlen += 2;
  3951. // SSID
  3952. pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
  3953. // supported rates...
  3954. // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
  3955. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
  3956. // DS parameter set
  3957. #ifdef CONFIG_IOCTL_CFG80211
  3958. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && listen_channel !=0 && pwdinfo->driver_interface == DRIVER_CFG80211 )
  3959. {
  3960. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&listen_channel, &pattrib->pktlen);
  3961. }
  3962. else
  3963. #endif //CONFIG_IOCTL_CFG80211
  3964. {
  3965. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
  3966. }
  3967. #ifdef CONFIG_IOCTL_CFG80211
  3968. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  3969. {
  3970. if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
  3971. {
  3972. //WPS IE
  3973. _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
  3974. pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
  3975. pframe += pmlmepriv->wps_probe_resp_ie_len;
  3976. //P2P IE
  3977. _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
  3978. pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
  3979. pframe += pmlmepriv->p2p_probe_resp_ie_len;
  3980. }
  3981. }
  3982. else
  3983. #endif //CONFIG_IOCTL_CFG80211
  3984. {
  3985. // Todo: WPS IE
  3986. // Noted by Albert 20100907
  3987. // According to the WPS specification, all the WPS attribute is presented by Big Endian.
  3988. wpsielen = 0;
  3989. // WPS OUI
  3990. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  3991. wpsielen += 4;
  3992. // WPS version
  3993. // Type:
  3994. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  3995. wpsielen += 2;
  3996. // Length:
  3997. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  3998. wpsielen += 2;
  3999. // Value:
  4000. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  4001. #ifdef CONFIG_INTEL_WIDI
  4002. // Commented by Kurt
  4003. // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
  4004. if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
  4005. {
  4006. //Sec dev type
  4007. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
  4008. wpsielen += 2;
  4009. // Length:
  4010. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4011. wpsielen += 2;
  4012. // Value:
  4013. // Category ID
  4014. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
  4015. wpsielen += 2;
  4016. // OUI
  4017. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
  4018. wpsielen += 4;
  4019. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
  4020. wpsielen += 2;
  4021. // Vendor Extension
  4022. _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
  4023. wpsielen += L2SDTA_SERVICE_VE_LEN;
  4024. }
  4025. #endif //CONFIG_INTEL_WIDI
  4026. // WiFi Simple Config State
  4027. // Type:
  4028. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
  4029. wpsielen += 2;
  4030. // Length:
  4031. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4032. wpsielen += 2;
  4033. // Value:
  4034. wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
  4035. // Response Type
  4036. // Type:
  4037. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
  4038. wpsielen += 2;
  4039. // Length:
  4040. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4041. wpsielen += 2;
  4042. // Value:
  4043. wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
  4044. // UUID-E
  4045. // Type:
  4046. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
  4047. wpsielen += 2;
  4048. // Length:
  4049. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
  4050. wpsielen += 2;
  4051. // Value:
  4052. _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  4053. wpsielen += 0x10;
  4054. // Manufacturer
  4055. // Type:
  4056. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
  4057. wpsielen += 2;
  4058. // Length:
  4059. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
  4060. wpsielen += 2;
  4061. // Value:
  4062. _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
  4063. wpsielen += 7;
  4064. // Model Name
  4065. // Type:
  4066. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
  4067. wpsielen += 2;
  4068. // Length:
  4069. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
  4070. wpsielen += 2;
  4071. // Value:
  4072. _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
  4073. wpsielen += 6;
  4074. // Model Number
  4075. // Type:
  4076. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
  4077. wpsielen += 2;
  4078. // Length:
  4079. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4080. wpsielen += 2;
  4081. // Value:
  4082. wpsie[ wpsielen++ ] = 0x31; // character 1
  4083. // Serial Number
  4084. // Type:
  4085. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
  4086. wpsielen += 2;
  4087. // Length:
  4088. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
  4089. wpsielen += 2;
  4090. // Value:
  4091. _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
  4092. wpsielen += ETH_ALEN;
  4093. // Primary Device Type
  4094. // Type:
  4095. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  4096. wpsielen += 2;
  4097. // Length:
  4098. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4099. wpsielen += 2;
  4100. // Value:
  4101. // Category ID
  4102. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  4103. wpsielen += 2;
  4104. // OUI
  4105. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
  4106. wpsielen += 4;
  4107. // Sub Category ID
  4108. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  4109. wpsielen += 2;
  4110. // Device Name
  4111. // Type:
  4112. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  4113. wpsielen += 2;
  4114. // Length:
  4115. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
  4116. wpsielen += 2;
  4117. // Value:
  4118. _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
  4119. wpsielen += pwdinfo->device_name_len;
  4120. // Config Method
  4121. // Type:
  4122. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  4123. wpsielen += 2;
  4124. // Length:
  4125. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4126. wpsielen += 2;
  4127. // Value:
  4128. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  4129. wpsielen += 2;
  4130. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  4131. p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
  4132. pframe += p2pielen;
  4133. pattrib->pktlen += p2pielen;
  4134. }
  4135. #ifdef CONFIG_WFD
  4136. #ifdef CONFIG_IOCTL_CFG80211
  4137. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  4138. #endif //CONFIG_IOCTL_CFG80211
  4139. {
  4140. wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
  4141. pframe += wfdielen;
  4142. pattrib->pktlen += wfdielen;
  4143. }
  4144. #ifdef CONFIG_IOCTL_CFG80211
  4145. else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
  4146. {
  4147. //WFD IE
  4148. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
  4149. pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
  4150. pframe += pmlmepriv->wfd_probe_resp_ie_len;
  4151. }
  4152. #endif //CONFIG_IOCTL_CFG80211
  4153. #endif //CONFIG_WFD
  4154. pattrib->last_txcmdsz = pattrib->pktlen;
  4155. dump_mgntframe(padapter, pmgntframe);
  4156. return;
  4157. }
  4158. int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
  4159. {
  4160. int ret = _FAIL;
  4161. struct xmit_frame *pmgntframe;
  4162. struct pkt_attrib *pattrib;
  4163. unsigned char *pframe;
  4164. struct rtw_ieee80211_hdr *pwlanhdr;
  4165. unsigned short *fctrl;
  4166. unsigned char *mac;
  4167. unsigned char bssrate[NumRates];
  4168. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  4169. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  4170. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  4171. int bssrate_len = 0;
  4172. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  4173. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  4174. u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
  4175. u16 wpsielen = 0, p2pielen = 0;
  4176. #ifdef CONFIG_WFD
  4177. u32 wfdielen = 0;
  4178. #endif //CONFIG_WFD
  4179. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  4180. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  4181. {
  4182. goto exit;
  4183. }
  4184. //update attribute
  4185. pattrib = &pmgntframe->attrib;
  4186. update_mgntframe_attrib(padapter, pattrib);
  4187. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  4188. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  4189. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  4190. mac = myid(&(padapter->eeprompriv));
  4191. fctrl = &(pwlanhdr->frame_ctl);
  4192. *(fctrl) = 0;
  4193. if (da) {
  4194. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  4195. _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
  4196. } else {
  4197. if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
  4198. {
  4199. // This two flags will be set when this is only the P2P client mode.
  4200. _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
  4201. _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
  4202. }
  4203. else
  4204. {
  4205. // broadcast probe request frame
  4206. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  4207. _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
  4208. }
  4209. }
  4210. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  4211. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  4212. pmlmeext->mgnt_seq++;
  4213. SetFrameSubType(pframe, WIFI_PROBEREQ);
  4214. pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
  4215. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  4216. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
  4217. {
  4218. pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
  4219. }
  4220. else
  4221. {
  4222. pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
  4223. }
  4224. // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
  4225. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
  4226. #ifdef CONFIG_IOCTL_CFG80211
  4227. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  4228. {
  4229. if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
  4230. {
  4231. //WPS IE
  4232. _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
  4233. pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
  4234. pframe += pmlmepriv->wps_probe_req_ie_len;
  4235. //P2P IE
  4236. _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
  4237. pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
  4238. pframe += pmlmepriv->p2p_probe_req_ie_len;
  4239. }
  4240. }
  4241. else
  4242. #endif //CONFIG_IOCTL_CFG80211
  4243. {
  4244. // WPS IE
  4245. // Noted by Albert 20110221
  4246. // According to the WPS specification, all the WPS attribute is presented by Big Endian.
  4247. wpsielen = 0;
  4248. // WPS OUI
  4249. *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
  4250. wpsielen += 4;
  4251. // WPS version
  4252. // Type:
  4253. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
  4254. wpsielen += 2;
  4255. // Length:
  4256. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
  4257. wpsielen += 2;
  4258. // Value:
  4259. wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
  4260. if( pmlmepriv->wps_probe_req_ie == NULL )
  4261. {
  4262. // UUID-E
  4263. // Type:
  4264. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
  4265. wpsielen += 2;
  4266. // Length:
  4267. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
  4268. wpsielen += 2;
  4269. // Value:
  4270. _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  4271. wpsielen += 0x10;
  4272. // Config Method
  4273. // Type:
  4274. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
  4275. wpsielen += 2;
  4276. // Length:
  4277. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4278. wpsielen += 2;
  4279. // Value:
  4280. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
  4281. wpsielen += 2;
  4282. }
  4283. // Device Name
  4284. // Type:
  4285. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  4286. wpsielen += 2;
  4287. // Length:
  4288. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
  4289. wpsielen += 2;
  4290. // Value:
  4291. _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
  4292. wpsielen += pwdinfo->device_name_len;
  4293. // Primary Device Type
  4294. // Type:
  4295. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  4296. wpsielen += 2;
  4297. // Length:
  4298. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
  4299. wpsielen += 2;
  4300. // Value:
  4301. // Category ID
  4302. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
  4303. wpsielen += 2;
  4304. // OUI
  4305. *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
  4306. wpsielen += 4;
  4307. // Sub Category ID
  4308. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
  4309. wpsielen += 2;
  4310. // Device Password ID
  4311. // Type:
  4312. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
  4313. wpsielen += 2;
  4314. // Length:
  4315. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
  4316. wpsielen += 2;
  4317. // Value:
  4318. *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
  4319. wpsielen += 2;
  4320. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
  4321. // P2P OUI
  4322. p2pielen = 0;
  4323. p2pie[ p2pielen++ ] = 0x50;
  4324. p2pie[ p2pielen++ ] = 0x6F;
  4325. p2pie[ p2pielen++ ] = 0x9A;
  4326. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  4327. // Commented by Albert 20110221
  4328. // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
  4329. // 1. P2P Capability
  4330. // 2. P2P Device ID if this probe request wants to find the specific P2P device
  4331. // 3. Listen Channel
  4332. // 4. Extended Listen Timing
  4333. // 5. Operating Channel if this WiFi is working as the group owner now
  4334. // P2P Capability
  4335. // Type:
  4336. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  4337. // Length:
  4338. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  4339. p2pielen += 2;
  4340. // Value:
  4341. // Device Capability Bitmap, 1 byte
  4342. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  4343. // Group Capability Bitmap, 1 byte
  4344. if ( pwdinfo->persistent_supported )
  4345. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  4346. else
  4347. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  4348. // Listen Channel
  4349. // Type:
  4350. p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
  4351. // Length:
  4352. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  4353. p2pielen += 2;
  4354. // Value:
  4355. // Country String
  4356. p2pie[ p2pielen++ ] = 'X';
  4357. p2pie[ p2pielen++ ] = 'X';
  4358. // The third byte should be set to 0x04.
  4359. // Described in the "Operating Channel Attribute" section.
  4360. p2pie[ p2pielen++ ] = 0x04;
  4361. // Operating Class
  4362. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  4363. // Channel Number
  4364. p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
  4365. // Extended Listen Timing
  4366. // Type:
  4367. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  4368. // Length:
  4369. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  4370. p2pielen += 2;
  4371. // Value:
  4372. // Availability Period
  4373. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  4374. p2pielen += 2;
  4375. // Availability Interval
  4376. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  4377. p2pielen += 2;
  4378. if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
  4379. {
  4380. // Operating Channel (if this WiFi is working as the group owner now)
  4381. // Type:
  4382. p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
  4383. // Length:
  4384. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
  4385. p2pielen += 2;
  4386. // Value:
  4387. // Country String
  4388. p2pie[ p2pielen++ ] = 'X';
  4389. p2pie[ p2pielen++ ] = 'X';
  4390. // The third byte should be set to 0x04.
  4391. // Described in the "Operating Channel Attribute" section.
  4392. p2pie[ p2pielen++ ] = 0x04;
  4393. // Operating Class
  4394. p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
  4395. // Channel Number
  4396. p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
  4397. }
  4398. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  4399. }
  4400. #ifdef CONFIG_WFD
  4401. #ifdef CONFIG_IOCTL_CFG80211
  4402. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  4403. #endif
  4404. {
  4405. wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
  4406. pframe += wfdielen;
  4407. pattrib->pktlen += wfdielen;
  4408. }
  4409. #ifdef CONFIG_IOCTL_CFG80211
  4410. else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
  4411. {
  4412. //WFD IE
  4413. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
  4414. pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
  4415. pframe += pmlmepriv->wfd_probe_req_ie_len;
  4416. }
  4417. #endif //CONFIG_IOCTL_CFG80211
  4418. #endif //CONFIG_WFD
  4419. pattrib->last_txcmdsz = pattrib->pktlen;
  4420. RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
  4421. if (wait_ack) {
  4422. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  4423. } else {
  4424. dump_mgntframe(padapter, pmgntframe);
  4425. ret = _SUCCESS;
  4426. }
  4427. exit:
  4428. return ret;
  4429. }
  4430. inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
  4431. {
  4432. _issue_probereq_p2p(adapter, da, _FALSE);
  4433. }
  4434. int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
  4435. {
  4436. int ret;
  4437. int i = 0;
  4438. u32 start = rtw_get_current_time();
  4439. do
  4440. {
  4441. ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
  4442. i++;
  4443. if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
  4444. break;
  4445. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  4446. rtw_msleep_os(wait_ms);
  4447. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  4448. if (ret != _FAIL) {
  4449. ret = _SUCCESS;
  4450. #ifndef DBG_XMIT_ACK
  4451. goto exit;
  4452. #endif
  4453. }
  4454. if (try_cnt && wait_ms) {
  4455. if (da)
  4456. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  4457. FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
  4458. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  4459. else
  4460. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  4461. FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
  4462. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  4463. }
  4464. exit:
  4465. return ret;
  4466. }
  4467. #endif //CONFIG_P2P
  4468. s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
  4469. {
  4470. _adapter *adapter = recv_frame->u.hdr.adapter;
  4471. struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
  4472. u8 *frame = recv_frame->u.hdr.rx_data;
  4473. u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
  4474. (recv_frame->u.hdr.attrib.frag_num & 0xf);
  4475. if (GetRetry(frame)) {
  4476. if (token >= 0) {
  4477. if ((seq_ctrl == mlmeext->action_public_rxseq)
  4478. && (token == mlmeext->action_public_dialog_token))
  4479. {
  4480. DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
  4481. FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
  4482. return _FAIL;
  4483. }
  4484. } else {
  4485. if (seq_ctrl == mlmeext->action_public_rxseq) {
  4486. DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
  4487. FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
  4488. return _FAIL;
  4489. }
  4490. }
  4491. }
  4492. mlmeext->action_public_rxseq = seq_ctrl;
  4493. if (token >= 0)
  4494. mlmeext->action_public_dialog_token = token;
  4495. return _SUCCESS;
  4496. }
  4497. unsigned int on_action_public_p2p(union recv_frame *precv_frame)
  4498. {
  4499. _adapter *padapter = precv_frame->u.hdr.adapter;
  4500. u8 *pframe = precv_frame->u.hdr.rx_data;
  4501. uint len = precv_frame->u.hdr.len;
  4502. u8 *frame_body;
  4503. u8 dialogToken=0;
  4504. #ifdef CONFIG_P2P
  4505. u8 *p2p_ie;
  4506. u32 p2p_ielen, wps_ielen;
  4507. struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
  4508. u8 result = P2P_STATUS_SUCCESS;
  4509. u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  4510. #endif //CONFIG_P2P
  4511. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4512. dialogToken = frame_body[7];
  4513. if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
  4514. return _FAIL;
  4515. #ifdef CONFIG_P2P
  4516. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  4517. #ifdef CONFIG_IOCTL_CFG80211
  4518. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
  4519. {
  4520. rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
  4521. }
  4522. else
  4523. #endif //CONFIG_IOCTL_CFG80211
  4524. {
  4525. // Do nothing if the driver doesn't enable the P2P function.
  4526. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  4527. return _SUCCESS;
  4528. len -= sizeof(struct rtw_ieee80211_hdr_3addr);
  4529. switch( frame_body[ 6 ] )//OUI Subtype
  4530. {
  4531. case P2P_GO_NEGO_REQ:
  4532. {
  4533. DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
  4534. _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
  4535. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
  4536. {
  4537. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  4538. }
  4539. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
  4540. {
  4541. // Commented by Albert 20110526
  4542. // In this case, this means the previous nego fail doesn't be reset yet.
  4543. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4544. // Restore the previous p2p state
  4545. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  4546. DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
  4547. }
  4548. #ifdef CONFIG_CONCURRENT_MODE
  4549. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  4550. {
  4551. _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
  4552. }
  4553. #endif // CONFIG_CONCURRENT_MODE
  4554. // Commented by Kurt 20110902
  4555. //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
  4556. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  4557. rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
  4558. // Commented by Kurt 20120113
  4559. // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
  4560. if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
  4561. _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
  4562. result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
  4563. issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
  4564. #ifdef CONFIG_INTEL_WIDI
  4565. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4566. {
  4567. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4568. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4569. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4570. }
  4571. #endif //CONFIG_INTEL_WIDI
  4572. // Commented by Albert 20110718
  4573. // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
  4574. #ifdef CONFIG_CONCURRENT_MODE
  4575. // Commented by Albert 20120107
  4576. _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
  4577. #else // CONFIG_CONCURRENT_MODE
  4578. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4579. #endif // CONFIG_CONCURRENT_MODE
  4580. break;
  4581. }
  4582. case P2P_GO_NEGO_RESP:
  4583. {
  4584. DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
  4585. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
  4586. {
  4587. // Commented by Albert 20110425
  4588. // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
  4589. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4590. pwdinfo->nego_req_info.benable = _FALSE;
  4591. result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
  4592. issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
  4593. if ( P2P_STATUS_SUCCESS == result )
  4594. {
  4595. if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
  4596. {
  4597. pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
  4598. pwdinfo->p2p_info.scan_op_ch_only = 1;
  4599. _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
  4600. }
  4601. }
  4602. // Reset the dialog token for group negotiation frames.
  4603. pwdinfo->negotiation_dialog_token = 1;
  4604. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
  4605. {
  4606. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4607. }
  4608. }
  4609. else
  4610. {
  4611. DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
  4612. }
  4613. break;
  4614. }
  4615. case P2P_GO_NEGO_CONF:
  4616. {
  4617. DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
  4618. result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
  4619. if ( P2P_STATUS_SUCCESS == result )
  4620. {
  4621. if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
  4622. {
  4623. pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
  4624. pwdinfo->p2p_info.scan_op_ch_only = 1;
  4625. _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
  4626. }
  4627. }
  4628. break;
  4629. }
  4630. case P2P_INVIT_REQ:
  4631. {
  4632. // Added by Albert 2010/10/05
  4633. // Received the P2P Invite Request frame.
  4634. DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
  4635. if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
  4636. {
  4637. // Parse the necessary information from the P2P Invitation Request frame.
  4638. // For example: The MAC address of sending this P2P Invitation Request frame.
  4639. u32 attr_contentlen = 0;
  4640. u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4641. struct group_id_info group_id;
  4642. u8 invitation_flag = 0;
  4643. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
  4644. if ( attr_contentlen )
  4645. {
  4646. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
  4647. // Commented by Albert 20120510
  4648. // Copy to the pwdinfo->p2p_peer_interface_addr.
  4649. // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
  4650. // #> iwpriv wlan0 p2p_get peer_ifa
  4651. // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
  4652. if ( attr_contentlen )
  4653. {
  4654. DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
  4655. pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
  4656. pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
  4657. pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
  4658. }
  4659. if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
  4660. {
  4661. // Re-invoke the persistent group.
  4662. _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
  4663. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
  4664. if ( attr_contentlen )
  4665. {
  4666. if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
  4667. {
  4668. // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
  4669. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
  4670. rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
  4671. status_code = P2P_STATUS_SUCCESS;
  4672. }
  4673. else
  4674. {
  4675. // The p2p device sending this p2p invitation request wants to be the persistent GO.
  4676. if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
  4677. {
  4678. u8 operatingch_info[5] = { 0x00 };
  4679. if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
  4680. {
  4681. if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) )
  4682. {
  4683. // The operating channel is acceptable for this device.
  4684. pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
  4685. pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
  4686. _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
  4687. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
  4688. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4689. status_code = P2P_STATUS_SUCCESS;
  4690. }
  4691. else
  4692. {
  4693. // The operating channel isn't supported by this device.
  4694. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4695. rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
  4696. status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
  4697. _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
  4698. }
  4699. }
  4700. else
  4701. {
  4702. // Commented by Albert 20121130
  4703. // Intel will use the different P2P IE to store the operating channel information
  4704. // Workaround for Intel WiDi 3.5
  4705. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
  4706. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4707. status_code = P2P_STATUS_SUCCESS;
  4708. }
  4709. }
  4710. else
  4711. {
  4712. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4713. #ifdef CONFIG_INTEL_WIDI
  4714. _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
  4715. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4716. #endif //CONFIG_INTEL_WIDI
  4717. status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
  4718. }
  4719. }
  4720. }
  4721. else
  4722. {
  4723. DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
  4724. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4725. }
  4726. }
  4727. else
  4728. {
  4729. // Received the invitation to join a P2P group.
  4730. _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
  4731. rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
  4732. if ( attr_contentlen )
  4733. {
  4734. if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
  4735. {
  4736. // In this case, the GO can't be myself.
  4737. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
  4738. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4739. }
  4740. else
  4741. {
  4742. // The p2p device sending this p2p invitation request wants to join an existing P2P group
  4743. // Commented by Albert 2012/06/28
  4744. // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
  4745. // The peer device address should be the destination address for the provisioning discovery request.
  4746. // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
  4747. // The peer interface address should be the address for WPS mac address
  4748. _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
  4749. rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
  4750. rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
  4751. status_code = P2P_STATUS_SUCCESS;
  4752. }
  4753. }
  4754. else
  4755. {
  4756. DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
  4757. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4758. }
  4759. }
  4760. }
  4761. else
  4762. {
  4763. DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
  4764. status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
  4765. }
  4766. DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
  4767. pwdinfo->inviteresp_info.token = frame_body[ 7 ];
  4768. issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
  4769. }
  4770. #ifdef CONFIG_INTEL_WIDI
  4771. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4772. {
  4773. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4774. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4775. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4776. }
  4777. #endif //CONFIG_INTEL_WIDI
  4778. break;
  4779. }
  4780. case P2P_INVIT_RESP:
  4781. {
  4782. u8 attr_content = 0x00;
  4783. u32 attr_contentlen = 0;
  4784. DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
  4785. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4786. if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
  4787. {
  4788. rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
  4789. if ( attr_contentlen == 1 )
  4790. {
  4791. DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
  4792. pwdinfo->invitereq_info.benable = _FALSE;
  4793. if ( attr_content == P2P_STATUS_SUCCESS )
  4794. {
  4795. if ( _rtw_memcmp( pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv ), ETH_ALEN ))
  4796. {
  4797. rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
  4798. }
  4799. else
  4800. {
  4801. rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
  4802. }
  4803. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
  4804. }
  4805. else
  4806. {
  4807. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4808. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4809. }
  4810. }
  4811. else
  4812. {
  4813. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4814. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4815. }
  4816. }
  4817. else
  4818. {
  4819. rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
  4820. rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
  4821. }
  4822. if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
  4823. {
  4824. _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
  4825. }
  4826. break;
  4827. }
  4828. case P2P_DEVDISC_REQ:
  4829. process_p2p_devdisc_req(pwdinfo, pframe, len);
  4830. break;
  4831. case P2P_DEVDISC_RESP:
  4832. process_p2p_devdisc_resp(pwdinfo, pframe, len);
  4833. break;
  4834. case P2P_PROVISION_DISC_REQ:
  4835. DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
  4836. process_p2p_provdisc_req(pwdinfo, pframe, len);
  4837. _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
  4838. //20110902 Kurt
  4839. //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
  4840. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
  4841. rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
  4842. rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
  4843. _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
  4844. #ifdef CONFIG_INTEL_WIDI
  4845. if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
  4846. {
  4847. padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
  4848. _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
  4849. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
  4850. }
  4851. #endif //CONFIG_INTEL_WIDI
  4852. break;
  4853. case P2P_PROVISION_DISC_RESP:
  4854. // Commented by Albert 20110707
  4855. // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
  4856. DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
  4857. // Commented by Albert 20110426
  4858. // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
  4859. _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
  4860. rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
  4861. process_p2p_provdisc_resp(pwdinfo, pframe);
  4862. _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
  4863. break;
  4864. }
  4865. }
  4866. #endif //CONFIG_P2P
  4867. return _SUCCESS;
  4868. }
  4869. unsigned int on_action_public_vendor(union recv_frame *precv_frame)
  4870. {
  4871. unsigned int ret = _FAIL;
  4872. u8 *pframe = precv_frame->u.hdr.rx_data;
  4873. uint frame_len = precv_frame->u.hdr.len;
  4874. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4875. if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
  4876. ret = on_action_public_p2p(precv_frame);
  4877. }
  4878. return ret;
  4879. }
  4880. unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
  4881. {
  4882. unsigned int ret = _FAIL;
  4883. u8 *pframe = precv_frame->u.hdr.rx_data;
  4884. uint frame_len = precv_frame->u.hdr.len;
  4885. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4886. u8 token;
  4887. _adapter *adapter = precv_frame->u.hdr.adapter;
  4888. int cnt = 0;
  4889. char msg[64];
  4890. token = frame_body[2];
  4891. if (rtw_action_public_decache(precv_frame, token) == _FAIL)
  4892. goto exit;
  4893. #ifdef CONFIG_IOCTL_CFG80211
  4894. cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
  4895. rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
  4896. #endif
  4897. ret = _SUCCESS;
  4898. exit:
  4899. return ret;
  4900. }
  4901. unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
  4902. {
  4903. unsigned int ret = _FAIL;
  4904. u8 *pframe = precv_frame->u.hdr.rx_data;
  4905. uint frame_len = precv_frame->u.hdr.len;
  4906. u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
  4907. u8 category, action;
  4908. /* check RA matches or not */
  4909. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
  4910. goto exit;
  4911. category = frame_body[0];
  4912. if(category != RTW_WLAN_CATEGORY_PUBLIC)
  4913. goto exit;
  4914. action = frame_body[1];
  4915. switch (action) {
  4916. case ACT_PUBLIC_VENDOR:
  4917. ret = on_action_public_vendor(precv_frame);
  4918. break;
  4919. default:
  4920. ret = on_action_public_default(precv_frame, action);
  4921. break;
  4922. }
  4923. exit:
  4924. return ret;
  4925. }
  4926. unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
  4927. {
  4928. return _SUCCESS;
  4929. }
  4930. unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
  4931. {
  4932. return _SUCCESS;
  4933. }
  4934. unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
  4935. {
  4936. #ifdef CONFIG_P2P
  4937. u8 *frame_body;
  4938. u8 category, OUI_Subtype, dialogToken=0;
  4939. u8 *pframe = precv_frame->u.hdr.rx_data;
  4940. uint len = precv_frame->u.hdr.len;
  4941. struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
  4942. DBG_871X("%s\n", __FUNCTION__);
  4943. //check RA matches or not
  4944. if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
  4945. return _SUCCESS;
  4946. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4947. category = frame_body[0];
  4948. if(category != RTW_WLAN_CATEGORY_P2P)
  4949. return _SUCCESS;
  4950. if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
  4951. return _SUCCESS;
  4952. #ifdef CONFIG_IOCTL_CFG80211
  4953. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  4954. {
  4955. rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
  4956. return _SUCCESS;
  4957. }
  4958. else
  4959. #endif //CONFIG_IOCTL_CFG80211
  4960. {
  4961. len -= sizeof(struct rtw_ieee80211_hdr_3addr);
  4962. OUI_Subtype = frame_body[5];
  4963. dialogToken = frame_body[6];
  4964. switch(OUI_Subtype)
  4965. {
  4966. case P2P_NOTICE_OF_ABSENCE:
  4967. break;
  4968. case P2P_PRESENCE_REQUEST:
  4969. process_p2p_presence_req(pwdinfo, pframe, len);
  4970. break;
  4971. case P2P_PRESENCE_RESPONSE:
  4972. break;
  4973. case P2P_GO_DISC_REQUEST:
  4974. break;
  4975. default:
  4976. break;
  4977. }
  4978. }
  4979. #endif //CONFIG_P2P
  4980. return _SUCCESS;
  4981. }
  4982. unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
  4983. {
  4984. int i;
  4985. unsigned char category;
  4986. struct action_handler *ptable;
  4987. unsigned char *frame_body;
  4988. u8 *pframe = precv_frame->u.hdr.rx_data;
  4989. frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
  4990. category = frame_body[0];
  4991. for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
  4992. {
  4993. ptable = &OnAction_tbl[i];
  4994. if(category == ptable->num)
  4995. ptable->func(padapter, precv_frame);
  4996. }
  4997. return _SUCCESS;
  4998. }
  4999. unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
  5000. {
  5001. //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
  5002. return _SUCCESS;
  5003. }
  5004. struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
  5005. {
  5006. struct xmit_frame *pmgntframe;
  5007. struct xmit_buf *pxmitbuf;
  5008. if (once)
  5009. pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
  5010. else
  5011. pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
  5012. if (pmgntframe == NULL) {
  5013. DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
  5014. goto exit;
  5015. }
  5016. if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
  5017. DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
  5018. rtw_free_xmitframe(pxmitpriv, pmgntframe);
  5019. pmgntframe = NULL;
  5020. goto exit;
  5021. }
  5022. pmgntframe->frame_tag = MGNT_FRAMETAG;
  5023. pmgntframe->pxmitbuf = pxmitbuf;
  5024. pmgntframe->buf_addr = pxmitbuf->pbuf;
  5025. pxmitbuf->priv_data = pmgntframe;
  5026. exit:
  5027. return pmgntframe;
  5028. }
  5029. inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
  5030. {
  5031. return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
  5032. }
  5033. inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
  5034. {
  5035. return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
  5036. }
  5037. /****************************************************************************
  5038. Following are some TX fuctions for WiFi MLME
  5039. *****************************************************************************/
  5040. void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
  5041. {
  5042. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5043. pmlmeext->tx_rate = rate;
  5044. //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
  5045. }
  5046. void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
  5047. {
  5048. u8 wireless_mode;
  5049. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5050. //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
  5051. pattrib->hdrlen = 24;
  5052. pattrib->nr_frags = 1;
  5053. pattrib->priority = 7;
  5054. pattrib->mac_id = 0;
  5055. pattrib->qsel = 0x12;
  5056. pattrib->pktlen = 0;
  5057. if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
  5058. wireless_mode = WIRELESS_11B;
  5059. else
  5060. wireless_mode = WIRELESS_11G;
  5061. pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
  5062. pattrib->encrypt = _NO_PRIVACY_;
  5063. pattrib->bswenc = _FALSE;
  5064. pattrib->qos_en = _FALSE;
  5065. pattrib->ht_en = _FALSE;
  5066. pattrib->bwmode = CHANNEL_WIDTH_20;
  5067. pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  5068. pattrib->sgi = _FALSE;
  5069. pattrib->seqnum = pmlmeext->mgnt_seq;
  5070. pattrib->retry_ctrl = _TRUE;
  5071. pattrib->mbssid = 0;
  5072. }
  5073. void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
  5074. {
  5075. u8 *pframe;
  5076. struct pkt_attrib *pattrib = &pmgntframe->attrib;
  5077. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5078. _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
  5079. _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
  5080. }
  5081. void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
  5082. {
  5083. if(padapter->bSurpriseRemoved == _TRUE ||
  5084. padapter->bDriverStopped == _TRUE)
  5085. return;
  5086. rtw_hal_mgnt_xmit(padapter, pmgntframe);
  5087. }
  5088. s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
  5089. {
  5090. s32 ret = _FAIL;
  5091. _irqL irqL;
  5092. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  5093. struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
  5094. struct submit_ctx sctx;
  5095. if(padapter->bSurpriseRemoved == _TRUE ||
  5096. padapter->bDriverStopped == _TRUE)
  5097. return ret;
  5098. rtw_sctx_init(&sctx, timeout_ms);
  5099. pxmitbuf->sctx = &sctx;
  5100. ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
  5101. if (ret == _SUCCESS)
  5102. ret = rtw_sctx_wait(&sctx);
  5103. _enter_critical(&pxmitpriv->lock_sctx, &irqL);
  5104. pxmitbuf->sctx = NULL;
  5105. _exit_critical(&pxmitpriv->lock_sctx, &irqL);
  5106. return ret;
  5107. }
  5108. s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
  5109. {
  5110. #ifdef CONFIG_XMIT_ACK
  5111. s32 ret = _FAIL;
  5112. u32 timeout_ms = 500;// 500ms
  5113. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  5114. #ifdef CONFIG_CONCURRENT_MODE
  5115. if (padapter->pbuddy_adapter && !padapter->isprimary)
  5116. pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
  5117. #endif
  5118. if(padapter->bSurpriseRemoved == _TRUE ||
  5119. padapter->bDriverStopped == _TRUE)
  5120. return -1;
  5121. _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
  5122. pxmitpriv->ack_tx = _TRUE;
  5123. pmgntframe->ack_report = 1;
  5124. if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
  5125. ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
  5126. }
  5127. pxmitpriv->ack_tx = _FALSE;
  5128. _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
  5129. return ret;
  5130. #else //!CONFIG_XMIT_ACK
  5131. dump_mgntframe(padapter, pmgntframe);
  5132. rtw_msleep_os(50);
  5133. return _SUCCESS;
  5134. #endif //!CONFIG_XMIT_ACK
  5135. }
  5136. int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
  5137. {
  5138. u8 *ssid_ie;
  5139. sint ssid_len_ori;
  5140. int len_diff = 0;
  5141. ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
  5142. //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
  5143. if(ssid_ie && ssid_len_ori>0)
  5144. {
  5145. switch(hidden_ssid_mode)
  5146. {
  5147. case 1:
  5148. {
  5149. u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
  5150. u32 remain_len = 0;
  5151. remain_len = ies_len -(next_ie-ies);
  5152. ssid_ie[1] = 0;
  5153. _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
  5154. len_diff -= ssid_len_ori;
  5155. break;
  5156. }
  5157. case 2:
  5158. _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
  5159. break;
  5160. default:
  5161. break;
  5162. }
  5163. }
  5164. return len_diff;
  5165. }
  5166. void issue_beacon(_adapter *padapter, int timeout_ms)
  5167. {
  5168. struct xmit_frame *pmgntframe;
  5169. struct pkt_attrib *pattrib;
  5170. unsigned char *pframe;
  5171. struct rtw_ieee80211_hdr *pwlanhdr;
  5172. unsigned short *fctrl;
  5173. unsigned int rate_len;
  5174. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5175. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5176. _irqL irqL;
  5177. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5178. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5179. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5180. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5181. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  5182. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  5183. #ifdef CONFIG_P2P
  5184. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5185. #endif //CONFIG_P2P
  5186. //DBG_871X("%s\n", __FUNCTION__);
  5187. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5188. {
  5189. DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
  5190. return;
  5191. }
  5192. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5193. _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5194. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5195. //update attribute
  5196. pattrib = &pmgntframe->attrib;
  5197. update_mgntframe_attrib(padapter, pattrib);
  5198. pattrib->qsel = 0x10;
  5199. #ifdef CONFIG_CONCURRENT_MODE
  5200. if(padapter->iface_type == IFACE_PORT1)
  5201. pattrib->mbssid = 1;
  5202. #endif
  5203. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5204. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5205. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5206. fctrl = &(pwlanhdr->frame_ctl);
  5207. *(fctrl) = 0;
  5208. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  5209. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5210. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
  5211. SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
  5212. //pmlmeext->mgnt_seq++;
  5213. SetFrameSubType(pframe, WIFI_BEACON);
  5214. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5215. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  5216. if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  5217. {
  5218. //DBG_871X("ie len=%d\n", cur_network->IELength);
  5219. #ifdef CONFIG_P2P
  5220. // for P2P : Primary Device Type & Device Name
  5221. u32 wpsielen=0, insert_len=0;
  5222. u8 *wpsie=NULL;
  5223. wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
  5224. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
  5225. {
  5226. uint wps_offset, remainder_ielen;
  5227. u8 *premainder_ie, *pframe_wscie;
  5228. wps_offset = (uint)(wpsie - cur_network->IEs);
  5229. premainder_ie = wpsie + wpsielen;
  5230. remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
  5231. #ifdef CONFIG_IOCTL_CFG80211
  5232. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5233. {
  5234. if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
  5235. {
  5236. _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
  5237. pframe += wps_offset;
  5238. pattrib->pktlen += wps_offset;
  5239. _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
  5240. pframe += pmlmepriv->wps_beacon_ie_len;
  5241. pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
  5242. //copy remainder_ie to pframe
  5243. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5244. pframe += remainder_ielen;
  5245. pattrib->pktlen += remainder_ielen;
  5246. }
  5247. else
  5248. {
  5249. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5250. pframe += cur_network->IELength;
  5251. pattrib->pktlen += cur_network->IELength;
  5252. }
  5253. }
  5254. else
  5255. #endif //CONFIG_IOCTL_CFG80211
  5256. {
  5257. pframe_wscie = pframe + wps_offset;
  5258. _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
  5259. pframe += (wps_offset + wpsielen);
  5260. pattrib->pktlen += (wps_offset + wpsielen);
  5261. //now pframe is end of wsc ie, insert Primary Device Type & Device Name
  5262. // Primary Device Type
  5263. // Type:
  5264. *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
  5265. insert_len += 2;
  5266. // Length:
  5267. *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
  5268. insert_len += 2;
  5269. // Value:
  5270. // Category ID
  5271. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  5272. insert_len += 2;
  5273. // OUI
  5274. *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
  5275. insert_len += 4;
  5276. // Sub Category ID
  5277. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  5278. insert_len += 2;
  5279. // Device Name
  5280. // Type:
  5281. *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  5282. insert_len += 2;
  5283. // Length:
  5284. *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
  5285. insert_len += 2;
  5286. // Value:
  5287. _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
  5288. insert_len += pwdinfo->device_name_len;
  5289. //update wsc ie length
  5290. *(pframe_wscie+1) = (wpsielen -2) + insert_len;
  5291. //pframe move to end
  5292. pframe+=insert_len;
  5293. pattrib->pktlen += insert_len;
  5294. //copy remainder_ie to pframe
  5295. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5296. pframe += remainder_ielen;
  5297. pattrib->pktlen += remainder_ielen;
  5298. }
  5299. }
  5300. else
  5301. #endif //CONFIG_P2P
  5302. {
  5303. int len_diff;
  5304. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5305. len_diff = update_hidden_ssid(
  5306. pframe+_BEACON_IE_OFFSET_
  5307. , cur_network->IELength-_BEACON_IE_OFFSET_
  5308. , pmlmeinfo->hidden_ssid_mode
  5309. );
  5310. pframe += (cur_network->IELength+len_diff);
  5311. pattrib->pktlen += (cur_network->IELength+len_diff);
  5312. }
  5313. {
  5314. u8 *wps_ie;
  5315. uint wps_ielen;
  5316. u8 sr = 0;
  5317. wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
  5318. pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
  5319. if (wps_ie && wps_ielen>0) {
  5320. rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
  5321. }
  5322. if (sr != 0)
  5323. set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
  5324. else
  5325. _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
  5326. }
  5327. #ifdef CONFIG_P2P
  5328. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
  5329. {
  5330. u32 len;
  5331. #ifdef CONFIG_IOCTL_CFG80211
  5332. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5333. {
  5334. len = pmlmepriv->p2p_beacon_ie_len;
  5335. if(pmlmepriv->p2p_beacon_ie && len>0)
  5336. _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
  5337. }
  5338. else
  5339. #endif //CONFIG_IOCTL_CFG80211
  5340. {
  5341. len = build_beacon_p2p_ie(pwdinfo, pframe);
  5342. }
  5343. pframe += len;
  5344. pattrib->pktlen += len;
  5345. #ifdef CONFIG_WFD
  5346. #ifdef CONFIG_IOCTL_CFG80211
  5347. if(_TRUE == pwdinfo->wfd_info->wfd_enable)
  5348. #endif //CONFIG_IOCTL_CFG80211
  5349. {
  5350. len = build_beacon_wfd_ie( pwdinfo, pframe );
  5351. }
  5352. #ifdef CONFIG_IOCTL_CFG80211
  5353. else
  5354. {
  5355. len = 0;
  5356. if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
  5357. {
  5358. len = pmlmepriv->wfd_beacon_ie_len;
  5359. _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
  5360. }
  5361. }
  5362. #endif //CONFIG_IOCTL_CFG80211
  5363. pframe += len;
  5364. pattrib->pktlen += len;
  5365. #endif //CONFIG_WFD
  5366. }
  5367. #endif //CONFIG_P2P
  5368. goto _issue_bcn;
  5369. }
  5370. //below for ad-hoc mode
  5371. //timestamp will be inserted by hardware
  5372. pframe += 8;
  5373. pattrib->pktlen += 8;
  5374. // beacon interval: 2 bytes
  5375. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  5376. pframe += 2;
  5377. pattrib->pktlen += 2;
  5378. // capability info: 2 bytes
  5379. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  5380. pframe += 2;
  5381. pattrib->pktlen += 2;
  5382. // SSID
  5383. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
  5384. // supported rates...
  5385. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  5386. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
  5387. // DS parameter set
  5388. pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
  5389. //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  5390. {
  5391. u8 erpinfo=0;
  5392. u32 ATIMWindow;
  5393. // IBSS Parameter Set...
  5394. //ATIMWindow = cur->Configuration.ATIMWindow;
  5395. ATIMWindow = 0;
  5396. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
  5397. //ERP IE
  5398. pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
  5399. }
  5400. // EXTERNDED SUPPORTED RATE
  5401. if (rate_len > 8)
  5402. {
  5403. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
  5404. }
  5405. //todo:HT for adhoc
  5406. _issue_bcn:
  5407. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5408. pmlmepriv->update_bcn = _FALSE;
  5409. _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
  5410. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5411. if ((pattrib->pktlen + TXDESC_SIZE) > 512)
  5412. {
  5413. DBG_871X("beacon frame too large\n");
  5414. return;
  5415. }
  5416. pattrib->last_txcmdsz = pattrib->pktlen;
  5417. //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
  5418. if(timeout_ms > 0)
  5419. dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
  5420. else
  5421. dump_mgntframe(padapter, pmgntframe);
  5422. }
  5423. void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
  5424. {
  5425. struct xmit_frame *pmgntframe;
  5426. struct pkt_attrib *pattrib;
  5427. unsigned char *pframe;
  5428. struct rtw_ieee80211_hdr *pwlanhdr;
  5429. unsigned short *fctrl;
  5430. unsigned char *mac, *bssid;
  5431. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5432. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5433. u8 *pwps_ie;
  5434. uint wps_ielen;
  5435. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  5436. #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5437. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5438. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5439. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  5440. unsigned int rate_len;
  5441. #ifdef CONFIG_P2P
  5442. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5443. #ifdef CONFIG_WFD
  5444. u32 wfdielen = 0;
  5445. #endif //CONFIG_WFD
  5446. #endif //CONFIG_P2P
  5447. //DBG_871X("%s\n", __FUNCTION__);
  5448. if(da == NULL)
  5449. return;
  5450. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5451. {
  5452. DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
  5453. return;
  5454. }
  5455. //update attribute
  5456. pattrib = &pmgntframe->attrib;
  5457. update_mgntframe_attrib(padapter, pattrib);
  5458. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5459. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5460. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5461. mac = myid(&(padapter->eeprompriv));
  5462. bssid = cur_network->MacAddress;
  5463. fctrl = &(pwlanhdr->frame_ctl);
  5464. *(fctrl) = 0;
  5465. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  5466. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  5467. _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
  5468. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5469. pmlmeext->mgnt_seq++;
  5470. SetFrameSubType(fctrl, WIFI_PROBERSP);
  5471. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5472. pattrib->pktlen = pattrib->hdrlen;
  5473. pframe += pattrib->hdrlen;
  5474. if(cur_network->IELength>MAX_IE_SZ)
  5475. return;
  5476. #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
  5477. if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  5478. {
  5479. pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
  5480. //inerset & update wps_probe_resp_ie
  5481. if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
  5482. {
  5483. uint wps_offset, remainder_ielen;
  5484. u8 *premainder_ie;
  5485. wps_offset = (uint)(pwps_ie - cur_network->IEs);
  5486. premainder_ie = pwps_ie + wps_ielen;
  5487. remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
  5488. _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
  5489. pframe += wps_offset;
  5490. pattrib->pktlen += wps_offset;
  5491. wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
  5492. if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
  5493. {
  5494. _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
  5495. pframe += wps_ielen+2;
  5496. pattrib->pktlen += wps_ielen+2;
  5497. }
  5498. if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
  5499. {
  5500. _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
  5501. pframe += remainder_ielen;
  5502. pattrib->pktlen += remainder_ielen;
  5503. }
  5504. }
  5505. else
  5506. {
  5507. _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
  5508. pframe += cur_network->IELength;
  5509. pattrib->pktlen += cur_network->IELength;
  5510. }
  5511. /* retrieve SSID IE from cur_network->Ssid */
  5512. {
  5513. u8 *ssid_ie;
  5514. sint ssid_ielen;
  5515. sint ssid_ielen_diff;
  5516. u8 buf[MAX_IE_SZ];
  5517. u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
  5518. ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
  5519. (pframe-ies)-_FIXED_IE_LENGTH_);
  5520. ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
  5521. if (ssid_ie && cur_network->Ssid.SsidLength) {
  5522. uint remainder_ielen;
  5523. u8 *remainder_ie;
  5524. remainder_ie = ssid_ie+2;
  5525. remainder_ielen = (pframe-remainder_ie);
  5526. DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
  5527. if (remainder_ielen > MAX_IE_SZ) {
  5528. remainder_ielen = MAX_IE_SZ;
  5529. }
  5530. _rtw_memcpy(buf, remainder_ie, remainder_ielen);
  5531. _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
  5532. *(ssid_ie+1) = cur_network->Ssid.SsidLength;
  5533. _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
  5534. pframe += ssid_ielen_diff;
  5535. pattrib->pktlen += ssid_ielen_diff;
  5536. }
  5537. }
  5538. }
  5539. else
  5540. #endif
  5541. {
  5542. //timestamp will be inserted by hardware
  5543. pframe += 8;
  5544. pattrib->pktlen += 8;
  5545. // beacon interval: 2 bytes
  5546. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
  5547. pframe += 2;
  5548. pattrib->pktlen += 2;
  5549. // capability info: 2 bytes
  5550. _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
  5551. pframe += 2;
  5552. pattrib->pktlen += 2;
  5553. //below for ad-hoc mode
  5554. // SSID
  5555. pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
  5556. // supported rates...
  5557. rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
  5558. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
  5559. // DS parameter set
  5560. pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
  5561. if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  5562. {
  5563. u8 erpinfo=0;
  5564. u32 ATIMWindow;
  5565. // IBSS Parameter Set...
  5566. //ATIMWindow = cur->Configuration.ATIMWindow;
  5567. ATIMWindow = 0;
  5568. pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
  5569. //ERP IE
  5570. pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
  5571. }
  5572. // EXTERNDED SUPPORTED RATE
  5573. if (rate_len > 8)
  5574. {
  5575. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
  5576. }
  5577. //todo:HT for adhoc
  5578. }
  5579. #ifdef CONFIG_P2P
  5580. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq)
  5581. {
  5582. u32 len;
  5583. #ifdef CONFIG_IOCTL_CFG80211
  5584. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  5585. {
  5586. //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
  5587. len = pmlmepriv->p2p_go_probe_resp_ie_len;
  5588. if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
  5589. _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
  5590. }
  5591. else
  5592. #endif //CONFIG_IOCTL_CFG80211
  5593. {
  5594. len = build_probe_resp_p2p_ie(pwdinfo, pframe);
  5595. }
  5596. pframe += len;
  5597. pattrib->pktlen += len;
  5598. #ifdef CONFIG_WFD
  5599. #ifdef CONFIG_IOCTL_CFG80211
  5600. if(_TRUE == pwdinfo->wfd_info->wfd_enable)
  5601. #endif //CONFIG_IOCTL_CFG80211
  5602. {
  5603. len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
  5604. }
  5605. #ifdef CONFIG_IOCTL_CFG80211
  5606. else
  5607. {
  5608. len = 0;
  5609. if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
  5610. {
  5611. len = pmlmepriv->wfd_probe_resp_ie_len;
  5612. _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
  5613. }
  5614. }
  5615. #endif //CONFIG_IOCTL_CFG80211
  5616. pframe += len;
  5617. pattrib->pktlen += len;
  5618. #endif //CONFIG_WFD
  5619. }
  5620. #endif //CONFIG_P2P
  5621. #ifdef CONFIG_AUTO_AP_MODE
  5622. {
  5623. struct sta_info *psta;
  5624. struct sta_priv *pstapriv = &padapter->stapriv;
  5625. DBG_871X("(%s)\n", __FUNCTION__);
  5626. //check rc station
  5627. psta = rtw_get_stainfo(pstapriv, da);
  5628. if (psta && psta->isrc && psta->pid>0)
  5629. {
  5630. u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
  5631. u8 RC_INFO[14] = {0};
  5632. //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
  5633. u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
  5634. DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
  5635. psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
  5636. //append vendor specific ie
  5637. _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
  5638. _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
  5639. _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
  5640. _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
  5641. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
  5642. }
  5643. }
  5644. #endif //CONFIG_AUTO_AP_MODE
  5645. pattrib->last_txcmdsz = pattrib->pktlen;
  5646. dump_mgntframe(padapter, pmgntframe);
  5647. return;
  5648. }
  5649. int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack)
  5650. {
  5651. int ret = _FAIL;
  5652. struct xmit_frame *pmgntframe;
  5653. struct pkt_attrib *pattrib;
  5654. unsigned char *pframe;
  5655. struct rtw_ieee80211_hdr *pwlanhdr;
  5656. unsigned short *fctrl;
  5657. unsigned char *mac;
  5658. unsigned char bssrate[NumRates];
  5659. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5660. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5661. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5662. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5663. int bssrate_len = 0;
  5664. u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  5665. RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
  5666. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5667. {
  5668. goto exit;
  5669. }
  5670. //update attribute
  5671. pattrib = &pmgntframe->attrib;
  5672. update_mgntframe_attrib(padapter, pattrib);
  5673. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5674. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5675. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5676. mac = myid(&(padapter->eeprompriv));
  5677. fctrl = &(pwlanhdr->frame_ctl);
  5678. *(fctrl) = 0;
  5679. if (da)
  5680. {
  5681. // unicast probe request frame
  5682. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  5683. _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
  5684. }
  5685. else
  5686. {
  5687. // broadcast probe request frame
  5688. _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
  5689. _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
  5690. }
  5691. _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
  5692. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5693. pmlmeext->mgnt_seq++;
  5694. SetFrameSubType(pframe, WIFI_PROBEREQ);
  5695. pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
  5696. pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
  5697. if(pssid)
  5698. pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
  5699. else
  5700. pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
  5701. get_rate_set(padapter, bssrate, &bssrate_len);
  5702. if (bssrate_len > 8)
  5703. {
  5704. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
  5705. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
  5706. }
  5707. else
  5708. {
  5709. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
  5710. }
  5711. #if 0
  5712. //add wps_ie for wps2.0
  5713. if(pmlmepriv->probereq_wpsie_len>0 && pmlmepriv->probereq_wpsie_len<MAX_WPS_IE_LEN)
  5714. {
  5715. _rtw_memcpy(pframe, pmlmepriv->probereq_wpsie, pmlmepriv->probereq_wpsie_len);
  5716. pframe += pmlmepriv->probereq_wpsie_len;
  5717. pattrib->pktlen += pmlmepriv->probereq_wpsie_len;
  5718. //pmlmepriv->probereq_wpsie_len = 0 ;//reset to zero
  5719. }
  5720. #else
  5721. //add wps_ie for wps2.0
  5722. if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
  5723. {
  5724. _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
  5725. pframe += pmlmepriv->wps_probe_req_ie_len;
  5726. pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
  5727. //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
  5728. }
  5729. #endif
  5730. pattrib->last_txcmdsz = pattrib->pktlen;
  5731. RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
  5732. if (wait_ack) {
  5733. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  5734. } else {
  5735. dump_mgntframe(padapter, pmgntframe);
  5736. ret = _SUCCESS;
  5737. }
  5738. exit:
  5739. return ret;
  5740. }
  5741. inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
  5742. {
  5743. _issue_probereq(padapter, pssid, da, _FALSE);
  5744. }
  5745. int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da,
  5746. int try_cnt, int wait_ms)
  5747. {
  5748. int ret;
  5749. int i = 0;
  5750. u32 start = rtw_get_current_time();
  5751. do
  5752. {
  5753. ret = _issue_probereq(padapter, pssid, da, wait_ms>0?_TRUE:_FALSE);
  5754. i++;
  5755. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  5756. break;
  5757. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  5758. rtw_msleep_os(wait_ms);
  5759. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  5760. if (ret != _FAIL) {
  5761. ret = _SUCCESS;
  5762. #ifndef DBG_XMIT_ACK
  5763. goto exit;
  5764. #endif
  5765. }
  5766. if (try_cnt && wait_ms) {
  5767. if (da)
  5768. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  5769. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  5770. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  5771. else
  5772. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  5773. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  5774. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  5775. }
  5776. exit:
  5777. return ret;
  5778. }
  5779. // if psta == NULL, indiate we are station(client) now...
  5780. void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
  5781. {
  5782. struct xmit_frame *pmgntframe;
  5783. struct pkt_attrib *pattrib;
  5784. unsigned char *pframe;
  5785. struct rtw_ieee80211_hdr *pwlanhdr;
  5786. unsigned short *fctrl;
  5787. unsigned int val32;
  5788. unsigned short val16;
  5789. int use_shared_key = 0;
  5790. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5791. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  5792. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5793. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5794. {
  5795. return;
  5796. }
  5797. //update attribute
  5798. pattrib = &pmgntframe->attrib;
  5799. update_mgntframe_attrib(padapter, pattrib);
  5800. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5801. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5802. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5803. fctrl = &(pwlanhdr->frame_ctl);
  5804. *(fctrl) = 0;
  5805. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5806. pmlmeext->mgnt_seq++;
  5807. SetFrameSubType(pframe, WIFI_AUTH);
  5808. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  5809. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5810. if(psta)// for AP mode
  5811. {
  5812. #ifdef CONFIG_NATIVEAP_MLME
  5813. _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
  5814. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5815. _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
  5816. // setting auth algo number
  5817. val16 = (u16)psta->authalg;
  5818. if(status != _STATS_SUCCESSFUL_)
  5819. val16 = 0;
  5820. if (val16) {
  5821. val16 = cpu_to_le16(val16);
  5822. use_shared_key = 1;
  5823. }
  5824. pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5825. // setting auth seq number
  5826. val16 =(u16)psta->auth_seq;
  5827. val16 = cpu_to_le16(val16);
  5828. pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5829. // setting status code...
  5830. val16 = status;
  5831. val16 = cpu_to_le16(val16);
  5832. pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
  5833. // added challenging text...
  5834. if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5835. {
  5836. pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
  5837. }
  5838. #endif
  5839. }
  5840. else
  5841. {
  5842. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
  5843. _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
  5844. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
  5845. // setting auth algo number
  5846. val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
  5847. if (val16) {
  5848. val16 = cpu_to_le16(val16);
  5849. use_shared_key = 1;
  5850. }
  5851. //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
  5852. //setting IV for auth seq #3
  5853. if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5854. {
  5855. //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
  5856. val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
  5857. val32 = cpu_to_le32(val32);
  5858. pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
  5859. pattrib->iv_len = 4;
  5860. }
  5861. pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5862. // setting auth seq number
  5863. val16 = pmlmeinfo->auth_seq;
  5864. val16 = cpu_to_le16(val16);
  5865. pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
  5866. // setting status code...
  5867. val16 = status;
  5868. val16 = cpu_to_le16(val16);
  5869. pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
  5870. // then checking to see if sending challenging text...
  5871. if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
  5872. {
  5873. pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
  5874. SetPrivacy(fctrl);
  5875. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5876. pattrib->encrypt = _WEP40_;
  5877. pattrib->icv_len = 4;
  5878. pattrib->pktlen += pattrib->icv_len;
  5879. }
  5880. }
  5881. pattrib->last_txcmdsz = pattrib->pktlen;
  5882. rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
  5883. DBG_871X("%s\n", __FUNCTION__);
  5884. dump_mgntframe(padapter, pmgntframe);
  5885. return;
  5886. }
  5887. void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
  5888. {
  5889. #ifdef CONFIG_AP_MODE
  5890. struct xmit_frame *pmgntframe;
  5891. struct rtw_ieee80211_hdr *pwlanhdr;
  5892. struct pkt_attrib *pattrib;
  5893. unsigned char *pbuf, *pframe;
  5894. unsigned short val;
  5895. unsigned short *fctrl;
  5896. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  5897. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  5898. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  5899. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  5900. WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
  5901. u8 *ie = pnetwork->IEs;
  5902. #ifdef CONFIG_P2P
  5903. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  5904. #ifdef CONFIG_WFD
  5905. u32 wfdielen = 0;
  5906. #endif //CONFIG_WFD
  5907. #endif //CONFIG_P2P
  5908. DBG_871X("%s\n", __FUNCTION__);
  5909. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  5910. {
  5911. return;
  5912. }
  5913. //update attribute
  5914. pattrib = &pmgntframe->attrib;
  5915. update_mgntframe_attrib(padapter, pattrib);
  5916. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  5917. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  5918. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  5919. fctrl = &(pwlanhdr->frame_ctl);
  5920. *(fctrl) = 0;
  5921. _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
  5922. _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
  5923. _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  5924. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  5925. pmlmeext->mgnt_seq++;
  5926. if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
  5927. SetFrameSubType(pwlanhdr, pkt_type);
  5928. else
  5929. return;
  5930. pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  5931. pattrib->pktlen += pattrib->hdrlen;
  5932. pframe += pattrib->hdrlen;
  5933. //capability
  5934. val = *(unsigned short *)rtw_get_capability_from_ie(ie);
  5935. pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
  5936. status = cpu_to_le16(status);
  5937. pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
  5938. val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
  5939. pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
  5940. if (pstat->bssratelen <= 8)
  5941. {
  5942. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
  5943. }
  5944. else
  5945. {
  5946. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
  5947. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
  5948. }
  5949. #ifdef CONFIG_80211N_HT
  5950. if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
  5951. {
  5952. uint ie_len=0;
  5953. //FILL HT CAP INFO IE
  5954. //p = hostapd_eid_ht_capabilities_info(hapd, p);
  5955. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5956. if(pbuf && ie_len>0)
  5957. {
  5958. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5959. pframe += (ie_len+2);
  5960. pattrib->pktlen +=(ie_len+2);
  5961. }
  5962. //FILL HT ADD INFO IE
  5963. //p = hostapd_eid_ht_operation(hapd, p);
  5964. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5965. if(pbuf && ie_len>0)
  5966. {
  5967. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5968. pframe += (ie_len+2);
  5969. pattrib->pktlen +=(ie_len+2);
  5970. }
  5971. }
  5972. #endif
  5973. #ifdef CONFIG_80211AC_VHT
  5974. if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option))
  5975. {
  5976. u32 ie_len=0;
  5977. //FILL VHT CAP IE
  5978. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5979. if(pbuf && ie_len>0)
  5980. {
  5981. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5982. pframe += (ie_len+2);
  5983. pattrib->pktlen +=(ie_len+2);
  5984. }
  5985. //FILL VHT OPERATION IE
  5986. pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
  5987. if(pbuf && ie_len>0)
  5988. {
  5989. _rtw_memcpy(pframe, pbuf, ie_len+2);
  5990. pframe += (ie_len+2);
  5991. pattrib->pktlen +=(ie_len+2);
  5992. }
  5993. }
  5994. #endif //CONFIG_80211AC_VHT
  5995. //FILL WMM IE
  5996. if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
  5997. {
  5998. uint ie_len=0;
  5999. unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
  6000. for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
  6001. {
  6002. pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
  6003. if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
  6004. {
  6005. _rtw_memcpy(pframe, pbuf, ie_len+2);
  6006. pframe += (ie_len+2);
  6007. pattrib->pktlen +=(ie_len+2);
  6008. break;
  6009. }
  6010. if ((pbuf == NULL) || (ie_len == 0))
  6011. {
  6012. break;
  6013. }
  6014. }
  6015. }
  6016. if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
  6017. {
  6018. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
  6019. }
  6020. //add WPS IE ie for wps 2.0
  6021. if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
  6022. {
  6023. _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
  6024. pframe += pmlmepriv->wps_assoc_resp_ie_len;
  6025. pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
  6026. }
  6027. #ifdef CONFIG_P2P
  6028. if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
  6029. {
  6030. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
  6031. {
  6032. u32 len;
  6033. len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
  6034. pframe += len;
  6035. pattrib->pktlen += len;
  6036. }
  6037. }
  6038. #ifdef CONFIG_WFD
  6039. if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
  6040. #ifdef CONFIG_IOCTL_CFG80211
  6041. && (_TRUE == pwdinfo->wfd_info->wfd_enable)
  6042. #endif //CONFIG_IOCTL_CFG80211
  6043. )
  6044. {
  6045. wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
  6046. pframe += wfdielen;
  6047. pattrib->pktlen += wfdielen;
  6048. }
  6049. #endif //CONFIG_WFD
  6050. #endif //CONFIG_P2P
  6051. pattrib->last_txcmdsz = pattrib->pktlen;
  6052. dump_mgntframe(padapter, pmgntframe);
  6053. #endif
  6054. }
  6055. void issue_assocreq(_adapter *padapter)
  6056. {
  6057. int ret = _FAIL;
  6058. struct xmit_frame *pmgntframe;
  6059. struct pkt_attrib *pattrib;
  6060. unsigned char *pframe, *p;
  6061. struct rtw_ieee80211_hdr *pwlanhdr;
  6062. unsigned short *fctrl;
  6063. unsigned short val16;
  6064. unsigned int i, j, ie_len, index=0;
  6065. unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
  6066. PNDIS_802_11_VARIABLE_IEs pIE;
  6067. struct registry_priv *pregpriv = &padapter->registrypriv;
  6068. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6069. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  6070. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6071. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6072. int bssrate_len = 0, sta_bssrate_len = 0;
  6073. u8 cbw40_enable = 0;
  6074. #ifdef CONFIG_P2P
  6075. struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
  6076. u8 p2pie[ 255 ] = { 0x00 };
  6077. u16 p2pielen = 0;
  6078. #ifdef CONFIG_WFD
  6079. u32 wfdielen = 0;
  6080. #endif //CONFIG_WFD
  6081. #endif //CONFIG_P2P
  6082. #ifdef CONFIG_DFS
  6083. u16 cap;
  6084. #endif //CONFIG_DFS
  6085. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6086. goto exit;
  6087. //update attribute
  6088. pattrib = &pmgntframe->attrib;
  6089. update_mgntframe_attrib(padapter, pattrib);
  6090. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6091. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6092. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6093. fctrl = &(pwlanhdr->frame_ctl);
  6094. *(fctrl) = 0;
  6095. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6096. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6097. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6098. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6099. pmlmeext->mgnt_seq++;
  6100. SetFrameSubType(pframe, WIFI_ASSOCREQ);
  6101. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6102. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6103. //caps
  6104. #ifdef CONFIG_DFS
  6105. _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
  6106. cap |= BIT(8);
  6107. _rtw_memcpy(pframe, &cap, 2);
  6108. #else
  6109. _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
  6110. #endif //CONFIG_DFS
  6111. pframe += 2;
  6112. pattrib->pktlen += 2;
  6113. //listen interval
  6114. //todo: listen interval for power saving
  6115. val16 = cpu_to_le16(3);
  6116. _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
  6117. pframe += 2;
  6118. pattrib->pktlen += 2;
  6119. //SSID
  6120. pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
  6121. //supported rate & extended supported rate
  6122. #if 1 // Check if the AP's supported rates are also supported by STA.
  6123. get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
  6124. //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
  6125. if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
  6126. {
  6127. sta_bssrate_len = 4;
  6128. }
  6129. //for (i = 0; i < sta_bssrate_len; i++) {
  6130. // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
  6131. //}
  6132. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  6133. if (pmlmeinfo->network.SupportedRates[i] == 0) break;
  6134. DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
  6135. }
  6136. for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
  6137. if (pmlmeinfo->network.SupportedRates[i] == 0) break;
  6138. // Check if the AP's supported rates are also supported by STA.
  6139. for (j=0; j < sta_bssrate_len; j++) {
  6140. // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
  6141. if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
  6142. == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
  6143. //DBG_871X("match i = %d, j=%d\n", i, j);
  6144. break;
  6145. } else {
  6146. //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
  6147. }
  6148. }
  6149. if (j == sta_bssrate_len) {
  6150. // the rate is not supported by STA
  6151. DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
  6152. } else {
  6153. // the rate is supported by STA
  6154. bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
  6155. }
  6156. }
  6157. bssrate_len = index;
  6158. DBG_871X("bssrate_len = %d\n", bssrate_len);
  6159. #else // Check if the AP's supported rates are also supported by STA.
  6160. #if 0
  6161. get_rate_set(padapter, bssrate, &bssrate_len);
  6162. #else
  6163. for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
  6164. if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
  6165. if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
  6166. break;
  6167. bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
  6168. }
  6169. #endif
  6170. #endif // Check if the AP's supported rates are also supported by STA.
  6171. if (bssrate_len == 0) {
  6172. rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
  6173. rtw_free_xmitframe(pxmitpriv, pmgntframe);
  6174. goto exit; //don't connect to AP if no joint supported rate
  6175. }
  6176. if (bssrate_len > 8)
  6177. {
  6178. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
  6179. pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
  6180. }
  6181. else
  6182. {
  6183. pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
  6184. }
  6185. //RSN
  6186. 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)));
  6187. if (p != NULL)
  6188. {
  6189. pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
  6190. }
  6191. #ifdef CONFIG_80211N_HT
  6192. //HT caps
  6193. if(padapter->mlmepriv.htpriv.ht_option==_TRUE)
  6194. {
  6195. 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)));
  6196. if ((p != NULL) && (!(is_ap_in_tkip(padapter))))
  6197. {
  6198. _rtw_memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
  6199. //to disable 40M Hz support while gd_bw_40MHz_en = 0
  6200. if (pmlmeext->cur_channel > 14) {
  6201. if ((pregpriv->bw_mode & 0xf0) > 0)
  6202. cbw40_enable = 1;
  6203. } else {
  6204. if ((pregpriv->bw_mode & 0x0f) > 0)
  6205. cbw40_enable = 1;
  6206. }
  6207. if (cbw40_enable == 0)
  6208. {
  6209. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
  6210. }
  6211. else
  6212. {
  6213. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
  6214. }
  6215. //todo: disable SM power save mode
  6216. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c;
  6217. rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  6218. //switch (pregpriv->rf_config)
  6219. switch(rf_type)
  6220. {
  6221. case RF_1T1R:
  6222. if(pregpriv->rx_stbc)
  6223. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
  6224. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
  6225. break;
  6226. case RF_2T2R:
  6227. case RF_1T2R:
  6228. default:
  6229. if((pregpriv->rx_stbc == 0x3) ||//enable for 2.4/5 GHz
  6230. ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || //enable for 2.4GHz
  6231. ((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || //enable for 5GHz
  6232. (pregpriv->wifi_spec==1))
  6233. {
  6234. DBG_871X("declare supporting RX STBC\n");
  6235. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);//RX STBC two spatial stream
  6236. }
  6237. #ifdef CONFIG_DISABLE_MCS13TO15
  6238. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1))
  6239. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16);
  6240. else
  6241. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
  6242. #else //CONFIG_DISABLE_MCS13TO15
  6243. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
  6244. #endif //CONFIG_DISABLE_MCS13TO15
  6245. break;
  6246. }
  6247. #ifdef RTL8192C_RECONFIG_TO_1T1R
  6248. {
  6249. if(pregpriv->rx_stbc)
  6250. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
  6251. _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
  6252. }
  6253. #endif
  6254. pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
  6255. #ifdef CONFIG_BT_COEXIST
  6256. if (BT_1Ant(padapter) == _TRUE)
  6257. {
  6258. // set to 8K
  6259. pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_CAP_AMPDU_FACTOR;
  6260. // pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K
  6261. }
  6262. #endif
  6263. pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
  6264. }
  6265. }
  6266. #endif
  6267. //vendor specific IE, such as WPA, WMM, WPS
  6268. for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
  6269. {
  6270. pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
  6271. switch (pIE->ElementID)
  6272. {
  6273. case _VENDOR_SPECIFIC_IE_:
  6274. if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
  6275. (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
  6276. (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
  6277. {
  6278. if(!padapter->registrypriv.wifi_spec)
  6279. {
  6280. //Commented by Kurt 20110629
  6281. //In some older APs, WPS handshake
  6282. //would be fail if we append vender extensions informations to AP
  6283. if(_rtw_memcmp(pIE->data, WPS_OUI, 4)){
  6284. pIE->Length=14;
  6285. }
  6286. }
  6287. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
  6288. }
  6289. break;
  6290. #ifdef CONFIG_80211AC_VHT
  6291. case EID_VHTCapability:
  6292. if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
  6293. pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
  6294. }
  6295. break;
  6296. case EID_OpModeNotification:
  6297. if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
  6298. pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
  6299. }
  6300. break;
  6301. #endif // CONFIG_80211AC_VHT
  6302. default:
  6303. break;
  6304. }
  6305. i += (pIE->Length + 2);
  6306. }
  6307. if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
  6308. {
  6309. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
  6310. }
  6311. #ifdef CONFIG_WAPI_SUPPORT
  6312. rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
  6313. #endif
  6314. #ifdef CONFIG_P2P
  6315. #ifdef CONFIG_IOCTL_CFG80211
  6316. if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
  6317. {
  6318. if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
  6319. {
  6320. _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
  6321. pframe += pmlmepriv->p2p_assoc_req_ie_len;
  6322. pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
  6323. }
  6324. }
  6325. else
  6326. #endif //CONFIG_IOCTL_CFG80211
  6327. {
  6328. if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
  6329. {
  6330. // Should add the P2P IE in the association request frame.
  6331. // P2P OUI
  6332. p2pielen = 0;
  6333. p2pie[ p2pielen++ ] = 0x50;
  6334. p2pie[ p2pielen++ ] = 0x6F;
  6335. p2pie[ p2pielen++ ] = 0x9A;
  6336. p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
  6337. // Commented by Albert 20101109
  6338. // According to the P2P Specification, the association request frame should contain 3 P2P attributes
  6339. // 1. P2P Capability
  6340. // 2. Extended Listen Timing
  6341. // 3. Device Info
  6342. // Commented by Albert 20110516
  6343. // 4. P2P Interface
  6344. // P2P Capability
  6345. // Type:
  6346. p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
  6347. // Length:
  6348. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
  6349. p2pielen += 2;
  6350. // Value:
  6351. // Device Capability Bitmap, 1 byte
  6352. p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
  6353. // Group Capability Bitmap, 1 byte
  6354. if ( pwdinfo->persistent_supported )
  6355. p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
  6356. else
  6357. p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
  6358. // Extended Listen Timing
  6359. // Type:
  6360. p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
  6361. // Length:
  6362. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
  6363. p2pielen += 2;
  6364. // Value:
  6365. // Availability Period
  6366. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  6367. p2pielen += 2;
  6368. // Availability Interval
  6369. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
  6370. p2pielen += 2;
  6371. // Device Info
  6372. // Type:
  6373. p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
  6374. // Length:
  6375. // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
  6376. // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
  6377. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
  6378. p2pielen += 2;
  6379. // Value:
  6380. // P2P Device Address
  6381. _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
  6382. p2pielen += ETH_ALEN;
  6383. // Config Method
  6384. // This field should be big endian. Noted by P2P specification.
  6385. if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
  6386. ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
  6387. {
  6388. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
  6389. }
  6390. else
  6391. {
  6392. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
  6393. }
  6394. p2pielen += 2;
  6395. // Primary Device Type
  6396. // Category ID
  6397. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
  6398. p2pielen += 2;
  6399. // OUI
  6400. *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
  6401. p2pielen += 4;
  6402. // Sub Category ID
  6403. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
  6404. p2pielen += 2;
  6405. // Number of Secondary Device Types
  6406. p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
  6407. // Device Name
  6408. // Type:
  6409. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
  6410. p2pielen += 2;
  6411. // Length:
  6412. *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
  6413. p2pielen += 2;
  6414. // Value:
  6415. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
  6416. p2pielen += pwdinfo->device_name_len;
  6417. // P2P Interface
  6418. // Type:
  6419. p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
  6420. // Length:
  6421. *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
  6422. p2pielen += 2;
  6423. // Value:
  6424. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
  6425. p2pielen += ETH_ALEN;
  6426. p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
  6427. _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
  6428. p2pielen += ETH_ALEN;
  6429. pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
  6430. #ifdef CONFIG_WFD
  6431. //wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
  6432. //pframe += wfdielen;
  6433. //pattrib->pktlen += wfdielen;
  6434. #endif //CONFIG_WFD
  6435. }
  6436. }
  6437. #endif //CONFIG_P2P
  6438. #ifdef CONFIG_WFD
  6439. #ifdef CONFIG_IOCTL_CFG80211
  6440. if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
  6441. #endif //CONFIG_IOCTL_CFG80211
  6442. {
  6443. wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
  6444. pframe += wfdielen;
  6445. pattrib->pktlen += wfdielen;
  6446. }
  6447. #ifdef CONFIG_IOCTL_CFG80211
  6448. else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
  6449. {
  6450. //WFD IE
  6451. _rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
  6452. pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
  6453. pframe += pmlmepriv->wfd_assoc_req_ie_len;
  6454. }
  6455. #endif //CONFIG_IOCTL_CFG80211
  6456. #endif //CONFIG_WFD
  6457. pattrib->last_txcmdsz = pattrib->pktlen;
  6458. dump_mgntframe(padapter, pmgntframe);
  6459. ret = _SUCCESS;
  6460. exit:
  6461. if (ret == _SUCCESS)
  6462. rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
  6463. else
  6464. rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
  6465. return;
  6466. }
  6467. //when wait_ack is ture, this function shoule be called at process context
  6468. static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
  6469. {
  6470. int ret = _FAIL;
  6471. struct xmit_frame *pmgntframe;
  6472. struct pkt_attrib *pattrib;
  6473. unsigned char *pframe;
  6474. struct rtw_ieee80211_hdr *pwlanhdr;
  6475. unsigned short *fctrl;
  6476. struct xmit_priv *pxmitpriv;
  6477. struct mlme_ext_priv *pmlmeext;
  6478. struct mlme_ext_info *pmlmeinfo;
  6479. //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
  6480. if(!padapter)
  6481. goto exit;
  6482. pxmitpriv = &(padapter->xmitpriv);
  6483. pmlmeext = &(padapter->mlmeextpriv);
  6484. pmlmeinfo = &(pmlmeext->mlmext_info);
  6485. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6486. {
  6487. goto exit;
  6488. }
  6489. //update attribute
  6490. pattrib = &pmgntframe->attrib;
  6491. update_mgntframe_attrib(padapter, pattrib);
  6492. pattrib->retry_ctrl = _FALSE;
  6493. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6494. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6495. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6496. fctrl = &(pwlanhdr->frame_ctl);
  6497. *(fctrl) = 0;
  6498. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  6499. {
  6500. SetFrDs(fctrl);
  6501. }
  6502. else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  6503. {
  6504. SetToDs(fctrl);
  6505. }
  6506. if (power_mode)
  6507. {
  6508. SetPwrMgt(fctrl);
  6509. }
  6510. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6511. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6512. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6513. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6514. pmlmeext->mgnt_seq++;
  6515. SetFrameSubType(pframe, WIFI_DATA_NULL);
  6516. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6517. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6518. pattrib->last_txcmdsz = pattrib->pktlen;
  6519. if(wait_ack)
  6520. {
  6521. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6522. }
  6523. else
  6524. {
  6525. dump_mgntframe(padapter, pmgntframe);
  6526. ret = _SUCCESS;
  6527. }
  6528. exit:
  6529. return ret;
  6530. }
  6531. //when wait_ms >0 , this function shoule be called at process context
  6532. //da == NULL for station mode
  6533. int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
  6534. {
  6535. int ret;
  6536. int i = 0;
  6537. u32 start = rtw_get_current_time();
  6538. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6539. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6540. /* da == NULL, assum it's null data for sta to ap*/
  6541. if (da == NULL)
  6542. da = get_my_bssid(&(pmlmeinfo->network));
  6543. do
  6544. {
  6545. ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
  6546. i++;
  6547. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6548. break;
  6549. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6550. rtw_msleep_os(wait_ms);
  6551. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6552. if (ret != _FAIL) {
  6553. ret = _SUCCESS;
  6554. #ifndef DBG_XMIT_ACK
  6555. goto exit;
  6556. #endif
  6557. }
  6558. if (try_cnt && wait_ms) {
  6559. if (da)
  6560. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6561. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6562. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6563. else
  6564. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6565. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6566. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6567. }
  6568. exit:
  6569. return ret;
  6570. }
  6571. //when wait_ack is ture, this function shoule be called at process context
  6572. static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
  6573. {
  6574. int ret = _FAIL;
  6575. struct xmit_frame *pmgntframe;
  6576. struct pkt_attrib *pattrib;
  6577. unsigned char *pframe;
  6578. struct rtw_ieee80211_hdr *pwlanhdr;
  6579. unsigned short *fctrl, *qc;
  6580. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6581. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6582. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6583. DBG_871X("%s\n", __FUNCTION__);
  6584. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6585. {
  6586. goto exit;
  6587. }
  6588. //update attribute
  6589. pattrib = &pmgntframe->attrib;
  6590. update_mgntframe_attrib(padapter, pattrib);
  6591. pattrib->hdrlen +=2;
  6592. pattrib->qos_en = _TRUE;
  6593. pattrib->eosp = 1;
  6594. pattrib->ack_policy = 0;
  6595. pattrib->mdata = 0;
  6596. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6597. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6598. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6599. fctrl = &(pwlanhdr->frame_ctl);
  6600. *(fctrl) = 0;
  6601. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  6602. {
  6603. SetFrDs(fctrl);
  6604. }
  6605. else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  6606. {
  6607. SetToDs(fctrl);
  6608. }
  6609. if(pattrib->mdata)
  6610. SetMData(fctrl);
  6611. qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
  6612. SetPriority(qc, tid);
  6613. SetEOSP(qc, pattrib->eosp);
  6614. SetAckpolicy(qc, pattrib->ack_policy);
  6615. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6616. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6617. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6618. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6619. pmlmeext->mgnt_seq++;
  6620. SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
  6621. pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
  6622. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
  6623. pattrib->last_txcmdsz = pattrib->pktlen;
  6624. if(wait_ack)
  6625. {
  6626. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6627. }
  6628. else
  6629. {
  6630. dump_mgntframe(padapter, pmgntframe);
  6631. ret = _SUCCESS;
  6632. }
  6633. exit:
  6634. return ret;
  6635. }
  6636. //when wait_ms >0 , this function shoule be called at process context
  6637. //da == NULL for station mode
  6638. int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
  6639. {
  6640. int ret;
  6641. int i = 0;
  6642. u32 start = rtw_get_current_time();
  6643. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6644. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6645. /* da == NULL, assum it's null data for sta to ap*/
  6646. if (da == NULL)
  6647. da = get_my_bssid(&(pmlmeinfo->network));
  6648. do
  6649. {
  6650. ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
  6651. i++;
  6652. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6653. break;
  6654. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6655. rtw_msleep_os(wait_ms);
  6656. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6657. if (ret != _FAIL) {
  6658. ret = _SUCCESS;
  6659. #ifndef DBG_XMIT_ACK
  6660. goto exit;
  6661. #endif
  6662. }
  6663. if (try_cnt && wait_ms) {
  6664. if (da)
  6665. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6666. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6667. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6668. else
  6669. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6670. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6671. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6672. }
  6673. exit:
  6674. return ret;
  6675. }
  6676. static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
  6677. {
  6678. struct xmit_frame *pmgntframe;
  6679. struct pkt_attrib *pattrib;
  6680. unsigned char *pframe;
  6681. struct rtw_ieee80211_hdr *pwlanhdr;
  6682. unsigned short *fctrl;
  6683. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6684. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6685. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6686. int ret = _FAIL;
  6687. #ifdef CONFIG_P2P
  6688. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  6689. #endif //CONFIG_P2P
  6690. //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
  6691. #ifdef CONFIG_P2P
  6692. if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
  6693. {
  6694. _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
  6695. _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
  6696. }
  6697. #endif //CONFIG_P2P
  6698. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6699. {
  6700. goto exit;
  6701. }
  6702. //update attribute
  6703. pattrib = &pmgntframe->attrib;
  6704. update_mgntframe_attrib(padapter, pattrib);
  6705. pattrib->retry_ctrl = _FALSE;
  6706. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6707. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6708. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6709. fctrl = &(pwlanhdr->frame_ctl);
  6710. *(fctrl) = 0;
  6711. _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
  6712. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6713. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6714. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6715. pmlmeext->mgnt_seq++;
  6716. SetFrameSubType(pframe, WIFI_DEAUTH);
  6717. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6718. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6719. reason = cpu_to_le16(reason);
  6720. pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
  6721. pattrib->last_txcmdsz = pattrib->pktlen;
  6722. if(wait_ack)
  6723. {
  6724. ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
  6725. }
  6726. else
  6727. {
  6728. dump_mgntframe(padapter, pmgntframe);
  6729. ret = _SUCCESS;
  6730. }
  6731. exit:
  6732. return ret;
  6733. }
  6734. int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
  6735. {
  6736. DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
  6737. return _issue_deauth(padapter, da, reason, _FALSE);
  6738. }
  6739. int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
  6740. int wait_ms)
  6741. {
  6742. int ret;
  6743. int i = 0;
  6744. u32 start = rtw_get_current_time();
  6745. do
  6746. {
  6747. ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
  6748. i++;
  6749. if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
  6750. break;
  6751. if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
  6752. rtw_msleep_os(wait_ms);
  6753. }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
  6754. if (ret != _FAIL) {
  6755. ret = _SUCCESS;
  6756. #ifndef DBG_XMIT_ACK
  6757. goto exit;
  6758. #endif
  6759. }
  6760. if (try_cnt && wait_ms) {
  6761. if (da)
  6762. DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
  6763. FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
  6764. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6765. else
  6766. DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
  6767. FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
  6768. ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
  6769. }
  6770. exit:
  6771. return ret;
  6772. }
  6773. void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
  6774. {
  6775. _irqL irqL;
  6776. _list *plist, *phead;
  6777. struct xmit_frame *pmgntframe;
  6778. struct pkt_attrib *pattrib;
  6779. unsigned char *pframe;
  6780. struct rtw_ieee80211_hdr *pwlanhdr;
  6781. unsigned short *fctrl;
  6782. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6783. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6784. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6785. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6786. DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
  6787. FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
  6788. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6789. return;
  6790. //update attribute
  6791. pattrib = &pmgntframe->attrib;
  6792. update_mgntframe_attrib(padapter, pattrib);
  6793. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6794. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6795. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6796. fctrl = &(pwlanhdr->frame_ctl);
  6797. *(fctrl) = 0;
  6798. _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
  6799. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
  6800. _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
  6801. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6802. pmlmeext->mgnt_seq++;
  6803. SetFrameSubType(pframe, WIFI_ACTION);
  6804. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6805. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6806. /* category, action */
  6807. {
  6808. u8 category, action;
  6809. category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
  6810. action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
  6811. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  6812. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  6813. }
  6814. pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
  6815. pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
  6816. hal_ch_offset_to_secondary_ch_offset(ch_offset));
  6817. pattrib->last_txcmdsz = pattrib->pktlen;
  6818. dump_mgntframe(padapter, pmgntframe);
  6819. }
  6820. void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
  6821. {
  6822. u8 category = RTW_WLAN_CATEGORY_BACK;
  6823. u16 start_seq;
  6824. u16 BA_para_set;
  6825. u16 reason_code;
  6826. u16 BA_timeout_value;
  6827. u16 BA_starting_seqctrl;
  6828. HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
  6829. struct xmit_frame *pmgntframe;
  6830. struct pkt_attrib *pattrib;
  6831. u8 *pframe;
  6832. struct rtw_ieee80211_hdr *pwlanhdr;
  6833. u16 *fctrl;
  6834. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6835. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6836. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6837. struct sta_info *psta;
  6838. struct sta_priv *pstapriv = &padapter->stapriv;
  6839. struct registry_priv *pregpriv = &padapter->registrypriv;
  6840. #ifdef CONFIG_BT_COEXIST
  6841. u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
  6842. #endif
  6843. #ifdef CONFIG_80211N_HT
  6844. DBG_871X("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status);
  6845. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  6846. {
  6847. return;
  6848. }
  6849. //update attribute
  6850. pattrib = &pmgntframe->attrib;
  6851. update_mgntframe_attrib(padapter, pattrib);
  6852. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  6853. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  6854. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  6855. fctrl = &(pwlanhdr->frame_ctl);
  6856. *(fctrl) = 0;
  6857. //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6858. _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
  6859. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  6860. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  6861. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  6862. pmlmeext->mgnt_seq++;
  6863. SetFrameSubType(pframe, WIFI_ACTION);
  6864. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  6865. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  6866. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  6867. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  6868. status = cpu_to_le16(status);
  6869. if (category == 3)
  6870. {
  6871. switch (action)
  6872. {
  6873. case 0: //ADDBA req
  6874. do {
  6875. pmlmeinfo->dialogToken++;
  6876. } while (pmlmeinfo->dialogToken == 0);
  6877. pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
  6878. #ifdef CONFIG_BT_COEXIST
  6879. if ((BT_1Ant(padapter) == _TRUE) &&
  6880. ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
  6881. (_rtw_memcmp(raddr, tendaAPMac, 3) == _FALSE)))
  6882. {
  6883. // A-MSDU NOT Supported
  6884. BA_para_set = 0;
  6885. // immediate Block Ack
  6886. BA_para_set |= (1 << 1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
  6887. // TID
  6888. BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
  6889. // max buffer size is 8 MSDU
  6890. BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6891. }
  6892. else
  6893. #endif
  6894. {
  6895. #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
  6896. BA_para_set = (0x0802 | ((status & 0xf) << 2)); //immediate ack & 16 buffer size
  6897. #else
  6898. BA_para_set = (0x1002 | ((status & 0xf) << 2)); //immediate ack & 64 buffer size
  6899. #endif
  6900. }
  6901. //sys_mib.BA_para_set = 0x0802; //immediate ack & 32 buffer size
  6902. BA_para_set = cpu_to_le16(BA_para_set);
  6903. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6904. //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
  6905. BA_timeout_value = 5000;//~ 5ms
  6906. BA_timeout_value = cpu_to_le16(BA_timeout_value);
  6907. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
  6908. //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  6909. if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
  6910. {
  6911. start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
  6912. DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07);
  6913. psta->BA_starting_seqctrl[status & 0x07] = start_seq;
  6914. BA_starting_seqctrl = start_seq << 4;
  6915. }
  6916. BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
  6917. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
  6918. break;
  6919. case 1: //ADDBA rsp
  6920. pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
  6921. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
  6922. /*
  6923. //BA_para_set = cpu_to_le16((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6924. #if defined(CONFIG_RTL8188E )&& defined (CONFIG_SDIO_HCI)
  6925. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); //32buffer size
  6926. #else
  6927. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6928. #endif
  6929. */
  6930. rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
  6931. if(MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
  6932. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6933. else if(MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
  6934. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); //32 buffer size
  6935. else if(MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
  6936. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); //16 buffer size
  6937. else if(MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
  6938. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); //8 buffer size
  6939. else
  6940. BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
  6941. #ifdef CONFIG_BT_COEXIST
  6942. if ((BT_1Ant(padapter) == _TRUE) &&
  6943. ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
  6944. (_rtw_memcmp(raddr, tendaAPMac, 3) == _FALSE)))
  6945. {
  6946. // max buffer size is 8 MSDU
  6947. BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6948. BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
  6949. }
  6950. #endif
  6951. if(pregpriv->ampdu_amsdu==0)//disabled
  6952. BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
  6953. else if(pregpriv->ampdu_amsdu==1)//enabled
  6954. BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
  6955. else //auto
  6956. BA_para_set = cpu_to_le16(BA_para_set);
  6957. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6958. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
  6959. break;
  6960. case 2://DELBA
  6961. BA_para_set = (status & 0x1F) << 3;
  6962. BA_para_set = cpu_to_le16(BA_para_set);
  6963. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
  6964. reason_code = 37;//Requested from peer STA as it does not want to use the mechanism
  6965. reason_code = cpu_to_le16(reason_code);
  6966. pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen));
  6967. break;
  6968. default:
  6969. break;
  6970. }
  6971. }
  6972. pattrib->last_txcmdsz = pattrib->pktlen;
  6973. dump_mgntframe(padapter, pmgntframe);
  6974. #endif //CONFIG_80211N_HT
  6975. }
  6976. static void issue_action_BSSCoexistPacket(_adapter *padapter)
  6977. {
  6978. _irqL irqL;
  6979. _list *plist, *phead;
  6980. unsigned char category, action;
  6981. struct xmit_frame *pmgntframe;
  6982. struct pkt_attrib *pattrib;
  6983. unsigned char *pframe;
  6984. struct rtw_ieee80211_hdr *pwlanhdr;
  6985. unsigned short *fctrl;
  6986. struct wlan_network *pnetwork = NULL;
  6987. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  6988. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  6989. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  6990. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  6991. _queue *queue = &(pmlmepriv->scanned_queue);
  6992. u8 InfoContent[16] = {0};
  6993. u8 ICS[8][15];
  6994. #ifdef CONFIG_80211N_HT
  6995. if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
  6996. return;
  6997. if(_TRUE == pmlmeinfo->bwmode_updated)
  6998. return;
  6999. DBG_871X("%s\n", __FUNCTION__);
  7000. category = RTW_WLAN_CATEGORY_PUBLIC;
  7001. action = ACT_PUBLIC_BSSCOEXIST;
  7002. if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
  7003. {
  7004. return;
  7005. }
  7006. //update attribute
  7007. pattrib = &pmgntframe->attrib;
  7008. update_mgntframe_attrib(padapter, pattrib);
  7009. _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
  7010. pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
  7011. pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
  7012. fctrl = &(pwlanhdr->frame_ctl);
  7013. *(fctrl) = 0;
  7014. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  7015. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
  7016. _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
  7017. SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
  7018. pmlmeext->mgnt_seq++;
  7019. SetFrameSubType(pframe, WIFI_ACTION);
  7020. pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
  7021. pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
  7022. pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
  7023. pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
  7024. //
  7025. if(pmlmepriv->num_FortyMHzIntolerant>0)
  7026. {
  7027. u8 iedata=0;
  7028. iedata |= BIT(2);//20 MHz BSS Width Request
  7029. pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
  7030. }
  7031. //
  7032. _rtw_memset(ICS, 0, sizeof(ICS));
  7033. if(pmlmepriv->num_sta_no_ht>0)
  7034. {
  7035. int i;
  7036. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  7037. phead = get_list_head(queue);
  7038. plist = get_next(phead);
  7039. while(1)
  7040. {
  7041. int len;
  7042. u8 *p;
  7043. WLAN_BSSID_EX *pbss_network;
  7044. if (rtw_end_of_queue_search(phead,plist)== _TRUE)
  7045. break;
  7046. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  7047. plist = get_next(plist);
  7048. pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
  7049. p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
  7050. if((p==NULL) || (len==0))//non-HT
  7051. {
  7052. if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
  7053. continue;
  7054. ICS[0][pbss_network->Configuration.DSConfig]=1;
  7055. if(ICS[0][0] == 0)
  7056. ICS[0][0] = 1;
  7057. }
  7058. }
  7059. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  7060. for(i= 0;i<8;i++)
  7061. {
  7062. if(ICS[i][0] == 1)
  7063. {
  7064. int j, k = 0;
  7065. InfoContent[k] = i;
  7066. //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
  7067. k++;
  7068. for(j=1;j<=14;j++)
  7069. {
  7070. if(ICS[i][j]==1)
  7071. {
  7072. if(k<16)
  7073. {
  7074. InfoContent[k] = j; //channel number
  7075. //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
  7076. k++;
  7077. }
  7078. }
  7079. }
  7080. pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
  7081. }
  7082. }
  7083. }
  7084. pattrib->last_txcmdsz = pattrib->pktlen;
  7085. dump_mgntframe(padapter, pmgntframe);
  7086. #endif //CONFIG_80211N_HT
  7087. }
  7088. unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
  7089. {
  7090. struct sta_priv *pstapriv = &padapter->stapriv;
  7091. struct sta_info *psta = NULL;
  7092. //struct recv_reorder_ctrl *preorder_ctrl;
  7093. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7094. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7095. u16 tid;
  7096. if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
  7097. if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
  7098. return _SUCCESS;
  7099. psta = rtw_get_stainfo(pstapriv, addr);
  7100. if(psta==NULL)
  7101. return _SUCCESS;
  7102. //DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR");
  7103. if(initiator==0) // recipient
  7104. {
  7105. for(tid = 0;tid<MAXTID;tid++)
  7106. {
  7107. if(psta->recvreorder_ctrl[tid].enable == _TRUE)
  7108. {
  7109. DBG_871X("rx agg disable tid(%d)\n",tid);
  7110. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
  7111. psta->recvreorder_ctrl[tid].enable = _FALSE;
  7112. psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
  7113. #ifdef DBG_RX_SEQ
  7114. DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
  7115. psta->recvreorder_ctrl[tid].indicate_seq);
  7116. #endif
  7117. }
  7118. }
  7119. }
  7120. else if(initiator == 1)// originator
  7121. {
  7122. #ifdef CONFIG_80211N_HT
  7123. //DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
  7124. for(tid = 0;tid<MAXTID;tid++)
  7125. {
  7126. if(psta->htpriv.agg_enable_bitmap & BIT(tid))
  7127. {
  7128. DBG_871X("tx agg disable tid(%d)\n",tid);
  7129. issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) );
  7130. psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
  7131. psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
  7132. }
  7133. }
  7134. #endif //CONFIG_80211N_HT
  7135. }
  7136. return _SUCCESS;
  7137. }
  7138. unsigned int send_beacon(_adapter *padapter)
  7139. {
  7140. u8 bxmitok = _FALSE;
  7141. int issue=0;
  7142. int poll = 0;
  7143. //#ifdef CONFIG_CONCURRENT_MODE
  7144. //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  7145. //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7146. //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  7147. //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  7148. //#endif
  7149. #ifdef CONFIG_PCI_HCI
  7150. //DBG_871X("%s\n", __FUNCTION__);
  7151. issue_beacon(padapter, 0);
  7152. return _SUCCESS;
  7153. #endif
  7154. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  7155. u32 start = rtw_get_current_time();
  7156. rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
  7157. rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
  7158. do{
  7159. issue_beacon(padapter, 100);
  7160. issue++;
  7161. do {
  7162. rtw_yield_os();
  7163. rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
  7164. poll++;
  7165. }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
  7166. }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
  7167. if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
  7168. {
  7169. return _FAIL;
  7170. }
  7171. if(_FALSE == bxmitok)
  7172. {
  7173. DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
  7174. return _FAIL;
  7175. }
  7176. else
  7177. {
  7178. u32 passing_time = rtw_get_passing_time_ms(start);
  7179. if(passing_time > 100 || issue > 3)
  7180. DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
  7181. //else
  7182. // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
  7183. return _SUCCESS;
  7184. }
  7185. #endif
  7186. }
  7187. /****************************************************************************
  7188. Following are some utitity fuctions for WiFi MLME
  7189. *****************************************************************************/
  7190. BOOLEAN IsLegal5GChannel(
  7191. IN PADAPTER Adapter,
  7192. IN u8 channel)
  7193. {
  7194. int i=0;
  7195. u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
  7196. 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
  7197. 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
  7198. 161,163,165};
  7199. for(i=0;i<sizeof(Channel_5G);i++)
  7200. if(channel == Channel_5G[i])
  7201. return _TRUE;
  7202. return _FALSE;
  7203. }
  7204. void site_survey(_adapter *padapter)
  7205. {
  7206. unsigned char survey_channel = 0, val8;
  7207. RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
  7208. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7209. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7210. u32 initialgain = 0;
  7211. #ifdef CONFIG_P2P
  7212. #ifdef CONFIG_CONCURRENT_MODE
  7213. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7214. u8 stay_buddy_ch = 0;
  7215. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7216. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  7217. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  7218. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  7219. #endif //CONFIG_CONCURRENT_MODE
  7220. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  7221. static unsigned char prev_survey_channel = 0;
  7222. static unsigned int p2p_scan_count = 0;
  7223. if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
  7224. {
  7225. if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
  7226. {
  7227. survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
  7228. }
  7229. else
  7230. {
  7231. survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
  7232. }
  7233. ScanType = SCAN_ACTIVE;
  7234. }
  7235. else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
  7236. {
  7237. // Commented by Albert 2011/06/03
  7238. // The driver is in the find phase, it should go through the social channel.
  7239. int ch_set_idx;
  7240. survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
  7241. ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
  7242. if (ch_set_idx >= 0)
  7243. ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
  7244. else
  7245. ScanType = SCAN_ACTIVE;
  7246. }
  7247. else
  7248. #endif //CONFIG_P2P
  7249. {
  7250. struct rtw_ieee80211_channel *ch;
  7251. if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
  7252. ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
  7253. survey_channel = ch->hw_value;
  7254. ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
  7255. }
  7256. }
  7257. if (0){
  7258. DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
  7259. , FUNC_ADPT_ARG(padapter)
  7260. , survey_channel
  7261. , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
  7262. , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
  7263. , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
  7264. , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
  7265. );
  7266. #ifdef DBG_FIXED_CHAN
  7267. DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
  7268. #endif
  7269. }
  7270. if(survey_channel != 0)
  7271. {
  7272. //PAUSE 4-AC Queue when site_survey
  7273. //rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7274. //val8 |= 0x0f;
  7275. //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7276. #ifdef CONFIG_CONCURRENT_MODE
  7277. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7278. if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
  7279. {
  7280. if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH )
  7281. {
  7282. pmlmeinfo->scan_cnt = 0;
  7283. survey_channel = pbuddy_mlmeext->cur_channel;
  7284. ScanType = SCAN_ACTIVE;
  7285. stay_buddy_ch = 1;
  7286. }
  7287. else
  7288. {
  7289. if( pmlmeinfo->scan_cnt == 0 )
  7290. stay_buddy_ch = 2;
  7291. pmlmeinfo->scan_cnt++;
  7292. }
  7293. }
  7294. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7295. #endif //CONFIG_CONCURRENT_MODE
  7296. if(pmlmeext->sitesurvey_res.channel_idx == 0)
  7297. {
  7298. #ifdef DBG_FIXED_CHAN
  7299. if(pmlmeext->fixed_chan !=0xff)
  7300. set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7301. else
  7302. #endif
  7303. set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7304. }
  7305. else
  7306. {
  7307. #ifdef DBG_FIXED_CHAN
  7308. if(pmlmeext->fixed_chan!=0xff)
  7309. SelectChannel(padapter, pmlmeext->fixed_chan);
  7310. else
  7311. #endif
  7312. SelectChannel(padapter, survey_channel);
  7313. }
  7314. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7315. if( stay_buddy_ch == 1 )
  7316. {
  7317. val8 = 0; //survey done
  7318. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7319. if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
  7320. check_buddy_fwstate(padapter, _FW_LINKED))
  7321. {
  7322. update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
  7323. }
  7324. }
  7325. else if( stay_buddy_ch == 2 )
  7326. {
  7327. val8 = 1; //under site survey
  7328. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7329. }
  7330. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7331. if(ScanType == SCAN_ACTIVE) //obey the channel plan setting...
  7332. {
  7333. #ifdef CONFIG_P2P
  7334. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
  7335. rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
  7336. )
  7337. {
  7338. issue_probereq_p2p(padapter, NULL);
  7339. issue_probereq_p2p(padapter, NULL);
  7340. issue_probereq_p2p(padapter, NULL);
  7341. }
  7342. else
  7343. #endif //CONFIG_P2P
  7344. {
  7345. int i;
  7346. for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
  7347. if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
  7348. //todo: to issue two probe req???
  7349. issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
  7350. //rtw_msleep_os(SURVEY_TO>>1);
  7351. issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
  7352. }
  7353. }
  7354. if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
  7355. //todo: to issue two probe req???
  7356. issue_probereq(padapter, NULL, NULL);
  7357. //rtw_msleep_os(SURVEY_TO>>1);
  7358. issue_probereq(padapter, NULL, NULL);
  7359. }
  7360. }
  7361. }
  7362. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7363. if( stay_buddy_ch == 1 )
  7364. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND );
  7365. else
  7366. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7367. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
  7368. }
  7369. else
  7370. {
  7371. // channel number is 0 or this channel is not valid.
  7372. #ifdef CONFIG_CONCURRENT_MODE
  7373. u8 cur_channel;
  7374. u8 cur_bwmode;
  7375. u8 cur_ch_offset;
  7376. if(check_fwstate(pmlmepriv, _FW_LINKED))
  7377. {
  7378. cur_channel = pmlmeext->cur_channel;
  7379. cur_bwmode = pmlmeext->cur_bwmode;
  7380. cur_ch_offset = pmlmeext->cur_ch_offset;
  7381. }
  7382. //else if((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  7383. else if(check_buddy_fwstate(padapter, _FW_LINKED)) // for AP or STA
  7384. {
  7385. cur_channel = pbuddy_mlmeext->cur_channel;
  7386. cur_bwmode = pbuddy_mlmeext->cur_bwmode;
  7387. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  7388. }
  7389. else
  7390. {
  7391. cur_channel = pmlmeext->cur_channel;
  7392. cur_bwmode = pmlmeext->cur_bwmode;
  7393. cur_ch_offset = pmlmeext->cur_ch_offset;
  7394. }
  7395. #endif
  7396. #ifdef CONFIG_P2P
  7397. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
  7398. {
  7399. if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
  7400. {
  7401. // Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT.
  7402. // This will let the following flow to run the scanning end.
  7403. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
  7404. }
  7405. #ifdef CONFIG_DBG_P2P
  7406. DBG_871X( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
  7407. #endif
  7408. }
  7409. if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
  7410. {
  7411. // Set the P2P State to the listen state of find phase and set the current channel to the listen channel
  7412. set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7413. rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
  7414. pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
  7415. initialgain = 0xff; //restore RX GAIN
  7416. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  7417. //turn on dynamic functions
  7418. Restore_DM_Func_Flag(padapter);
  7419. //Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
  7420. _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
  7421. }
  7422. else
  7423. #endif //CONFIG_P2P
  7424. {
  7425. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  7426. pmlmeinfo->scan_cnt = 0;
  7427. #endif //CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE
  7428. #ifdef CONFIG_ANTENNA_DIVERSITY
  7429. // 20100721:Interrupt scan operation here.
  7430. // For SW antenna diversity before link, it needs to switch to another antenna and scan again.
  7431. // It compares the scan result and select beter one to do connection.
  7432. if(rtw_hal_antdiv_before_linked(padapter))
  7433. {
  7434. pmlmeext->sitesurvey_res.bss_cnt = 0;
  7435. pmlmeext->sitesurvey_res.channel_idx = -1;
  7436. pmlmeext->chan_scan_time = SURVEY_TO /2;
  7437. set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
  7438. return;
  7439. }
  7440. #endif
  7441. #ifdef CONFIG_P2P
  7442. if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
  7443. {
  7444. #ifdef CONFIG_CONCURRENT_MODE
  7445. if( pwdinfo->driver_interface == DRIVER_WEXT )
  7446. {
  7447. if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
  7448. {
  7449. _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
  7450. }
  7451. }
  7452. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  7453. #else
  7454. rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
  7455. #endif
  7456. }
  7457. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
  7458. #endif //CONFIG_P2P
  7459. pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
  7460. //switch back to the original channel
  7461. //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
  7462. {
  7463. #ifdef CONFIG_CONCURRENT_MODE
  7464. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  7465. #else
  7466. #ifdef CONFIG_DUALMAC_CONCURRENT
  7467. dc_set_channel_bwmode_survey_done(padapter);
  7468. #else
  7469. if( pwdinfo->driver_interface == DRIVER_WEXT )
  7470. {
  7471. if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
  7472. {
  7473. set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7474. }
  7475. else
  7476. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7477. }
  7478. else if( pwdinfo->driver_interface == DRIVER_CFG80211 )
  7479. {
  7480. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7481. }
  7482. #endif //CONFIG_DUALMAC_CONCURRENT
  7483. #endif //CONFIG_CONCURRENT_MODE
  7484. }
  7485. //flush 4-AC Queue after site_survey
  7486. //val8 = 0;
  7487. //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
  7488. //config MSR
  7489. Set_MSR(padapter, (pmlmeinfo->state & 0x3));
  7490. initialgain = 0xff; //restore RX GAIN
  7491. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  7492. //turn on dynamic functions
  7493. Restore_DM_Func_Flag(padapter);
  7494. //Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
  7495. if (is_client_associated_to_ap(padapter) == _TRUE)
  7496. {
  7497. issue_nulldata(padapter, NULL, 0, 3, 500);
  7498. #ifdef CONFIG_CONCURRENT_MODE
  7499. if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  7500. {
  7501. DBG_871X("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
  7502. issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
  7503. }
  7504. #endif
  7505. }
  7506. #ifdef CONFIG_CONCURRENT_MODE
  7507. else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  7508. {
  7509. issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
  7510. }
  7511. #endif
  7512. val8 = 0; //survey done
  7513. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  7514. report_surveydone_event(padapter);
  7515. pmlmeext->chan_scan_time = SURVEY_TO;
  7516. pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
  7517. issue_action_BSSCoexistPacket(padapter);
  7518. issue_action_BSSCoexistPacket(padapter);
  7519. issue_action_BSSCoexistPacket(padapter);
  7520. }
  7521. #ifdef CONFIG_CONCURRENT_MODE
  7522. if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
  7523. check_buddy_fwstate(padapter, _FW_LINKED))
  7524. {
  7525. DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  7526. DBG_871X("restart pbuddy_adapter's beacon\n");
  7527. update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
  7528. }
  7529. #endif
  7530. }
  7531. return;
  7532. }
  7533. //collect bss info from Beacon and Probe response frames.
  7534. u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
  7535. {
  7536. int i;
  7537. u32 len;
  7538. u8 *p;
  7539. u16 val16, subtype;
  7540. u8 *pframe = precv_frame->u.hdr.rx_data;
  7541. u32 packet_len = precv_frame->u.hdr.len;
  7542. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  7543. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7544. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7545. len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
  7546. if (len > MAX_IE_SZ)
  7547. {
  7548. //DBG_871X("IE too long for survey event\n");
  7549. return _FAIL;
  7550. }
  7551. _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
  7552. subtype = GetFrameSubType(pframe);
  7553. if(subtype==WIFI_BEACON)
  7554. bssid->Reserved[0] = 1;
  7555. else
  7556. bssid->Reserved[0] = 0;
  7557. bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
  7558. //below is to copy the information element
  7559. bssid->IELength = len;
  7560. _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
  7561. //get the signal strength
  7562. //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
  7563. bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
  7564. bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
  7565. bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
  7566. #ifdef CONFIG_ANTENNA_DIVERSITY
  7567. //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
  7568. rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
  7569. #endif
  7570. // checking SSID
  7571. if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL)
  7572. {
  7573. DBG_871X("marc: cannot find SSID for survey event\n");
  7574. return _FAIL;
  7575. }
  7576. if (*(p + 1))
  7577. {
  7578. if (len > NDIS_802_11_LENGTH_SSID)
  7579. {
  7580. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7581. return _FAIL;
  7582. }
  7583. _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
  7584. bssid->Ssid.SsidLength = *(p + 1);
  7585. }
  7586. else
  7587. {
  7588. bssid->Ssid.SsidLength = 0;
  7589. }
  7590. _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
  7591. //checking rate info...
  7592. i = 0;
  7593. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7594. if (p != NULL)
  7595. {
  7596. if (len > NDIS_802_11_LENGTH_RATES_EX)
  7597. {
  7598. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7599. return _FAIL;
  7600. }
  7601. _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
  7602. i = len;
  7603. }
  7604. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7605. if (p != NULL)
  7606. {
  7607. if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
  7608. {
  7609. DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
  7610. return _FAIL;
  7611. }
  7612. _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
  7613. }
  7614. //todo:
  7615. #if 0
  7616. if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
  7617. {
  7618. bssid->NetworkTypeInUse = Ndis802_11DS;
  7619. }
  7620. else
  7621. #endif
  7622. {
  7623. bssid->NetworkTypeInUse = Ndis802_11OFDM24;
  7624. }
  7625. if (bssid->IELength < 12)
  7626. return _FAIL;
  7627. // Checking for DSConfig
  7628. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7629. bssid->Configuration.DSConfig = 0;
  7630. bssid->Configuration.Length = 0;
  7631. if (p)
  7632. {
  7633. bssid->Configuration.DSConfig = *(p + 2);
  7634. }
  7635. else
  7636. {// In 5G, some ap do not have DSSET IE
  7637. // checking HT info for channel
  7638. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7639. if(p)
  7640. {
  7641. struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
  7642. bssid->Configuration.DSConfig = HT_info->primary_channel;
  7643. }
  7644. else
  7645. { // use current channel
  7646. bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
  7647. }
  7648. }
  7649. _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
  7650. bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
  7651. val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
  7652. if (val16 & BIT(0))
  7653. {
  7654. bssid->InfrastructureMode = Ndis802_11Infrastructure;
  7655. _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
  7656. }
  7657. else
  7658. {
  7659. bssid->InfrastructureMode = Ndis802_11IBSS;
  7660. _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
  7661. }
  7662. if (val16 & BIT(4))
  7663. bssid->Privacy = 1;
  7664. else
  7665. bssid->Privacy = 0;
  7666. bssid->Configuration.ATIMWindow = 0;
  7667. //20/40 BSS Coexistence check
  7668. if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
  7669. {
  7670. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  7671. #ifdef CONFIG_80211N_HT
  7672. p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7673. if(p && len>0)
  7674. {
  7675. struct HT_caps_element *pHT_caps;
  7676. pHT_caps = (struct HT_caps_element *)(p + 2);
  7677. if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
  7678. {
  7679. pmlmepriv->num_FortyMHzIntolerant++;
  7680. }
  7681. }
  7682. else
  7683. {
  7684. pmlmepriv->num_sta_no_ht++;
  7685. }
  7686. #endif //CONFIG_80211N_HT
  7687. }
  7688. #ifdef CONFIG_INTEL_WIDI
  7689. //process_intel_widi_query_or_tigger(padapter, bssid);
  7690. if(process_intel_widi_query_or_tigger(padapter, bssid))
  7691. {
  7692. return _FAIL;
  7693. }
  7694. #endif // CONFIG_INTEL_WIDI
  7695. #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) & 1
  7696. if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
  7697. DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
  7698. , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
  7699. , rtw_get_oper_ch(padapter)
  7700. , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
  7701. );
  7702. }
  7703. #endif
  7704. // mark bss info receving from nearby channel as SignalQuality 101
  7705. if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
  7706. {
  7707. bssid->PhyInfo.SignalQuality= 101;
  7708. }
  7709. return _SUCCESS;
  7710. }
  7711. void start_create_ibss(_adapter* padapter)
  7712. {
  7713. unsigned short caps;
  7714. u8 val8;
  7715. u8 join_type;
  7716. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7717. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7718. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  7719. pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
  7720. pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
  7721. //update wireless mode
  7722. update_wireless_mode(padapter);
  7723. //udpate capability
  7724. caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
  7725. update_capinfo(padapter, caps);
  7726. if(caps&cap_IBSS)//adhoc master
  7727. {
  7728. //set_opmode_cmd(padapter, adhoc);//removed
  7729. val8 = 0xcf;
  7730. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7731. //switch channel
  7732. //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
  7733. set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  7734. beacon_timing_control(padapter);
  7735. //set msr to WIFI_FW_ADHOC_STATE
  7736. pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
  7737. Set_MSR(padapter, (pmlmeinfo->state & 0x3));
  7738. //issue beacon
  7739. if(send_beacon(padapter)==_FAIL)
  7740. {
  7741. RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
  7742. report_join_res(padapter, -1);
  7743. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7744. }
  7745. else
  7746. {
  7747. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
  7748. join_type = 0;
  7749. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  7750. report_join_res(padapter, 1);
  7751. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  7752. }
  7753. }
  7754. else
  7755. {
  7756. DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
  7757. return;
  7758. }
  7759. }
  7760. void start_clnt_join(_adapter* padapter)
  7761. {
  7762. unsigned short caps;
  7763. u8 val8;
  7764. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7765. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7766. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  7767. int beacon_timeout;
  7768. pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
  7769. pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
  7770. #ifdef CONFIG_DUALMAC_CONCURRENT
  7771. if(dc_handle_join_request(padapter) == _FAIL)
  7772. {
  7773. DBG_871X("dc_handle_join_request fail !!!\n");
  7774. return;
  7775. }
  7776. //switch channel
  7777. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7778. #elif defined (CONFIG_CONCURRENT_MODE)
  7779. if(concurrent_chk_start_clnt_join(padapter) == _FAIL)
  7780. return;
  7781. #else //NON CONCURRENT_MODE
  7782. //switch channel
  7783. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7784. #endif
  7785. //update wireless mode
  7786. update_wireless_mode(padapter);
  7787. //udpate capability
  7788. caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
  7789. update_capinfo(padapter, caps);
  7790. if (caps&cap_ESS)
  7791. {
  7792. Set_MSR(padapter, WIFI_FW_STATION_STATE);
  7793. val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
  7794. #ifdef CONFIG_WAPI_SUPPORT
  7795. if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
  7796. {
  7797. //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
  7798. val8 = 0x4c;
  7799. }
  7800. #endif
  7801. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7802. //switch channel
  7803. //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7804. //here wait for receiving the beacon to start auth
  7805. //and enable a timer
  7806. beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
  7807. set_link_timer(pmlmeext, beacon_timeout);
  7808. _set_timer( &padapter->mlmepriv.assoc_timer,
  7809. (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
  7810. pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
  7811. }
  7812. else if (caps&cap_IBSS) //adhoc client
  7813. {
  7814. Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
  7815. val8 = 0xcf;
  7816. rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
  7817. //switch channel
  7818. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  7819. beacon_timing_control(padapter);
  7820. pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
  7821. report_join_res(padapter, 1);
  7822. }
  7823. else
  7824. {
  7825. //DBG_871X("marc: invalid cap:%x\n", caps);
  7826. return;
  7827. }
  7828. }
  7829. void start_clnt_auth(_adapter* padapter)
  7830. {
  7831. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7832. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7833. _cancel_timer_ex(&pmlmeext->link_timer);
  7834. pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
  7835. pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
  7836. pmlmeinfo->auth_seq = 1;
  7837. pmlmeinfo->reauth_count = 0;
  7838. pmlmeinfo->reassoc_count = 0;
  7839. pmlmeinfo->link_count = 0;
  7840. pmlmeext->retry = 0;
  7841. // Because of AP's not receiving deauth before
  7842. // AP may: 1)not response auth or 2)deauth us after link is complete
  7843. // issue deauth before issuing auth to deal with the situation
  7844. #ifndef CONFIG_PLATFORM_RTK_DMP
  7845. // Commented by Albert 2012/07/21
  7846. // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
  7847. issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
  7848. #endif
  7849. DBG_871X_LEVEL(_drv_always_, "start auth\n");
  7850. issue_auth(padapter, NULL, 0);
  7851. set_link_timer(pmlmeext, REAUTH_TO);
  7852. }
  7853. void start_clnt_assoc(_adapter* padapter)
  7854. {
  7855. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7856. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7857. _cancel_timer_ex(&pmlmeext->link_timer);
  7858. pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
  7859. pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
  7860. issue_assocreq(padapter);
  7861. set_link_timer(pmlmeext, REASSOC_TO);
  7862. }
  7863. unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
  7864. {
  7865. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  7866. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  7867. //check A3
  7868. if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
  7869. return _SUCCESS;
  7870. DBG_871X("%s\n", __FUNCTION__);
  7871. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  7872. {
  7873. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  7874. {
  7875. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7876. report_del_sta_event(padapter, MacAddr, reason);
  7877. }
  7878. else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
  7879. {
  7880. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  7881. report_join_res(padapter, -2);
  7882. }
  7883. }
  7884. return _SUCCESS;
  7885. }
  7886. #ifdef CONFIG_80211D
  7887. static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
  7888. {
  7889. struct registry_priv *pregistrypriv;
  7890. struct mlme_ext_priv *pmlmeext;
  7891. RT_CHANNEL_INFO *chplan_new;
  7892. u8 channel;
  7893. u8 i;
  7894. pregistrypriv = &padapter->registrypriv;
  7895. pmlmeext = &padapter->mlmeextpriv;
  7896. // Adjust channel plan by AP Country IE
  7897. if (pregistrypriv->enable80211d &&
  7898. (!pmlmeext->update_channel_plan_by_ap_done))
  7899. {
  7900. u8 *ie, *p;
  7901. u32 len;
  7902. RT_CHANNEL_PLAN chplan_ap;
  7903. RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
  7904. u8 country[4];
  7905. u8 fcn; // first channel number
  7906. u8 noc; // number of channel
  7907. u8 j, k;
  7908. ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
  7909. if (!ie) return;
  7910. if (len < 6) return;
  7911. ie += 2;
  7912. p = ie;
  7913. ie += len;
  7914. _rtw_memset(country, 0, 4);
  7915. _rtw_memcpy(country, p, 3);
  7916. p += 3;
  7917. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  7918. ("%s: 802.11d country=%s\n", __FUNCTION__, country));
  7919. i = 0;
  7920. while ((ie - p) >= 3)
  7921. {
  7922. fcn = *(p++);
  7923. noc = *(p++);
  7924. p++;
  7925. for (j = 0; j < noc; j++)
  7926. {
  7927. if (fcn <= 14) channel = fcn + j; // 2.4 GHz
  7928. else channel = fcn + j*4; // 5 GHz
  7929. chplan_ap.Channel[i++] = channel;
  7930. }
  7931. }
  7932. chplan_ap.Len = i;
  7933. #ifdef CONFIG_DEBUG_RTL871X
  7934. i = 0;
  7935. DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
  7936. while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
  7937. {
  7938. DBG_8192C("%02d,", chplan_ap.Channel[i]);
  7939. i++;
  7940. }
  7941. DBG_871X("}\n");
  7942. #endif
  7943. _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
  7944. #ifdef CONFIG_DEBUG_RTL871X
  7945. i = 0;
  7946. DBG_871X("%s: STA channel plan {", __FUNCTION__);
  7947. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  7948. {
  7949. DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
  7950. i++;
  7951. }
  7952. DBG_871X("}\n");
  7953. #endif
  7954. _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
  7955. chplan_new = pmlmeext->channel_set;
  7956. i = j = k = 0;
  7957. if (pregistrypriv->wireless_mode & WIRELESS_11G)
  7958. {
  7959. do {
  7960. if ((i == MAX_CHANNEL_NUM) ||
  7961. (chplan_sta[i].ChannelNum == 0) ||
  7962. (chplan_sta[i].ChannelNum > 14))
  7963. break;
  7964. if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
  7965. break;
  7966. if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
  7967. {
  7968. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  7969. chplan_new[k].ScanType = SCAN_ACTIVE;
  7970. i++;
  7971. j++;
  7972. k++;
  7973. }
  7974. else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
  7975. {
  7976. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  7977. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  7978. chplan_new[k].ScanType = SCAN_PASSIVE;
  7979. i++;
  7980. k++;
  7981. }
  7982. else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
  7983. {
  7984. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  7985. chplan_new[k].ScanType = SCAN_ACTIVE;
  7986. j++;
  7987. k++;
  7988. }
  7989. } while (1);
  7990. // change AP not support channel to Passive scan
  7991. while ((i < MAX_CHANNEL_NUM) &&
  7992. (chplan_sta[i].ChannelNum != 0) &&
  7993. (chplan_sta[i].ChannelNum <= 14))
  7994. {
  7995. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  7996. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  7997. chplan_new[k].ScanType = SCAN_PASSIVE;
  7998. i++;
  7999. k++;
  8000. }
  8001. // add channel AP supported
  8002. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
  8003. {
  8004. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8005. chplan_new[k].ScanType = SCAN_ACTIVE;
  8006. j++;
  8007. k++;
  8008. }
  8009. }
  8010. else
  8011. {
  8012. // keep original STA 2.4G channel plan
  8013. while ((i < MAX_CHANNEL_NUM) &&
  8014. (chplan_sta[i].ChannelNum != 0) &&
  8015. (chplan_sta[i].ChannelNum <= 14))
  8016. {
  8017. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8018. chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8019. i++;
  8020. k++;
  8021. }
  8022. // skip AP 2.4G channel plan
  8023. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
  8024. {
  8025. j++;
  8026. }
  8027. }
  8028. if (pregistrypriv->wireless_mode & WIRELESS_11A)
  8029. {
  8030. do {
  8031. if ((i == MAX_CHANNEL_NUM) ||
  8032. (chplan_sta[i].ChannelNum == 0))
  8033. break;
  8034. if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
  8035. break;
  8036. if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
  8037. {
  8038. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8039. chplan_new[k].ScanType = SCAN_ACTIVE;
  8040. i++;
  8041. j++;
  8042. k++;
  8043. }
  8044. else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
  8045. {
  8046. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8047. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8048. chplan_new[k].ScanType = SCAN_PASSIVE;
  8049. i++;
  8050. k++;
  8051. }
  8052. else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
  8053. {
  8054. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8055. chplan_new[k].ScanType = SCAN_ACTIVE;
  8056. j++;
  8057. k++;
  8058. }
  8059. } while (1);
  8060. // change AP not support channel to Passive scan
  8061. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  8062. {
  8063. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8064. // chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8065. chplan_new[k].ScanType = SCAN_PASSIVE;
  8066. i++;
  8067. k++;
  8068. }
  8069. // add channel AP supported
  8070. while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
  8071. {
  8072. chplan_new[k].ChannelNum = chplan_ap.Channel[j];
  8073. chplan_new[k].ScanType = SCAN_ACTIVE;
  8074. j++;
  8075. k++;
  8076. }
  8077. }
  8078. else
  8079. {
  8080. // keep original STA 5G channel plan
  8081. while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
  8082. {
  8083. chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
  8084. chplan_new[k].ScanType = chplan_sta[i].ScanType;
  8085. i++;
  8086. k++;
  8087. }
  8088. }
  8089. pmlmeext->update_channel_plan_by_ap_done = 1;
  8090. #ifdef CONFIG_DEBUG_RTL871X
  8091. k = 0;
  8092. DBG_871X("%s: new STA channel plan {", __FUNCTION__);
  8093. while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
  8094. {
  8095. DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
  8096. k++;
  8097. }
  8098. DBG_871X("}\n");
  8099. #endif
  8100. #if 0
  8101. // recover the right channel index
  8102. channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
  8103. k = 0;
  8104. while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
  8105. {
  8106. if (chplan_new[k].ChannelNum == channel) {
  8107. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  8108. ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
  8109. __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
  8110. pmlmeext->sitesurvey_res.channel_idx = k;
  8111. break;
  8112. }
  8113. k++;
  8114. }
  8115. #endif
  8116. }
  8117. // If channel is used by AP, set channel scan type to active
  8118. channel = bssid->Configuration.DSConfig;
  8119. chplan_new = pmlmeext->channel_set;
  8120. i = 0;
  8121. while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
  8122. {
  8123. if (chplan_new[i].ChannelNum == channel)
  8124. {
  8125. if (chplan_new[i].ScanType == SCAN_PASSIVE)
  8126. {
  8127. //5G Bnad 2, 3 (DFS) doesn't change to active scan
  8128. if(channel >= 52 && channel <= 144)
  8129. break;
  8130. chplan_new[i].ScanType = SCAN_ACTIVE;
  8131. RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
  8132. ("%s: change channel %d scan type from passive to active\n",
  8133. __FUNCTION__, channel));
  8134. }
  8135. break;
  8136. }
  8137. i++;
  8138. }
  8139. }
  8140. #endif
  8141. /****************************************************************************
  8142. Following are the functions to report events
  8143. *****************************************************************************/
  8144. void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  8145. {
  8146. struct cmd_obj *pcmd_obj;
  8147. u8 *pevtcmd;
  8148. u32 cmdsz;
  8149. struct survey_event *psurvey_evt;
  8150. struct C2HEvent_Header *pc2h_evt_hdr;
  8151. struct mlme_ext_priv *pmlmeext;
  8152. struct cmd_priv *pcmdpriv;
  8153. //u8 *pframe = precv_frame->u.hdr.rx_data;
  8154. //uint len = precv_frame->u.hdr.len;
  8155. if(!padapter)
  8156. return;
  8157. pmlmeext = &padapter->mlmeextpriv;
  8158. pcmdpriv = &padapter->cmdpriv;
  8159. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8160. {
  8161. return;
  8162. }
  8163. cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
  8164. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8165. {
  8166. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8167. return;
  8168. }
  8169. _rtw_init_listhead(&pcmd_obj->list);
  8170. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8171. pcmd_obj->cmdsz = cmdsz;
  8172. pcmd_obj->parmbuf = pevtcmd;
  8173. pcmd_obj->rsp = NULL;
  8174. pcmd_obj->rspsz = 0;
  8175. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8176. pc2h_evt_hdr->len = sizeof(struct survey_event);
  8177. pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
  8178. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8179. psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8180. if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
  8181. {
  8182. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8183. rtw_mfree((u8 *)pevtcmd, cmdsz);
  8184. return;
  8185. }
  8186. #ifdef CONFIG_80211D
  8187. process_80211d(padapter, &psurvey_evt->bss);
  8188. #endif
  8189. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8190. pmlmeext->sitesurvey_res.bss_cnt++;
  8191. return;
  8192. }
  8193. void report_surveydone_event(_adapter *padapter)
  8194. {
  8195. struct cmd_obj *pcmd_obj;
  8196. u8 *pevtcmd;
  8197. u32 cmdsz;
  8198. struct surveydone_event *psurveydone_evt;
  8199. struct C2HEvent_Header *pc2h_evt_hdr;
  8200. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8201. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8202. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8203. {
  8204. return;
  8205. }
  8206. cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
  8207. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8208. {
  8209. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8210. return;
  8211. }
  8212. _rtw_init_listhead(&pcmd_obj->list);
  8213. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8214. pcmd_obj->cmdsz = cmdsz;
  8215. pcmd_obj->parmbuf = pevtcmd;
  8216. pcmd_obj->rsp = NULL;
  8217. pcmd_obj->rspsz = 0;
  8218. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8219. pc2h_evt_hdr->len = sizeof(struct surveydone_event);
  8220. pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
  8221. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8222. psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8223. psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
  8224. DBG_871X("survey done event(%x)\n", psurveydone_evt->bss_cnt);
  8225. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8226. return;
  8227. }
  8228. void report_join_res(_adapter *padapter, int res)
  8229. {
  8230. struct cmd_obj *pcmd_obj;
  8231. u8 *pevtcmd;
  8232. u32 cmdsz;
  8233. struct joinbss_event *pjoinbss_evt;
  8234. struct C2HEvent_Header *pc2h_evt_hdr;
  8235. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8236. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8237. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8238. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8239. {
  8240. return;
  8241. }
  8242. cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
  8243. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8244. {
  8245. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8246. return;
  8247. }
  8248. _rtw_init_listhead(&pcmd_obj->list);
  8249. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8250. pcmd_obj->cmdsz = cmdsz;
  8251. pcmd_obj->parmbuf = pevtcmd;
  8252. pcmd_obj->rsp = NULL;
  8253. pcmd_obj->rspsz = 0;
  8254. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8255. pc2h_evt_hdr->len = sizeof(struct joinbss_event);
  8256. pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
  8257. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8258. pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8259. _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
  8260. pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
  8261. DBG_871X("report_join_res(%d)\n", res);
  8262. rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
  8263. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8264. return;
  8265. }
  8266. void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
  8267. {
  8268. struct cmd_obj *pcmd_obj;
  8269. u8 *pevtcmd;
  8270. u32 cmdsz;
  8271. struct sta_info *psta;
  8272. int mac_id;
  8273. struct stadel_event *pdel_sta_evt;
  8274. struct C2HEvent_Header *pc2h_evt_hdr;
  8275. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8276. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8277. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8278. {
  8279. return;
  8280. }
  8281. cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
  8282. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8283. {
  8284. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8285. return;
  8286. }
  8287. _rtw_init_listhead(&pcmd_obj->list);
  8288. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8289. pcmd_obj->cmdsz = cmdsz;
  8290. pcmd_obj->parmbuf = pevtcmd;
  8291. pcmd_obj->rsp = NULL;
  8292. pcmd_obj->rspsz = 0;
  8293. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8294. pc2h_evt_hdr->len = sizeof(struct stadel_event);
  8295. pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
  8296. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8297. pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8298. _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
  8299. _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
  8300. psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
  8301. if(psta)
  8302. mac_id = (int)psta->mac_id;
  8303. else
  8304. mac_id = (-1);
  8305. pdel_sta_evt->mac_id = mac_id;
  8306. DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
  8307. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8308. return;
  8309. }
  8310. void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
  8311. {
  8312. struct cmd_obj *pcmd_obj;
  8313. u8 *pevtcmd;
  8314. u32 cmdsz;
  8315. struct stassoc_event *padd_sta_evt;
  8316. struct C2HEvent_Header *pc2h_evt_hdr;
  8317. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8318. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  8319. if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8320. {
  8321. return;
  8322. }
  8323. cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
  8324. if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
  8325. {
  8326. rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
  8327. return;
  8328. }
  8329. _rtw_init_listhead(&pcmd_obj->list);
  8330. pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
  8331. pcmd_obj->cmdsz = cmdsz;
  8332. pcmd_obj->parmbuf = pevtcmd;
  8333. pcmd_obj->rsp = NULL;
  8334. pcmd_obj->rspsz = 0;
  8335. pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
  8336. pc2h_evt_hdr->len = sizeof(struct stassoc_event);
  8337. pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
  8338. pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
  8339. padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
  8340. _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
  8341. padd_sta_evt->cam_id = cam_idx;
  8342. DBG_871X("report_add_sta_event: add STA\n");
  8343. rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
  8344. return;
  8345. }
  8346. /****************************************************************************
  8347. Following are the event callback functions
  8348. *****************************************************************************/
  8349. //for sta/adhoc mode
  8350. void update_sta_info(_adapter *padapter, struct sta_info *psta)
  8351. {
  8352. _irqL irqL;
  8353. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  8354. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8355. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8356. //ERP
  8357. VCS_update(padapter, psta);
  8358. #ifdef CONFIG_80211N_HT
  8359. //HT
  8360. if(pmlmepriv->htpriv.ht_option)
  8361. {
  8362. psta->htpriv.ht_option = _TRUE;
  8363. psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
  8364. if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
  8365. psta->htpriv.sgi = _TRUE;
  8366. psta->qos_option = _TRUE;
  8367. }
  8368. else
  8369. #endif //CONFIG_80211N_HT
  8370. {
  8371. #ifdef CONFIG_80211N_HT
  8372. psta->htpriv.ht_option = _FALSE;
  8373. psta->htpriv.ampdu_enable = _FALSE;
  8374. psta->htpriv.sgi = _FALSE;
  8375. #endif //CONFIG_80211N_HT
  8376. psta->qos_option = _FALSE;
  8377. }
  8378. #ifdef CONFIG_80211N_HT
  8379. psta->htpriv.bwmode = pmlmeext->cur_bwmode;
  8380. psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
  8381. psta->htpriv.agg_enable_bitmap = 0x0;//reset
  8382. psta->htpriv.candidate_tid_bitmap = 0x0;//reset
  8383. #endif //CONFIG_80211N_HT
  8384. //QoS
  8385. if(pmlmepriv->qospriv.qos_option)
  8386. psta->qos_option = _TRUE;
  8387. #ifdef CONFIG_80211AC_VHT
  8388. if (pmlmepriv->vhtpriv.bwmode < CHANNEL_WIDTH_80)
  8389. pmlmepriv->vhtpriv.sgi = psta->htpriv.sgi;
  8390. _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
  8391. #endif //CONFIG_80211AC_VHT
  8392. _enter_critical_bh(&psta->lock, &irqL);
  8393. psta->state = _FW_LINKED;
  8394. _exit_critical_bh(&psta->lock, &irqL);
  8395. }
  8396. void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
  8397. {
  8398. struct sta_info *psta, *psta_bmc;
  8399. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8400. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8401. WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
  8402. struct sta_priv *pstapriv = &padapter->stapriv;
  8403. u8 join_type;
  8404. u16 media_status;
  8405. if(join_res < 0)
  8406. {
  8407. join_type = 1;
  8408. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8409. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  8410. goto exit_mlmeext_joinbss_event_callback;
  8411. }
  8412. if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  8413. {
  8414. //for bc/mc
  8415. psta_bmc = rtw_get_bcmc_stainfo(padapter);
  8416. if(psta_bmc)
  8417. {
  8418. pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
  8419. update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
  8420. Update_RA_Entry(padapter, psta_bmc);
  8421. }
  8422. }
  8423. //turn on dynamic functions
  8424. Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
  8425. // update IOT-releated issue
  8426. update_IOT_info(padapter);
  8427. rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
  8428. //BCN interval
  8429. rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
  8430. //udpate capability
  8431. update_capinfo(padapter, pmlmeinfo->capability);
  8432. //WMM, Update EDCA param
  8433. WMMOnAssocRsp(padapter);
  8434. //HT
  8435. HTOnAssocRsp(padapter);
  8436. #ifdef CONFIG_80211AC_VHT
  8437. //VHT
  8438. VHTOnAssocRsp(padapter);
  8439. #endif
  8440. #ifndef CONFIG_CONCURRENT_MODE
  8441. // Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined.
  8442. //Set cur_channel&cur_bwmode&cur_ch_offset
  8443. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  8444. #endif
  8445. psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
  8446. if (psta) //only for infra. mode
  8447. {
  8448. pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
  8449. //DBG_871X("set_sta_rate\n");
  8450. psta->wireless_mode = pmlmeext->cur_wireless_mode;
  8451. //set per sta rate after updating HT cap.
  8452. set_sta_rate(padapter, psta);
  8453. #if (RATE_ADAPTIVE_SUPPORT==1) //for 88E RA
  8454. rtw_hal_set_hwreg(padapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&psta->mac_id);
  8455. #endif
  8456. media_status = (psta->mac_id<<8)|1; // MACID|OPMODE: 1 means connect
  8457. rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
  8458. }
  8459. join_type = 2;
  8460. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8461. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  8462. {
  8463. // correcting TSF
  8464. correct_TSF(padapter, pmlmeext);
  8465. //set_link_timer(pmlmeext, DISCONNECT_TO);
  8466. }
  8467. #ifdef CONFIG_LPS
  8468. #ifdef CONFIG_CONCURRENT_MODE
  8469. if(padapter->iface_type == IFACE_PORT0)
  8470. #endif
  8471. rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
  8472. #endif
  8473. exit_mlmeext_joinbss_event_callback:
  8474. #ifdef CONFIG_DUALMAC_CONCURRENT
  8475. dc_handle_join_done(padapter, join_res);
  8476. #endif
  8477. #ifdef CONFIG_CONCURRENT_MODE
  8478. concurrent_chk_joinbss_done(padapter, join_res);
  8479. #endif
  8480. DBG_871X("=>%s\n", __FUNCTION__);
  8481. }
  8482. //currently only adhoc mode will go here
  8483. void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
  8484. {
  8485. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  8486. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8487. u8 join_type;
  8488. DBG_871X("%s\n", __FUNCTION__);
  8489. if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
  8490. {
  8491. if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
  8492. {
  8493. //nothing to do
  8494. }
  8495. else//adhoc client
  8496. {
  8497. //update TSF Value
  8498. //update_TSF(pmlmeext, pframe, len);
  8499. // correcting TSF
  8500. correct_TSF(padapter, pmlmeext);
  8501. //start beacon
  8502. if(send_beacon(padapter)==_FAIL)
  8503. {
  8504. pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
  8505. pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
  8506. return;
  8507. }
  8508. pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
  8509. }
  8510. join_type = 2;
  8511. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  8512. }
  8513. pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
  8514. //rate radaptive
  8515. Update_RA_Entry(padapter, psta);
  8516. //update adhoc sta_info
  8517. update_sta_info(padapter, psta);
  8518. }
  8519. void mlmeext_sta_del_event_callback(_adapter *padapter)
  8520. {
  8521. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8522. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8523. if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
  8524. {
  8525. //set_opmode_cmd(padapter, infra_client_with_mlme);
  8526. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  8527. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  8528. #ifdef CONFIG_DUALMAC_CONCURRENT
  8529. dc_set_channel_bwmode_disconnect(padapter);
  8530. #else
  8531. #ifdef CONFIG_CONCURRENT_MODE
  8532. if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
  8533. {
  8534. #endif //CONFIG_CONCURRENT_MODE
  8535. //switch to the 20M Hz mode after disconnect
  8536. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  8537. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  8538. //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
  8539. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  8540. #ifdef CONFIG_CONCURRENT_MODE
  8541. }
  8542. #endif //CONFIG_CONCURRENT_MODE
  8543. #endif //CONFIG_DUALMAC_CONCURRENT
  8544. flush_all_cam_entry(padapter);
  8545. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8546. //set MSR to no link state -> infra. mode
  8547. Set_MSR(padapter, _HW_STATE_STATION_);
  8548. _cancel_timer_ex(&pmlmeext->link_timer);
  8549. }
  8550. }
  8551. /****************************************************************************
  8552. Following are the functions for the timer handlers
  8553. *****************************************************************************/
  8554. void _linked_info_dump(_adapter *padapter);
  8555. void _linked_info_dump(_adapter *padapter)
  8556. {
  8557. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8558. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8559. u8 mac_id;
  8560. int UndecoratedSmoothedPWDB;
  8561. #if 0
  8562. DBG_871X("============ linked status check ===================\n");
  8563. DBG_871X("pathA Rx SNRdb:%d, pathB Rx SNRdb:%d\n",padapter->recvpriv.RxSNRdB[0], padapter->recvpriv.RxSNRdB[1]);
  8564. DBG_871X("pathA Rx PWDB:%d\n",padapter->recvpriv.rxpwdb);
  8565. rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
  8566. DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
  8567. DBG_871X("Rx RSSI:%d\n",padapter->recvpriv.rssi);
  8568. DBG_871X("Rx Signal_strength:%d\n",padapter->recvpriv.signal_strength);
  8569. DBG_871X("Rx Signal_qual:%d \n",padapter->recvpriv.signal_qual);
  8570. if ( check_fwstate( &padapter->mlmepriv, _FW_LINKED ) )
  8571. {
  8572. DBG_871X("bw mode: %d, channel: %d\n", padapter->mlmeextpriv.cur_bwmode, padapter->mlmeextpriv.cur_channel );
  8573. DBG_871X("received bytes = %d\n", (u32) (padapter->recvpriv.rx_bytes - padapter->recvpriv.last_rx_bytes ) );
  8574. }
  8575. DBG_871X("============ linked status check ===================\n");
  8576. DBG_871X("============ RX GAIN / FALSE ALARM ===================\n");
  8577. DBG_871X(" DIG PATH-A(0x%02x), PATH-B(0x%02x)\n",rtw_read8(padapter,0xc50),rtw_read8(padapter,0xc58));
  8578. DBG_871X(" OFDM -Alarm DA2(0x%04x),DA4(0x%04x),DA6(0x%04x),DA8(0x%04x)\n",
  8579. rtw_read16(padapter,0xDA2),rtw_read16(padapter,0xDA4),rtw_read16(padapter,0xDA6),rtw_read16(padapter,0xDA8));
  8580. DBG_871X(" CCK -Alarm A5B(0x%02x),A5C(0x%02x)\n",rtw_read8(padapter,0xA5B),rtw_read8(padapter,0xA5C));
  8581. #endif
  8582. if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
  8583. {
  8584. mac_id=0;
  8585. }
  8586. else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
  8587. {
  8588. mac_id=2;
  8589. }
  8590. if(padapter->bLinkInfoDump){
  8591. DBG_871X("\n============ linked status check ===================\n");
  8592. rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
  8593. DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
  8594. }
  8595. //============ tx info ============
  8596. rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
  8597. //============ rx info ============
  8598. rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP,&mac_id);
  8599. }
  8600. u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
  8601. {
  8602. u8 ret = _FALSE;
  8603. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8604. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8605. #ifdef DBG_EXPIRATION_CHK
  8606. DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
  8607. /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
  8608. ", retry:%u\n"
  8609. , FUNC_ADPT_ARG(padapter)
  8610. , STA_RX_PKTS_DIFF_ARG(psta)
  8611. , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
  8612. , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
  8613. /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
  8614. , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
  8615. , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
  8616. , pmlmeinfo->bcn_interval*/
  8617. , pmlmeext->retry
  8618. );
  8619. DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
  8620. , padapter->xmitpriv.tx_pkts
  8621. , pmlmeinfo->link_count
  8622. );
  8623. #endif
  8624. if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
  8625. && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
  8626. && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
  8627. )
  8628. {
  8629. ret = _FALSE;
  8630. }
  8631. else
  8632. {
  8633. ret = _TRUE;
  8634. }
  8635. sta_update_last_rx_pkts(psta);
  8636. return ret;
  8637. }
  8638. void linked_status_chk(_adapter *padapter)
  8639. {
  8640. u32 i;
  8641. struct sta_info *psta;
  8642. struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  8643. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8644. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8645. struct sta_priv *pstapriv = &padapter->stapriv;
  8646. _linked_info_dump(padapter);
  8647. #ifdef DBG_CONFIG_ERROR_DETECT
  8648. rtw_hal_sreset_linked_status_check(padapter);
  8649. #endif
  8650. if (is_client_associated_to_ap(padapter))
  8651. {
  8652. //linked infrastructure client mode
  8653. int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
  8654. int rx_chk_limit;
  8655. #if defined(DBG_ROAMING_TEST)
  8656. rx_chk_limit = 1;
  8657. #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
  8658. rx_chk_limit = 4;
  8659. #else
  8660. rx_chk_limit = 8;
  8661. #endif
  8662. #ifdef CONFIG_INTEL_WIDI
  8663. if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
  8664. rx_chk_limit = 1;
  8665. #endif
  8666. if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  8667. {
  8668. bool is_p2p_enable = _FALSE;
  8669. #ifdef CONFIG_P2P
  8670. is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
  8671. #endif
  8672. if (chk_ap_is_alive(padapter, psta) == _FALSE)
  8673. rx_chk = _FAIL;
  8674. if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
  8675. tx_chk = _FAIL;
  8676. #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
  8677. if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
  8678. u8 backup_oper_channel=0;
  8679. /* switch to correct channel of current network before issue keep-alive frames */
  8680. if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
  8681. backup_oper_channel = rtw_get_oper_ch(padapter);
  8682. SelectChannel(padapter, pmlmeext->cur_channel);
  8683. }
  8684. if (rx_chk != _SUCCESS)
  8685. issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
  8686. if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
  8687. tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
  8688. /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
  8689. if (tx_chk == _SUCCESS && !is_p2p_enable)
  8690. rx_chk = _SUCCESS;
  8691. }
  8692. /* back to the original operation channel */
  8693. if(backup_oper_channel>0)
  8694. SelectChannel(padapter, backup_oper_channel);
  8695. }
  8696. else
  8697. #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
  8698. {
  8699. if (rx_chk != _SUCCESS) {
  8700. if (pmlmeext->retry == 0) {
  8701. #ifdef DBG_EXPIRATION_CHK
  8702. DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
  8703. #endif
  8704. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8705. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8706. issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
  8707. }
  8708. }
  8709. if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
  8710. #ifdef DBG_EXPIRATION_CHK
  8711. DBG_871X("%s issue_nulldata 0\n", __FUNCTION__);
  8712. #endif
  8713. tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
  8714. }
  8715. }
  8716. if (rx_chk == _FAIL) {
  8717. pmlmeext->retry++;
  8718. if (pmlmeext->retry > rx_chk_limit) {
  8719. DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
  8720. FUNC_ADPT_ARG(padapter));
  8721. receive_disconnect(padapter, pmlmeinfo->network.MacAddress
  8722. , WLAN_REASON_EXPIRATION_CHK);
  8723. return;
  8724. }
  8725. } else {
  8726. pmlmeext->retry = 0;
  8727. }
  8728. if (tx_chk == _FAIL) {
  8729. pmlmeinfo->link_count &= 0xf;
  8730. } else {
  8731. pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
  8732. pmlmeinfo->link_count = 0;
  8733. }
  8734. } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
  8735. }
  8736. else if (is_client_associated_to_ibss(padapter))
  8737. {
  8738. //linked IBSS mode
  8739. //for each assoc list entry to check the rx pkt counter
  8740. for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
  8741. {
  8742. if (pmlmeinfo->FW_sta_info[i].status == 1)
  8743. {
  8744. psta = pmlmeinfo->FW_sta_info[i].psta;
  8745. if(NULL==psta) continue;
  8746. if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
  8747. {
  8748. if(pmlmeinfo->FW_sta_info[i].retry<3)
  8749. {
  8750. pmlmeinfo->FW_sta_info[i].retry++;
  8751. }
  8752. else
  8753. {
  8754. pmlmeinfo->FW_sta_info[i].retry = 0;
  8755. pmlmeinfo->FW_sta_info[i].status = 0;
  8756. report_del_sta_event(padapter, psta->hwaddr
  8757. , 65535// indicate disconnect caused by no rx
  8758. );
  8759. }
  8760. }
  8761. else
  8762. {
  8763. pmlmeinfo->FW_sta_info[i].retry = 0;
  8764. pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
  8765. }
  8766. }
  8767. }
  8768. //set_link_timer(pmlmeext, DISCONNECT_TO);
  8769. }
  8770. }
  8771. void survey_timer_hdl(_adapter *padapter)
  8772. {
  8773. struct cmd_obj *ph2c;
  8774. struct sitesurvey_parm *psurveyPara;
  8775. struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
  8776. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8777. #ifdef CONFIG_P2P
  8778. struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
  8779. #endif
  8780. //DBG_871X("marc: survey timer\n");
  8781. //issue rtw_sitesurvey_cmd
  8782. if (pmlmeext->sitesurvey_res.state > SCAN_START)
  8783. {
  8784. if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
  8785. {
  8786. #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  8787. if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH )
  8788. #endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
  8789. pmlmeext->sitesurvey_res.channel_idx++;
  8790. }
  8791. if(pmlmeext->scan_abort == _TRUE)
  8792. {
  8793. #ifdef CONFIG_P2P
  8794. if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
  8795. {
  8796. rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
  8797. pmlmeext->sitesurvey_res.channel_idx = 3;
  8798. DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
  8799. , pmlmeext->sitesurvey_res.channel_idx
  8800. , pwdinfo->find_phase_state_exchange_cnt
  8801. );
  8802. }
  8803. else
  8804. #endif
  8805. {
  8806. pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
  8807. DBG_871X("%s idx:%d\n", __FUNCTION__
  8808. , pmlmeext->sitesurvey_res.channel_idx
  8809. );
  8810. }
  8811. pmlmeext->scan_abort = _FALSE;//reset
  8812. }
  8813. if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  8814. {
  8815. goto exit_survey_timer_hdl;
  8816. }
  8817. if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL)
  8818. {
  8819. rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
  8820. goto exit_survey_timer_hdl;
  8821. }
  8822. init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
  8823. rtw_enqueue_cmd(pcmdpriv, ph2c);
  8824. }
  8825. exit_survey_timer_hdl:
  8826. return;
  8827. }
  8828. void link_timer_hdl(_adapter *padapter)
  8829. {
  8830. //static unsigned int rx_pkt = 0;
  8831. //static u64 tx_cnt = 0;
  8832. //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
  8833. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  8834. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  8835. //struct sta_priv *pstapriv = &padapter->stapriv;
  8836. if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
  8837. {
  8838. DBG_871X("link_timer_hdl:no beacon while connecting\n");
  8839. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8840. report_join_res(padapter, -3);
  8841. }
  8842. else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
  8843. {
  8844. //re-auth timer
  8845. if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
  8846. {
  8847. //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
  8848. //{
  8849. pmlmeinfo->state = 0;
  8850. report_join_res(padapter, -1);
  8851. return;
  8852. //}
  8853. //else
  8854. //{
  8855. // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
  8856. // pmlmeinfo->reauth_count = 0;
  8857. //}
  8858. }
  8859. DBG_871X("link_timer_hdl: auth timeout and try again\n");
  8860. pmlmeinfo->auth_seq = 1;
  8861. issue_auth(padapter, NULL, 0);
  8862. set_link_timer(pmlmeext, REAUTH_TO);
  8863. }
  8864. else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
  8865. {
  8866. //re-assoc timer
  8867. if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
  8868. {
  8869. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  8870. report_join_res(padapter, -2);
  8871. return;
  8872. }
  8873. DBG_871X("link_timer_hdl: assoc timeout and try again\n");
  8874. issue_assocreq(padapter);
  8875. set_link_timer(pmlmeext, REASSOC_TO);
  8876. }
  8877. #if 0
  8878. else if (is_client_associated_to_ap(padapter))
  8879. {
  8880. //linked infrastructure client mode
  8881. if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
  8882. {
  8883. /*to monitor whether the AP is alive or not*/
  8884. if (rx_pkt == psta->sta_stats.rx_pkts)
  8885. {
  8886. receive_disconnect(padapter, pmlmeinfo->network.MacAddress);
  8887. return;
  8888. }
  8889. else
  8890. {
  8891. rx_pkt = psta->sta_stats.rx_pkts;
  8892. set_link_timer(pmlmeext, DISCONNECT_TO);
  8893. }
  8894. //update the EDCA paramter according to the Tx/RX mode
  8895. update_EDCA_param(padapter);
  8896. /*to send the AP a nulldata if no frame is xmitted in order to keep alive*/
  8897. if (pmlmeinfo->link_count++ == 0)
  8898. {
  8899. tx_cnt = pxmitpriv->tx_pkts;
  8900. }
  8901. else if ((pmlmeinfo->link_count & 0xf) == 0)
  8902. {
  8903. if (tx_cnt == pxmitpriv->tx_pkts)
  8904. {
  8905. issue_nulldata(padapter, NULL, 0, 0, 0);
  8906. }
  8907. tx_cnt = pxmitpriv->tx_pkts;
  8908. }
  8909. } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
  8910. }
  8911. else if (is_client_associated_to_ibss(padapter))
  8912. {
  8913. //linked IBSS mode
  8914. //for each assoc list entry to check the rx pkt counter
  8915. for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
  8916. {
  8917. if (pmlmeinfo->FW_sta_info[i].status == 1)
  8918. {
  8919. psta = pmlmeinfo->FW_sta_info[i].psta;
  8920. if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts)
  8921. {
  8922. pmlmeinfo->FW_sta_info[i].status = 0;
  8923. report_del_sta_event(padapter, psta->hwaddr);
  8924. }
  8925. else
  8926. {
  8927. pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts;
  8928. }
  8929. }
  8930. }
  8931. set_link_timer(pmlmeext, DISCONNECT_TO);
  8932. }
  8933. #endif
  8934. return;
  8935. }
  8936. void addba_timer_hdl(struct sta_info *psta)
  8937. {
  8938. #ifdef CONFIG_80211N_HT
  8939. struct ht_priv *phtpriv;
  8940. if(!psta)
  8941. return;
  8942. phtpriv = &psta->htpriv;
  8943. if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
  8944. {
  8945. if(phtpriv->candidate_tid_bitmap)
  8946. phtpriv->candidate_tid_bitmap=0x0;
  8947. }
  8948. #endif //CONFIG_80211N_HT
  8949. }
  8950. u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
  8951. {
  8952. return H2C_SUCCESS;
  8953. }
  8954. #ifdef CONFIG_AUTO_AP_MODE
  8955. void rtw_start_auto_ap(_adapter *adapter)
  8956. {
  8957. DBG_871X("%s\n", __FUNCTION__);
  8958. rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
  8959. rtw_setopmode_cmd(adapter, Ndis802_11APMode);
  8960. }
  8961. static int rtw_auto_ap_start_beacon(_adapter *adapter)
  8962. {
  8963. int ret=0;
  8964. u8 *pbuf = NULL;
  8965. uint len;
  8966. u8 supportRate[16];
  8967. int sz = 0, rateLen;
  8968. u8 * ie;
  8969. u8 wireless_mode, oper_channel;
  8970. u8 ssid[3] = {0}; //hidden ssid
  8971. u32 ssid_len = sizeof(ssid);
  8972. struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
  8973. if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
  8974. return -EINVAL;
  8975. len = 128;
  8976. pbuf = rtw_zmalloc(len);
  8977. if(!pbuf)
  8978. return -ENOMEM;
  8979. //generate beacon
  8980. ie = pbuf;
  8981. //timestamp will be inserted by hardware
  8982. sz += 8;
  8983. ie += sz;
  8984. //beacon interval : 2bytes
  8985. *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
  8986. sz += 2;
  8987. ie += 2;
  8988. //capability info
  8989. *(u16*)ie = 0;
  8990. *(u16*)ie |= cpu_to_le16(cap_ESS);
  8991. *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
  8992. //*(u16*)ie |= cpu_to_le16(cap_Privacy);
  8993. sz += 2;
  8994. ie += 2;
  8995. //SSID
  8996. ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
  8997. //supported rates
  8998. wireless_mode = WIRELESS_11BG_24N;
  8999. rtw_set_supported_rate(supportRate, wireless_mode) ;
  9000. rateLen = rtw_get_rateset_len(supportRate);
  9001. if (rateLen > 8)
  9002. {
  9003. ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
  9004. }
  9005. else
  9006. {
  9007. ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
  9008. }
  9009. //DS parameter set
  9010. if(check_buddy_fwstate(adapter, _FW_LINKED) &&
  9011. check_buddy_fwstate(adapter, WIFI_STATION_STATE))
  9012. {
  9013. PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
  9014. struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9015. oper_channel = pbuddy_mlmeext->cur_channel;
  9016. }
  9017. else
  9018. {
  9019. oper_channel = adapter_to_dvobj(adapter)->oper_channel;
  9020. }
  9021. ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
  9022. //ext supported rates
  9023. if (rateLen > 8)
  9024. {
  9025. ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
  9026. }
  9027. DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
  9028. //lunch ap mode & start to issue beacon
  9029. if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
  9030. {
  9031. }
  9032. else
  9033. {
  9034. ret = -EINVAL;
  9035. }
  9036. rtw_mfree(pbuf, len);
  9037. return ret;
  9038. }
  9039. #endif//CONFIG_AUTO_AP_MODE
  9040. u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
  9041. {
  9042. u8 type;
  9043. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9044. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9045. struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
  9046. if(psetop->mode == Ndis802_11APMode)
  9047. {
  9048. pmlmeinfo->state = WIFI_FW_AP_STATE;
  9049. type = _HW_STATE_AP_;
  9050. #ifdef CONFIG_NATIVEAP_MLME
  9051. //start_ap_mode(padapter);
  9052. #endif
  9053. }
  9054. else if(psetop->mode == Ndis802_11Infrastructure)
  9055. {
  9056. pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
  9057. pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
  9058. type = _HW_STATE_STATION_;
  9059. }
  9060. else if(psetop->mode == Ndis802_11IBSS)
  9061. {
  9062. type = _HW_STATE_ADHOC_;
  9063. }
  9064. else
  9065. {
  9066. type = _HW_STATE_NOLINK_;
  9067. }
  9068. rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
  9069. //Set_NETYPE0_MSR(padapter, type);
  9070. #ifdef CONFIG_AUTO_AP_MODE
  9071. if(psetop->mode == Ndis802_11APMode)
  9072. rtw_auto_ap_start_beacon(padapter);
  9073. #endif
  9074. return H2C_SUCCESS;
  9075. }
  9076. u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
  9077. {
  9078. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9079. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9080. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9081. struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
  9082. //u32 initialgain;
  9083. if(pparm->network.InfrastructureMode == Ndis802_11APMode)
  9084. {
  9085. #ifdef CONFIG_AP_MODE
  9086. if(pmlmeinfo->state == WIFI_FW_AP_STATE)
  9087. {
  9088. //todo:
  9089. return H2C_SUCCESS;
  9090. }
  9091. #endif
  9092. }
  9093. //below is for ad-hoc master
  9094. if(pparm->network.InfrastructureMode == Ndis802_11IBSS)
  9095. {
  9096. rtw_joinbss_reset(padapter);
  9097. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9098. pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9099. pmlmeinfo->ERP_enable = 0;
  9100. pmlmeinfo->WMM_enable = 0;
  9101. pmlmeinfo->HT_enable = 0;
  9102. pmlmeinfo->HT_caps_enable = 0;
  9103. pmlmeinfo->HT_info_enable = 0;
  9104. pmlmeinfo->agg_enable_bitmap = 0;
  9105. pmlmeinfo->candidate_tid_bitmap = 0;
  9106. //disable dynamic functions, such as high power, DIG
  9107. Save_DM_Func_Flag(padapter);
  9108. Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9109. //config the initial gain under linking, need to write the BB registers
  9110. //initialgain = 0x1E;
  9111. //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9112. //cancel link timer
  9113. _cancel_timer_ex(&pmlmeext->link_timer);
  9114. //clear CAM
  9115. flush_all_cam_entry(padapter);
  9116. _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
  9117. pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
  9118. if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
  9119. return H2C_PARAMETERS_ERROR;
  9120. _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
  9121. start_create_ibss(padapter);
  9122. }
  9123. return H2C_SUCCESS;
  9124. }
  9125. u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
  9126. {
  9127. u8 join_type;
  9128. PNDIS_802_11_VARIABLE_IEs pIE;
  9129. struct registry_priv *pregpriv = &padapter->registrypriv;
  9130. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9131. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9132. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9133. #ifdef CONFIG_ANTENNA_DIVERSITY
  9134. struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
  9135. #endif //CONFIG_ANTENNA_DIVERSITY
  9136. u32 i;
  9137. u8 cbw40_enable=0;
  9138. //u32 initialgain;
  9139. //u32 acparm;
  9140. //check already connecting to AP or not
  9141. if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
  9142. {
  9143. if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
  9144. {
  9145. issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
  9146. }
  9147. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9148. //clear CAM
  9149. flush_all_cam_entry(padapter);
  9150. _cancel_timer_ex(&pmlmeext->link_timer);
  9151. //set MSR to nolink -> infra. mode
  9152. //Set_MSR(padapter, _HW_STATE_NOLINK_);
  9153. Set_MSR(padapter, _HW_STATE_STATION_);
  9154. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  9155. }
  9156. #ifdef CONFIG_ANTENNA_DIVERSITY
  9157. rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
  9158. #endif
  9159. #ifdef CONFIG_WAPI_SUPPORT
  9160. rtw_wapi_clear_all_cam_entry(padapter);
  9161. #endif
  9162. rtw_joinbss_reset(padapter);
  9163. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9164. pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9165. pmlmeinfo->ERP_enable = 0;
  9166. pmlmeinfo->WMM_enable = 0;
  9167. pmlmeinfo->HT_enable = 0;
  9168. pmlmeinfo->HT_caps_enable = 0;
  9169. pmlmeinfo->HT_info_enable = 0;
  9170. pmlmeinfo->agg_enable_bitmap = 0;
  9171. pmlmeinfo->candidate_tid_bitmap = 0;
  9172. pmlmeinfo->bwmode_updated = _FALSE;
  9173. //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
  9174. pmlmeinfo->VHT_enable = 0;
  9175. _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
  9176. pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
  9177. if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
  9178. return H2C_PARAMETERS_ERROR;
  9179. _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
  9180. //Check AP vendor to move rtw_joinbss_cmd()
  9181. //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
  9182. //sizeof(NDIS_802_11_FIXED_IEs)
  9183. for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;)
  9184. {
  9185. pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
  9186. switch (pIE->ElementID)
  9187. {
  9188. case _VENDOR_SPECIFIC_IE_://Get WMM IE.
  9189. if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
  9190. {
  9191. WMM_param_handler(padapter, pIE);
  9192. }
  9193. break;
  9194. case _HT_CAPABILITY_IE_: //Get HT Cap IE.
  9195. pmlmeinfo->HT_caps_enable = 1;
  9196. break;
  9197. case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
  9198. #ifdef CONFIG_80211N_HT
  9199. pmlmeinfo->HT_info_enable = 1;
  9200. //spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz
  9201. //#if !defined(CONFIG_CONCURRENT_MODE) && !defined(CONFIG_DUALMAC_CONCURRENT)
  9202. // if(pmlmeinfo->assoc_AP_vendor == ciscoAP)
  9203. //#endif
  9204. {
  9205. struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
  9206. if (pnetwork->Configuration.DSConfig > 14) {
  9207. if ((pregpriv->bw_mode & 0xf0) > CHANNEL_WIDTH_20)
  9208. cbw40_enable = 1;
  9209. } else {
  9210. if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
  9211. cbw40_enable = 1;
  9212. }
  9213. if ((cbw40_enable) && (pht_info->infos[0] & BIT(2)))
  9214. {
  9215. //switch to the 40M Hz mode according to the AP
  9216. pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  9217. switch (pht_info->infos[0] & 0x3)
  9218. {
  9219. case 1:
  9220. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  9221. break;
  9222. case 3:
  9223. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  9224. break;
  9225. default:
  9226. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9227. break;
  9228. }
  9229. DBG_871X("set HT ch/bw before connected\n");
  9230. }
  9231. }
  9232. #endif //CONFIG_80211N_HT
  9233. break;
  9234. #ifdef CONFIG_80211AC_VHT
  9235. case EID_VHTCapability://Get VHT Cap IE.
  9236. pmlmeinfo->VHT_enable = 1;
  9237. break;
  9238. case EID_VHTOperation://Get VHT Operation IE.
  9239. if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) {
  9240. if((GET_VHT_OPERATION_ELE_CHL_WIDTH(pIE->data) >= 1)
  9241. && ((pregpriv->bw_mode & 0xf0) >= CHANNEL_WIDTH_80)) {
  9242. pmlmeext->cur_bwmode = CHANNEL_WIDTH_80;
  9243. DBG_871X("VHT center ch = %d\n", GET_VHT_OPERATION_ELE_CENTER_FREQ1(pIE->data));
  9244. DBG_871X("set VHT ch/bw before connected\n");
  9245. }
  9246. }
  9247. break;
  9248. #endif
  9249. default:
  9250. break;
  9251. }
  9252. i += (pIE->Length + 2);
  9253. }
  9254. #if 0
  9255. if (padapter->registrypriv.wifi_spec) {
  9256. // for WiFi test, follow WMM test plan spec
  9257. acparm = 0x002F431C; // VO
  9258. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
  9259. acparm = 0x005E541C; // VI
  9260. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
  9261. acparm = 0x0000A525; // BE
  9262. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9263. acparm = 0x0000A549; // BK
  9264. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
  9265. // for WiFi test, mixed mode with intel STA under bg mode throughput issue
  9266. if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
  9267. acparm = 0x00004320;
  9268. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9269. }
  9270. }
  9271. else {
  9272. acparm = 0x002F3217; // VO
  9273. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
  9274. acparm = 0x005E4317; // VI
  9275. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
  9276. acparm = 0x00105320; // BE
  9277. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
  9278. acparm = 0x0000A444; // BK
  9279. rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
  9280. }
  9281. #endif
  9282. //disable dynamic functions, such as high power, DIG
  9283. //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9284. //config the initial gain under linking, need to write the BB registers
  9285. //initialgain = 0x1E;
  9286. //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9287. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
  9288. join_type = 0;
  9289. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
  9290. //cancel link timer
  9291. _cancel_timer_ex(&pmlmeext->link_timer);
  9292. start_clnt_join(padapter);
  9293. return H2C_SUCCESS;
  9294. }
  9295. u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
  9296. {
  9297. struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
  9298. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9299. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9300. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9301. u8 val8;
  9302. if (is_client_associated_to_ap(padapter))
  9303. {
  9304. issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
  9305. }
  9306. //set_opmode_cmd(padapter, infra_client_with_mlme);
  9307. //pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9308. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
  9309. rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
  9310. if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
  9311. {
  9312. //Stop BCN
  9313. val8 = 0;
  9314. rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
  9315. }
  9316. //set MSR to no link state -> infra. mode
  9317. Set_MSR(padapter, _HW_STATE_STATION_);
  9318. pmlmeinfo->state = WIFI_FW_NULL_STATE;
  9319. #ifdef CONFIG_DUALMAC_CONCURRENT
  9320. dc_set_channel_bwmode_disconnect(padapter);
  9321. #else
  9322. #ifdef CONFIG_CONCURRENT_MODE
  9323. if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
  9324. {
  9325. #endif //CONFIG_CONCURRENT_MODE
  9326. //switch to the 20M Hz mode after disconnect
  9327. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9328. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9329. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9330. #ifdef CONFIG_CONCURRENT_MODE
  9331. }
  9332. #endif //CONFIG_CONCURRENT_MODE
  9333. #endif //CONFIG_DUALMAC_CONCURRENT
  9334. flush_all_cam_entry(padapter);
  9335. _cancel_timer_ex(&pmlmeext->link_timer);
  9336. rtw_free_uc_swdec_pending_queue(padapter);
  9337. return H2C_SUCCESS;
  9338. }
  9339. int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
  9340. u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
  9341. {
  9342. int i, j;
  9343. int scan_ch_num = 0;
  9344. int set_idx;
  9345. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9346. /* clear out first */
  9347. _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
  9348. /* acquire channels from in */
  9349. j = 0;
  9350. for (i=0;i<in_num;i++) {
  9351. if (0)
  9352. DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
  9353. if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
  9354. && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
  9355. )
  9356. {
  9357. _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
  9358. if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
  9359. out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
  9360. j++;
  9361. }
  9362. if(j>=out_num)
  9363. break;
  9364. }
  9365. /* if out is empty, use channel_set as default */
  9366. if(j == 0) {
  9367. for (i=0;i<pmlmeext->max_chan_nums;i++) {
  9368. out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
  9369. if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
  9370. out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
  9371. j++;
  9372. }
  9373. }
  9374. if (padapter->setband == GHZ_24) { // 2.4G
  9375. for (i=0; i < j ; i++) {
  9376. if (out[i].hw_value > 35)
  9377. _rtw_memset(&out[i], 0 , sizeof(struct rtw_ieee80211_channel));
  9378. else
  9379. scan_ch_num++;
  9380. }
  9381. j = scan_ch_num;
  9382. } else if (padapter->setband == GHZ_50) { // 5G
  9383. for (i=0; i < j ; i++) {
  9384. if (out[i].hw_value > 35) {
  9385. _rtw_memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
  9386. }
  9387. }
  9388. j = scan_ch_num;
  9389. } else
  9390. {}
  9391. return j;
  9392. }
  9393. u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
  9394. {
  9395. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9396. struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
  9397. u8 bdelayscan = _FALSE;
  9398. u8 val8;
  9399. u32 initialgain;
  9400. u32 i;
  9401. #ifdef CONFIG_P2P
  9402. struct wifidirect_info* pwdinfo = &padapter->wdinfo;
  9403. #endif
  9404. if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
  9405. {
  9406. #ifdef CONFIG_CONCURRENT_MODE
  9407. //for first time sitesurvey_cmd
  9408. rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  9409. #endif //CONFIG_CONCURRENT_MODE
  9410. pmlmeext->sitesurvey_res.state = SCAN_START;
  9411. pmlmeext->sitesurvey_res.bss_cnt = 0;
  9412. pmlmeext->sitesurvey_res.channel_idx = 0;
  9413. for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
  9414. if(pparm->ssid[i].SsidLength) {
  9415. _rtw_memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
  9416. pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength;
  9417. } else {
  9418. pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0;
  9419. }
  9420. }
  9421. pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
  9422. , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
  9423. , pparm->ch, pparm->ch_num
  9424. );
  9425. pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
  9426. #ifdef CONFIG_DUALMAC_CONCURRENT
  9427. bdelayscan = dc_handle_site_survey(padapter);
  9428. #endif
  9429. //issue null data if associating to the AP
  9430. if (is_client_associated_to_ap(padapter) == _TRUE)
  9431. {
  9432. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  9433. issue_nulldata(padapter, NULL, 1, 3, 500);
  9434. #ifdef CONFIG_CONCURRENT_MODE
  9435. if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  9436. {
  9437. DBG_871X("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n");
  9438. issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
  9439. }
  9440. #endif
  9441. bdelayscan = _TRUE;
  9442. }
  9443. #ifdef CONFIG_CONCURRENT_MODE
  9444. else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
  9445. {
  9446. #ifdef CONFIG_TDLS
  9447. if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1)
  9448. {
  9449. issue_tunneled_probe_req(padapter->pbuddy_adapter);
  9450. }
  9451. #endif //CONFIG_TDLS
  9452. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  9453. issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
  9454. bdelayscan = _TRUE;
  9455. }
  9456. #endif
  9457. if(bdelayscan)
  9458. {
  9459. //delay 50ms to protect nulldata(1).
  9460. set_survey_timer(pmlmeext, 50);
  9461. return H2C_SUCCESS;
  9462. }
  9463. }
  9464. if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL))
  9465. {
  9466. #ifdef CONFIG_FIND_BEST_CHANNEL
  9467. #if 0
  9468. for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
  9469. pmlmeext->channel_set[i].rx_count = 0;
  9470. }
  9471. #endif
  9472. #endif /* CONFIG_FIND_BEST_CHANNEL */
  9473. //disable dynamic functions, such as high power, DIG
  9474. Save_DM_Func_Flag(padapter);
  9475. Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
  9476. //config the initial gain under scaning, need to write the BB registers
  9477. #ifdef CONFIG_P2P
  9478. #ifdef CONFIG_IOCTL_CFG80211
  9479. if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211 )
  9480. initialgain = 0x30;
  9481. else
  9482. #endif //CONFIG_IOCTL_CFG80211
  9483. if ( !rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
  9484. initialgain = 0x28;
  9485. else
  9486. #endif //CONFIG_P2P
  9487. initialgain = 0x1e;
  9488. rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
  9489. //set MSR to no link state
  9490. Set_MSR(padapter, _HW_STATE_NOLINK_);
  9491. val8 = 1; //under site survey
  9492. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  9493. pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
  9494. }
  9495. site_survey(padapter);
  9496. return H2C_SUCCESS;
  9497. }
  9498. u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
  9499. {
  9500. struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
  9501. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9502. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9503. if (pparm->mode < 4)
  9504. {
  9505. pmlmeinfo->auth_algo = pparm->mode;
  9506. }
  9507. return H2C_SUCCESS;
  9508. }
  9509. u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
  9510. {
  9511. unsigned short ctrl;
  9512. struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
  9513. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9514. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9515. unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  9516. //main tx key for wep.
  9517. if(pparm->set_tx)
  9518. pmlmeinfo->key_index = pparm->keyid;
  9519. //write cam
  9520. ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
  9521. DBG_871X_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
  9522. "keyid:%d\n", pparm->algorithm, pparm->keyid);
  9523. write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
  9524. //allow multicast packets to driver
  9525. padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
  9526. return H2C_SUCCESS;
  9527. }
  9528. u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
  9529. {
  9530. u16 ctrl=0;
  9531. u8 cam_id = 0;//cam_entry
  9532. u8 ret = H2C_SUCCESS;
  9533. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9534. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9535. struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
  9536. struct sta_priv *pstapriv = &padapter->stapriv;
  9537. struct sta_info *psta;
  9538. #ifdef CONFIG_TDLS
  9539. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  9540. #endif //CONFIG_TDLS
  9541. //cam_entry:
  9542. //0~3 for default key
  9543. //for concurrent mode (ap+sta, sta+sta):
  9544. //default key is disable, using sw encrypt/decrypt
  9545. //camid 0, 1, 2, 3 is default entry for default key/group key
  9546. //macid = 1 is for bc/mc stainfo, no mapping to camid
  9547. //macid = 0 mapping to camid 4
  9548. //for macid >=2, camid = macid+3;
  9549. if(pparm->algorithm == _NO_PRIVACY_) // clear cam entry
  9550. {
  9551. clear_cam_entry(padapter, pparm->id);
  9552. ret = H2C_SUCCESS;
  9553. goto exit_set_stakey_hdl;
  9554. }
  9555. if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
  9556. {
  9557. psta = rtw_get_stainfo(pstapriv, pparm->addr);
  9558. if(psta)
  9559. {
  9560. ctrl = (BIT(15) | ((pparm->algorithm) << 2));
  9561. DBG_871X("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
  9562. if((psta->mac_id == 1) || (psta->mac_id>(NUM_STA-4)))
  9563. {
  9564. DBG_871X("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
  9565. ret = H2C_REJECTED;
  9566. goto exit_set_stakey_hdl;
  9567. }
  9568. cam_id = (u8)rtw_get_camid(psta->mac_id);//0~3 for default key, cmd_id=macid + 3;
  9569. DBG_871X("Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
  9570. pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
  9571. pparm->addr[5], cam_id);
  9572. write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
  9573. ret = H2C_SUCCESS_RSP;
  9574. goto exit_set_stakey_hdl;
  9575. }
  9576. else
  9577. {
  9578. DBG_871X("r871x_set_stakey_hdl(): sta has been free\n");
  9579. ret = H2C_REJECTED;
  9580. goto exit_set_stakey_hdl;
  9581. }
  9582. }
  9583. //below for sta mode
  9584. if((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)))
  9585. cam_id = (u8)rtw_get_camid(psta->mac_id);
  9586. else
  9587. cam_id = 4;
  9588. ctrl = BIT(15) | ((pparm->algorithm) << 2);
  9589. #ifdef CONFIG_TDLS
  9590. if(ptdlsinfo->clear_cam!=0){
  9591. clear_cam_entry(padapter, ptdlsinfo->clear_cam);
  9592. ptdlsinfo->clear_cam=0;
  9593. ret = H2C_SUCCESS;
  9594. goto exit_set_stakey_hdl;
  9595. }
  9596. psta = rtw_get_stainfo(pstapriv, pparm->addr);//Get TDLS Peer STA
  9597. if( psta->tdls_sta_state&TDLS_LINKED_STATE ){
  9598. write_cam(padapter, psta->mac_id, ctrl, pparm->addr, pparm->key);
  9599. }
  9600. else
  9601. #endif //CONFIG_TDLS
  9602. write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
  9603. pmlmeinfo->enc_algo = pparm->algorithm;
  9604. exit_set_stakey_hdl:
  9605. DBG_871X_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
  9606. pparm->algorithm, cam_id);
  9607. return ret;
  9608. }
  9609. u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
  9610. {
  9611. struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
  9612. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9613. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9614. struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
  9615. if(!psta)
  9616. return H2C_SUCCESS;
  9617. #ifdef CONFIG_80211N_HT
  9618. if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
  9619. ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
  9620. {
  9621. //pmlmeinfo->ADDBA_retry_count = 0;
  9622. //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
  9623. //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
  9624. issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
  9625. //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
  9626. _set_timer(&psta->addba_retry_timer, ADDBA_TO);
  9627. }
  9628. #ifdef CONFIG_TDLS
  9629. else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
  9630. (psta->htpriv.ht_option==_TRUE) &&
  9631. (psta->htpriv.ampdu_enable==_TRUE) )
  9632. {
  9633. issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
  9634. //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
  9635. _set_timer(&psta->addba_retry_timer, ADDBA_TO);
  9636. }
  9637. #endif //CONFIG
  9638. else
  9639. {
  9640. psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
  9641. }
  9642. #endif //CONFIG_80211N_HT
  9643. return H2C_SUCCESS;
  9644. }
  9645. u8 set_tx_beacon_cmd(_adapter* padapter)
  9646. {
  9647. struct cmd_obj *ph2c;
  9648. struct Tx_Beacon_param *ptxBeacon_parm;
  9649. struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
  9650. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9651. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9652. u8 res = _SUCCESS;
  9653. int len_diff = 0;
  9654. _func_enter_;
  9655. if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
  9656. {
  9657. res= _FAIL;
  9658. goto exit;
  9659. }
  9660. if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
  9661. {
  9662. rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
  9663. res= _FAIL;
  9664. goto exit;
  9665. }
  9666. _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
  9667. len_diff = update_hidden_ssid(
  9668. ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
  9669. , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
  9670. , pmlmeinfo->hidden_ssid_mode
  9671. );
  9672. ptxBeacon_parm->network.IELength += len_diff;
  9673. init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
  9674. res = rtw_enqueue_cmd(pcmdpriv, ph2c);
  9675. exit:
  9676. _func_exit_;
  9677. return res;
  9678. }
  9679. u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
  9680. {
  9681. u8 evt_code, evt_seq;
  9682. u16 evt_sz;
  9683. uint *peventbuf;
  9684. void (*event_callback)(_adapter *dev, u8 *pbuf);
  9685. struct evt_priv *pevt_priv = &(padapter->evtpriv);
  9686. peventbuf = (uint*)pbuf;
  9687. evt_sz = (u16)(*peventbuf&0xffff);
  9688. evt_seq = (u8)((*peventbuf>>24)&0x7f);
  9689. evt_code = (u8)((*peventbuf>>16)&0xff);
  9690. #ifdef CHECK_EVENT_SEQ
  9691. // checking event sequence...
  9692. if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
  9693. {
  9694. 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)));
  9695. pevt_priv->event_seq = (evt_seq+1)&0x7f;
  9696. goto _abort_event_;
  9697. }
  9698. #endif
  9699. // checking if event code is valid
  9700. if (evt_code >= MAX_C2HEVT)
  9701. {
  9702. RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
  9703. goto _abort_event_;
  9704. }
  9705. // checking if event size match the event parm size
  9706. if ((wlanevents[evt_code].parmsize != 0) &&
  9707. (wlanevents[evt_code].parmsize != evt_sz))
  9708. {
  9709. RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
  9710. evt_code, wlanevents[evt_code].parmsize, evt_sz));
  9711. goto _abort_event_;
  9712. }
  9713. ATOMIC_INC(&pevt_priv->event_seq);
  9714. peventbuf += 2;
  9715. if(peventbuf)
  9716. {
  9717. event_callback = wlanevents[evt_code].event_callback;
  9718. event_callback(padapter, (u8*)peventbuf);
  9719. pevt_priv->evt_done_cnt++;
  9720. }
  9721. _abort_event_:
  9722. return H2C_SUCCESS;
  9723. }
  9724. u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
  9725. {
  9726. if(!pbuf)
  9727. return H2C_PARAMETERS_ERROR;
  9728. return H2C_SUCCESS;
  9729. }
  9730. u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
  9731. {
  9732. if(send_beacon(padapter)==_FAIL)
  9733. {
  9734. DBG_871X("issue_beacon, fail!\n");
  9735. return H2C_PARAMETERS_ERROR;
  9736. }
  9737. #ifdef CONFIG_AP_MODE
  9738. else //tx bc/mc frames after update TIM
  9739. {
  9740. _irqL irqL;
  9741. struct sta_info *psta_bmc;
  9742. _list *xmitframe_plist, *xmitframe_phead;
  9743. struct xmit_frame *pxmitframe=NULL;
  9744. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  9745. struct sta_priv *pstapriv = &padapter->stapriv;
  9746. //for BC/MC Frames
  9747. psta_bmc = rtw_get_bcmc_stainfo(padapter);
  9748. if(!psta_bmc)
  9749. return H2C_SUCCESS;
  9750. if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
  9751. {
  9752. #ifndef CONFIG_PCI_HCI
  9753. rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
  9754. #endif
  9755. //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9756. _enter_critical_bh(&pxmitpriv->lock, &irqL);
  9757. xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
  9758. xmitframe_plist = get_next(xmitframe_phead);
  9759. while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
  9760. {
  9761. pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
  9762. xmitframe_plist = get_next(xmitframe_plist);
  9763. rtw_list_delete(&pxmitframe->list);
  9764. psta_bmc->sleepq_len--;
  9765. if(psta_bmc->sleepq_len>0)
  9766. pxmitframe->attrib.mdata = 1;
  9767. else
  9768. pxmitframe->attrib.mdata = 0;
  9769. pxmitframe->attrib.triggered=1;
  9770. pxmitframe->attrib.qsel = 0x11;//HIQ
  9771. #if 0
  9772. _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9773. if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
  9774. {
  9775. rtw_os_xmit_complete(padapter, pxmitframe);
  9776. }
  9777. _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9778. #endif
  9779. rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
  9780. //pstapriv->tim_bitmap &= ~BIT(0);
  9781. }
  9782. //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
  9783. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  9784. //#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  9785. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  9786. rtw_chk_hi_queue_cmd(padapter);
  9787. #endif
  9788. }
  9789. }
  9790. #endif
  9791. return H2C_SUCCESS;
  9792. }
  9793. void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
  9794. {
  9795. u8 network_type,rate_len, total_rate_len,remainder_rate_len;
  9796. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  9797. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9798. u8 erpinfo=0x4;
  9799. //DBG_871X("%s\n", __FUNCTION__);
  9800. if(pmlmeext->cur_channel >= 36)
  9801. {
  9802. network_type = WIRELESS_11A;
  9803. total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
  9804. DBG_871X("%s(): change to 5G Band\n",__FUNCTION__);
  9805. rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
  9806. }
  9807. else
  9808. {
  9809. network_type = WIRELESS_11BG;
  9810. total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
  9811. DBG_871X("%s(): change to 2.4G Band\n",__FUNCTION__);
  9812. rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
  9813. }
  9814. rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
  9815. UpdateBrateTbl(padapter, pnetwork->SupportedRates);
  9816. rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
  9817. if(total_rate_len > 8)
  9818. {
  9819. rate_len = 8;
  9820. remainder_rate_len = total_rate_len - 8;
  9821. }
  9822. else
  9823. {
  9824. rate_len = total_rate_len;
  9825. remainder_rate_len = 0;
  9826. }
  9827. rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
  9828. if(remainder_rate_len)
  9829. {
  9830. rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
  9831. }
  9832. else
  9833. {
  9834. rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
  9835. }
  9836. }
  9837. #ifdef CONFIG_DUALMAC_CONCURRENT
  9838. void dc_SelectChannel(_adapter *padapter, unsigned char channel)
  9839. {
  9840. PADAPTER ptarget_adapter;
  9841. if( (padapter->pbuddy_adapter != NULL) &&
  9842. (padapter->DualMacConcurrent == _TRUE) &&
  9843. (padapter->adapter_type == SECONDARY_ADAPTER))
  9844. {
  9845. // only mac0 could control BB&RF
  9846. ptarget_adapter = padapter->pbuddy_adapter;
  9847. }
  9848. else
  9849. {
  9850. ptarget_adapter = padapter;
  9851. }
  9852. _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
  9853. rtw_hal_set_chan(ptarget_adapter, channel);
  9854. _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
  9855. }
  9856. void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
  9857. {
  9858. PADAPTER ptarget_adapter;
  9859. if( (padapter->pbuddy_adapter != NULL) &&
  9860. (padapter->DualMacConcurrent == _TRUE) &&
  9861. (padapter->adapter_type == SECONDARY_ADAPTER))
  9862. {
  9863. // only mac0 could control BB&RF
  9864. ptarget_adapter = padapter->pbuddy_adapter;
  9865. }
  9866. else
  9867. {
  9868. ptarget_adapter = padapter;
  9869. }
  9870. _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
  9871. rtw_hal_set_bwmode(ptarget_adapter, (CHANNEL_WIDTH)bwmode, channel_offset);
  9872. _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
  9873. }
  9874. void dc_set_channel_bwmode_disconnect(_adapter *padapter)
  9875. {
  9876. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9877. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9878. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9879. if(pbuddy_adapter != NULL &&
  9880. padapter->DualMacConcurrent == _TRUE)
  9881. {
  9882. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9883. if((check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) != _TRUE)
  9884. {
  9885. //switch to the 20M Hz mode after disconnect
  9886. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9887. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9888. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9889. }
  9890. }
  9891. else
  9892. {
  9893. //switch to the 20M Hz mode after disconnect
  9894. pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  9895. pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  9896. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  9897. }
  9898. }
  9899. u8 dc_handle_join_request(_adapter *padapter)
  9900. {
  9901. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9902. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9903. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
  9904. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9905. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  9906. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9907. u8 ret = _SUCCESS;
  9908. if(pbuddy_adapter != NULL &&
  9909. padapter->DualMacConcurrent == _TRUE)
  9910. {
  9911. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9912. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9913. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel ||
  9914. pmlmeext->cur_bwmode != pbuddy_mlmeext->cur_bwmode ||
  9915. pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
  9916. {
  9917. if((check_fwstate(pbuddy_mlmepriv, WIFI_AP_STATE)) == _TRUE)
  9918. {
  9919. //issue deauth to all stas if if2 is at ap mode
  9920. rtw_sta_flush(pbuddy_adapter);
  9921. //rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  9922. rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_CHECK_TXBUF, 0);
  9923. }
  9924. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE)
  9925. {
  9926. if(pmlmeext->cur_channel == pbuddy_mlmeext->cur_channel)
  9927. {
  9928. // CHANNEL_WIDTH_40 or CHANNEL_WIDTH_20 but channel offset is different
  9929. if((pmlmeext->cur_bwmode == pbuddy_mlmeext->cur_bwmode) &&
  9930. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) )
  9931. {
  9932. report_join_res(padapter, -4);
  9933. ret = _FAIL;
  9934. }
  9935. }
  9936. else
  9937. {
  9938. report_join_res(padapter, -4);
  9939. ret = _FAIL;
  9940. }
  9941. }
  9942. }
  9943. else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  9944. {
  9945. issue_nulldata(pbuddy_adapter, NULL, 1, 0, 0);
  9946. }
  9947. }
  9948. return ret;
  9949. }
  9950. void dc_handle_join_done(_adapter *padapter, u8 join_res)
  9951. {
  9952. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  9953. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  9954. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  9955. struct mlme_priv *pbuddy_mlmepriv = NULL;
  9956. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  9957. struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
  9958. WLAN_BSSID_EX *pbuddy_network_mlmeext = NULL;
  9959. u8 change_band = _FALSE;
  9960. if(pbuddy_adapter != NULL &&
  9961. padapter->DualMacConcurrent == _TRUE)
  9962. {
  9963. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  9964. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  9965. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  9966. pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
  9967. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  9968. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  9969. {
  9970. //restart and update beacon
  9971. DBG_871X("after join, current adapter, CH=%d, BW=%d, offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
  9972. if(join_res >= 0)
  9973. {
  9974. u8 *p;
  9975. int ie_len;
  9976. struct HT_info_element *pht_info=NULL;
  9977. if((pbuddy_mlmeext->cur_channel <= 14 && pmlmeext->cur_channel >= 36) ||
  9978. (pbuddy_mlmeext->cur_channel >= 36 && pmlmeext->cur_channel <= 14))
  9979. {
  9980. change_band = _TRUE;
  9981. }
  9982. //sync channel/bwmode/ch_offset with another adapter
  9983. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  9984. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  9985. {
  9986. 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)));
  9987. if( p && ie_len)
  9988. {
  9989. pht_info = (struct HT_info_element *)(p+2);
  9990. pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present
  9991. }
  9992. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  9993. {
  9994. pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
  9995. //to update cur_ch_offset value in beacon
  9996. if( pht_info )
  9997. {
  9998. switch(pmlmeext->cur_ch_offset)
  9999. {
  10000. case HAL_PRIME_CHNL_OFFSET_LOWER:
  10001. pht_info->infos[0] |= 0x1;
  10002. break;
  10003. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10004. pht_info->infos[0] |= 0x3;
  10005. break;
  10006. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10007. default:
  10008. break;
  10009. }
  10010. }
  10011. }
  10012. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10013. {
  10014. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  10015. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10016. if(pmlmeext->cur_channel>0 && pmlmeext->cur_channel<5)
  10017. {
  10018. if(pht_info)
  10019. pht_info->infos[0] |= 0x1;
  10020. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10021. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10022. }
  10023. if(pmlmeext->cur_channel>7 && pmlmeext->cur_channel<(14+1))
  10024. {
  10025. if(pht_info)
  10026. pht_info->infos[0] |= 0x3;
  10027. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10028. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10029. }
  10030. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10031. }
  10032. }
  10033. // to update channel value in beacon
  10034. pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
  10035. 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)));
  10036. if(p && ie_len>0)
  10037. *(p + 2) = pmlmeext->cur_channel;
  10038. 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)));
  10039. if( p && ie_len)
  10040. {
  10041. pht_info = (struct HT_info_element *)(p+2);
  10042. pht_info->primary_channel = pmlmeext->cur_channel;
  10043. }
  10044. // update mlmepriv's cur_network
  10045. _rtw_memcpy(&pbuddy_mlmepriv->cur_network.network, pbuddy_network_mlmeext, pbuddy_network_mlmeext->Length);
  10046. }
  10047. else
  10048. {
  10049. // switch back to original channel/bwmode/ch_offset;
  10050. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10051. }
  10052. 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);
  10053. if(change_band == _TRUE)
  10054. change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext);
  10055. DBG_871X("update pbuddy_adapter's beacon\n");
  10056. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10057. }
  10058. else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10059. {
  10060. if((pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10061. (pmlmeext->cur_bwmode == CHANNEL_WIDTH_20))
  10062. {
  10063. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10064. }
  10065. issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
  10066. }
  10067. }
  10068. }
  10069. sint dc_check_fwstate(_adapter *padapter, sint fw_state)
  10070. {
  10071. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10072. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10073. if(padapter->pbuddy_adapter != NULL &&
  10074. padapter->DualMacConcurrent == _TRUE)
  10075. {
  10076. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10077. return check_fwstate(pbuddy_mlmepriv, fw_state);
  10078. }
  10079. return _FALSE;
  10080. }
  10081. u8 dc_handle_site_survey(_adapter *padapter)
  10082. {
  10083. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10084. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  10085. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10086. // only mac0 can do scan request, help issue nulldata(1) for mac1
  10087. if(pbuddy_adapter != NULL &&
  10088. padapter->DualMacConcurrent == _TRUE)
  10089. {
  10090. if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10091. {
  10092. pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
  10093. issue_nulldata(pbuddy_adapter, NULL, 1, 2, 0);
  10094. return _TRUE;
  10095. }
  10096. }
  10097. return _FALSE;
  10098. }
  10099. void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  10100. {
  10101. if(padapter->pbuddy_adapter != NULL &&
  10102. padapter->DualMacConcurrent == _TRUE)
  10103. {
  10104. report_survey_event(padapter->pbuddy_adapter, precv_frame);
  10105. }
  10106. }
  10107. void dc_set_channel_bwmode_survey_done(_adapter *padapter)
  10108. {
  10109. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10110. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10111. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10112. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10113. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  10114. struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
  10115. u8 cur_channel;
  10116. u8 cur_bwmode;
  10117. u8 cur_ch_offset;
  10118. if(pbuddy_adapter != NULL &&
  10119. padapter->DualMacConcurrent == _TRUE)
  10120. {
  10121. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10122. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10123. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10124. if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10125. {
  10126. if(check_fwstate(pmlmepriv, _FW_LINKED) &&
  10127. (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40))
  10128. {
  10129. cur_channel = pmlmeext->cur_channel;
  10130. cur_bwmode = pmlmeext->cur_bwmode;
  10131. cur_ch_offset = pmlmeext->cur_ch_offset;
  10132. }
  10133. else
  10134. {
  10135. cur_channel = pbuddy_mlmeext->cur_channel;
  10136. cur_bwmode = pbuddy_mlmeext->cur_bwmode;
  10137. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10138. }
  10139. }
  10140. else
  10141. {
  10142. cur_channel = pmlmeext->cur_channel;
  10143. cur_bwmode = pmlmeext->cur_bwmode;
  10144. cur_ch_offset = pmlmeext->cur_ch_offset;
  10145. }
  10146. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10147. if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
  10148. {
  10149. //issue null data
  10150. issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
  10151. }
  10152. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  10153. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10154. {
  10155. DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10156. DBG_871X("restart pbuddy_adapter's beacon\n");
  10157. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10158. }
  10159. }
  10160. else
  10161. {
  10162. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10163. }
  10164. }
  10165. void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)
  10166. {
  10167. u8 *p;
  10168. u8 val8, cur_channel, cur_bwmode, cur_ch_offset, change_band;
  10169. int ie_len;
  10170. struct registry_priv *pregpriv = &padapter->registrypriv;
  10171. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  10172. WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
  10173. struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  10174. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  10175. struct HT_info_element *pht_info=NULL;
  10176. _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
  10177. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10178. struct mlme_ext_priv *pbuddy_mlmeext = NULL;
  10179. DBG_871X("dualmac_concurrent_ap_set_channel_bwmode ==>\n");
  10180. cur_channel = channel;
  10181. cur_bwmode = bwmode;
  10182. cur_ch_offset = channel_offset;
  10183. change_band = _FALSE;
  10184. 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)));
  10185. if( p && ie_len)
  10186. {
  10187. pht_info = (struct HT_info_element *)(p+2);
  10188. }
  10189. if(pbuddy_adapter != NULL &&
  10190. padapter->DualMacConcurrent == _TRUE)
  10191. {
  10192. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10193. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10194. if(!check_fwstate(pbuddy_mlmepriv, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
  10195. {
  10196. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10197. }
  10198. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)==_TRUE)
  10199. {
  10200. //To sync cur_channel/cur_bwmode/cur_ch_offset with another adapter
  10201. DBG_871X("Another iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
  10202. DBG_871X("Another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10203. DBG_871X("Current adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10204. cur_channel = pbuddy_mlmeext->cur_channel;
  10205. if(cur_bwmode == CHANNEL_WIDTH_40)
  10206. {
  10207. if(pht_info)
  10208. pht_info->infos[0] &= ~(BIT(0)|BIT(1));
  10209. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10210. {
  10211. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10212. //to update cur_ch_offset value in beacon
  10213. if(pht_info)
  10214. {
  10215. switch(cur_ch_offset)
  10216. {
  10217. case HAL_PRIME_CHNL_OFFSET_LOWER:
  10218. pht_info->infos[0] |= 0x1;
  10219. break;
  10220. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10221. pht_info->infos[0] |= 0x3;
  10222. break;
  10223. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10224. default:
  10225. break;
  10226. }
  10227. }
  10228. }
  10229. else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10230. {
  10231. cur_bwmode = CHANNEL_WIDTH_20;
  10232. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10233. if(cur_channel>0 && cur_channel<5)
  10234. {
  10235. if(pht_info)
  10236. pht_info->infos[0] |= 0x1;
  10237. cur_bwmode = CHANNEL_WIDTH_40;
  10238. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10239. }
  10240. if(cur_channel>7 && cur_channel<(14+1))
  10241. {
  10242. if(pht_info)
  10243. pht_info->infos[0] |= 0x3;
  10244. cur_bwmode = CHANNEL_WIDTH_40;
  10245. cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10246. }
  10247. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10248. }
  10249. }
  10250. // to update channel value in beacon
  10251. pnetwork->Configuration.DSConfig = cur_channel;
  10252. p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
  10253. if(p && ie_len>0)
  10254. *(p + 2) = cur_channel;
  10255. if(pht_info)
  10256. pht_info->primary_channel = cur_channel;
  10257. }
  10258. }
  10259. else
  10260. {
  10261. set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
  10262. }
  10263. DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
  10264. if((channel <= 14 && cur_channel >= 36) ||
  10265. (channel >= 36 && cur_channel <= 14))
  10266. {
  10267. change_band = _TRUE;
  10268. }
  10269. pmlmeext->cur_channel = cur_channel;
  10270. pmlmeext->cur_bwmode = cur_bwmode;
  10271. pmlmeext->cur_ch_offset = cur_ch_offset;
  10272. if(change_band == _TRUE)
  10273. change_band_update_ie(padapter, pnetwork);
  10274. DBG_871X("dualmac_concurrent_ap_set_channel_bwmode <==\n");
  10275. }
  10276. void dc_resume_xmit(_adapter *padapter)
  10277. {
  10278. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10279. if(pbuddy_adapter != NULL &&
  10280. padapter->DualMacConcurrent == _TRUE)
  10281. {
  10282. DBG_871X("dc_resume_xmit, resume pbuddy_adapter Tx\n");
  10283. rtw_os_xmit_schedule(pbuddy_adapter);
  10284. }
  10285. }
  10286. u8 dc_check_xmit(_adapter *padapter)
  10287. {
  10288. PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
  10289. struct mlme_priv *pbuddy_mlmepriv = NULL;
  10290. if(pbuddy_adapter != NULL &&
  10291. padapter->DualMacConcurrent == _TRUE)
  10292. {
  10293. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10294. if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
  10295. {
  10296. DBG_871X("dc_check_xmit pbuddy_adapter is under survey or under linking\n");
  10297. return _FALSE;
  10298. }
  10299. }
  10300. return _TRUE;
  10301. }
  10302. #endif
  10303. #ifdef CONFIG_CONCURRENT_MODE
  10304. sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
  10305. {
  10306. PADAPTER pbuddy_adapter;
  10307. struct mlme_ext_priv *pbuddy_mlmeext;
  10308. struct mlme_ext_info *pbuddy_mlmeinfo;
  10309. if(padapter == NULL)
  10310. return _FALSE;
  10311. pbuddy_adapter = padapter->pbuddy_adapter;
  10312. if(pbuddy_adapter == NULL)
  10313. return _FALSE;
  10314. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10315. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10316. if((pbuddy_mlmeinfo->state&0x03) == state)
  10317. return _TRUE;
  10318. return _FALSE;
  10319. }
  10320. int concurrent_chk_start_clnt_join(_adapter *padapter)
  10321. {
  10322. int ret = _FAIL;
  10323. PADAPTER pbuddy_adapter;
  10324. struct mlme_ext_priv *pbuddy_mlmeext;
  10325. struct mlme_ext_info *pbuddy_pmlmeinfo;
  10326. struct mlme_priv *pbuddy_mlmepriv;
  10327. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10328. unsigned char cur_ch = pmlmeext->cur_channel;
  10329. unsigned char cur_bw = pmlmeext->cur_bwmode;
  10330. unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
  10331. if(!rtw_buddy_adapter_up(padapter))
  10332. {
  10333. goto start_join_set_ch_bw;
  10334. }
  10335. pbuddy_adapter = padapter->pbuddy_adapter;
  10336. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10337. pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10338. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10339. if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE
  10340. {
  10341. bool inform_ch_switch = _FALSE;
  10342. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
  10343. {
  10344. inform_ch_switch = _TRUE;
  10345. }
  10346. else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10347. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10348. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
  10349. {
  10350. inform_ch_switch = _TRUE;
  10351. }
  10352. else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_20) &&
  10353. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40))
  10354. {
  10355. inform_ch_switch = _FALSE;
  10356. cur_ch = pmlmeext->cur_channel;
  10357. cur_bw = pbuddy_mlmeext->cur_bwmode;
  10358. cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
  10359. }
  10360. if (inform_ch_switch) {
  10361. #ifdef CONFIG_SPCT_CH_SWITCH
  10362. if (1) {
  10363. rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
  10364. } else
  10365. #endif
  10366. {
  10367. //issue deauth to all stas if if2 is at ap mode
  10368. rtw_sta_flush(pbuddy_adapter);
  10369. }
  10370. rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
  10371. }
  10372. }
  10373. else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
  10374. check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client
  10375. {
  10376. #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
  10377. struct wifidirect_info *pbuddy_wdinfo = &(pbuddy_adapter->wdinfo);
  10378. if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE) && pbuddy_wdinfo->driver_interface == DRIVER_CFG80211 )
  10379. {
  10380. goto start_join_set_ch_bw;//wlan0-sta mode has higher priority than p2p0-p2p client
  10381. }
  10382. #endif //CONFIG_P2P && CONFIG_IOCTL_CFG80211
  10383. if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
  10384. {
  10385. DBG_871X("start_clnt_join(ch=%d), but channel mismatch with buddy(ch=%d) interface\n",
  10386. pmlmeext->cur_channel, pbuddy_mlmeext->cur_channel);
  10387. report_join_res(padapter, (-4));
  10388. return ret;
  10389. }
  10390. if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10391. (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
  10392. (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
  10393. {
  10394. DBG_871X("start_clnt_join(bwmode=%d, ch_offset=%d), but bwmode & ch_offset mismatch with buddy(bwmode=%d, ch_offset=%d) interface\n",
  10395. pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
  10396. report_join_res(padapter, (-4));
  10397. return ret;
  10398. }
  10399. }
  10400. start_join_set_ch_bw:
  10401. set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
  10402. return _SUCCESS;
  10403. }
  10404. void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
  10405. {
  10406. struct mlme_ext_priv *pmlmeext;
  10407. struct mlme_ext_info *pmlmeinfo;
  10408. PADAPTER pbuddy_adapter;
  10409. struct mlme_priv *pbuddy_mlmepriv;
  10410. struct mlme_ext_priv *pbuddy_mlmeext;
  10411. struct mlme_ext_info *pbuddy_mlmeinfo;
  10412. WLAN_BSSID_EX *pbuddy_network_mlmeext;
  10413. pmlmeext = &padapter->mlmeextpriv;
  10414. pmlmeinfo = &(pmlmeext->mlmext_info);
  10415. if(!rtw_buddy_adapter_up(padapter))
  10416. {
  10417. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10418. return;
  10419. }
  10420. pbuddy_adapter = padapter->pbuddy_adapter;
  10421. pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
  10422. pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
  10423. pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
  10424. pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
  10425. if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
  10426. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10427. {
  10428. //restart and update beacon
  10429. DBG_871X("after join,primary adapter, CH=%d, BW=%d, offset=%d\n"
  10430. , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
  10431. if(join_res >= 0)
  10432. {
  10433. u8 *p;
  10434. int ie_len;
  10435. u8 change_band = _FALSE;
  10436. struct HT_info_element *pht_info=NULL;
  10437. if((pmlmeext->cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||
  10438. (pmlmeext->cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))
  10439. change_band = _TRUE;
  10440. //sync channel/bwmode/ch_offset with primary adapter
  10441. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  10442. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10443. {
  10444. 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)));
  10445. if( p && ie_len)
  10446. {
  10447. pht_info = (struct HT_info_element *)(p+2);
  10448. pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present
  10449. }
  10450. if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10451. {
  10452. pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
  10453. //to update cur_ch_offset value in beacon
  10454. if( pht_info )
  10455. {
  10456. switch(pmlmeext->cur_ch_offset)
  10457. {
  10458. case HAL_PRIME_CHNL_OFFSET_LOWER:
  10459. pht_info->infos[0] |= 0x1;
  10460. break;
  10461. case HAL_PRIME_CHNL_OFFSET_UPPER:
  10462. pht_info->infos[0] |= 0x3;
  10463. break;
  10464. case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
  10465. default:
  10466. break;
  10467. }
  10468. }
  10469. }
  10470. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
  10471. {
  10472. if(pmlmeext->cur_channel>=1 && pmlmeext->cur_channel<=4)
  10473. {
  10474. if(pht_info)
  10475. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
  10476. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10477. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10478. }
  10479. else if(pmlmeext->cur_channel>=5 && pmlmeext->cur_channel<=14)
  10480. {
  10481. if(pht_info)
  10482. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10483. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10484. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10485. }
  10486. else
  10487. {
  10488. switch(pmlmeext->cur_channel)
  10489. {
  10490. case 36:
  10491. case 44:
  10492. case 52:
  10493. case 60:
  10494. case 100:
  10495. case 108:
  10496. case 116:
  10497. case 124:
  10498. case 132:
  10499. case 149:
  10500. case 157:
  10501. {
  10502. if(pht_info)
  10503. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
  10504. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10505. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
  10506. break;
  10507. }
  10508. case 40:
  10509. case 48:
  10510. case 56:
  10511. case 64:
  10512. case 104:
  10513. case 112:
  10514. case 120:
  10515. case 128:
  10516. case 136:
  10517. case 153:
  10518. case 161:
  10519. {
  10520. if(pht_info)
  10521. pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10522. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
  10523. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
  10524. break;
  10525. }
  10526. default:
  10527. if(pht_info)
  10528. pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
  10529. pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
  10530. pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  10531. break;
  10532. }
  10533. }
  10534. }
  10535. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10536. }
  10537. else
  10538. {
  10539. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10540. }
  10541. // to update channel value in beacon
  10542. pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
  10543. 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)));
  10544. if(p && ie_len>0)
  10545. *(p + 2) = pmlmeext->cur_channel;
  10546. 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)));
  10547. if( p && ie_len)
  10548. {
  10549. pht_info = (struct HT_info_element *)(p+2);
  10550. pht_info->primary_channel = pmlmeext->cur_channel;
  10551. }
  10552. //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE
  10553. if(change_band == _TRUE)
  10554. change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext);
  10555. }
  10556. else
  10557. {
  10558. // switch back to original channel/bwmode/ch_offset;
  10559. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10560. }
  10561. 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);
  10562. DBG_871X("update pbuddy_adapter's beacon\n");
  10563. update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
  10564. }
  10565. else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
  10566. check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
  10567. {
  10568. if(join_res >= 0)
  10569. {
  10570. pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
  10571. if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10572. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10573. else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40)
  10574. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10575. else
  10576. set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
  10577. }
  10578. else
  10579. {
  10580. // switch back to original channel/bwmode/ch_offset;
  10581. set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
  10582. }
  10583. }
  10584. else
  10585. {
  10586. set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
  10587. }
  10588. }
  10589. #endif //CONFIG_CONCURRENT_MODE
  10590. u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
  10591. {
  10592. struct set_ch_parm *set_ch_parm;
  10593. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10594. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10595. if(!pbuf)
  10596. return H2C_PARAMETERS_ERROR;
  10597. set_ch_parm = (struct set_ch_parm *)pbuf;
  10598. DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
  10599. FUNC_NDEV_ARG(padapter->pnetdev),
  10600. set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
  10601. pmlmeext->cur_channel = set_ch_parm->ch;
  10602. pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
  10603. pmlmeext->cur_bwmode = set_ch_parm->bw;
  10604. set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
  10605. return H2C_SUCCESS;
  10606. }
  10607. u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
  10608. {
  10609. struct SetChannelPlan_param *setChannelPlan_param;
  10610. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10611. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10612. if(!pbuf)
  10613. return H2C_PARAMETERS_ERROR;
  10614. setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
  10615. pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
  10616. init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
  10617. return H2C_SUCCESS;
  10618. }
  10619. u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
  10620. {
  10621. struct LedBlink_param *ledBlink_param;
  10622. if(!pbuf)
  10623. return H2C_PARAMETERS_ERROR;
  10624. ledBlink_param = (struct LedBlink_param *)pbuf;
  10625. #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
  10626. BlinkHandler((PLED_DATA)ledBlink_param->pLed);
  10627. #endif
  10628. return H2C_SUCCESS;
  10629. }
  10630. u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
  10631. {
  10632. #ifdef CONFIG_DFS
  10633. struct SetChannelSwitch_param *setChannelSwitch_param;
  10634. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  10635. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10636. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  10637. u8 new_ch_no;
  10638. u8 gval8 = 0x00, sval8 = 0xff;
  10639. if(!pbuf)
  10640. return H2C_PARAMETERS_ERROR;
  10641. setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
  10642. new_ch_no = setChannelSwitch_param->new_ch_no;
  10643. rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
  10644. rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
  10645. DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
  10646. SelectChannel(padapter, new_ch_no);
  10647. rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
  10648. rtw_free_network_queue(padapter, _TRUE);
  10649. rtw_indicate_disconnect(padapter);
  10650. if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
  10651. DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
  10652. }
  10653. return H2C_SUCCESS;
  10654. #else
  10655. return H2C_REJECTED;
  10656. #endif //CONFIG_DFS
  10657. }
  10658. // TDLS_WRCR : write RCR DATA BIT
  10659. // TDLS_SD_PTI : issue peer traffic indication
  10660. // TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure
  10661. // TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame
  10662. // TDLS_DONE_CH_SEN: channel sensing and report candidate channel
  10663. // TDLS_OFF_CH : first time set channel to off channel
  10664. // TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel
  10665. // TDLS_P_OFF_CH : periodically go to off channel
  10666. // TDLS_P_BASE_CH : periodically go back to base channel
  10667. // TDLS_RS_RCR : restore RCR
  10668. // TDLS_CKALV_PH1 : check alive timer phase1
  10669. // TDLS_CKALV_PH2 : check alive timer phase2
  10670. // TDLS_FREE_STA : free tdls sta
  10671. u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
  10672. {
  10673. #ifdef CONFIG_TDLS
  10674. _irqL irqL;
  10675. struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
  10676. struct TDLSoption_param *TDLSoption;
  10677. struct sta_info *ptdls_sta;
  10678. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  10679. struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  10680. u8 survey_channel, i, min, option;
  10681. if(!pbuf)
  10682. return H2C_PARAMETERS_ERROR;
  10683. TDLSoption = (struct TDLSoption_param *)pbuf;
  10684. ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
  10685. option = TDLSoption->option;
  10686. if( ptdls_sta == NULL )
  10687. {
  10688. if( option != TDLS_RS_RCR )
  10689. return H2C_REJECTED;
  10690. }
  10691. //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
  10692. DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
  10693. switch(option){
  10694. case TDLS_WRCR:
  10695. //As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0
  10696. //such we can receive all kinds of data frames.
  10697. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
  10698. DBG_871X("TDLS with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
  10699. pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
  10700. //set TDLS sta rate.
  10701. set_sta_rate(padapter, ptdls_sta);
  10702. break;
  10703. case TDLS_SD_PTI:
  10704. issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
  10705. break;
  10706. case TDLS_CS_OFF:
  10707. _cancel_timer_ex(&ptdls_sta->base_ch_timer);
  10708. _cancel_timer_ex(&ptdls_sta->off_ch_timer);
  10709. SelectChannel(padapter, pmlmeext->cur_channel);
  10710. ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
  10711. TDLS_PEER_AT_OFF_STATE |
  10712. TDLS_AT_OFF_CH_STATE);
  10713. DBG_871X("go back to base channel\n ");
  10714. issue_nulldata(padapter, NULL, 0, 0, 0);
  10715. break;
  10716. case TDLS_INIT_CH_SEN:
  10717. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_INIT_CH_SEN, 0);
  10718. pmlmeext->sitesurvey_res.channel_idx = 0;
  10719. ptdls_sta->option = TDLS_DONE_CH_SEN;
  10720. rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
  10721. break;
  10722. case TDLS_DONE_CH_SEN:
  10723. survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
  10724. if(survey_channel){
  10725. SelectChannel(padapter, survey_channel);
  10726. ptdlsinfo->cur_channel = survey_channel;
  10727. pmlmeext->sitesurvey_res.channel_idx++;
  10728. _set_timer(&ptdls_sta->option_timer, SURVEY_TO);
  10729. }else{
  10730. SelectChannel(padapter, pmlmeext->cur_channel);
  10731. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_DONE_CH_SEN, 0);
  10732. if(ptdlsinfo->ch_sensing==1){
  10733. ptdlsinfo->ch_sensing=0;
  10734. ptdlsinfo->cur_channel=1;
  10735. min=ptdlsinfo->collect_pkt_num[0];
  10736. for(i=1; i<MAX_CHANNEL_NUM-1; i++){
  10737. if(min > ptdlsinfo->collect_pkt_num[i]){
  10738. ptdlsinfo->cur_channel=i+1;
  10739. min=ptdlsinfo->collect_pkt_num[i];
  10740. }
  10741. ptdlsinfo->collect_pkt_num[i]=0;
  10742. }
  10743. ptdlsinfo->collect_pkt_num[0]=0;
  10744. ptdlsinfo->candidate_ch=ptdlsinfo->cur_channel;
  10745. DBG_871X("TDLS channel sensing done, candidate channel: %02x\n", ptdlsinfo->candidate_ch);
  10746. ptdlsinfo->cur_channel=0;
  10747. }
  10748. if(ptdls_sta->tdls_sta_state & TDLS_PEER_SLEEP_STATE){
  10749. ptdls_sta->tdls_sta_state |= TDLS_APSD_CHSW_STATE;
  10750. }else{
  10751. //send null data with pwrbit==1 before send ch_switching_req to peer STA.
  10752. issue_nulldata(padapter, NULL, 1, 0, 0);
  10753. ptdls_sta->tdls_sta_state |= TDLS_CH_SW_INITIATOR_STATE;
  10754. issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr);
  10755. DBG_871X("issue tdls ch switch req\n");
  10756. }
  10757. }
  10758. break;
  10759. case TDLS_OFF_CH:
  10760. issue_nulldata(padapter, NULL, 1, 0, 0);
  10761. SelectChannel(padapter, ptdls_sta->off_ch);
  10762. DBG_871X("change channel to tar ch:%02x\n", ptdls_sta->off_ch);
  10763. ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
  10764. ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE);
  10765. _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
  10766. break;
  10767. case TDLS_BASE_CH:
  10768. _cancel_timer_ex(&ptdls_sta->base_ch_timer);
  10769. _cancel_timer_ex(&ptdls_sta->off_ch_timer);
  10770. SelectChannel(padapter, pmlmeext->cur_channel);
  10771. ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
  10772. TDLS_PEER_AT_OFF_STATE |
  10773. TDLS_AT_OFF_CH_STATE);
  10774. DBG_871X("go back to base channel\n ");
  10775. issue_nulldata(padapter, NULL, 0, 0, 0);
  10776. _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
  10777. break;
  10778. case TDLS_P_OFF_CH:
  10779. SelectChannel(padapter, pmlmeext->cur_channel);
  10780. issue_nulldata(padapter, NULL, 0, 0, 0);
  10781. DBG_871X("change channel to base ch:%02x\n", pmlmeext->cur_channel);
  10782. ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE| TDLS_AT_OFF_CH_STATE);
  10783. _set_timer(&ptdls_sta->off_ch_timer, TDLS_STAY_TIME);
  10784. break;
  10785. case TDLS_P_BASE_CH:
  10786. issue_nulldata(ptdls_sta->padapter, NULL, 1, 0, 0);
  10787. SelectChannel(padapter, ptdls_sta->off_ch);
  10788. DBG_871X("change channel to off ch:%02x\n", ptdls_sta->off_ch);
  10789. ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
  10790. if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE){
  10791. issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
  10792. }
  10793. _set_timer(&ptdls_sta->base_ch_timer, TDLS_STAY_TIME);
  10794. break;
  10795. case TDLS_RS_RCR:
  10796. rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
  10797. DBG_871X("wirte REG_RCR, set bit6 on\n");
  10798. break;
  10799. case TDLS_CKALV_PH1:
  10800. _set_timer(&ptdls_sta->alive_timer2, TDLS_ALIVE_TIMER_PH2);
  10801. break;
  10802. case TDLS_CKALV_PH2:
  10803. _set_timer(&ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
  10804. break;
  10805. case TDLS_FREE_STA:
  10806. free_tdls_sta(padapter, ptdls_sta);
  10807. break;
  10808. }
  10809. //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
  10810. return H2C_SUCCESS;
  10811. #else
  10812. return H2C_REJECTED;
  10813. #endif //CONFIG_TDLS
  10814. }