123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143 |
- /*
- * Linux cfg80211 driver - Android related functions
- *
- * Copyright (C) 1999-2014, Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- *
- * As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module. An independent module is a module which is not
- * derived from this software. The special exception does not apply to any
- * modifications of the software.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- * $Id: wl_android.c 517113 2014-11-24 06:29:50Z $
- */
- #include <linux/module.h>
- #include <linux/netdevice.h>
- #include <net/netlink.h>
- #ifdef CONFIG_COMPAT
- #include <linux/compat.h>
- #endif
- #include <wl_android.h>
- #include <wldev_common.h>
- #include <wlioctl.h>
- #include <bcmutils.h>
- #include <linux_osl.h>
- #include <dhd_dbg.h>
- #include <dngl_stats.h>
- #include <dhd.h>
- #include <proto/bcmip.h>
- #ifdef PNO_SUPPORT
- #include <dhd_pno.h>
- #endif
- #include <bcmsdbus.h>
- #ifdef WL_CFG80211
- #include <wl_cfg80211.h>
- #endif
- /*
- * Android private command strings, PLEASE define new private commands here
- * so they can be updated easily in the future (if needed)
- */
- #define CMD_START "START"
- #define CMD_STOP "STOP"
- #define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
- #define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
- #define CMD_RSSI "RSSI"
- #define CMD_LINKSPEED "LINKSPEED"
- #define CMD_RXFILTER_START "RXFILTER-START"
- #define CMD_RXFILTER_STOP "RXFILTER-STOP"
- #define CMD_RXFILTER_ADD "RXFILTER-ADD"
- #define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
- #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
- #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
- #define CMD_BTCOEXMODE "BTCOEXMODE"
- #define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
- #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
- #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
- #define CMD_SETFWPATH "SETFWPATH"
- #define CMD_SETBAND "SETBAND"
- #define CMD_GETBAND "GETBAND"
- #define CMD_COUNTRY "COUNTRY"
- #define CMD_P2P_SET_NOA "P2P_SET_NOA"
- #if !defined WL_ENABLE_P2P_IF
- #define CMD_P2P_GET_NOA "P2P_GET_NOA"
- #endif /* WL_ENABLE_P2P_IF */
- #define CMD_P2P_SD_OFFLOAD "P2P_SD_"
- #define CMD_P2P_SET_PS "P2P_SET_PS"
- #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
- #define CMD_SETROAMMODE "SETROAMMODE"
- #define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA"
- #define CMD_MIRACAST "MIRACAST"
- #if defined(WL_SUPPORT_AUTO_CHANNEL)
- #define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS"
- #endif /* WL_SUPPORT_AUTO_CHANNEL */
- #ifdef CUSTOMER_HW4
- #ifdef WL_SUPPORT_AUTO_CHANNEL
- #define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
- #endif /* WL_SUPPORT_AUTO_CHANNEL */
- #ifdef SUPPORT_HIDDEN_AP
- /* Hostapd private command */
- #define CMD_SET_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA"
- #define CMD_SET_HAPD_SSID "HAPD_SSID"
- #define CMD_SET_HAPD_HIDE_SSID "HAPD_HIDE_SSID"
- #endif /* SUPPORT_HIDDEN_AP */
- #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
- #define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC"
- #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
- #ifdef SUPPORT_SET_LPC
- #define CMD_HAPD_LPC_ENABLED "HAPD_LPC_ENABLED"
- #endif /* SUPPORT_SET_LPC */
- #ifdef SUPPORT_TRIGGER_HANG_EVENT
- #define CMD_TEST_FORCE_HANG "TEST_FORCE_HANG"
- #endif /* SUPPORT_TRIGGER_HANG_EVENT */
- #ifdef SUPPORT_LTECX
- #define CMD_LTECX_SET "LTECOEX"
- #endif /* SUPPORT_LTECX */
- #ifdef TEST_TX_POWER_CONTROL
- #define CMD_TEST_SET_TX_POWER "TEST_SET_TX_POWER"
- #define CMD_TEST_GET_TX_POWER "TEST_GET_TX_POWER"
- #endif /* TEST_TX_POWER_CONTROL */
- #ifdef TX_POWER_CONTROL_CALLING
- #define CMD_SET_TX_POWER_CALLING "SET_TX_POWER_CALLING"
- #endif /* TX_POWER_CONTROL_CALLING */
- #ifdef SARLIMIT_TX_CONTROL_NVRAM
- #define CMD_SARLIMIT_TX_CONTROL "SET_TX_POWER_CALLING"
- #endif /* SARLIMIT_TX_CONTROL_NVRAM */
- #endif /* CUSTOMER_HW4 */
- #ifdef WLFBT
- #define CMD_GET_FTKEY "GET_FTKEY"
- #endif
- #define CMD_KEEP_ALIVE "KEEPALIVE"
- /* CCX Private Commands */
- #ifdef BCMCCX
- #define CMD_GETCCKM_RN "get cckm_rn"
- #define CMD_SETCCKM_KRK "set cckm_krk"
- #define CMD_GET_ASSOC_RES_IES "get assoc_res_ies"
- #endif
- #ifdef PNO_SUPPORT
- #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR"
- #define CMD_PNOSETUP_SET "PNOSETUP "
- #define CMD_PNOENABLE_SET "PNOFORCE"
- #define CMD_PNODEBUG_SET "PNODEBUG"
- #define CMD_WLS_BATCHING "WLS_BATCHING"
- #endif /* PNO_SUPPORT */
- #define CMD_OKC_SET_PMK "SET_PMK"
- #define CMD_OKC_ENABLE "OKC_ENABLE"
- #define CMD_HAPD_MAC_FILTER "HAPD_MAC_FILTER"
- #ifdef CUSTOMER_HW4
- #ifdef ROAM_API
- #define CMD_ROAMTRIGGER_SET "SETROAMTRIGGER"
- #define CMD_ROAMTRIGGER_GET "GETROAMTRIGGER"
- #define CMD_ROAMDELTA_SET "SETROAMDELTA"
- #define CMD_ROAMDELTA_GET "GETROAMDELTA"
- #define CMD_ROAMSCANPERIOD_SET "SETROAMSCANPERIOD"
- #define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD"
- #define CMD_FULLROAMSCANPERIOD_SET "SETFULLROAMSCANPERIOD"
- #define CMD_FULLROAMSCANPERIOD_GET "GETFULLROAMSCANPERIOD"
- #define CMD_COUNTRYREV_SET "SETCOUNTRYREV"
- #define CMD_COUNTRYREV_GET "GETCOUNTRYREV"
- #endif /* ROAM_API */
- #ifdef WES_SUPPORT
- #define CMD_GETROAMSCANCONTROL "GETROAMSCANCONTROL"
- #define CMD_SETROAMSCANCONTROL "SETROAMSCANCONTROL"
- #define CMD_GETROAMSCANCHANNELS "GETROAMSCANCHANNELS"
- #define CMD_SETROAMSCANCHANNELS "SETROAMSCANCHANNELS"
- #define CMD_GETSCANCHANNELTIME "GETSCANCHANNELTIME"
- #define CMD_SETSCANCHANNELTIME "SETSCANCHANNELTIME"
- #define CMD_GETSCANHOMETIME "GETSCANHOMETIME"
- #define CMD_SETSCANHOMETIME "SETSCANHOMETIME"
- #define CMD_GETSCANHOMEAWAYTIME "GETSCANHOMEAWAYTIME"
- #define CMD_SETSCANHOMEAWAYTIME "SETSCANHOMEAWAYTIME"
- #define CMD_GETSCANNPROBES "GETSCANNPROBES"
- #define CMD_SETSCANNPROBES "SETSCANNPROBES"
- #define CMD_GETDFSSCANMODE "GETDFSSCANMODE"
- #define CMD_SETDFSSCANMODE "SETDFSSCANMODE"
- #define CMD_SENDACTIONFRAME "SENDACTIONFRAME"
- #define CMD_REASSOC "REASSOC"
- #define CMD_GETWESMODE "GETWESMODE"
- #define CMD_SETWESMODE "SETWESMODE"
- #define CMD_GETOKCMODE "GETOKCMODE"
- #define CMD_SETOKCMODE "SETOKCMODE"
- #define ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS 100
- typedef struct android_wifi_reassoc_params {
- unsigned char bssid[18];
- int channel;
- } android_wifi_reassoc_params_t;
- #define ANDROID_WIFI_REASSOC_PARAMS_SIZE sizeof(struct android_wifi_reassoc_params)
- #define ANDROID_WIFI_ACTION_FRAME_SIZE 1040
- typedef struct android_wifi_af_params {
- unsigned char bssid[18];
- int channel;
- int dwell_time;
- int len;
- unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE];
- } android_wifi_af_params_t;
- #define ANDROID_WIFI_AF_PARAMS_SIZE sizeof(struct android_wifi_af_params)
- #endif /* WES_SUPPORT */
- #ifdef SUPPORT_AMPDU_MPDU_CMD
- #define CMD_AMPDU_MPDU "AMPDU_MPDU"
- #endif /* SUPPORT_AMPDU_MPDU_CMD */
- #define CMD_CHANGE_RL "CHANGE_RL"
- #define CMD_RESTORE_RL "RESTORE_RL"
- #define CMD_SET_RMC_ENABLE "SETRMCENABLE"
- #define CMD_SET_RMC_TXRATE "SETRMCTXRATE"
- #define CMD_SET_RMC_ACTPERIOD "SETRMCACTIONPERIOD"
- #define CMD_SET_RMC_IDLEPERIOD "SETRMCIDLEPERIOD"
- #define CMD_SET_RMC_LEADER "SETRMCLEADER"
- #define CMD_SET_RMC_EVENT "SETRMCEVENT"
- #define CMD_SET_SCSCAN "SETSINGLEANT"
- #define CMD_GET_SCSCAN "GETSINGLEANT"
- #endif /* CUSTOMER_HW4 */
- #ifdef WLAIBSS
- #define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT"
- #define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO"
- #define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL"
- #define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE"
- #define CMD_SETIBSSAMPDU "SETIBSSAMPDU"
- #define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE"
- #endif /* WLAIBSS */
- #define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD"
- /* miracast related definition */
- #define MIRACAST_MODE_OFF 0
- #define MIRACAST_MODE_SOURCE 1
- #define MIRACAST_MODE_SINK 2
- #ifndef MIRACAST_AMPDU_SIZE
- #define MIRACAST_AMPDU_SIZE 8
- #endif
- #ifndef MIRACAST_MCHAN_ALGO
- #define MIRACAST_MCHAN_ALGO 1
- #endif
- #ifndef MIRACAST_MCHAN_BW
- #define MIRACAST_MCHAN_BW 25
- #endif
- #ifdef CONNECTION_STATISTICS
- #define CMD_GET_CONNECTION_STATS "GET_CONNECTION_STATS"
- struct connection_stats {
- u32 txframe;
- u32 txbyte;
- u32 txerror;
- u32 rxframe;
- u32 rxbyte;
- u32 txfail;
- u32 txretry;
- u32 txretrie;
- u32 txrts;
- u32 txnocts;
- u32 txexptime;
- u32 txrate;
- u8 chan_idle;
- };
- #endif /* CONNECTION_STATISTICS */
- static LIST_HEAD(miracast_resume_list);
- static u8 miracast_cur_mode;
- struct io_cfg {
- s8 *iovar;
- s32 param;
- u32 ioctl;
- void *arg;
- u32 len;
- struct list_head list;
- };
- typedef struct _android_wifi_priv_cmd {
- char *buf;
- int used_len;
- int total_len;
- } android_wifi_priv_cmd;
- #ifdef CONFIG_COMPAT
- typedef struct _compat_android_wifi_priv_cmd {
- compat_caddr_t buf;
- int used_len;
- int total_len;
- } compat_android_wifi_priv_cmd;
- #endif /* CONFIG_COMPAT */
- #if defined(BCMFW_ROAM_ENABLE)
- #define CMD_SET_ROAMPREF "SET_ROAMPREF"
- #define MAX_NUM_SUITES 10
- #define WIDTH_AKM_SUITE 8
- #define JOIN_PREF_RSSI_LEN 0x02
- #define JOIN_PREF_RSSI_SIZE 4 /* RSSI pref header size in bytes */
- #define JOIN_PREF_WPA_HDR_SIZE 4 /* WPA pref header size in bytes */
- #define JOIN_PREF_WPA_TUPLE_SIZE 12 /* Tuple size in bytes */
- #define JOIN_PREF_MAX_WPA_TUPLES 16
- #define MAX_BUF_SIZE (JOIN_PREF_RSSI_SIZE + JOIN_PREF_WPA_HDR_SIZE + \
- (JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES))
- #endif /* BCMFW_ROAM_ENABLE */
- #ifdef WL_GENL
- static s32 wl_genl_handle_msg(struct sk_buff *skb, struct genl_info *info);
- static int wl_genl_init(void);
- static int wl_genl_deinit(void);
- extern struct net init_net;
- /* attribute policy: defines which attribute has which type (e.g int, char * etc)
- * possible values defined in net/netlink.h
- */
- static struct nla_policy wl_genl_policy[BCM_GENL_ATTR_MAX + 1] = {
- [BCM_GENL_ATTR_STRING] = { .type = NLA_NUL_STRING },
- [BCM_GENL_ATTR_MSG] = { .type = NLA_BINARY },
- };
- #define WL_GENL_VER 1
- /* family definition */
- static struct genl_family wl_genl_family = {
- .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */
- .hdrsize = 0,
- .name = "bcm-genl", /* Netlink I/F for Android */
- .version = WL_GENL_VER, /* Version Number */
- .maxattr = BCM_GENL_ATTR_MAX,
- };
- /* commands: mapping between the command enumeration and the actual function */
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
- struct genl_ops wl_genl_ops[] = {
- {
- .cmd = BCM_GENL_CMD_MSG,
- .flags = 0,
- .policy = wl_genl_policy,
- .doit = wl_genl_handle_msg,
- .dumpit = NULL,
- },
- };
- #else
- struct genl_ops wl_genl_ops = {
- .cmd = BCM_GENL_CMD_MSG,
- .flags = 0,
- .policy = wl_genl_policy,
- .doit = wl_genl_handle_msg,
- .dumpit = NULL,
- };
- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
- static struct genl_multicast_group wl_genl_mcast[] = {
- { .name = "bcm-genl-mcast", },
- };
- #else
- static struct genl_multicast_group wl_genl_mcast = {
- .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */
- .name = "bcm-genl-mcast",
- };
- #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
- #endif /* WL_GENL */
- /**
- * Extern function declarations (TODO: move them to dhd_linux.h)
- */
- int dhd_net_bus_devreset(struct net_device *dev, uint8 flag);
- int dhd_dev_init_ioctl(struct net_device *dev);
- #ifdef WL_CFG80211
- int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
- int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *command);
- #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
- int wl_cfg80211_set_wes_mode(int mode);
- int wl_cfg80211_get_wes_mode(void);
- #endif
- #else
- int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
- { return 0; }
- int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
- { return 0; }
- int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
- { return 0; }
- int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
- { return 0; }
- #endif /* WK_CFG80211 */
- #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
- /* wl_roam.c */
- extern int get_roamscan_mode(struct net_device *dev, int *mode);
- extern int set_roamscan_mode(struct net_device *dev, int mode);
- extern int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[]);
- extern int set_roamscan_channel_list(struct net_device *dev, unsigned char n,
- unsigned char channels[], int ioctl_ver);
- #endif
- #if defined(CUSTOMER_HW4) && defined(ROAM_CHANNEL_CACHE)
- extern void wl_update_roamscan_cache_by_band(struct net_device *dev, int band);
- #endif
- #ifdef ENABLE_4335BT_WAR
- extern int bcm_bt_lock(int cookie);
- extern void bcm_bt_unlock(int cookie);
- static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "WiFi" */
- #endif /* ENABLE_4335BT_WAR */
- extern bool ap_fw_loaded;
- #if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4)
- extern char iface_name[IFNAMSIZ];
- #endif /* CUSTOMER_HW2 || CUSTOMER_HW4 */
- /**
- * Local (static) functions and variables
- */
- /* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
- * time (only) in dhd_open, subsequential wifi on will be handled by
- * wl_android_wifi_on
- */
- static int g_wifi_on = TRUE;
- /**
- * Local (static) function definitions
- */
- static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len)
- {
- int link_speed;
- int bytes_written;
- int error;
- error = wldev_get_link_speed(net, &link_speed);
- if (error)
- return -1;
- /* Convert Kbps to Android Mbps */
- link_speed = link_speed / 1000;
- bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
- DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
- return bytes_written;
- }
- static int wl_android_get_rssi(struct net_device *net, char *command, int total_len)
- {
- wlc_ssid_t ssid = {0};
- int rssi;
- int bytes_written = 0;
- int error;
- error = wldev_get_rssi(net, &rssi);
- if (error)
- return -1;
- error = wldev_get_ssid(net, &ssid);
- if (error)
- return -1;
- if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) {
- DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__));
- } else {
- memcpy(command, ssid.SSID, ssid.SSID_len);
- bytes_written = ssid.SSID_len;
- }
- bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi);
- DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written));
- return bytes_written;
- }
- static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len)
- {
- int suspend_flag;
- int ret_now;
- int ret = 0;
- #ifdef CUSTOMER_HW4
- if (!dhd_download_fw_on_driverload) {
- #endif /* CUSTOMER_HW4 */
- suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0';
- if (suspend_flag != 0)
- suspend_flag = 1;
- ret_now = net_os_set_suspend_disable(dev, suspend_flag);
- if (ret_now != suspend_flag) {
- if (!(ret = net_os_set_suspend(dev, ret_now, 1)))
- DHD_INFO(("%s: Suspend Flag %d -> %d\n",
- __FUNCTION__, ret_now, suspend_flag));
- else
- DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
- }
- #ifdef CUSTOMER_HW4
- }
- #endif /* CUSTOMER_HW4 */
- return ret;
- }
- static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len)
- {
- int ret = 0;
- #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND)
- int suspend_flag;
- suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0';
- if (suspend_flag != 0)
- suspend_flag = 1;
- if (!(ret = net_os_set_suspend(dev, suspend_flag, 0)))
- DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__, suspend_flag));
- else
- DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
- #endif
- return ret;
- }
- static int wl_android_get_band(struct net_device *dev, char *command, int total_len)
- {
- uint band;
- int bytes_written;
- int error;
- error = wldev_get_band(dev, &band);
- if (error)
- return -1;
- bytes_written = snprintf(command, total_len, "Band %d", band);
- return bytes_written;
- }
- #ifdef CUSTOMER_HW4
- #ifdef ROAM_API
- int wl_android_set_roam_trigger(
- struct net_device *dev, char* command, int total_len)
- {
- int roam_trigger[2];
- sscanf(command, "%*s %10d", &roam_trigger[0]);
- roam_trigger[1] = WLC_BAND_ALL;
- return wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
- sizeof(roam_trigger), 1);
- }
- static int wl_android_get_roam_trigger(
- struct net_device *dev, char *command, int total_len)
- {
- int bytes_written;
- int roam_trigger[2] = {0, 0};
- roam_trigger[1] = WLC_BAND_2G;
- if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
- sizeof(roam_trigger), 0)) {
- roam_trigger[1] = WLC_BAND_5G;
- if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
- sizeof(roam_trigger), 0))
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d",
- CMD_ROAMTRIGGER_GET, roam_trigger[0]);
- return bytes_written;
- }
- int wl_android_set_roam_delta(
- struct net_device *dev, char* command, int total_len)
- {
- int roam_delta[2];
- sscanf(command, "%*s %10d", &roam_delta[0]);
- roam_delta[1] = WLC_BAND_ALL;
- return wldev_ioctl(dev, WLC_SET_ROAM_DELTA, roam_delta,
- sizeof(roam_delta), 1);
- }
- static int wl_android_get_roam_delta(
- struct net_device *dev, char *command, int total_len)
- {
- int bytes_written;
- int roam_delta[2] = {0, 0};
- roam_delta[1] = WLC_BAND_2G;
- if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
- sizeof(roam_delta), 0)) {
- roam_delta[1] = WLC_BAND_5G;
- if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
- sizeof(roam_delta), 0))
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d",
- CMD_ROAMDELTA_GET, roam_delta[0]);
- return bytes_written;
- }
- int wl_android_set_roam_scan_period(
- struct net_device *dev, char* command, int total_len)
- {
- int roam_scan_period = 0;
- sscanf(command, "%*s %10d", &roam_scan_period);
- return wldev_ioctl(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period,
- sizeof(roam_scan_period), 1);
- }
- static int wl_android_get_roam_scan_period(
- struct net_device *dev, char *command, int total_len)
- {
- int bytes_written;
- int roam_scan_period = 0;
- if (wldev_ioctl(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period,
- sizeof(roam_scan_period), 0))
- return -1;
- bytes_written = snprintf(command, total_len, "%s %d",
- CMD_ROAMSCANPERIOD_GET, roam_scan_period);
- return bytes_written;
- }
- int wl_android_set_full_roam_scan_period(
- struct net_device *dev, char* command, int total_len)
- {
- int error = 0;
- int full_roam_scan_period = 0;
- char smbuf[WLC_IOCTL_SMLEN];
- sscanf(command+sizeof("SETFULLROAMSCANPERIOD"), "%d", &full_roam_scan_period);
- WL_TRACE(("fullroamperiod = %d\n", full_roam_scan_period));
- error = wldev_iovar_setbuf(dev, "fullroamperiod", &full_roam_scan_period,
- sizeof(full_roam_scan_period), smbuf, sizeof(smbuf), NULL);
- if (error) {
- DHD_ERROR(("Failed to set full roam scan period, error = %d\n", error));
- }
- return error;
- }
- static int wl_android_get_full_roam_scan_period(
- struct net_device *dev, char *command, int total_len)
- {
- int error;
- int bytes_written;
- int full_roam_scan_period = 0;
- error = wldev_iovar_getint(dev, "fullroamperiod", &full_roam_scan_period);
- if (error) {
- DHD_ERROR(("%s: get full roam scan period failed code %d\n",
- __func__, error));
- return -1;
- } else {
- DHD_INFO(("%s: get full roam scan period %d\n", __func__, full_roam_scan_period));
- }
- bytes_written = snprintf(command, total_len, "%s %d",
- CMD_FULLROAMSCANPERIOD_GET, full_roam_scan_period);
- return bytes_written;
- }
- int wl_android_set_country_rev(
- struct net_device *dev, char* command, int total_len)
- {
- int error = 0;
- wl_country_t cspec = {{0}, 0, {0} };
- char country_code[WLC_CNTRY_BUF_SZ];
- char smbuf[WLC_IOCTL_SMLEN];
- int rev = 0;
- memset(country_code, 0, sizeof(country_code));
- sscanf(command+sizeof("SETCOUNTRYREV"), "%3s %10d", country_code, &rev);
- WL_TRACE(("country_code = %s, rev = %d\n", country_code, rev));
- memcpy(cspec.country_abbrev, country_code, sizeof(country_code));
- memcpy(cspec.ccode, country_code, sizeof(country_code));
- cspec.rev = rev;
- error = wldev_iovar_setbuf(dev, "country", (char *)&cspec,
- sizeof(cspec), smbuf, sizeof(smbuf), NULL);
- if (error) {
- DHD_ERROR(("%s: set country '%s/%d' failed code %d\n",
- __FUNCTION__, cspec.ccode, cspec.rev, error));
- } else {
- dhd_bus_country_set(dev, &cspec, true);
- DHD_INFO(("%s: set country '%s/%d'\n",
- __FUNCTION__, cspec.ccode, cspec.rev));
- }
- return error;
- }
- static int wl_android_get_country_rev(
- struct net_device *dev, char *command, int total_len)
- {
- int error;
- int bytes_written;
- char smbuf[WLC_IOCTL_SMLEN];
- wl_country_t cspec;
- error = wldev_iovar_getbuf(dev, "country", NULL, 0, smbuf,
- sizeof(smbuf), NULL);
- if (error) {
- DHD_ERROR(("%s: get country failed code %d\n",
- __FUNCTION__, error));
- return -1;
- } else {
- memcpy(&cspec, smbuf, sizeof(cspec));
- DHD_INFO(("%s: get country '%c%c %d'\n",
- __FUNCTION__, cspec.ccode[0], cspec.ccode[1], cspec.rev));
- }
- bytes_written = snprintf(command, total_len, "%s %c%c %d",
- CMD_COUNTRYREV_GET, cspec.ccode[0], cspec.ccode[1], cspec.rev);
- return bytes_written;
- }
- #endif /* ROAM_API */
- #ifdef WES_SUPPORT
- int wl_android_get_roam_scan_control(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int mode = 0;
- error = get_roamscan_mode(dev, &mode);
- if (error) {
- DHD_ERROR(("%s: Failed to get Scan Control, error = %d\n", __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETROAMSCANCONTROL, mode);
- return bytes_written;
- }
- int wl_android_set_roam_scan_control(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = set_roamscan_mode(dev, mode);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Control %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_roam_scan_channels(struct net_device *dev, char *command, int total_len)
- {
- int bytes_written = 0;
- unsigned char channels[ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS] = {0};
- int channel_cnt = 0;
- char channel_info[10 + (ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS * 3)] = {0};
- int channel_info_len = 0;
- int i = 0;
- channel_cnt = get_roamscan_channel_list(dev, channels);
- channel_info_len += sprintf(&channel_info[channel_info_len], "%d ", channel_cnt);
- for (i = 0; i < channel_cnt; i++) {
- channel_info_len += sprintf(&channel_info[channel_info_len], "%d ", channels[i]);
- if (channel_info_len > (sizeof(channel_info) - 10))
- break;
- }
- channel_info_len += sprintf(&channel_info[channel_info_len], "%s", "\0");
- bytes_written = snprintf(command, total_len, "%s %s",
- CMD_GETROAMSCANCHANNELS, channel_info);
- return bytes_written;
- }
- int wl_android_set_roam_scan_channels(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- unsigned char *p = (unsigned char *)(command + strlen(CMD_SETROAMSCANCHANNELS) + 1);
- int ioctl_version = wl_cfg80211_get_ioctl_version();
- error = set_roamscan_channel_list(dev, p[0], &p[1], ioctl_version);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Channels %d, error = %d\n",
- __FUNCTION__, p[0], error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_scan_channel_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int time = 0;
- error = wldev_ioctl(dev, WLC_GET_SCAN_CHANNEL_TIME, &time, sizeof(time), 0);
- if (error) {
- DHD_ERROR(("%s: Failed to get Scan Channel Time, error = %d\n",
- __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANCHANNELTIME, time);
- return bytes_written;
- }
- int wl_android_set_scan_channel_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int time = 0;
- if (sscanf(command, "%*s %d", &time) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_ioctl(dev, WLC_SET_SCAN_CHANNEL_TIME, &time, sizeof(time), 1);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Channel Time %d, error = %d\n",
- __FUNCTION__, time, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_scan_home_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int time = 0;
- error = wldev_ioctl(dev, WLC_GET_SCAN_HOME_TIME, &time, sizeof(time), 0);
- if (error) {
- DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMETIME, time);
- return bytes_written;
- }
- int wl_android_set_scan_home_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int time = 0;
- if (sscanf(command, "%*s %d", &time) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_ioctl(dev, WLC_SET_SCAN_HOME_TIME, &time, sizeof(time), 1);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Home Time %d, error = %d\n",
- __FUNCTION__, time, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_scan_home_away_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int time = 0;
- error = wldev_iovar_getint(dev, "scan_home_away_time", &time);
- if (error) {
- DHD_ERROR(("%s: Failed to get Scan Home Away Time, error = %d\n",
- __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMEAWAYTIME, time);
- return bytes_written;
- }
- int wl_android_set_scan_home_away_time(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int time = 0;
- if (sscanf(command, "%*s %d", &time) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_iovar_setint(dev, "scan_home_away_time", time);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Home Away Time %d, error = %d\n",
- __FUNCTION__, time, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_scan_nprobes(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int num = 0;
- error = wldev_ioctl(dev, WLC_GET_SCAN_NPROBES, &num, sizeof(num), 0);
- if (error) {
- DHD_ERROR(("%s: Failed to get Scan NProbes, error = %d\n", __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANNPROBES, num);
- return bytes_written;
- }
- int wl_android_set_scan_nprobes(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int num = 0;
- if (sscanf(command, "%*s %d", &num) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_ioctl(dev, WLC_SET_SCAN_NPROBES, &num, sizeof(num), 1);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan NProbes %d, error = %d\n",
- __FUNCTION__, num, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_scan_dfs_channel_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int mode = 0;
- int scan_passive_time = 0;
- error = wldev_iovar_getint(dev, "scan_passive_time", &scan_passive_time);
- if (error) {
- DHD_ERROR(("%s: Failed to get Passive Time, error = %d\n", __FUNCTION__, error));
- return -1;
- }
- if (scan_passive_time == 0) {
- mode = 0;
- } else {
- mode = 1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETDFSSCANMODE, mode);
- return bytes_written;
- }
- int wl_android_set_scan_dfs_channel_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- int scan_passive_time = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- if (mode == 1) {
- scan_passive_time = DHD_SCAN_PASSIVE_TIME;
- } else if (mode == 0) {
- scan_passive_time = 0;
- } else {
- DHD_ERROR(("%s: Failed to set Scan DFS channel mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- error = wldev_iovar_setint(dev, "scan_passive_time", scan_passive_time);
- if (error) {
- DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
- __FUNCTION__, scan_passive_time, error));
- return -1;
- }
- return 0;
- }
- int wl_android_send_action_frame(struct net_device *dev, char *command, int total_len)
- {
- int error = -1;
- android_wifi_af_params_t *params = NULL;
- wl_action_frame_t *action_frame = NULL;
- wl_af_params_t *af_params = NULL;
- char *smbuf = NULL;
- struct ether_addr tmp_bssid;
- int tmp_channel = 0;
- params = (android_wifi_af_params_t *)(command + strlen(CMD_SENDACTIONFRAME) + 1);
- if (params == NULL) {
- DHD_ERROR(("%s: Invalid params \n", __FUNCTION__));
- goto send_action_frame_out;
- }
- if (params->len > ANDROID_WIFI_ACTION_FRAME_SIZE) {
- DHD_ERROR(("%s: Requested action frame len was out of range(%d)\n",
- __FUNCTION__, params->len));
- goto send_action_frame_out;
- }
- smbuf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
- if (smbuf == NULL) {
- DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
- __FUNCTION__, WLC_IOCTL_MAXLEN));
- goto send_action_frame_out;
- }
- af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
- if (af_params == NULL)
- {
- DHD_ERROR(("%s: unable to allocate frame\n", __FUNCTION__));
- goto send_action_frame_out;
- }
- memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
- if (bcm_ether_atoe((const char *)params->bssid, (struct ether_addr *)&tmp_bssid) == 0) {
- memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
- error = wldev_ioctl(dev, WLC_GET_BSSID, &tmp_bssid, ETHER_ADDR_LEN, false);
- if (error) {
- memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
- DHD_ERROR(("%s: failed to get bssid, error=%d\n", __FUNCTION__, error));
- goto send_action_frame_out;
- }
- }
- if (params->channel < 0) {
- struct channel_info ci;
- error = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci), false);
- if (error) {
- DHD_ERROR(("%s: failed to get channel, error=%d\n", __FUNCTION__, error));
- goto send_action_frame_out;
- }
- tmp_channel = ci.hw_channel;
- }
- else {
- tmp_channel = params->channel;
- }
- af_params->channel = tmp_channel;
- af_params->dwell_time = params->dwell_time;
- memcpy(&af_params->BSSID, &tmp_bssid, ETHER_ADDR_LEN);
- action_frame = &af_params->action_frame;
- action_frame->packetId = 0;
- memcpy(&action_frame->da, &tmp_bssid, ETHER_ADDR_LEN);
- action_frame->len = params->len;
- memcpy(action_frame->data, params->data, action_frame->len);
- error = wldev_iovar_setbuf(dev, "actframe", af_params,
- sizeof(wl_af_params_t), smbuf, WLC_IOCTL_MAXLEN, NULL);
- if (error) {
- DHD_ERROR(("%s: failed to set action frame, error=%d\n", __FUNCTION__, error));
- }
- send_action_frame_out:
- if (af_params)
- kfree(af_params);
- if (smbuf)
- kfree(smbuf);
- if (error)
- return -1;
- else
- return 0;
- }
- int wl_android_reassoc(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- android_wifi_reassoc_params_t *params = NULL;
- uint band;
- chanspec_t channel;
- u32 params_size;
- wl_reassoc_params_t reassoc_params;
- params = (android_wifi_reassoc_params_t *)(command + strlen(CMD_REASSOC) + 1);
- if (params == NULL) {
- DHD_ERROR(("%s: Invalid params \n", __FUNCTION__));
- return -1;
- }
- memset(&reassoc_params, 0, WL_REASSOC_PARAMS_FIXED_SIZE);
- if (bcm_ether_atoe((const char *)params->bssid,
- (struct ether_addr *)&reassoc_params.bssid) == 0) {
- DHD_ERROR(("%s: Invalid bssid \n", __FUNCTION__));
- return -1;
- }
- if (params->channel < 0) {
- DHD_ERROR(("%s: Invalid Channel \n", __FUNCTION__));
- return -1;
- }
- reassoc_params.chanspec_num = 1;
- channel = params->channel;
- #ifdef D11AC_IOTYPES
- if (wl_cfg80211_get_ioctl_version() == 1) {
- band = ((channel <= CH_MAX_2G_CHANNEL) ?
- WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G);
- reassoc_params.chanspec_list[0] = channel |
- band | WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE;
- }
- else {
- band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
- reassoc_params.chanspec_list[0] = channel | band | WL_CHANSPEC_BW_20;
- }
- #else
- band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
- reassoc_params.chanspec_list[0] = channel |
- band | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
- #endif /* D11AC_IOTYPES */
- params_size = WL_REASSOC_PARAMS_FIXED_SIZE + sizeof(chanspec_t);
- error = wldev_ioctl(dev, WLC_REASSOC, &reassoc_params, params_size, true);
- if (error) {
- DHD_ERROR(("%s: failed to reassoc, error=%d\n", __FUNCTION__, error));
- }
- if (error)
- return -1;
- else
- return 0;
- }
- int wl_android_get_wes_mode(struct net_device *dev, char *command, int total_len)
- {
- int bytes_written = 0;
- int mode = 0;
- mode = wl_cfg80211_get_wes_mode();
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETWESMODE, mode);
- return bytes_written;
- }
- int wl_android_set_wes_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wl_cfg80211_set_wes_mode(mode);
- if (error) {
- DHD_ERROR(("%s: Failed to set WES Mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- return 0;
- }
- int wl_android_get_okc_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int mode = 0;
- error = wldev_iovar_getint(dev, "okc_enable", &mode);
- if (error) {
- DHD_ERROR(("%s: Failed to get OKC Mode, error = %d\n", __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GETOKCMODE, mode);
- return bytes_written;
- }
- int wl_android_set_okc_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_iovar_setint(dev, "okc_enable", mode);
- if (error) {
- DHD_ERROR(("%s: Failed to set OKC Mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- if (mode)
- wldev_iovar_setint(dev, "ccx_enable", 0);
- return error;
- }
- #endif /* WES_SUPPORT */
- #endif /* CUSTOMER_HW4 */
- #ifdef PNO_SUPPORT
- #define PNO_PARAM_SIZE 50
- #define VALUE_SIZE 50
- #define LIMIT_STR_FMT ("%50s %50s")
- static int
- wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len)
- {
- int err = BCME_OK;
- uint i, tokens;
- char *pos, *pos2, *token, *token2, *delim;
- char param[PNO_PARAM_SIZE+1], value[VALUE_SIZE+1];
- struct dhd_pno_batch_params batch_params;
- DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
- if (total_len < strlen(CMD_WLS_BATCHING)) {
- DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
- err = BCME_ERROR;
- goto exit;
- }
- pos = command + strlen(CMD_WLS_BATCHING) + 1;
- memset(&batch_params, 0, sizeof(struct dhd_pno_batch_params));
- if (!strncmp(pos, PNO_BATCHING_SET, strlen(PNO_BATCHING_SET))) {
- pos += strlen(PNO_BATCHING_SET) + 1;
- while ((token = strsep(&pos, PNO_PARAMS_DELIMETER)) != NULL) {
- memset(param, 0, sizeof(param));
- memset(value, 0, sizeof(value));
- if (token == NULL || !*token)
- break;
- if (*token == '\0')
- continue;
- delim = strchr(token, PNO_PARAM_VALUE_DELLIMETER);
- if (delim != NULL)
- *delim = ' ';
- tokens = sscanf(token, LIMIT_STR_FMT, param, value);
- if (!strncmp(param, PNO_PARAM_SCANFREQ, strlen(PNO_PARAM_SCANFREQ))) {
- batch_params.scan_fr = simple_strtol(value, NULL, 0);
- DHD_PNO(("scan_freq : %d\n", batch_params.scan_fr));
- } else if (!strncmp(param, PNO_PARAM_BESTN, strlen(PNO_PARAM_BESTN))) {
- batch_params.bestn = simple_strtol(value, NULL, 0);
- DHD_PNO(("bestn : %d\n", batch_params.bestn));
- } else if (!strncmp(param, PNO_PARAM_MSCAN, strlen(PNO_PARAM_MSCAN))) {
- batch_params.mscan = simple_strtol(value, NULL, 0);
- DHD_PNO(("mscan : %d\n", batch_params.mscan));
- } else if (!strncmp(param, PNO_PARAM_CHANNEL, strlen(PNO_PARAM_CHANNEL))) {
- i = 0;
- pos2 = value;
- tokens = sscanf(value, "<%s>", value);
- if (tokens != 1) {
- err = BCME_ERROR;
- DHD_ERROR(("%s : invalid format for channel"
- " <> params\n", __FUNCTION__));
- goto exit;
- }
- while ((token2 = strsep(&pos2, PNO_PARAM_CHANNEL_DELIMETER))
- != NULL) {
- if (token2 == NULL || !*token2)
- break;
- if (*token2 == '\0')
- continue;
- if (*token2 == 'A' || *token2 == 'B') {
- batch_params.band = (*token2 == 'A')?
- WLC_BAND_5G : WLC_BAND_2G;
- DHD_PNO(("band : %s\n",
- (*token2 == 'A')? "A" : "B"));
- } else {
- if ((batch_params.nchan >= WL_NUMCHANNELS) ||
- (i >= WL_NUMCHANNELS)) {
- DHD_ERROR(("Too many nchan %d\n",
- batch_params.nchan));
- err = BCME_BUFTOOSHORT;
- goto exit;
- }
- batch_params.chan_list[i++] =
- simple_strtol(token2, NULL, 0);
- batch_params.nchan++;
- DHD_PNO(("channel :%d\n",
- batch_params.chan_list[i-1]));
- }
- }
- } else if (!strncmp(param, PNO_PARAM_RTT, strlen(PNO_PARAM_RTT))) {
- batch_params.rtt = simple_strtol(value, NULL, 0);
- DHD_PNO(("rtt : %d\n", batch_params.rtt));
- } else {
- DHD_ERROR(("%s : unknown param: %s\n", __FUNCTION__, param));
- err = BCME_ERROR;
- goto exit;
- }
- }
- err = dhd_dev_pno_set_for_batch(dev, &batch_params);
- if (err < 0) {
- DHD_ERROR(("failed to configure batch scan\n"));
- } else {
- memset(command, 0, total_len);
- err = sprintf(command, "%d", err);
- }
- } else if (!strncmp(pos, PNO_BATCHING_GET, strlen(PNO_BATCHING_GET))) {
- err = dhd_dev_pno_get_for_batch(dev, command, total_len);
- if (err < 0) {
- DHD_ERROR(("failed to getting batching results\n"));
- } else {
- err = strlen(command);
- }
- } else if (!strncmp(pos, PNO_BATCHING_STOP, strlen(PNO_BATCHING_STOP))) {
- err = dhd_dev_pno_stop_for_batch(dev);
- if (err < 0) {
- DHD_ERROR(("failed to stop batching scan\n"));
- } else {
- memset(command, 0, total_len);
- err = sprintf(command, "OK");
- }
- } else {
- DHD_ERROR(("%s : unknown command\n", __FUNCTION__));
- err = BCME_ERROR;
- goto exit;
- }
- exit:
- return err;
- }
- #ifndef WL_SCHED_SCAN
- static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
- {
- wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
- int res = -1;
- int nssid = 0;
- cmd_tlv_t *cmd_tlv_temp;
- char *str_ptr;
- int tlv_size_left;
- int pno_time = 0;
- int pno_repeat = 0;
- int pno_freq_expo_max = 0;
- #ifdef PNO_SET_DEBUG
- int i;
- char pno_in_example[] = {
- 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
- 'S', '1', '2', '0',
- 'S',
- 0x05,
- 'd', 'l', 'i', 'n', 'k',
- 'S',
- 0x04,
- 'G', 'O', 'O', 'G',
- 'T',
- '0', 'B',
- 'R',
- '2',
- 'M',
- '2',
- 0x00
- };
- #endif /* PNO_SET_DEBUG */
- DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
- if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
- DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
- goto exit_proc;
- }
- #ifdef PNO_SET_DEBUG
- memcpy(command, pno_in_example, sizeof(pno_in_example));
- total_len = sizeof(pno_in_example);
- #endif
- str_ptr = command + strlen(CMD_PNOSETUP_SET);
- tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
- cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
- memset(ssids_local, 0, sizeof(ssids_local));
- if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
- (cmd_tlv_temp->version == PNO_TLV_VERSION) &&
- (cmd_tlv_temp->subtype == PNO_TLV_SUBTYPE_LEGACY_PNO)) {
- str_ptr += sizeof(cmd_tlv_t);
- tlv_size_left -= sizeof(cmd_tlv_t);
- if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
- MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
- DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid));
- goto exit_proc;
- } else {
- if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
- DHD_ERROR(("%s scan duration corrupted field size %d\n",
- __FUNCTION__, tlv_size_left));
- goto exit_proc;
- }
- str_ptr++;
- pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
- DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
- if (str_ptr[0] != 0) {
- if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
- DHD_ERROR(("%s pno repeat : corrupted field\n",
- __FUNCTION__));
- goto exit_proc;
- }
- str_ptr++;
- pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
- DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
- if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
- DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
- __FUNCTION__));
- goto exit_proc;
- }
- str_ptr++;
- pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
- DHD_PNO(("%s: pno_freq_expo_max=%d\n",
- __FUNCTION__, pno_freq_expo_max));
- }
- }
- } else {
- DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__));
- goto exit_proc;
- }
- res = dhd_dev_pno_set_for_ssid(dev, ssids_local, nssid, pno_time, pno_repeat,
- pno_freq_expo_max, NULL, 0);
- exit_proc:
- return res;
- }
- #endif /* !WL_SCHED_SCAN */
- #endif /* PNO_SUPPORT */
- static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len)
- {
- int ret;
- int bytes_written = 0;
- ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command);
- if (ret)
- return 0;
- bytes_written = sizeof(struct ether_addr);
- return bytes_written;
- }
- #ifdef BCMCCX
- static int wl_android_get_cckm_rn(struct net_device *dev, char *command)
- {
- int error, rn;
- WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev->name));
- error = wldev_iovar_getint(dev, "cckm_rn", &rn);
- if (unlikely(error)) {
- WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error));
- return -1;
- }
- memcpy(command, &rn, sizeof(int));
- return sizeof(int);
- }
- static int wl_android_set_cckm_krk(struct net_device *dev, char *command)
- {
- int error;
- unsigned char key[16];
- static char iovar_buf[WLC_IOCTL_MEDLEN];
- WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev->name));
- memset(iovar_buf, 0, sizeof(iovar_buf));
- memcpy(key, command+strlen("set cckm_krk")+1, 16);
- error = wldev_iovar_setbuf(dev, "cckm_krk", key, sizeof(key),
- iovar_buf, WLC_IOCTL_MEDLEN, NULL);
- if (unlikely(error))
- {
- WL_ERR((" cckm_krk set error (%d)\n", error));
- return -1;
- }
- return 0;
- }
- static int wl_android_get_assoc_res_ies(struct net_device *dev, char *command)
- {
- int error;
- u8 buf[WL_ASSOC_INFO_MAX];
- wl_assoc_info_t assoc_info;
- u32 resp_ies_len = 0;
- int bytes_written = 0;
- WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev->name));
- error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL);
- if (unlikely(error)) {
- WL_ERR(("could not get assoc info (%d)\n", error));
- return -1;
- }
- memcpy(&assoc_info, buf, sizeof(wl_assoc_info_t));
- assoc_info.req_len = htod32(assoc_info.req_len);
- assoc_info.resp_len = htod32(assoc_info.resp_len);
- assoc_info.flags = htod32(assoc_info.flags);
- if (assoc_info.resp_len) {
- resp_ies_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp);
- }
- /* first 4 bytes are ie len */
- memcpy(command, &resp_ies_len, sizeof(u32));
- bytes_written = sizeof(u32);
- /* get the association resp IE's if there are any */
- if (resp_ies_len) {
- error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0,
- buf, WL_ASSOC_INFO_MAX, NULL);
- if (unlikely(error)) {
- WL_ERR(("could not get assoc resp_ies (%d)\n", error));
- return -1;
- }
- memcpy(command+sizeof(u32), buf, resp_ies_len);
- bytes_written += resp_ies_len;
- }
- return bytes_written;
- }
- #endif /* BCMCCX */
- int
- wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist)
- {
- int i, j, match;
- int ret = 0;
- char mac_buf[MAX_NUM_OF_ASSOCLIST *
- sizeof(struct ether_addr) + sizeof(uint)] = {0};
- struct maclist *assoc_maclist = (struct maclist *)mac_buf;
- /* set filtering mode */
- if ((ret = wldev_ioctl(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode), true)) != 0) {
- DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__, ret));
- return ret;
- }
- if (macmode != MACLIST_MODE_DISABLED) {
- /* set the MAC filter list */
- if ((ret = wldev_ioctl(dev, WLC_SET_MACLIST, maclist,
- sizeof(int) + sizeof(struct ether_addr) * maclist->count, true)) != 0) {
- DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__, ret));
- return ret;
- }
- /* get the current list of associated STAs */
- assoc_maclist->count = MAX_NUM_OF_ASSOCLIST;
- if ((ret = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist,
- sizeof(mac_buf), false)) != 0) {
- DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__, ret));
- return ret;
- }
- /* do we have any STA associated? */
- if (assoc_maclist->count) {
- /* iterate each associated STA */
- for (i = 0; i < assoc_maclist->count; i++) {
- match = 0;
- /* compare with each entry */
- for (j = 0; j < maclist->count; j++) {
- DHD_INFO(("%s : associated="MACDBG " list="MACDBG "\n",
- __FUNCTION__, MAC2STRDBG(assoc_maclist->ea[i].octet),
- MAC2STRDBG(maclist->ea[j].octet)));
- if (memcmp(assoc_maclist->ea[i].octet,
- maclist->ea[j].octet, ETHER_ADDR_LEN) == 0) {
- match = 1;
- break;
- }
- }
- /* do conditional deauth */
- /* "if not in the allow list" or "if in the deny list" */
- if ((macmode == MACLIST_MODE_ALLOW && !match) ||
- (macmode == MACLIST_MODE_DENY && match)) {
- scb_val_t scbval;
- scbval.val = htod32(1);
- memcpy(&scbval.ea, &assoc_maclist->ea[i],
- ETHER_ADDR_LEN);
- if ((ret = wldev_ioctl(dev,
- WLC_SCB_DEAUTHENTICATE_FOR_REASON,
- &scbval, sizeof(scb_val_t), true)) != 0)
- DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n",
- __FUNCTION__, ret));
- }
- }
- }
- }
- return ret;
- }
- /*
- * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2
- *
- */
- static int
- wl_android_set_mac_address_filter(struct net_device *dev, const char* str)
- {
- int i;
- int ret = 0;
- int macnum = 0;
- int macmode = MACLIST_MODE_DISABLED;
- struct maclist *list;
- char eabuf[ETHER_ADDR_STR_LEN];
- /* string should look like below (macmode/macnum/maclist) */
- /* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */
- /* get the MAC filter mode */
- macmode = bcm_atoi(strsep((char**)&str, " "));
- if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) {
- DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__, macmode));
- return -1;
- }
- macnum = bcm_atoi(strsep((char**)&str, " "));
- if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) {
- DHD_ERROR(("%s : invalid number of MAC address entries %d\n",
- __FUNCTION__, macnum));
- return -1;
- }
- /* allocate memory for the MAC list */
- list = (struct maclist*)kmalloc(sizeof(int) +
- sizeof(struct ether_addr) * macnum, GFP_KERNEL);
- if (!list) {
- DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__));
- return -1;
- }
- /* prepare the MAC list */
- list->count = htod32(macnum);
- bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
- for (i = 0; i < list->count; i++) {
- strncpy(eabuf, strsep((char**)&str, " "), ETHER_ADDR_STR_LEN - 1);
- if (!(ret = bcm_ether_atoe(eabuf, &list->ea[i]))) {
- DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n",
- __FUNCTION__, i, eabuf));
- list->count--;
- break;
- }
- DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__, i, list->count, eabuf));
- }
- /* set the list */
- if ((ret = wl_android_set_ap_mac_list(dev, macmode, list)) != 0)
- DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__, ret));
- kfree(list);
- return 0;
- }
- /**
- * Global function definitions (declared in wl_android.h)
- */
- int wl_android_wifi_on(struct net_device *dev)
- {
- int ret = 0;
- int retry = POWERUP_MAX_RETRY;
- DHD_ERROR(("%s in\n", __FUNCTION__));
- if (!dev) {
- DHD_ERROR(("%s: dev is null\n", __FUNCTION__));
- return -EINVAL;
- }
- dhd_net_if_lock(dev);
- if (!g_wifi_on) {
- do {
- dhd_net_wifi_platform_set_power(dev, TRUE, WIFI_TURNON_DELAY);
- ret = dhd_net_bus_resume(dev, 0);
- if (ret == 0)
- break;
- DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
- retry+1));
- dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY);
- } while (retry-- >= 0);
- if (ret != 0) {
- DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n"));
- goto exit;
- }
- ret = dhd_net_bus_devreset(dev, FALSE);
- dhd_net_bus_resume(dev, 1);
- if (!ret) {
- if (dhd_dev_init_ioctl(dev) < 0)
- ret = -EFAULT;
- }
- #if defined(ENABLE_4335BT_WAR) && defined(CUSTOMER_HW4)
- bcm_bt_unlock(lock_cookie_wifi);
- DHD_ERROR(("%s() bcm_bt_unlock\n", __FUNCTION__));
- #endif
- g_wifi_on = TRUE;
- }
- exit:
- dhd_net_if_unlock(dev);
- return ret;
- }
- int wl_android_wifi_off(struct net_device *dev)
- {
- int ret = 0;
- DHD_ERROR(("%s in\n", __FUNCTION__));
- if (!dev) {
- DHD_TRACE(("%s: dev is null\n", __FUNCTION__));
- return -EINVAL;
- }
- dhd_net_if_lock(dev);
- if (g_wifi_on) {
- ret = dhd_net_bus_devreset(dev, TRUE);
- dhd_net_bus_suspend(dev);
- dhd_net_wifi_platform_set_power(dev, FALSE, WIFI_TURNOFF_DELAY);
- g_wifi_on = FALSE;
- }
- dhd_net_if_unlock(dev);
- return ret;
- }
- static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len)
- {
- if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN)
- return -1;
- return dhd_net_set_fw_path(net, command + strlen(CMD_SETFWPATH) + 1);
- }
- #ifdef CONNECTION_STATISTICS
- static int
- wl_chanim_stats(struct net_device *dev, u8 *chan_idle)
- {
- int err;
- wl_chanim_stats_t *list;
- /* Parameter _and_ returned buffer of chanim_stats. */
- wl_chanim_stats_t param;
- u8 result[WLC_IOCTL_SMLEN];
- chanim_stats_t *stats;
- memset(¶m, 0, sizeof(param));
- memset(result, 0, sizeof(result));
- param.buflen = htod32(sizeof(wl_chanim_stats_t));
- param.count = htod32(WL_CHANIM_COUNT_ONE);
- if ((err = wldev_iovar_getbuf(dev, "chanim_stats", (char*)¶m, sizeof(wl_chanim_stats_t),
- (char*)result, sizeof(result), 0)) < 0) {
- WL_ERR(("Failed to get chanim results %d \n", err));
- return err;
- }
- list = (wl_chanim_stats_t*)result;
- list->buflen = dtoh32(list->buflen);
- list->version = dtoh32(list->version);
- list->count = dtoh32(list->count);
- if (list->buflen == 0) {
- list->version = 0;
- list->count = 0;
- } else if (list->version != WL_CHANIM_STATS_VERSION) {
- WL_ERR(("Sorry, firmware has wl_chanim_stats version %d "
- "but driver supports only version %d.\n",
- list->version, WL_CHANIM_STATS_VERSION));
- list->buflen = 0;
- list->count = 0;
- }
- stats = list->stats;
- stats->glitchcnt = dtoh32(stats->glitchcnt);
- stats->badplcp = dtoh32(stats->badplcp);
- stats->chanspec = dtoh16(stats->chanspec);
- stats->timestamp = dtoh32(stats->timestamp);
- stats->chan_idle = dtoh32(stats->chan_idle);
- WL_INFO(("chanspec: 0x%4x glitch: %d badplcp: %d idle: %d timestamp: %d\n",
- stats->chanspec, stats->glitchcnt, stats->badplcp, stats->chan_idle,
- stats->timestamp));
- *chan_idle = stats->chan_idle;
- return (err);
- }
- static int
- wl_android_get_connection_stats(struct net_device *dev, char *command, int total_len)
- {
- wl_cnt_t* cnt = NULL;
- int link_speed = 0;
- struct connection_stats *output;
- unsigned int bufsize = 0;
- int bytes_written = 0;
- int ret = 0;
- WL_INFO(("%s: enter Get Connection Stats\n", __FUNCTION__));
- if (total_len <= 0) {
- WL_ERR(("%s: invalid buffer size %d\n", __FUNCTION__, total_len));
- goto error;
- }
- bufsize = total_len;
- if (bufsize < sizeof(struct connection_stats)) {
- WL_ERR(("%s: not enough buffer size, provided=%u, requires=%u\n",
- __FUNCTION__, bufsize,
- sizeof(struct connection_stats)));
- goto error;
- }
- if ((cnt = kmalloc(sizeof(*cnt), GFP_KERNEL)) == NULL) {
- WL_ERR(("kmalloc failed\n"));
- return -1;
- }
- memset(cnt, 0, sizeof(*cnt));
- ret = wldev_iovar_getbuf(dev, "counters", NULL, 0, (char *)cnt, sizeof(wl_cnt_t), NULL);
- if (ret) {
- WL_ERR(("%s: wldev_iovar_getbuf() failed, ret=%d\n",
- __FUNCTION__, ret));
- goto error;
- }
- if (dtoh16(cnt->version) > WL_CNT_T_VERSION) {
- WL_ERR(("%s: incorrect version of wl_cnt_t, expected=%u got=%u\n",
- __FUNCTION__, WL_CNT_T_VERSION, cnt->version));
- goto error;
- }
- /* link_speed is in kbps */
- ret = wldev_get_link_speed(dev, &link_speed);
- if (ret || link_speed < 0) {
- WL_ERR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n",
- __FUNCTION__, ret, link_speed));
- goto error;
- }
- output = (struct connection_stats *)command;
- output->txframe = dtoh32(cnt->txframe);
- output->txbyte = dtoh32(cnt->txbyte);
- output->txerror = dtoh32(cnt->txerror);
- output->rxframe = dtoh32(cnt->rxframe);
- output->rxbyte = dtoh32(cnt->rxbyte);
- output->txfail = dtoh32(cnt->txfail);
- output->txretry = dtoh32(cnt->txretry);
- output->txretrie = dtoh32(cnt->txretrie);
- output->txrts = dtoh32(cnt->txrts);
- output->txnocts = dtoh32(cnt->txnocts);
- output->txexptime = dtoh32(cnt->txexptime);
- output->txrate = link_speed;
- /* Channel idle ratio. */
- if (wl_chanim_stats(dev, &(output->chan_idle)) < 0) {
- output->chan_idle = 0;
- };
- kfree(cnt);
- bytes_written = sizeof(struct connection_stats);
- return bytes_written;
- error:
- if (cnt) {
- kfree(cnt);
- }
- return -1;
- }
- #endif /* CONNECTION_STATISTICS */
- static int
- wl_android_set_pmk(struct net_device *dev, char *command, int total_len)
- {
- uchar pmk[33];
- int error = 0;
- char smbuf[WLC_IOCTL_SMLEN];
- #ifdef OKC_DEBUG
- int i = 0;
- #endif
- bzero(pmk, sizeof(pmk));
- memcpy((char *)pmk, command + strlen("SET_PMK "), 32);
- error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL);
- if (error) {
- DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error));
- }
- #ifdef OKC_DEBUG
- DHD_ERROR(("PMK is "));
- for (i = 0; i < 32; i++)
- DHD_ERROR(("%02X ", pmk[i]));
- DHD_ERROR(("\n"));
- #endif
- return error;
- }
- static int
- wl_android_okc_enable(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- char okc_enable = 0;
- okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0';
- error = wldev_iovar_setint(dev, "okc_enable", okc_enable);
- if (error) {
- DHD_ERROR(("Failed to %s OKC, error = %d\n",
- okc_enable ? "enable" : "disable", error));
- }
- wldev_iovar_setint(dev, "ccx_enable", 0);
- return error;
- }
- #ifdef CUSTOMER_HW4
- #ifdef SUPPORT_AMPDU_MPDU_CMD
- /* CMD_AMPDU_MPDU */
- static int
- wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num)
- {
- int err = 0;
- int ampdu_mpdu;
- ampdu_mpdu = bcm_atoi(string_num);
- if (ampdu_mpdu > 32) {
- DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__));
- return -1;
- }
- DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__, ampdu_mpdu));
- err = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu);
- if (err < 0) {
- DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__, err));
- return -1;
- }
- return 0;
- }
- #endif /* SUPPORT_AMPDU_MPDU_CMD */
- /* SoftAP feature */
- #if defined(WL_SUPPORT_AUTO_CHANNEL)
- static int
- wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
- char* command, int total_len)
- {
- int channel;
- int chosen = 0;
- int retry = 0;
- int ret = 0;
- u32 req_buf[7] = {0};
- channel = bcm_atoi(string_num);
- DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d\n", __FUNCTION__, channel));
- if (channel == 20) {
- /* Restrict channel to 1 - 6: 2GHz, 20MHz BW, No SB */
- req_buf[0] = 6;
- for (channel = 1; channel <= 6; channel++) {
- #ifdef D11AC_IOTYPES
- if (wl_cfg80211_get_ioctl_version() == 1)
- req_buf[channel] = CH20MHZ_LCHSPEC(channel);
- else
- req_buf[channel] = CH20MHZ_CHSPEC(channel);
- #else
- req_buf[channel] = CH20MHZ_CHSPEC(channel);
- #endif /* D11AC_IOTYPES */
- DHD_INFO(("%s: channel=%d, chanspec=0x%04X\n",
- __FUNCTION__, channel, req_buf[channel]));
- }
- }
- ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&req_buf,
- sizeof(req_buf), true);
- if (ret < 0) {
- DHD_ERROR(("%s: can't start auto channel scan, err = %d\n",
- __FUNCTION__, ret));
- channel = 0;
- goto done;
- }
- /* Wait for auto channel selection, max 2500 ms */
- OSL_SLEEP(500);
- retry = 10;
- while (retry--) {
- ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen,
- sizeof(chosen), false);
- if (ret < 0 || dtoh32(chosen) == 0) {
- DHD_INFO(("%s: %d tried, ret = %d, chosen = %d\n",
- __FUNCTION__, (10 - retry), ret, chosen));
- OSL_SLEEP(200);
- } else {
- #ifdef D11AC_IOTYPES
- if (wl_cfg80211_get_ioctl_version() == 1)
- channel = LCHSPEC_CHANNEL((u16)chosen);
- else
- channel = CHSPEC_CHANNEL((u16)chosen);
- #else
- channel = CHSPEC_CHANNEL((u16)chosen);
- #endif /* D11AC_IOTYPES */
- DHD_ERROR(("%s: selected channel = %d\n", __FUNCTION__, channel));
- break;
- }
- }
- if (retry == 0) {
- DHD_ERROR(("%s: auto channel timed out, failed\n", __FUNCTION__));
- channel = 0;
- }
- done:
- snprintf(command, 4, "%d", channel);
- DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
- return 4;
- }
- #endif /* WL_SUPPORT_AUTO_CHANNEL */
- #ifdef SUPPORT_HIDDEN_AP
- static int
- wl_android_set_max_num_sta(struct net_device *dev, const char* string_num)
- {
- int max_assoc;
- max_assoc = bcm_atoi(string_num);
- DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc));
- wldev_iovar_setint(dev, "maxassoc", max_assoc);
- return 1;
- }
- static int
- wl_android_set_ssid(struct net_device *dev, const char* hapd_ssid)
- {
- wlc_ssid_t ssid;
- s32 ret;
- ssid.SSID_len = strlen(hapd_ssid);
- if (ssid.SSID_len > DOT11_MAX_SSID_LEN) {
- ssid.SSID_len = DOT11_MAX_SSID_LEN;
- DHD_ERROR(("%s : Too long SSID Length %d\n", __FUNCTION__, strlen(hapd_ssid)));
- }
- bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len);
- DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__, ssid.SSID));
- ret = wldev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t), true);
- if (ret < 0) {
- DHD_ERROR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__, ret));
- }
- return 1;
- }
- static int
- wl_android_set_hide_ssid(struct net_device *dev, const char* string_num)
- {
- int hide_ssid;
- int enable = 0;
- hide_ssid = bcm_atoi(string_num);
- DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__, hide_ssid));
- if (hide_ssid)
- enable = 1;
- wldev_iovar_setint(dev, "closednet", enable);
- return 1;
- }
- #endif /* SUPPORT_HIDDEN_AP */
- #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
- static int
- wl_android_sta_diassoc(struct net_device *dev, const char* straddr)
- {
- scb_val_t scbval;
- int error = 0;
- DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__, straddr));
- /* Unspecified reason */
- scbval.val = htod32(1);
- bcm_ether_atoe(straddr, &scbval.ea);
- DHD_ERROR(("%s: deauth STA: "MACDBG " scb_val.val %d\n", __FUNCTION__,
- MAC2STRDBG(scbval.ea.octet), scbval.val));
- error = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
- sizeof(scb_val_t), true);
- if (error) {
- DHD_ERROR(("Fail to DEAUTH station, error = %d\n", error));
- }
- return 1;
- }
- #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
- #ifdef SUPPORT_SET_LPC
- static int
- wl_android_set_lpc(struct net_device *dev, const char* string_num)
- {
- int lpc_enabled, ret;
- s32 val = 1;
- lpc_enabled = bcm_atoi(string_num);
- DHD_INFO(("%s : HAPD_LPC_ENABLED = %d\n", __FUNCTION__, lpc_enabled));
- ret = wldev_ioctl(dev, WLC_DOWN, &val, sizeof(s32), true);
- if (ret < 0)
- DHD_ERROR(("WLC_DOWN error %d\n", ret));
- wldev_iovar_setint(dev, "lpc", lpc_enabled);
- ret = wldev_ioctl(dev, WLC_UP, &val, sizeof(s32), true);
- if (ret < 0)
- DHD_ERROR(("WLC_UP error %d\n", ret));
- return 1;
- }
- #endif /* SUPPORT_SET_LPC */
- static int
- wl_android_ch_res_rl(struct net_device *dev, bool change)
- {
- int error = 0;
- s32 srl = 7;
- s32 lrl = 4;
- printk("%s enter\n", __FUNCTION__);
- if (change) {
- srl = 4;
- lrl = 2;
- }
- error = wldev_ioctl(dev, WLC_SET_SRL, &srl, sizeof(s32), true);
- if (error) {
- DHD_ERROR(("Failed to set SRL, error = %d\n", error));
- }
- error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(s32), true);
- if (error) {
- DHD_ERROR(("Failed to set LRL, error = %d\n", error));
- }
- return error;
- }
- #ifdef SUPPORT_LTECX
- #define DEFAULT_WLANRX_PROT 1
- #define DEFAULT_LTERX_PROT 0
- #define DEFAULT_LTETX_ADV 1200
- static int
- wl_android_set_ltecx(struct net_device *dev, const char* string_num)
- {
- uint16 chan_bitmap;
- int ret;
- chan_bitmap = bcm_strtoul(string_num, NULL, 16);
- DHD_INFO(("%s : LTECOEX 0x%x\n", __FUNCTION__, chan_bitmap));
- if (chan_bitmap) {
- ret = wldev_iovar_setint(dev, "mws_coex_bitmap", chan_bitmap);
- if (ret < 0)
- DHD_ERROR(("mws_coex_bitmap error %d\n", ret));
- ret = wldev_iovar_setint(dev, "mws_wlanrx_prot", DEFAULT_WLANRX_PROT);
- if (ret < 0)
- DHD_ERROR(("mws_wlanrx_prot error %d\n", ret));
- ret = wldev_iovar_setint(dev, "mws_lterx_prot", DEFAULT_LTERX_PROT);
- if (ret < 0)
- DHD_ERROR(("mws_lterx_prot error %d\n", ret));
- ret = wldev_iovar_setint(dev, "mws_ltetx_adv", DEFAULT_LTETX_ADV);
- if (ret < 0)
- DHD_ERROR(("mws_ltetx_adv error %d\n", ret));
- } else {
- ret = wldev_iovar_setint(dev, "mws_coex_bitmap", chan_bitmap);
- if (ret < 0)
- DHD_ERROR(("LTECX_CHAN_BITMAP error %d\n", ret));
- }
- return 1;
- }
- #endif /* SUPPORT_LTECX */
- static int
- wl_android_rmc_enable(struct net_device *net, int rmc_enable)
- {
- int err;
- err = wldev_iovar_setint(net, "rmc_ackreq", rmc_enable);
- return err;
- }
- static int
- wl_android_rmc_set_leader(struct net_device *dev, const char* straddr)
- {
- int error = BCME_OK;
- char smbuf[WLC_IOCTL_SMLEN];
- wl_rmc_entry_t rmc_entry;
- DHD_INFO(("%s: Set new RMC leader %s\n", __FUNCTION__, straddr));
- memset(&rmc_entry, 0, sizeof(wl_rmc_entry_t));
- if (!bcm_ether_atoe(straddr, &rmc_entry.addr)) {
- if (strlen(straddr) == 1 && bcm_atoi(straddr) == 0) {
- DHD_INFO(("%s: Set auto leader selection mode\n", __FUNCTION__));
- memset(&rmc_entry, 0, sizeof(wl_rmc_entry_t));
- } else {
- DHD_ERROR(("%s: No valid mac address provided\n",
- __FUNCTION__));
- return BCME_ERROR;
- }
- }
- error = wldev_iovar_setbuf(dev, "rmc_ar", &rmc_entry, sizeof(wl_rmc_entry_t),
- smbuf, sizeof(smbuf), NULL);
- if (error != BCME_OK) {
- DHD_ERROR(("%s: Unable to set RMC leader, error = %d\n",
- __FUNCTION__, error));
- }
- return error;
- }
- static int wl_android_set_rmc_event(struct net_device *dev, char *command, int total_len)
- {
- int err = 0;
- int pid = 0;
- if (sscanf(command, CMD_SET_RMC_EVENT " %d", &pid) <= 0) {
- WL_ERR(("Failed to get Parameter from : %s\n", command));
- return -1;
- }
- /* set pid, and if the event was happened, let's send a notification through netlink */
- wl_cfg80211_set_rmc_pid(pid);
- WL_DBG(("RMC pid=%d\n", pid));
- return err;
- }
- int wl_android_get_singlecore_scan(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int bytes_written = 0;
- int mode = 0;
- error = wldev_iovar_getint(dev, "scan_ps", &mode);
- if (error) {
- DHD_ERROR(("%s: Failed to get single core scan Mode, error = %d\n",
- __FUNCTION__, error));
- return -1;
- }
- bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_SCSCAN, mode);
- return bytes_written;
- }
- int wl_android_set_singlecore_scan(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_iovar_setint(dev, "scan_ps", mode);
- if (error) {
- DHD_ERROR(("%s[1]: Failed to set Mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- return error;
- }
- #if defined(TEST_TX_POWER_CONTROL) || defined(TX_POWER_CONTROL_CALLING)
- static int
- wl_android_set_tx_power(struct net_device *dev, const char* string_num)
- {
- int err = 0;
- s32 dbm;
- enum nl80211_tx_power_setting type;
- dbm = bcm_atoi(string_num);
- if (dbm < -1) {
- DHD_ERROR(("%s: dbm is negative...\n", __FUNCTION__));
- return -EINVAL;
- }
- if (dbm == -1)
- type = NL80211_TX_POWER_AUTOMATIC;
- else
- type = NL80211_TX_POWER_FIXED;
- #ifdef TX_POWER_CONTROL_CALLING
- if (dbm == 0) {
- dbm = TX_CALLING_POWER;
- }
- #endif
- err = wl_set_tx_power(dev, type, dbm);
- if (unlikely(err)) {
- DHD_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
- return err;
- }
- return 1;
- }
- #endif /* TEST_TX_POWER_CONTROL || TX_POWER_CONTROL_CALLING */
- #ifdef TEST_TX_POWER_CONTROL
- static int
- wl_android_get_tx_power(struct net_device *dev, char *command, int total_len)
- {
- int err;
- int bytes_written;
- s32 dbm = 0;
- err = wl_get_tx_power(dev, &dbm);
- if (unlikely(err)) {
- DHD_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
- return err;
- }
- bytes_written = snprintf(command, total_len, "%s %d",
- CMD_TEST_GET_TX_POWER, dbm);
- DHD_ERROR(("%s: GET_TX_POWER: dBm=%d\n", __FUNCTION__, dbm));
- return bytes_written;
- }
- #endif /* TEST_TX_POWER_CONTROL */
- #ifdef SARLIMIT_TX_CONTROL_NVRAM
- static int
- wl_android_set_sarlimit_txctrl(struct net_device *dev, const char* string_num)
- {
- int err = 0;
- int setval = 0;
- s32 mode = bcm_atoi(string_num);
- /* As Samsung specific and their requirement, '0' means activate sarlimit
- * and '-1' means back to normal state (deactivate sarlimit)
- */
- if (mode == 0) {
- DHD_INFO(("%s: SAR limit control activated\n", __FUNCTION__));
- setval = 1;
- } else if (mode == -1) {
- DHD_INFO(("%s: SAR limit control deactivated\n", __FUNCTION__));
- setval = 0;
- } else {
- return -EINVAL;
- }
- err = wldev_iovar_setint(dev, "sar_enable", setval);
- if (unlikely(err)) {
- DHD_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
- return err;
- }
- return 1;
- }
- #endif /* SARLIMIT_TX_CONTROL_NVRAM */
- #endif /* CUSTOMER_HW4 */
- int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- int mode = 0;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- error = wldev_iovar_setint(dev, "roam_off", mode);
- if (error) {
- DHD_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return -1;
- }
- else
- DHD_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n",
- __FUNCTION__, mode, error));
- return 0;
- }
- int wl_android_set_ibss_beacon_ouidata(struct net_device *dev, char *command, int total_len)
- {
- char ie_buf[VNDR_IE_MAX_LEN];
- char *ioctl_buf = NULL;
- char hex[] = "XX";
- char *pcmd = NULL;
- int ielen = 0, datalen = 0, idx = 0, tot_len = 0;
- vndr_ie_setbuf_t *vndr_ie = NULL;
- s32 iecount;
- uint32 pktflag;
- u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- s32 err = BCME_OK;
- /* Check the VSIE (Vendor Specific IE) which was added.
- * If exist then send IOVAR to delete it
- */
- if (wl_cfg80211_ibss_vsie_delete(dev) != BCME_OK) {
- return -EINVAL;
- }
- pcmd = command + strlen(CMD_SETIBSSBEACONOUIDATA) + 1;
- for (idx = 0; idx < DOT11_OUI_LEN; idx++) {
- hex[0] = *pcmd++;
- hex[1] = *pcmd++;
- ie_buf[idx] = (uint8)simple_strtoul(hex, NULL, 16);
- }
- pcmd++;
- while ((*pcmd != '\0') && (idx < VNDR_IE_MAX_LEN)) {
- hex[0] = *pcmd++;
- hex[1] = *pcmd++;
- ie_buf[idx++] = (uint8)simple_strtoul(hex, NULL, 16);
- datalen++;
- }
- tot_len = sizeof(vndr_ie_setbuf_t) + (datalen - 1);
- vndr_ie = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags);
- if (!vndr_ie) {
- WL_ERR(("IE memory alloc failed\n"));
- return -ENOMEM;
- }
- /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
- strncpy(vndr_ie->cmd, "add", VNDR_IE_CMD_LEN - 1);
- vndr_ie->cmd[VNDR_IE_CMD_LEN - 1] = '\0';
- /* Set the IE count - the buffer contains only 1 IE */
- iecount = htod32(1);
- memcpy((void *)&vndr_ie->vndr_ie_buffer.iecount, &iecount, sizeof(s32));
- /* Set packet flag to indicate that BEACON's will contain this IE */
- pktflag = htod32(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG);
- memcpy((void *)&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag,
- sizeof(u32));
- /* Set the IE ID */
- vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = (uchar) DOT11_MNG_PROPR_ID;
- memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, &ie_buf,
- DOT11_OUI_LEN);
- memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data,
- &ie_buf[DOT11_OUI_LEN], datalen);
- ielen = DOT11_OUI_LEN + datalen;
- vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = (uchar) ielen;
- ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
- if (!ioctl_buf) {
- WL_ERR(("ioctl memory alloc failed\n"));
- if (vndr_ie) {
- kfree(vndr_ie);
- }
- return -ENOMEM;
- }
- memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN); /* init the buffer */
- err = wldev_iovar_setbuf(dev, "ie", vndr_ie, tot_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
- if (err != BCME_OK) {
- err = -EINVAL;
- if (vndr_ie) {
- kfree(vndr_ie);
- }
- }
- else {
- /* do NOT free 'vndr_ie' for the next process */
- wl_cfg80211_ibss_vsie_set_buffer(vndr_ie, tot_len);
- }
- if (ioctl_buf) {
- kfree(ioctl_buf);
- }
- return err;
- }
- #if defined(BCMFW_ROAM_ENABLE)
- static int
- wl_android_set_roampref(struct net_device *dev, char *command, int total_len)
- {
- int error = 0;
- char smbuf[WLC_IOCTL_SMLEN];
- uint8 buf[MAX_BUF_SIZE];
- uint8 *pref = buf;
- char *pcmd;
- int num_ucipher_suites = 0;
- int num_akm_suites = 0;
- wpa_suite_t ucipher_suites[MAX_NUM_SUITES];
- wpa_suite_t akm_suites[MAX_NUM_SUITES];
- int num_tuples = 0;
- int total_bytes = 0;
- int total_len_left;
- int i, j;
- char hex[] = "XX";
- pcmd = command + strlen(CMD_SET_ROAMPREF) + 1;
- total_len_left = total_len - strlen(CMD_SET_ROAMPREF) + 1;
- num_akm_suites = simple_strtoul(pcmd, NULL, 16);
- /* Increment for number of AKM suites field + space */
- pcmd += 3;
- total_len_left -= 3;
- /* check to make sure pcmd does not overrun */
- if (total_len_left < (num_akm_suites * WIDTH_AKM_SUITE))
- return -1;
- memset(buf, 0, sizeof(buf));
- memset(akm_suites, 0, sizeof(akm_suites));
- memset(ucipher_suites, 0, sizeof(ucipher_suites));
- /* Save the AKM suites passed in the command */
- for (i = 0; i < num_akm_suites; i++) {
- /* Store the MSB first, as required by join_pref */
- for (j = 0; j < 4; j++) {
- hex[0] = *pcmd++;
- hex[1] = *pcmd++;
- buf[j] = (uint8)simple_strtoul(hex, NULL, 16);
- }
- memcpy((uint8 *)&akm_suites[i], buf, sizeof(uint32));
- }
- total_len_left -= (num_akm_suites * WIDTH_AKM_SUITE);
- num_ucipher_suites = simple_strtoul(pcmd, NULL, 16);
- /* Increment for number of cipher suites field + space */
- pcmd += 3;
- total_len_left -= 3;
- if (total_len_left < (num_ucipher_suites * WIDTH_AKM_SUITE))
- return -1;
- /* Save the cipher suites passed in the command */
- for (i = 0; i < num_ucipher_suites; i++) {
- /* Store the MSB first, as required by join_pref */
- for (j = 0; j < 4; j++) {
- hex[0] = *pcmd++;
- hex[1] = *pcmd++;
- buf[j] = (uint8)simple_strtoul(hex, NULL, 16);
- }
- memcpy((uint8 *)&ucipher_suites[i], buf, sizeof(uint32));
- }
- /* Join preference for RSSI
- * Type : 1 byte (0x01)
- * Length : 1 byte (0x02)
- * Value : 2 bytes (reserved)
- */
- *pref++ = WL_JOIN_PREF_RSSI;
- *pref++ = JOIN_PREF_RSSI_LEN;
- *pref++ = 0;
- *pref++ = 0;
- /* Join preference for WPA
- * Type : 1 byte (0x02)
- * Length : 1 byte (not used)
- * Value : (variable length)
- * reserved: 1 byte
- * count : 1 byte (no of tuples)
- * Tuple1 : 12 bytes
- * akm[4]
- * ucipher[4]
- * mcipher[4]
- * Tuple2 : 12 bytes
- * Tuplen : 12 bytes
- */
- num_tuples = num_akm_suites * num_ucipher_suites;
- if (num_tuples != 0) {
- if (num_tuples <= JOIN_PREF_MAX_WPA_TUPLES) {
- *pref++ = WL_JOIN_PREF_WPA;
- *pref++ = 0;
- *pref++ = 0;
- *pref++ = (uint8)num_tuples;
- total_bytes = JOIN_PREF_RSSI_SIZE + JOIN_PREF_WPA_HDR_SIZE +
- (JOIN_PREF_WPA_TUPLE_SIZE * num_tuples);
- } else {
- DHD_ERROR(("%s: Too many wpa configs for join_pref \n", __FUNCTION__));
- return -1;
- }
- } else {
- /* No WPA config, configure only RSSI preference */
- total_bytes = JOIN_PREF_RSSI_SIZE;
- }
- /* akm-ucipher-mcipher tuples in the format required for join_pref */
- for (i = 0; i < num_ucipher_suites; i++) {
- for (j = 0; j < num_akm_suites; j++) {
- memcpy(pref, (uint8 *)&akm_suites[j], WPA_SUITE_LEN);
- pref += WPA_SUITE_LEN;
- memcpy(pref, (uint8 *)&ucipher_suites[i], WPA_SUITE_LEN);
- pref += WPA_SUITE_LEN;
- /* Set to 0 to match any available multicast cipher */
- memset(pref, 0, WPA_SUITE_LEN);
- pref += WPA_SUITE_LEN;
- }
- }
- prhex("join pref", (uint8 *)buf, total_bytes);
- error = wldev_iovar_setbuf(dev, "join_pref", buf, total_bytes, smbuf, sizeof(smbuf), NULL);
- if (error) {
- DHD_ERROR(("Failed to set join_pref, error = %d\n", error));
- }
- return error;
- }
- #endif /* defined(BCMFW_ROAM_ENABLE */
- static int
- wl_android_iolist_add(struct net_device *dev, struct list_head *head, struct io_cfg *config)
- {
- struct io_cfg *resume_cfg;
- s32 ret;
- resume_cfg = kzalloc(sizeof(struct io_cfg), GFP_KERNEL);
- if (!resume_cfg)
- return -ENOMEM;
- if (config->iovar) {
- ret = wldev_iovar_getint(dev, config->iovar, &resume_cfg->param);
- if (ret) {
- DHD_ERROR(("%s: Failed to get current %s value\n",
- __FUNCTION__, config->iovar));
- goto error;
- }
- ret = wldev_iovar_setint(dev, config->iovar, config->param);
- if (ret) {
- DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__,
- config->iovar, config->param));
- goto error;
- }
- resume_cfg->iovar = config->iovar;
- } else {
- resume_cfg->arg = kzalloc(config->len, GFP_KERNEL);
- if (!resume_cfg->arg) {
- ret = -ENOMEM;
- goto error;
- }
- ret = wldev_ioctl(dev, config->ioctl, resume_cfg->arg, config->len, false);
- if (ret) {
- DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__,
- config->ioctl));
- goto error;
- }
- ret = wldev_ioctl(dev, config->ioctl + 1, config->arg, config->len, true);
- if (ret) {
- DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__,
- config->iovar, config->param));
- goto error;
- }
- if (config->ioctl + 1 == WLC_SET_PM)
- wl_cfg80211_update_power_mode(dev);
- resume_cfg->ioctl = config->ioctl;
- resume_cfg->len = config->len;
- }
- list_add(&resume_cfg->list, head);
- return 0;
- error:
- kfree(resume_cfg->arg);
- kfree(resume_cfg);
- return ret;
- }
- static void
- wl_android_iolist_resume(struct net_device *dev, struct list_head *head)
- {
- struct io_cfg *config;
- struct list_head *cur, *q;
- s32 ret = 0;
- list_for_each_safe(cur, q, head) {
- config = list_entry(cur, struct io_cfg, list);
- if (config->iovar) {
- if (!ret)
- ret = wldev_iovar_setint(dev, config->iovar,
- config->param);
- } else {
- if (!ret)
- ret = wldev_ioctl(dev, config->ioctl + 1,
- config->arg, config->len, true);
- if (config->ioctl + 1 == WLC_SET_PM)
- wl_cfg80211_update_power_mode(dev);
- kfree(config->arg);
- }
- list_del(cur);
- kfree(config);
- }
- }
- static int
- wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
- {
- int mode, val;
- int ret = 0;
- struct io_cfg config;
- if (sscanf(command, "%*s %d", &mode) != 1) {
- DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
- return -1;
- }
- DHD_INFO(("%s: enter miracast mode %d\n", __FUNCTION__, mode));
- if (miracast_cur_mode == mode) {
- return 0;
- }
- wl_android_iolist_resume(dev, &miracast_resume_list);
- miracast_cur_mode = MIRACAST_MODE_OFF;
- switch (mode) {
- case MIRACAST_MODE_SOURCE:
- /* setting mchan_algo to platform specific value */
- config.iovar = "mchan_algo";
- ret = wldev_ioctl(dev, WLC_GET_BCNPRD, &val, sizeof(int), false);
- if (!ret && val > 100) {
- config.param = 0;
- DHD_ERROR(("%s: Connected station's beacon interval: "
- "%d and set mchan_algo to %d \n",
- __FUNCTION__, val, config.param));
- }
- else {
- config.param = MIRACAST_MCHAN_ALGO;
- }
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret) {
- goto resume;
- }
- /* setting mchan_bw to platform specific value */
- config.iovar = "mchan_bw";
- config.param = MIRACAST_MCHAN_BW;
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret) {
- goto resume;
- }
- /* setting apmdu to platform specific value */
- config.iovar = "ampdu_mpdu";
- config.param = MIRACAST_AMPDU_SIZE;
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret) {
- goto resume;
- }
- /* FALLTROUGH */
- /* Source mode shares most configurations with sink mode.
- * Fall through here to avoid code duplication
- */
- case MIRACAST_MODE_SINK:
- /* disable internal roaming */
- config.iovar = "roam_off";
- config.param = 1;
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret) {
- goto resume;
- }
- /* turn off pm */
- ret = wldev_ioctl(dev, WLC_GET_PM, &val, sizeof(val), false);
- if(ret) {
- goto resume;
- }
- if (val != PM_OFF) {
- val = PM_OFF;
- config.iovar = NULL;
- config.ioctl = WLC_GET_PM;
- config.arg = &val;
- config.len = sizeof(int);
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret) {
- goto resume;
- }
- }
- break;
- case MIRACAST_MODE_OFF:
- default:
- break;
- }
- miracast_cur_mode = mode;
- return 0;
- resume:
- DHD_ERROR(("%s: turnoff miracast mode because of err%d\n", __FUNCTION__, ret));
- wl_android_iolist_resume(dev, &miracast_resume_list);
- return ret;
- }
- #define NETLINK_OXYGEN 30
- #define AIBSS_BEACON_TIMEOUT 10
- static struct sock *nl_sk = NULL;
- static void wl_netlink_recv(struct sk_buff *skb)
- {
- WL_ERR(("netlink_recv called\n"));
- }
- static int wl_netlink_init(void)
- {
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
- struct netlink_kernel_cfg cfg = {
- .input = wl_netlink_recv,
- };
- #endif
- if (nl_sk != NULL) {
- WL_ERR(("nl_sk already exist\n"));
- return BCME_ERROR;
- }
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
- nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN,
- 0, wl_netlink_recv, NULL, THIS_MODULE);
- #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
- nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, THIS_MODULE, &cfg);
- #else
- nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, &cfg);
- #endif
- if (nl_sk == NULL) {
- WL_ERR(("nl_sk is not ready\n"));
- return BCME_ERROR;
- }
- return BCME_OK;
- }
- static void wl_netlink_deinit(void)
- {
- if (nl_sk) {
- netlink_kernel_release(nl_sk);
- nl_sk = NULL;
- }
- }
- s32
- wl_netlink_send_msg(int pid, int type, int seq, void *data, size_t size)
- {
- struct sk_buff *skb = NULL;
- struct nlmsghdr *nlh = NULL;
- int ret = -1;
- if (nl_sk == NULL) {
- WL_ERR(("nl_sk was not initialized\n"));
- goto nlmsg_failure;
- }
- skb = alloc_skb(NLMSG_SPACE(size), GFP_ATOMIC);
- if (skb == NULL) {
- WL_ERR(("failed to allocate memory\n"));
- goto nlmsg_failure;
- }
- nlh = nlmsg_put(skb, 0, 0, 0, size, 0);
- if (nlh == NULL) {
- WL_ERR(("failed to build nlmsg, skb_tailroom:%d, nlmsg_total_size:%d\n",
- skb_tailroom(skb), nlmsg_total_size(size)));
- dev_kfree_skb(skb);
- goto nlmsg_failure;
- }
- memcpy(nlmsg_data(nlh), data, size);
- nlh->nlmsg_seq = seq;
- nlh->nlmsg_type = type;
- /* netlink_unicast() takes ownership of the skb and frees it itself. */
- ret = netlink_unicast(nl_sk, skb, pid, 0);
- WL_DBG(("netlink_unicast() pid=%d, ret=%d\n", pid, ret));
- nlmsg_failure:
- return ret;
- }
- #ifdef WLAIBSS
- static int wl_android_set_ibss_txfail_event(struct net_device *dev, char *command, int total_len)
- {
- int err = 0;
- int retry = 0;
- int pid = 0;
- aibss_txfail_config_t txfail_config = {0, 0, 0, 0};
- char smbuf[WLC_IOCTL_SMLEN];
- if (sscanf(command, CMD_SETIBSSTXFAILEVENT " %d %d", &retry, &pid) <= 0) {
- WL_ERR(("Failed to get Parameter from : %s\n", command));
- return -1;
- }
- /* set pid, and if the event was happened, let's send a notification through netlink */
- wl_cfg80211_set_txfail_pid(pid);
- #ifdef CUSTOMER_HW4
- /* using same pid for RMC, AIBSS shares same pid with RMC and it is set once */
- wl_cfg80211_set_rmc_pid(pid);
- #endif
- /* If retry value is 0, it disables the functionality for TX Fail. */
- if (retry > 0) {
- txfail_config.max_tx_retry = retry;
- txfail_config.bcn_timeout = 0; /* 0 : disable tx fail from beacon */
- }
- txfail_config.version = AIBSS_TXFAIL_CONFIG_VER_0;
- txfail_config.len = sizeof(txfail_config);
- err = wldev_iovar_setbuf(dev, "aibss_txfail_config", (void *) &txfail_config,
- sizeof(aibss_txfail_config_t), smbuf, WLC_IOCTL_SMLEN, NULL);
- WL_DBG(("retry=%d, pid=%d, err=%d\n", retry, pid, err));
- return ((err == 0)?total_len:err);
- }
- static int wl_android_get_ibss_peer_info(struct net_device *dev, char *command,
- int total_len, bool bAll)
- {
- int error;
- int bytes_written = 0;
- void *buf = NULL;
- bss_peer_list_info_t peer_list_info;
- bss_peer_info_t *peer_info;
- int i;
- bool found = false;
- struct ether_addr mac_ea;
- char *str = command;
- WL_DBG(("get ibss peer info(%s)\n", bAll?"true":"false"));
- if (!bAll) {
- if (bcmstrtok(&str, " ", NULL) == NULL) {
- WL_ERR(("invalid command\n"));
- return -1;
- }
- if (!str || !bcm_ether_atoe(str, &mac_ea)) {
- WL_ERR(("invalid MAC address\n"));
- return -1;
- }
- }
- if ((buf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL)) == NULL) {
- WL_ERR(("kmalloc failed\n"));
- return -1;
- }
- error = wldev_iovar_getbuf(dev, "bss_peer_info", NULL, 0, buf, WLC_IOCTL_MAXLEN, NULL);
- if (unlikely(error)) {
- WL_ERR(("could not get ibss peer info (%d)\n", error));
- kfree(buf);
- return -1;
- }
- memcpy(&peer_list_info, buf, sizeof(peer_list_info));
- peer_list_info.version = htod16(peer_list_info.version);
- peer_list_info.bss_peer_info_len = htod16(peer_list_info.bss_peer_info_len);
- peer_list_info.count = htod32(peer_list_info.count);
- WL_DBG(("ver:%d, len:%d, count:%d\n", peer_list_info.version,
- peer_list_info.bss_peer_info_len, peer_list_info.count));
- if (peer_list_info.count > 0) {
- if (bAll)
- bytes_written += sprintf(&command[bytes_written], "%u ",
- peer_list_info.count);
- peer_info = (bss_peer_info_t *) ((void *)buf + BSS_PEER_LIST_INFO_FIXED_LEN);
- for (i = 0; i < peer_list_info.count; i++) {
- WL_DBG(("index:%d rssi:%d, tx:%u, rx:%u\n", i, peer_info->rssi,
- peer_info->tx_rate, peer_info->rx_rate));
- if (!bAll &&
- memcmp(&mac_ea, &peer_info->ea, sizeof(struct ether_addr)) == 0) {
- found = true;
- }
- if (bAll || found) {
- bytes_written += sprintf(&command[bytes_written], MACF,
- ETHER_TO_MACF(peer_info->ea));
- bytes_written += sprintf(&command[bytes_written], " %u %d ",
- peer_info->tx_rate/1000, peer_info->rssi);
- }
- if (found)
- break;
- peer_info = (bss_peer_info_t *)((void *)peer_info+sizeof(bss_peer_info_t));
- }
- }
- else {
- WL_ERR(("could not get ibss peer info : no item\n"));
- }
- bytes_written += sprintf(&command[bytes_written], "%s", "\0");
- WL_DBG(("command(%u):%s\n", total_len, command));
- WL_DBG(("bytes_written:%d\n", bytes_written));
- kfree(buf);
- return bytes_written;
- }
- int wl_android_set_ibss_routetable(struct net_device *dev, char *command, int total_len)
- {
- char *pcmd = command;
- char *str = NULL;
- ibss_route_tbl_t *route_tbl = NULL;
- char *ioctl_buf = NULL;
- u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- s32 err = BCME_OK;
- uint32 route_tbl_len;
- uint32 entries;
- char *endptr;
- uint32 i = 0;
- struct ipv4_addr dipaddr;
- struct ether_addr ea;
- route_tbl_len = sizeof(ibss_route_tbl_t) +
- (MAX_IBSS_ROUTE_TBL_ENTRY - 1) * sizeof(ibss_route_entry_t);
- route_tbl = (ibss_route_tbl_t *)kzalloc(route_tbl_len, kflags);
- if (!route_tbl) {
- WL_ERR(("Route TBL alloc failed\n"));
- return -ENOMEM;
- }
- ioctl_buf = kzalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
- if (!ioctl_buf) {
- WL_ERR(("ioctl memory alloc failed\n"));
- if (route_tbl) {
- kfree(route_tbl);
- }
- return -ENOMEM;
- }
- memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN);
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
- /* get count */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- WL_ERR(("Invalid number parameter %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- entries = bcm_strtoul(str, &endptr, 0);
- if (*endptr != '\0') {
- WL_ERR(("Invalid number parameter %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- if (entries > MAX_IBSS_ROUTE_TBL_ENTRY) {
- WL_ERR(("Invalid entries number %u\n", entries));
- err = -EINVAL;
- goto exit;
- }
- WL_INFO(("Routing table count:%u\n", entries));
- route_tbl->num_entry = entries;
- for (i = 0; i < entries; i++) {
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str || !bcm_atoipv4(str, &dipaddr)) {
- WL_ERR(("Invalid ip string %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str || !bcm_ether_atoe(str, &ea)) {
- WL_ERR(("Invalid ethernet string %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- bcopy(&dipaddr, &route_tbl->route_entry[i].ipv4_addr, IPV4_ADDR_LEN);
- bcopy(&ea, &route_tbl->route_entry[i].nexthop, ETHER_ADDR_LEN);
- }
- route_tbl_len = sizeof(ibss_route_tbl_t) +
- ((!entries?0:(entries - 1)) * sizeof(ibss_route_entry_t));
- err = wldev_iovar_setbuf(dev, "ibss_route_tbl",
- route_tbl, route_tbl_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
- if (err != BCME_OK) {
- WL_ERR(("Fail to set iovar %d\n", err));
- err = -EINVAL;
- }
- exit:
- if (route_tbl)
- kfree(route_tbl);
- if (ioctl_buf)
- kfree(ioctl_buf);
- return err;
- }
- int wl_android_set_ibss_ampdu(struct net_device *dev, char *command, int total_len)
- {
- char *pcmd = command;
- char *str = NULL, *endptr = NULL;
- int category[4];
- int tid2category[NUMPRIO] = {2, 3, 3, 2, 1, 1, 0, 0};
- struct ampdu_tid_control_mode control;
- char smbuf[WLC_IOCTL_SMLEN];
- int idx;
- int err = 0;
- WL_DBG(("set ibss ampdu:%s\n", command));
- /* acquire parameters */
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
- for (idx = 0; idx < 4; idx++) {
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- WL_ERR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- category[idx] = bcm_strtoul(str, &endptr, 0);
- if (*endptr != '\0') {
- WL_ERR(("Invalid number format %s\n", str));
- return -EINVAL;
- }
- }
- sprintf(control.mode_name, "AIBSS");
- for (idx = 0; idx < NUMPRIO; idx++) {
- control.control[idx].tid = idx;
- control.control[idx].enable = category[tid2category[idx]];
- }
- err = wldev_iovar_setbuf(dev, "ampdu_tid_mode", (void *) &control,
- sizeof(struct ampdu_tid_control_mode), smbuf, WLC_IOCTL_SMLEN, NULL);
- return ((err == 0)?total_len:err);
- }
- int wl_android_set_ibss_antenna(struct net_device *dev, char *command, int total_len)
- {
- char *pcmd = command;
- char *str = NULL;
- int txchain, rxchain;
- int err = 0;
- WL_DBG(("set ibss antenna:%s\n", command));
- /* acquire parameters */
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
- /* TX chain */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- WL_ERR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- txchain = bcm_atoi(str);
- /* RX chain */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- WL_ERR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- rxchain = bcm_atoi(str);
- err = wldev_iovar_setint(dev, "txchain", txchain);
- if (err != 0)
- return err;
- err = wldev_iovar_setint(dev, "rxchain", rxchain);
- return ((err == 0)?total_len:err);
- }
- #endif /* WLAIBSS */
- int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len)
- {
- char buf[256];
- const char *str;
- wl_mkeep_alive_pkt_t mkeep_alive_pkt;
- wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
- int buf_len;
- int str_len;
- int res = -1;
- uint period_msec = 0;
- if (extra == NULL)
- {
- DHD_ERROR(("%s: extra is NULL\n", __FUNCTION__));
- return -1;
- }
- if (sscanf(extra, "%d", &period_msec) != 1)
- {
- DHD_ERROR(("%s: sscanf error. check period_msec value\n", __FUNCTION__));
- return -EINVAL;
- }
- DHD_ERROR(("%s: period_msec is %d\n", __FUNCTION__, period_msec));
- memset(&mkeep_alive_pkt, 0, sizeof(wl_mkeep_alive_pkt_t));
- str = "mkeep_alive";
- str_len = strlen(str);
- strncpy(buf, str, str_len);
- buf[ str_len ] = '\0';
- mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1);
- mkeep_alive_pkt.period_msec = period_msec;
- buf_len = str_len + 1;
- mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION);
- mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
- /* Setup keep alive zero for null packet generation */
- mkeep_alive_pkt.keep_alive_id = 0;
- mkeep_alive_pkt.len_bytes = 0;
- buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
- /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and
- * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
- * guarantee that the buffer is properly aligned.
- */
- memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
- if ((res = wldev_ioctl(dev, WLC_SET_VAR, buf, buf_len, TRUE)) < 0)
- {
- DHD_ERROR(("%s:keep_alive set failed. res[%d]\n", __FUNCTION__, res));
- }
- else
- {
- DHD_ERROR(("%s:keep_alive set ok. res[%d]\n", __FUNCTION__, res));
- }
- return res;
- }
- int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
- {
- #define PRIVATE_COMMAND_MAX_LEN 8192
- int ret = 0;
- char *command = NULL;
- int bytes_written = 0;
- android_wifi_priv_cmd priv_cmd;
- net_os_wake_lock(net);
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- goto exit;
- }
- if (!ifr->ifr_data) {
- ret = -EINVAL;
- goto exit;
- }
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- goto exit;
- }
- #ifdef CONFIG_COMPAT
- if (is_compat_task()) {
- compat_android_wifi_priv_cmd compat_priv_cmd;
- if (copy_from_user(&compat_priv_cmd, ifr->ifr_data,
- sizeof(compat_android_wifi_priv_cmd))) {
- ret = -EFAULT;
- goto exit;
- }
- priv_cmd.buf = compat_ptr(compat_priv_cmd.buf);
- priv_cmd.used_len = compat_priv_cmd.used_len;
- priv_cmd.total_len = compat_priv_cmd.total_len;
- } else
- #endif /* CONFIG_COMPAT */
- {
- if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
- ret = -EFAULT;
- goto exit;
- }
- }
- if ((priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) || (priv_cmd.total_len < 0)) {
- DHD_ERROR(("%s: invalid length of private command : %d\n",
- __FUNCTION__, priv_cmd.total_len));
- ret = -EINVAL;
- goto exit;
- }
- command = kmalloc((priv_cmd.total_len + 1), GFP_KERNEL);
- if (!command)
- {
- DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__));
- ret = -ENOMEM;
- goto exit;
- }
- if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) {
- ret = -EFAULT;
- goto exit;
- }
- command[priv_cmd.total_len] = '\0';
- DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name));
- if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) {
- DHD_INFO(("%s, Received regular START command\n", __FUNCTION__));
- #ifdef SUPPORT_DEEP_SLEEP
- trigger_deep_sleep = 1;
- #else
- bytes_written = wl_android_wifi_on(net);
- #endif /* SUPPORT_DEEP_SLEEP */
- }
- else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) {
- bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len);
- }
- if (!g_wifi_on) {
- DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n",
- __FUNCTION__, command, ifr->ifr_name));
- ret = 0;
- goto exit;
- }
- if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
- #ifdef SUPPORT_DEEP_SLEEP
- trigger_deep_sleep = 1;
- #else
- bytes_written = wl_android_wifi_off(net);
- #endif /* SUPPORT_DEEP_SLEEP */
- }
- else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
- /* TBD: SCAN-ACTIVE */
- }
- else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
- /* TBD: SCAN-PASSIVE */
- }
- else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
- bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
- bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len);
- }
- #ifdef PKT_FILTER_SUPPORT
- else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) {
- bytes_written = net_os_enable_packet_filter(net, 1);
- }
- else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) {
- bytes_written = net_os_enable_packet_filter(net, 0);
- }
- else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) {
- int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
- bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
- }
- else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) {
- int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
- bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
- }
- #endif /* PKT_FILTER_SUPPORT */
- else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) {
- /* TBD: BTCOEXSCAN-START */
- }
- else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) {
- /* TBD: BTCOEXSCAN-STOP */
- }
- else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
- #ifdef WL_CFG80211
- void *dhdp = wl_cfg80211_get_dhdp();
- bytes_written = wl_cfg80211_set_btcoex_dhcp(net, dhdp, command);
- #else
- #ifdef PKT_FILTER_SUPPORT
- uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
- if (mode == 1)
- net_os_enable_packet_filter(net, 0); /* DHCP starts */
- else
- net_os_enable_packet_filter(net, 1); /* DHCP ends */
- #endif /* PKT_FILTER_SUPPORT */
- #endif /* WL_CFG80211 */
- }
- else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
- bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
- bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
- uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
- #ifdef WL_HOST_BAND_MGMT
- s32 ret = 0;
- if ((ret = wl_cfg80211_set_band(net, band)) < 0) {
- if (ret == BCME_UNSUPPORTED) {
- /* If roam_var is unsupported, fallback to the original method */
- WL_ERR(("WL_HOST_BAND_MGMT defined, "
- "but roam_band iovar unsupported in the firmware\n"));
- } else {
- bytes_written = -1;
- goto exit;
- }
- }
- if ((band == WLC_BAND_AUTO) || (ret == BCME_UNSUPPORTED))
- bytes_written = wldev_set_band(net, band);
- #else
- bytes_written = wldev_set_band(net, band);
- #endif /* WL_HOST_BAND_MGMT */
- #if defined(CUSTOMER_HW4) && defined(ROAM_CHANNEL_CACHE)
- wl_update_roamscan_cache_by_band(net, band);
- #endif
- }
- else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
- bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
- }
- #ifdef WL_CFG80211
- #ifndef CUSTOMER_SET_COUNTRY
- /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
- else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
- char *country_code = command + strlen(CMD_COUNTRY) + 1;
- bytes_written = wldev_set_country(net, country_code, true, true);
- }
- #endif /* CUSTOMER_SET_COUNTRY */
- #endif /* WL_CFG80211 */
- #ifdef CUSTOMER_HW4
- #ifdef ROAM_API
- else if (strnicmp(command, CMD_ROAMTRIGGER_SET,
- strlen(CMD_ROAMTRIGGER_SET)) == 0) {
- bytes_written = wl_android_set_roam_trigger(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_ROAMTRIGGER_GET,
- strlen(CMD_ROAMTRIGGER_GET)) == 0) {
- bytes_written = wl_android_get_roam_trigger(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_ROAMDELTA_SET,
- strlen(CMD_ROAMDELTA_SET)) == 0) {
- bytes_written = wl_android_set_roam_delta(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_ROAMDELTA_GET,
- strlen(CMD_ROAMDELTA_GET)) == 0) {
- bytes_written = wl_android_get_roam_delta(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_ROAMSCANPERIOD_SET,
- strlen(CMD_ROAMSCANPERIOD_SET)) == 0) {
- bytes_written = wl_android_set_roam_scan_period(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_ROAMSCANPERIOD_GET,
- strlen(CMD_ROAMSCANPERIOD_GET)) == 0) {
- bytes_written = wl_android_get_roam_scan_period(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_SET,
- strlen(CMD_FULLROAMSCANPERIOD_SET)) == 0) {
- bytes_written = wl_android_set_full_roam_scan_period(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_GET,
- strlen(CMD_FULLROAMSCANPERIOD_GET)) == 0) {
- bytes_written = wl_android_get_full_roam_scan_period(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_COUNTRYREV_SET,
- strlen(CMD_COUNTRYREV_SET)) == 0) {
- bytes_written = wl_android_set_country_rev(net, command,
- priv_cmd.total_len);
- } else if (strnicmp(command, CMD_COUNTRYREV_GET,
- strlen(CMD_COUNTRYREV_GET)) == 0) {
- bytes_written = wl_android_get_country_rev(net, command,
- priv_cmd.total_len);
- }
- #endif /* ROAM_API */
- #ifdef WES_SUPPORT
- else if (strnicmp(command, CMD_GETROAMSCANCONTROL, strlen(CMD_GETROAMSCANCONTROL)) == 0) {
- bytes_written = wl_android_get_roam_scan_control(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETROAMSCANCONTROL, strlen(CMD_SETROAMSCANCONTROL)) == 0) {
- bytes_written = wl_android_set_roam_scan_control(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETROAMSCANCHANNELS, strlen(CMD_GETROAMSCANCHANNELS)) == 0) {
- bytes_written = wl_android_get_roam_scan_channels(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETROAMSCANCHANNELS, strlen(CMD_SETROAMSCANCHANNELS)) == 0) {
- bytes_written = wl_android_set_roam_scan_channels(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SENDACTIONFRAME, strlen(CMD_SENDACTIONFRAME)) == 0) {
- bytes_written = wl_android_send_action_frame(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_REASSOC, strlen(CMD_REASSOC)) == 0) {
- bytes_written = wl_android_reassoc(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETSCANCHANNELTIME, strlen(CMD_GETSCANCHANNELTIME)) == 0) {
- bytes_written = wl_android_get_scan_channel_time(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETSCANCHANNELTIME, strlen(CMD_SETSCANCHANNELTIME)) == 0) {
- bytes_written = wl_android_set_scan_channel_time(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETSCANHOMETIME, strlen(CMD_GETSCANHOMETIME)) == 0) {
- bytes_written = wl_android_get_scan_home_time(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETSCANHOMETIME, strlen(CMD_SETSCANHOMETIME)) == 0) {
- bytes_written = wl_android_set_scan_home_time(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETSCANHOMEAWAYTIME, strlen(CMD_GETSCANHOMEAWAYTIME)) == 0) {
- bytes_written = wl_android_get_scan_home_away_time(net, command,
- priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETSCANHOMEAWAYTIME, strlen(CMD_SETSCANHOMEAWAYTIME)) == 0) {
- bytes_written = wl_android_set_scan_home_away_time(net, command,
- priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETSCANNPROBES, strlen(CMD_GETSCANNPROBES)) == 0) {
- bytes_written = wl_android_get_scan_nprobes(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETSCANNPROBES, strlen(CMD_SETSCANNPROBES)) == 0) {
- bytes_written = wl_android_set_scan_nprobes(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETDFSSCANMODE, strlen(CMD_GETDFSSCANMODE)) == 0) {
- bytes_written = wl_android_get_scan_dfs_channel_mode(net, command,
- priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETDFSSCANMODE, strlen(CMD_SETDFSSCANMODE)) == 0) {
- bytes_written = wl_android_set_scan_dfs_channel_mode(net, command,
- priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETWESMODE, strlen(CMD_GETWESMODE)) == 0) {
- bytes_written = wl_android_get_wes_mode(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETWESMODE, strlen(CMD_SETWESMODE)) == 0) {
- bytes_written = wl_android_set_wes_mode(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_GETOKCMODE, strlen(CMD_GETOKCMODE)) == 0) {
- bytes_written = wl_android_get_okc_mode(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SETOKCMODE, strlen(CMD_SETOKCMODE)) == 0) {
- bytes_written = wl_android_set_okc_mode(net, command, priv_cmd.total_len);
- }
- #endif /* WES_SUPPORT */
- #endif /* CUSTOMER_HW4 */
- #ifdef PNO_SUPPORT
- else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
- bytes_written = dhd_dev_pno_stop_for_ssid(net);
- }
- #ifndef WL_SCHED_SCAN
- else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) {
- bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len);
- }
- #endif /* !WL_SCHED_SCAN */
- else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) {
- int enable = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0';
- bytes_written = (enable)? 0 : dhd_dev_pno_stop_for_ssid(net);
- }
- else if (strnicmp(command, CMD_WLS_BATCHING, strlen(CMD_WLS_BATCHING)) == 0) {
- bytes_written = wls_parse_batching_cmd(net, command, priv_cmd.total_len);
- }
- #endif /* PNO_SUPPORT */
- else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) {
- bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) {
- int skip = strlen(CMD_P2P_SET_NOA) + 1;
- bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
- priv_cmd.total_len - skip);
- }
- #if !defined WL_ENABLE_P2P_IF
- else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) {
- bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
- }
- #endif /* WL_ENABLE_P2P_IF */
- else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) {
- int skip = strlen(CMD_P2P_SET_PS) + 1;
- bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
- priv_cmd.total_len - skip);
- }
- #ifdef WL_CFG80211
- else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE,
- strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) {
- int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3;
- bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
- priv_cmd.total_len - skip, *(command + skip - 2) - '0');
- }
- #ifdef WLFBT
- else if (strnicmp(command, CMD_GET_FTKEY, strlen(CMD_GET_FTKEY)) == 0) {
- wl_cfg80211_get_fbt_key(command);
- bytes_written = FBT_KEYLEN;
- }
- #endif /* WLFBT */
- #endif /* WL_CFG80211 */
- else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0)
- bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0)
- bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len);
- #ifdef BCMCCX
- else if (strnicmp(command, CMD_GETCCKM_RN, strlen(CMD_GETCCKM_RN)) == 0) {
- bytes_written = wl_android_get_cckm_rn(net, command);
- }
- else if (strnicmp(command, CMD_SETCCKM_KRK, strlen(CMD_SETCCKM_KRK)) == 0) {
- bytes_written = wl_android_set_cckm_krk(net, command);
- }
- else if (strnicmp(command, CMD_GET_ASSOC_RES_IES, strlen(CMD_GET_ASSOC_RES_IES)) == 0) {
- bytes_written = wl_android_get_assoc_res_ies(net, command);
- }
- #endif /* BCMCCX */
- #if defined(WL_SUPPORT_AUTO_CHANNEL)
- else if (strnicmp(command, CMD_GET_BEST_CHANNELS,
- strlen(CMD_GET_BEST_CHANNELS)) == 0) {
- bytes_written = wl_cfg80211_get_best_channels(net, command,
- priv_cmd.total_len);
- }
- #endif /* WL_SUPPORT_AUTO_CHANNEL */
- #ifdef CUSTOMER_HW4
- #ifdef SUPPORT_AMPDU_MPDU_CMD
- /* CMD_AMPDU_MPDU */
- else if (strnicmp(command, CMD_AMPDU_MPDU, strlen(CMD_AMPDU_MPDU)) == 0) {
- int skip = strlen(CMD_AMPDU_MPDU) + 1;
- bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip);
- }
- #endif /* SUPPORT_AMPDU_MPDU_CMD */
- #if defined(WL_SUPPORT_AUTO_CHANNEL)
- else if (strnicmp(command, CMD_SET_HAPD_AUTO_CHANNEL,
- strlen(CMD_SET_HAPD_AUTO_CHANNEL)) == 0) {
- int skip = strlen(CMD_SET_HAPD_AUTO_CHANNEL) + 3;
- bytes_written = wl_android_set_auto_channel(net, (const char*)command+skip, command,
- priv_cmd.total_len);
- }
- #endif /* WL_SUPPORT_AUTO_CHANNEL */
- #if defined(SUPPORT_HIDDEN_AP)
- else if (strnicmp(command, CMD_SET_HAPD_MAX_NUM_STA,
- strlen(CMD_SET_HAPD_MAX_NUM_STA)) == 0) {
- int skip = strlen(CMD_SET_HAPD_MAX_NUM_STA) + 3;
- wl_android_set_max_num_sta(net, (const char*)command+skip);
- }
- else if (strnicmp(command, CMD_SET_HAPD_SSID,
- strlen(CMD_SET_HAPD_SSID)) == 0) {
- int skip = strlen(CMD_SET_HAPD_SSID) + 3;
- wl_android_set_ssid(net, (const char*)command+skip);
- }
- else if (strnicmp(command, CMD_SET_HAPD_HIDE_SSID,
- strlen(CMD_SET_HAPD_HIDE_SSID)) == 0) {
- int skip = strlen(CMD_SET_HAPD_HIDE_SSID) + 3;
- wl_android_set_hide_ssid(net, (const char*)command+skip);
- }
- #endif /* SUPPORT_HIDDEN_AP */
- #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
- else if (strnicmp(command, CMD_HAPD_STA_DISASSOC,
- strlen(CMD_HAPD_STA_DISASSOC)) == 0) {
- int skip = strlen(CMD_HAPD_STA_DISASSOC) + 1;
- wl_android_sta_diassoc(net, (const char*)command+skip);
- }
- #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
- #ifdef SUPPORT_SET_LPC
- else if (strnicmp(command, CMD_HAPD_LPC_ENABLED,
- strlen(CMD_HAPD_LPC_ENABLED)) == 0) {
- int skip = strlen(CMD_HAPD_LPC_ENABLED) + 3;
- wl_android_set_lpc(net, (const char*)command+skip);
- }
- #endif /* SUPPORT_SET_LPC */
- #ifdef SUPPORT_TRIGGER_HANG_EVENT
- else if (strnicmp(command, CMD_TEST_FORCE_HANG,
- strlen(CMD_TEST_FORCE_HANG)) == 0) {
- net_os_send_hang_message(net);
- }
- #endif /* SUPPORT_TRIGGER_HANG_EVENT */
- else if (strnicmp(command, CMD_CHANGE_RL, strlen(CMD_CHANGE_RL)) == 0)
- bytes_written = wl_android_ch_res_rl(net, true);
- else if (strnicmp(command, CMD_RESTORE_RL, strlen(CMD_RESTORE_RL)) == 0)
- bytes_written = wl_android_ch_res_rl(net, false);
- #ifdef SUPPORT_LTECX
- else if (strnicmp(command, CMD_LTECX_SET, strlen(CMD_LTECX_SET)) == 0) {
- int skip = strlen(CMD_LTECX_SET) + 1;
- bytes_written = wl_android_set_ltecx(net, (const char*)command+skip);
- }
- #endif /* SUPPORT_LTECX */
- else if (strnicmp(command, CMD_SET_RMC_ENABLE, strlen(CMD_SET_RMC_ENABLE)) == 0) {
- int rmc_enable = *(command + strlen(CMD_SET_RMC_ENABLE) + 1) - '0';
- bytes_written = wl_android_rmc_enable(net, rmc_enable);
- }
- else if (strnicmp(command, CMD_SET_RMC_TXRATE, strlen(CMD_SET_RMC_TXRATE)) == 0) {
- int rmc_txrate;
- sscanf(command, "%*s %10d", &rmc_txrate);
- bytes_written = wldev_iovar_setint(net, "rmc_txrate", rmc_txrate * 2);
- }
- else if (strnicmp(command, CMD_SET_RMC_ACTPERIOD, strlen(CMD_SET_RMC_ACTPERIOD)) == 0) {
- int actperiod;
- sscanf(command, "%*s %10d", &actperiod);
- bytes_written = wldev_iovar_setint(net, "rmc_actf_time", actperiod);
- }
- else if (strnicmp(command, CMD_SET_RMC_IDLEPERIOD, strlen(CMD_SET_RMC_IDLEPERIOD)) == 0) {
- int acktimeout;
- sscanf(command, "%*s %10d", &acktimeout);
- acktimeout *= 1000;
- bytes_written = wldev_iovar_setint(net, "rmc_acktmo", acktimeout);
- }
- else if (strnicmp(command, CMD_SET_RMC_LEADER, strlen(CMD_SET_RMC_LEADER)) == 0) {
- int skip = strlen(CMD_SET_RMC_LEADER) + 1;
- bytes_written = wl_android_rmc_set_leader(net, (const char*)command+skip);
- }
- else if (strnicmp(command, CMD_SET_RMC_EVENT,
- strlen(CMD_SET_RMC_EVENT)) == 0)
- bytes_written = wl_android_set_rmc_event(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_GET_SCSCAN, strlen(CMD_GET_SCSCAN)) == 0) {
- bytes_written = wl_android_get_singlecore_scan(net, command, priv_cmd.total_len);
- }
- else if (strnicmp(command, CMD_SET_SCSCAN, strlen(CMD_SET_SCSCAN)) == 0) {
- bytes_written = wl_android_set_singlecore_scan(net, command, priv_cmd.total_len);
- }
- #ifdef TEST_TX_POWER_CONTROL
- else if (strnicmp(command, CMD_TEST_SET_TX_POWER,
- strlen(CMD_TEST_SET_TX_POWER)) == 0) {
- int skip = strlen(CMD_TEST_SET_TX_POWER) + 1;
- wl_android_set_tx_power(net, (const char*)command+skip);
- }
- else if (strnicmp(command, CMD_TEST_GET_TX_POWER,
- strlen(CMD_TEST_GET_TX_POWER)) == 0) {
- wl_android_get_tx_power(net, command, priv_cmd.total_len);
- }
- #endif /* TEST_TX_POWER_CONTROL */
- #ifdef TX_POWER_CONTROL_CALLING
- else if (strnicmp(command, CMD_SET_TX_POWER_CALLING,
- strlen(CMD_SET_TX_POWER_CALLING)) == 0) {
- int skip = strlen(CMD_SET_TX_POWER_CALLING) + 1;
- wl_android_set_tx_power(net, (const char*)command+skip);
- }
- #endif /* TX_POWER_CONTROL_CALLING */
- #ifdef SARLIMIT_TX_CONTROL_NVRAM
- else if (strnicmp(command, CMD_SARLIMIT_TX_CONTROL,
- strlen(CMD_SARLIMIT_TX_CONTROL)) == 0) {
- int skip = strlen(CMD_SARLIMIT_TX_CONTROL) + 1;
- wl_android_set_sarlimit_txctrl(net, (const char*)command+skip);
- }
- #endif /* SARLIMIT_TX_CONTROL_NVRAM */
- #endif /* CUSTOMER_HW4 */
- else if (strnicmp(command, CMD_HAPD_MAC_FILTER, strlen(CMD_HAPD_MAC_FILTER)) == 0) {
- int skip = strlen(CMD_HAPD_MAC_FILTER) + 1;
- wl_android_set_mac_address_filter(net, (const char*)command+skip);
- }
- else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0)
- bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len);
- #if defined(BCMFW_ROAM_ENABLE)
- else if (strnicmp(command, CMD_SET_ROAMPREF, strlen(CMD_SET_ROAMPREF)) == 0) {
- bytes_written = wl_android_set_roampref(net, command, priv_cmd.total_len);
- }
- #endif /* BCMFW_ROAM_ENABLE */
- else if (strnicmp(command, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0)
- bytes_written = wl_android_set_miracast(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_SETIBSSBEACONOUIDATA, strlen(CMD_SETIBSSBEACONOUIDATA)) == 0)
- bytes_written = wl_android_set_ibss_beacon_ouidata(net,
- command, priv_cmd.total_len);
- #ifdef WLAIBSS
- else if (strnicmp(command, CMD_SETIBSSTXFAILEVENT,
- strlen(CMD_SETIBSSTXFAILEVENT)) == 0)
- bytes_written = wl_android_set_ibss_txfail_event(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO_ALL,
- strlen(CMD_GET_IBSS_PEER_INFO_ALL)) == 0)
- bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len,
- TRUE);
- else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO,
- strlen(CMD_GET_IBSS_PEER_INFO)) == 0)
- bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len,
- FALSE);
- else if (strnicmp(command, CMD_SETIBSSROUTETABLE,
- strlen(CMD_SETIBSSROUTETABLE)) == 0)
- bytes_written = wl_android_set_ibss_routetable(net, command,
- priv_cmd.total_len);
- else if (strnicmp(command, CMD_SETIBSSAMPDU, strlen(CMD_SETIBSSAMPDU)) == 0)
- bytes_written = wl_android_set_ibss_ampdu(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_SETIBSSANTENNAMODE, strlen(CMD_SETIBSSANTENNAMODE)) == 0)
- bytes_written = wl_android_set_ibss_antenna(net, command, priv_cmd.total_len);
- #endif /* WLAIBSS */
- else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
- int skip = strlen(CMD_KEEP_ALIVE) + 1;
- bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip);
- }
- else if (strnicmp(command, CMD_ROAM_OFFLOAD, strlen(CMD_ROAM_OFFLOAD)) == 0) {
- int enable = *(command + strlen(CMD_ROAM_OFFLOAD) + 1) - '0';
- bytes_written = wl_cfg80211_enable_roam_offload(net, enable);
- }
- #ifdef CONNECTION_STATISTICS
- else if (strnicmp(command, CMD_GET_CONNECTION_STATS,
- strlen(CMD_GET_CONNECTION_STATS)) == 0) {
- bytes_written = wl_android_get_connection_stats(net, command,
- priv_cmd.total_len);
- }
- #endif
- else {
- DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
- snprintf(command, 3, "OK");
- bytes_written = strlen("OK");
- }
- if (bytes_written >= 0) {
- if ((bytes_written == 0) && (priv_cmd.total_len > 0))
- command[0] = '\0';
- if (bytes_written >= priv_cmd.total_len) {
- DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
- bytes_written = priv_cmd.total_len;
- } else {
- bytes_written++;
- }
- priv_cmd.used_len = bytes_written;
- if (copy_to_user(priv_cmd.buf, command, bytes_written)) {
- DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__));
- ret = -EFAULT;
- }
- }
- else {
- ret = bytes_written;
- }
- exit:
- net_os_wake_unlock(net);
- if (command) {
- kfree(command);
- }
- return ret;
- }
- int wl_android_init(void)
- {
- int ret = 0;
- #ifdef ENABLE_INSMOD_NO_FW_LOAD
- dhd_download_fw_on_driverload = FALSE;
- #endif /* ENABLE_INSMOD_NO_FW_LOAD */
- #if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4)
- if (!iface_name[0]) {
- memset(iface_name, 0, IFNAMSIZ);
- bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ);
- }
- #endif /* CUSTOMER_HW2 || CUSTOMER_HW4 */
- #ifdef WL_GENL
- wl_genl_init();
- #endif
- wl_netlink_init();
- return ret;
- }
- int wl_android_exit(void)
- {
- int ret = 0;
- struct io_cfg *cur, *q;
- #ifdef WL_GENL
- wl_genl_deinit();
- #endif /* WL_GENL */
- wl_netlink_deinit();
- list_for_each_entry_safe(cur, q, &miracast_resume_list, list) {
- list_del(&cur->list);
- kfree(cur);
- }
- return ret;
- }
- void wl_android_post_init(void)
- {
- #ifdef ENABLE_4335BT_WAR
- bcm_bt_unlock(lock_cookie_wifi);
- printk("%s: btlock released\n", __FUNCTION__);
- #endif /* ENABLE_4335BT_WAR */
- if (!dhd_download_fw_on_driverload)
- g_wifi_on = FALSE;
- }
- #ifdef WL_GENL
- /* Generic Netlink Initializaiton */
- static int wl_genl_init(void)
- {
- int ret;
- WL_DBG(("GEN Netlink Init\n\n"));
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- /* register new family */
- ret = genl_register_family(&wl_genl_family);
- if (ret != 0)
- goto failure;
- /* register functions (commands) of the new family */
- ret = genl_register_ops(&wl_genl_family, &wl_genl_ops);
- if (ret != 0) {
- WL_ERR(("register ops failed: %i\n", ret));
- genl_unregister_family(&wl_genl_family);
- goto failure;
- }
- ret = genl_register_mc_group(&wl_genl_family, &wl_genl_mcast);
- #else
- ret = genl_register_family_with_ops_groups(&wl_genl_family, wl_genl_ops, wl_genl_mcast);
- #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
- if (ret != 0) {
- WL_ERR(("register mc_group failed: %i\n", ret));
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- genl_unregister_ops(&wl_genl_family, &wl_genl_ops);
- #endif
- genl_unregister_family(&wl_genl_family);
- goto failure;
- }
- return 0;
- failure:
- WL_ERR(("Registering Netlink failed!!\n"));
- return -1;
- }
- /* Generic netlink deinit */
- static int wl_genl_deinit(void)
- {
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- if (genl_unregister_ops(&wl_genl_family, &wl_genl_ops) < 0)
- WL_ERR(("Unregister wl_genl_ops failed\n"));
- #endif
- if (genl_unregister_family(&wl_genl_family) < 0)
- WL_ERR(("Unregister wl_genl_ops failed\n"));
- return 0;
- }
- s32 wl_event_to_bcm_event(u16 event_type)
- {
- u16 event = -1;
- switch (event_type) {
- case WLC_E_SERVICE_FOUND:
- event = BCM_E_SVC_FOUND;
- break;
- case WLC_E_P2PO_ADD_DEVICE:
- event = BCM_E_DEV_FOUND;
- break;
- case WLC_E_P2PO_DEL_DEVICE:
- event = BCM_E_DEV_LOST;
- break;
- /* Above events are supported from BCM Supp ver 47 Onwards */
- default:
- WL_ERR(("Event not supported\n"));
- }
- return event;
- }
- s32
- wl_genl_send_msg(
- struct net_device *ndev,
- u32 event_type,
- u8 *buf,
- u16 len,
- u8 *subhdr,
- u16 subhdr_len)
- {
- int ret = 0;
- struct sk_buff *skb;
- void *msg;
- u32 attr_type = 0;
- bcm_event_hdr_t *hdr = NULL;
- int mcast = 1; /* By default sent as mutlicast type */
- int pid = 0;
- u8 *ptr = NULL, *p = NULL;
- u32 tot_len = sizeof(bcm_event_hdr_t) + subhdr_len + len;
- u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- WL_DBG(("Enter \n"));
- /* Decide between STRING event and Data event */
- if (event_type == 0)
- attr_type = BCM_GENL_ATTR_STRING;
- else
- attr_type = BCM_GENL_ATTR_MSG;
- skb = genlmsg_new(NLMSG_GOODSIZE, kflags);
- if (skb == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- msg = genlmsg_put(skb, 0, 0, &wl_genl_family, 0, BCM_GENL_CMD_MSG);
- if (msg == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- if (attr_type == BCM_GENL_ATTR_STRING) {
- /* Add a BCM_GENL_MSG attribute. Since it is specified as a string.
- * make sure it is null terminated
- */
- if (subhdr || subhdr_len) {
- WL_ERR(("No sub hdr support for the ATTR STRING type \n"));
- ret = -EINVAL;
- goto out;
- }
- ret = nla_put_string(skb, BCM_GENL_ATTR_STRING, buf);
- if (ret != 0) {
- WL_ERR(("nla_put_string failed\n"));
- goto out;
- }
- } else {
- /* ATTR_MSG */
- /* Create a single buffer for all */
- p = ptr = kzalloc(tot_len, kflags);
- if (!ptr) {
- ret = -ENOMEM;
- WL_ERR(("ENOMEM!!\n"));
- goto out;
- }
- /* Include the bcm event header */
- hdr = (bcm_event_hdr_t *)ptr;
- hdr->event_type = wl_event_to_bcm_event(event_type);
- hdr->len = len + subhdr_len;
- ptr += sizeof(bcm_event_hdr_t);
- /* Copy subhdr (if any) */
- if (subhdr && subhdr_len) {
- memcpy(ptr, subhdr, subhdr_len);
- ptr += subhdr_len;
- }
- /* Copy the data */
- if (buf && len) {
- memcpy(ptr, buf, len);
- }
- ret = nla_put(skb, BCM_GENL_ATTR_MSG, tot_len, p);
- if (ret != 0) {
- WL_ERR(("nla_put_string failed\n"));
- goto out;
- }
- }
- if (mcast) {
- int err = 0;
- /* finalize the message */
- genlmsg_end(skb, msg);
- /* NETLINK_CB(skb).dst_group = 1; */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
- if ((err = genlmsg_multicast(skb, 0, wl_genl_mcast.id, GFP_ATOMIC)) < 0)
- #else
- if ((err = genlmsg_multicast(&wl_genl_family, skb, 0, 0, GFP_ATOMIC)) < 0)
- #endif
- WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n",
- attr_type, err));
- else
- WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n",
- attr_type, tot_len));
- } else {
- NETLINK_CB(skb).dst_group = 0; /* Not in multicast group */
- /* finalize the message */
- genlmsg_end(skb, msg);
- /* send the message back */
- if (genlmsg_unicast(&init_net, skb, pid) < 0)
- WL_ERR(("genlmsg_unicast failed\n"));
- }
- out:
- if (p)
- kfree(p);
- if (ret)
- nlmsg_free(skb);
- return ret;
- }
- static s32
- wl_genl_handle_msg(
- struct sk_buff *skb,
- struct genl_info *info)
- {
- struct nlattr *na;
- u8 *data = NULL;
- WL_DBG(("Enter \n"));
- if (info == NULL) {
- return -EINVAL;
- }
- na = info->attrs[BCM_GENL_ATTR_MSG];
- if (!na) {
- WL_ERR(("nlattribute NULL\n"));
- return -EINVAL;
- }
- data = (char *)nla_data(na);
- if (!data) {
- WL_ERR(("Invalid data\n"));
- return -EINVAL;
- } else {
- /* Handle the data */
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS)
- WL_DBG(("%s: Data received from pid (%d) \n", __func__,
- info->snd_pid));
- #else
- WL_DBG(("%s: Data received from pid (%d) \n", __func__,
- info->snd_portid));
- #endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */
- }
- return 0;
- }
- #endif /* WL_GENL */
|