lemote.patch 1.2 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947
  1. diff -Nur linux-2.6.33/arch/mips/boot/compressed/dbg.c linux-lemote/arch/mips/boot/compressed/dbg.c
  2. --- linux-2.6.33/arch/mips/boot/compressed/dbg.c 2010-02-24 19:52:17.000000000 +0100
  3. +++ linux-lemote/arch/mips/boot/compressed/dbg.c 2010-03-06 16:42:59.000000000 +0100
  4. @@ -9,7 +9,7 @@
  5. #include <linux/init.h>
  6. #include <linux/types.h>
  7. -void __attribute__ ((weak)) putc(char c)
  8. +void __weak putc(char c)
  9. {
  10. }
  11. diff -Nur linux-2.6.33/arch/mips/boot/compressed/decompress.c linux-lemote/arch/mips/boot/compressed/decompress.c
  12. --- linux-2.6.33/arch/mips/boot/compressed/decompress.c 2010-02-24 19:52:17.000000000 +0100
  13. +++ linux-lemote/arch/mips/boot/compressed/decompress.c 2010-03-06 16:42:59.000000000 +0100
  14. @@ -5,8 +5,8 @@
  15. * Author: Matt Porter <mporter@mvista.com> Derived from
  16. * arch/ppc/boot/prep/misc.c
  17. *
  18. - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
  19. - * Author: Wu Zhangjin <wuzj@lemote.com>
  20. + * Copyright (C) 2009 Lemote, Inc.
  21. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  22. *
  23. * This program is free software; you can redistribute it and/or modify it
  24. * under the terms of the GNU General Public License as published by the
  25. diff -Nur linux-2.6.33/arch/mips/boot/compressed/ld.script linux-lemote/arch/mips/boot/compressed/ld.script
  26. --- linux-2.6.33/arch/mips/boot/compressed/ld.script 2010-02-24 19:52:17.000000000 +0100
  27. +++ linux-lemote/arch/mips/boot/compressed/ld.script 2010-03-06 16:42:59.000000000 +0100
  28. @@ -2,7 +2,7 @@
  29. * ld.script for compressed kernel support of MIPS
  30. *
  31. * Copyright (C) 2009 Lemote Inc.
  32. - * Author: Wu Zhangjin <wuzj@lemote.com>
  33. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  34. */
  35. OUTPUT_ARCH(mips)
  36. @@ -29,8 +29,8 @@
  37. __image_end = .;
  38. CONSTRUCTORS
  39. }
  40. - .sdata : { *(.sdata) }
  41. - . = ALIGN(4);
  42. + .sdata : { *(.sdata) }
  43. + . = ALIGN(4);
  44. _edata = .; /* End of data section */
  45. /* BSS */
  46. diff -Nur linux-2.6.33/arch/mips/boot/compressed/Makefile linux-lemote/arch/mips/boot/compressed/Makefile
  47. --- linux-2.6.33/arch/mips/boot/compressed/Makefile 2010-02-24 19:52:17.000000000 +0100
  48. +++ linux-lemote/arch/mips/boot/compressed/Makefile 2010-03-06 16:42:59.000000000 +0100
  49. @@ -9,7 +9,7 @@
  50. # modified by Cort (cort@cs.nmt.edu)
  51. #
  52. # Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
  53. -# Author: Wu Zhangjin <wuzj@lemote.com>
  54. +# Author: Wu Zhangjin <wuzhangjin@gmail.com>
  55. #
  56. # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
  57. @@ -27,15 +27,17 @@
  58. KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
  59. KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
  60. - -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
  61. + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
  62. KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
  63. - -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
  64. - -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
  65. + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
  66. + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
  67. obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
  68. +ifdef CONFIG_DEBUG_ZBOOT
  69. obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
  70. +endif
  71. OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
  72. $(obj)/vmlinux.bin: $(KBUILD_IMAGE)
  73. diff -Nur linux-2.6.33/arch/mips/configs/fuloong2e_defconfig linux-lemote/arch/mips/configs/fuloong2e_defconfig
  74. --- linux-2.6.33/arch/mips/configs/fuloong2e_defconfig 2010-02-24 19:52:17.000000000 +0100
  75. +++ linux-lemote/arch/mips/configs/fuloong2e_defconfig 2010-03-06 16:42:59.000000000 +0100
  76. @@ -1,7 +1,7 @@
  77. #
  78. # Automatically generated make config: don't edit
  79. -# Linux kernel version: 2.6.32-rc4
  80. -# Fri Oct 16 13:18:01 2009
  81. +# Linux kernel version: 2.6.33
  82. +# Mon Mar 1 23:44:14 2010
  83. #
  84. CONFIG_MIPS=y
  85. @@ -27,6 +27,7 @@
  86. # CONFIG_PNX8550_STB810 is not set
  87. # CONFIG_PMC_MSP is not set
  88. # CONFIG_PMC_YOSEMITE is not set
  89. +# CONFIG_POWERTV is not set
  90. # CONFIG_SGI_IP22 is not set
  91. # CONFIG_SGI_IP27 is not set
  92. # CONFIG_SGI_IP28 is not set
  93. @@ -49,6 +50,8 @@
  94. # CONFIG_ALCHEMY_GPIO_INDIRECT is not set
  95. CONFIG_ARCH_SPARSEMEM_ENABLE=y
  96. CONFIG_LEMOTE_FULOONG2E=y
  97. +# CONFIG_LEMOTE_MACH2F is not set
  98. +CONFIG_LOONGSON_UART_BASE=y
  99. CONFIG_RWSEM_GENERIC_SPINLOCK=y
  100. # CONFIG_ARCH_HAS_ILOG2_U32 is not set
  101. # CONFIG_ARCH_HAS_ILOG2_U64 is not set
  102. @@ -67,7 +70,6 @@
  103. CONFIG_CSRC_R4K=y
  104. CONFIG_DMA_NONCOHERENT=y
  105. CONFIG_DMA_NEED_PCI_MAP_STATE=y
  106. -CONFIG_EARLY_PRINTK=y
  107. CONFIG_SYS_HAS_EARLY_PRINTK=y
  108. CONFIG_I8259=y
  109. # CONFIG_NO_IOPORT is not set
  110. @@ -84,6 +86,7 @@
  111. # CPU selection
  112. #
  113. CONFIG_CPU_LOONGSON2E=y
  114. +# CONFIG_CPU_LOONGSON2F is not set
  115. # CONFIG_CPU_MIPS32_R1 is not set
  116. # CONFIG_CPU_MIPS32_R2 is not set
  117. # CONFIG_CPU_MIPS64_R1 is not set
  118. @@ -106,7 +109,6 @@
  119. # CONFIG_CPU_SB1 is not set
  120. # CONFIG_CPU_CAVIUM_OCTEON is not set
  121. CONFIG_SYS_SUPPORTS_ZBOOT=y
  122. -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
  123. CONFIG_CPU_LOONGSON2=y
  124. CONFIG_SYS_HAS_CPU_LOONGSON2E=y
  125. CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
  126. @@ -134,7 +136,6 @@
  127. CONFIG_GENERIC_IRQ_PROBE=y
  128. CONFIG_CPU_SUPPORTS_HIGHMEM=y
  129. CONFIG_SYS_SUPPORTS_HIGHMEM=y
  130. -CONFIG_ARCH_FLATMEM_ENABLE=y
  131. CONFIG_ARCH_POPULATES_NODE_MAP=y
  132. CONFIG_SELECT_MEMORY_MODEL=y
  133. # CONFIG_FLATMEM_MANUAL is not set
  134. @@ -143,23 +144,18 @@
  135. CONFIG_SPARSEMEM=y
  136. CONFIG_HAVE_MEMORY_PRESENT=y
  137. CONFIG_SPARSEMEM_STATIC=y
  138. -
  139. -#
  140. -# Memory hotplug is currently incompatible with Software Suspend
  141. -#
  142. CONFIG_PAGEFLAGS_EXTENDED=y
  143. CONFIG_SPLIT_PTLOCK_CPUS=4
  144. CONFIG_PHYS_ADDR_T_64BIT=y
  145. CONFIG_ZONE_DMA_FLAG=0
  146. CONFIG_VIRT_TO_BUS=y
  147. -CONFIG_HAVE_MLOCK=y
  148. -CONFIG_HAVE_MLOCKED_PAGE_BIT=y
  149. # CONFIG_KSM is not set
  150. CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  151. CONFIG_TICK_ONESHOT=y
  152. CONFIG_NO_HZ=y
  153. CONFIG_HIGH_RES_TIMERS=y
  154. CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
  155. +CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK=y
  156. # CONFIG_HZ_48 is not set
  157. # CONFIG_HZ_100 is not set
  158. # CONFIG_HZ_128 is not set
  159. @@ -190,9 +186,11 @@
  160. CONFIG_HAVE_KERNEL_GZIP=y
  161. CONFIG_HAVE_KERNEL_BZIP2=y
  162. CONFIG_HAVE_KERNEL_LZMA=y
  163. +CONFIG_HAVE_KERNEL_LZO=y
  164. CONFIG_KERNEL_GZIP=y
  165. # CONFIG_KERNEL_BZIP2 is not set
  166. # CONFIG_KERNEL_LZMA is not set
  167. +# CONFIG_KERNEL_LZO is not set
  168. CONFIG_SWAP=y
  169. CONFIG_SYSVIPC=y
  170. CONFIG_SYSVIPC_SYSCTL=y
  171. @@ -208,6 +206,7 @@
  172. #
  173. CONFIG_TREE_RCU=y
  174. # CONFIG_TREE_PREEMPT_RCU is not set
  175. +# CONFIG_TINY_RCU is not set
  176. # CONFIG_RCU_TRACE is not set
  177. CONFIG_RCU_FANOUT=64
  178. # CONFIG_RCU_FANOUT_EXACT is not set
  179. @@ -217,8 +216,7 @@
  180. CONFIG_LOG_BUF_SHIFT=14
  181. # CONFIG_GROUP_SCHED is not set
  182. # CONFIG_CGROUPS is not set
  183. -CONFIG_SYSFS_DEPRECATED=y
  184. -CONFIG_SYSFS_DEPRECATED_V2=y
  185. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  186. # CONFIG_RELAY is not set
  187. CONFIG_NAMESPACES=y
  188. # CONFIG_UTS_NS is not set
  189. @@ -268,6 +266,7 @@
  190. #
  191. # CONFIG_GCOV_KERNEL is not set
  192. CONFIG_SLOW_WORK=y
  193. +# CONFIG_SLOW_WORK_DEBUG is not set
  194. CONFIG_HAVE_GENERIC_DMA_COHERENT=y
  195. CONFIG_SLABINFO=y
  196. CONFIG_RT_MUTEXES=y
  197. @@ -287,14 +286,41 @@
  198. # IO Schedulers
  199. #
  200. CONFIG_IOSCHED_NOOP=y
  201. -CONFIG_IOSCHED_AS=y
  202. CONFIG_IOSCHED_DEADLINE=y
  203. CONFIG_IOSCHED_CFQ=y
  204. -# CONFIG_DEFAULT_AS is not set
  205. # CONFIG_DEFAULT_DEADLINE is not set
  206. CONFIG_DEFAULT_CFQ=y
  207. # CONFIG_DEFAULT_NOOP is not set
  208. CONFIG_DEFAULT_IOSCHED="cfq"
  209. +# CONFIG_INLINE_SPIN_TRYLOCK is not set
  210. +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
  211. +# CONFIG_INLINE_SPIN_LOCK is not set
  212. +# CONFIG_INLINE_SPIN_LOCK_BH is not set
  213. +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
  214. +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
  215. +CONFIG_INLINE_SPIN_UNLOCK=y
  216. +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
  217. +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
  218. +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
  219. +# CONFIG_INLINE_READ_TRYLOCK is not set
  220. +# CONFIG_INLINE_READ_LOCK is not set
  221. +# CONFIG_INLINE_READ_LOCK_BH is not set
  222. +# CONFIG_INLINE_READ_LOCK_IRQ is not set
  223. +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
  224. +CONFIG_INLINE_READ_UNLOCK=y
  225. +# CONFIG_INLINE_READ_UNLOCK_BH is not set
  226. +CONFIG_INLINE_READ_UNLOCK_IRQ=y
  227. +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
  228. +# CONFIG_INLINE_WRITE_TRYLOCK is not set
  229. +# CONFIG_INLINE_WRITE_LOCK is not set
  230. +# CONFIG_INLINE_WRITE_LOCK_BH is not set
  231. +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
  232. +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
  233. +CONFIG_INLINE_WRITE_UNLOCK=y
  234. +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
  235. +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
  236. +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
  237. +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
  238. CONFIG_FREEZER=y
  239. #
  240. @@ -340,7 +366,6 @@
  241. CONFIG_PM_STD_PARTITION="/dev/hda3"
  242. # CONFIG_PM_RUNTIME is not set
  243. CONFIG_NET=y
  244. -CONFIG_COMPAT_NETLINK_MESSAGES=y
  245. #
  246. # Networking options
  247. @@ -491,10 +516,6 @@
  248. # CONFIG_AF_RXRPC is not set
  249. CONFIG_WIRELESS=y
  250. # CONFIG_CFG80211 is not set
  251. -CONFIG_CFG80211_DEFAULT_PS_VALUE=0
  252. -CONFIG_WIRELESS_OLD_REGULATORY=y
  253. -CONFIG_WIRELESS_EXT=y
  254. -CONFIG_WIRELESS_EXT_SYSFS=y
  255. # CONFIG_LIB80211 is not set
  256. #
  257. @@ -617,6 +638,10 @@
  258. # CONFIG_BLK_DEV_COW_COMMON is not set
  259. CONFIG_BLK_DEV_LOOP=y
  260. CONFIG_BLK_DEV_CRYPTOLOOP=m
  261. +
  262. +#
  263. +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
  264. +#
  265. # CONFIG_BLK_DEV_NBD is not set
  266. # CONFIG_BLK_DEV_SX8 is not set
  267. # CONFIG_BLK_DEV_UB is not set
  268. @@ -755,7 +780,7 @@
  269. #
  270. #
  271. -# See the help texts for more information.
  272. +# The newer stack is recommended.
  273. #
  274. # CONFIG_FIREWIRE is not set
  275. # CONFIG_IEEE1394 is not set
  276. @@ -798,6 +823,7 @@
  277. # CONFIG_SMC91X is not set
  278. # CONFIG_DM9000 is not set
  279. # CONFIG_ETHOC is not set
  280. +# CONFIG_SMSC911X is not set
  281. # CONFIG_NET_VENDOR_RACAL is not set
  282. # CONFIG_DNET is not set
  283. # CONFIG_NET_TULIP is not set
  284. @@ -888,8 +914,10 @@
  285. # CONFIG_BE2NET is not set
  286. # CONFIG_TR is not set
  287. CONFIG_WLAN=y
  288. -# CONFIG_WLAN_PRE80211 is not set
  289. -# CONFIG_WLAN_80211 is not set
  290. +# CONFIG_ATMEL is not set
  291. +# CONFIG_PRISM54 is not set
  292. +# CONFIG_USB_ZD1201 is not set
  293. +# CONFIG_HOSTAP is not set
  294. #
  295. # Enable WiMAX (Networking options) to see the WiMAX drivers
  296. @@ -926,6 +954,7 @@
  297. # CONFIG_NETCONSOLE is not set
  298. # CONFIG_NETPOLL is not set
  299. # CONFIG_NET_POLL_CONTROLLER is not set
  300. +# CONFIG_VMXNET3 is not set
  301. # CONFIG_ISDN is not set
  302. # CONFIG_PHONE is not set
  303. @@ -935,6 +964,7 @@
  304. CONFIG_INPUT=y
  305. CONFIG_INPUT_FF_MEMLESS=y
  306. # CONFIG_INPUT_POLLDEV is not set
  307. +# CONFIG_INPUT_SPARSEKMAP is not set
  308. #
  309. # Userland interfaces
  310. @@ -992,6 +1022,7 @@
  311. # CONFIG_SERIO_PCIPS2 is not set
  312. CONFIG_SERIO_LIBPS2=y
  313. # CONFIG_SERIO_RAW is not set
  314. +# CONFIG_SERIO_ALTERA_PS2 is not set
  315. # CONFIG_GAMEPORT is not set
  316. #
  317. @@ -1078,11 +1109,6 @@
  318. # CONFIG_I2C_TINY_USB is not set
  319. #
  320. -# Graphics adapter I2C/DDC channel drivers
  321. -#
  322. -# CONFIG_I2C_VOODOO3 is not set
  323. -
  324. -#
  325. # Other I2C/SMBus bus drivers
  326. #
  327. # CONFIG_I2C_ELEKTOR is not set
  328. @@ -1093,7 +1119,6 @@
  329. #
  330. # Miscellaneous I2C Chip support
  331. #
  332. -# CONFIG_DS1682 is not set
  333. # CONFIG_SENSORS_TSL2550 is not set
  334. # CONFIG_I2C_DEBUG_CORE is not set
  335. # CONFIG_I2C_DEBUG_ALGO is not set
  336. @@ -1125,7 +1150,6 @@
  337. # CONFIG_HTC_PASIC3 is not set
  338. # CONFIG_MFD_TMIO is not set
  339. # CONFIG_MFD_WM8400 is not set
  340. -# CONFIG_MFD_WM831X is not set
  341. # CONFIG_MFD_WM8350_I2C is not set
  342. # CONFIG_MFD_PCF50633 is not set
  343. # CONFIG_AB3100_CORE is not set
  344. @@ -1271,6 +1295,7 @@
  345. # CONFIG_SND_OXYGEN is not set
  346. # CONFIG_SND_CS4281 is not set
  347. # CONFIG_SND_CS46XX is not set
  348. +# CONFIG_SND_CS5535AUDIO is not set
  349. # CONFIG_SND_CTXFI is not set
  350. # CONFIG_SND_DARLA20 is not set
  351. # CONFIG_SND_GINA20 is not set
  352. @@ -1482,6 +1507,7 @@
  353. # TI VLYNQ
  354. #
  355. # CONFIG_STAGING is not set
  356. +CONFIG_MIPS_PLATFORM_DEVICES=y
  357. #
  358. # File systems
  359. @@ -1522,8 +1548,8 @@
  360. # CONFIG_QUOTA is not set
  361. CONFIG_AUTOFS_FS=y
  362. CONFIG_AUTOFS4_FS=y
  363. -CONFIG_FUSE_FS=y
  364. -# CONFIG_CUSE is not set
  365. +CONFIG_FUSE_FS=m
  366. +CONFIG_CUSE=m
  367. #
  368. # Caches
  369. @@ -1700,6 +1726,11 @@
  370. # CONFIG_RCU_CPU_STALL_DETECTOR is not set
  371. CONFIG_SYSCTL_SYSCALL_CHECK=y
  372. CONFIG_NOP_TRACER=y
  373. +CONFIG_HAVE_FUNCTION_TRACER=y
  374. +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
  375. +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
  376. +CONFIG_HAVE_DYNAMIC_FTRACE=y
  377. +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
  378. CONFIG_RING_BUFFER=y
  379. CONFIG_EVENT_TRACING=y
  380. CONFIG_CONTEXT_SWITCH_TRACER=y
  381. @@ -1710,6 +1741,7 @@
  382. # CONFIG_DYNAMIC_DEBUG is not set
  383. # CONFIG_SAMPLES is not set
  384. CONFIG_HAVE_ARCH_KGDB=y
  385. +CONFIG_EARLY_PRINTK=y
  386. # CONFIG_CMDLINE_BOOL is not set
  387. #
  388. @@ -1718,7 +1750,11 @@
  389. # CONFIG_KEYS is not set
  390. # CONFIG_SECURITY is not set
  391. # CONFIG_SECURITYFS is not set
  392. -CONFIG_SECURITY_FILE_CAPABILITIES=y
  393. +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
  394. +# CONFIG_DEFAULT_SECURITY_SMACK is not set
  395. +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
  396. +CONFIG_DEFAULT_SECURITY_DAC=y
  397. +CONFIG_DEFAULT_SECURITY=""
  398. CONFIG_CRYPTO=y
  399. #
  400. diff -Nur linux-2.6.33/arch/mips/configs/lemote2f_defconfig linux-lemote/arch/mips/configs/lemote2f_defconfig
  401. --- linux-2.6.33/arch/mips/configs/lemote2f_defconfig 2010-02-24 19:52:17.000000000 +0100
  402. +++ linux-lemote/arch/mips/configs/lemote2f_defconfig 2010-03-06 16:42:59.000000000 +0100
  403. @@ -1,7 +1,7 @@
  404. #
  405. # Automatically generated make config: don't edit
  406. -# Linux kernel version: 2.6.32-rc6
  407. -# Mon Nov 9 23:42:42 2009
  408. +# Linux kernel version: 2.6.33
  409. +# Mon Mar 1 23:36:53 2010
  410. #
  411. CONFIG_MIPS=y
  412. @@ -27,6 +27,7 @@
  413. # CONFIG_PNX8550_STB810 is not set
  414. # CONFIG_PMC_MSP is not set
  415. # CONFIG_PMC_YOSEMITE is not set
  416. +# CONFIG_POWERTV is not set
  417. # CONFIG_SGI_IP22 is not set
  418. # CONFIG_SGI_IP27 is not set
  419. # CONFIG_SGI_IP28 is not set
  420. @@ -51,6 +52,9 @@
  421. # CONFIG_LEMOTE_FULOONG2E is not set
  422. CONFIG_LEMOTE_MACH2F=y
  423. CONFIG_CS5536=y
  424. +CONFIG_CS5536_MFGPT=y
  425. +CONFIG_LOONGSON_SUSPEND=y
  426. +CONFIG_LOONGSON_UART_BASE=y
  427. CONFIG_RWSEM_GENERIC_SPINLOCK=y
  428. # CONFIG_ARCH_HAS_ILOG2_U32 is not set
  429. # CONFIG_ARCH_HAS_ILOG2_U64 is not set
  430. @@ -63,13 +67,8 @@
  431. CONFIG_GENERIC_CMOS_UPDATE=y
  432. CONFIG_SCHED_OMIT_FRAME_POINTER=y
  433. CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
  434. -CONFIG_CEVT_R4K_LIB=y
  435. -CONFIG_CEVT_R4K=y
  436. -CONFIG_CSRC_R4K_LIB=y
  437. -CONFIG_CSRC_R4K=y
  438. CONFIG_DMA_NONCOHERENT=y
  439. CONFIG_DMA_NEED_PCI_MAP_STATE=y
  440. -CONFIG_EARLY_PRINTK=y
  441. CONFIG_SYS_HAS_EARLY_PRINTK=y
  442. CONFIG_I8259=y
  443. # CONFIG_NO_IOPORT is not set
  444. @@ -109,13 +108,15 @@
  445. # CONFIG_CPU_SB1 is not set
  446. # CONFIG_CPU_CAVIUM_OCTEON is not set
  447. CONFIG_SYS_SUPPORTS_ZBOOT=y
  448. -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
  449. CONFIG_CPU_LOONGSON2=y
  450. CONFIG_SYS_HAS_CPU_LOONGSON2F=y
  451. CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
  452. CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
  453. CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
  454. CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
  455. +CONFIG_CPU_SUPPORTS_CPUFREQ=y
  456. +CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
  457. +CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
  458. #
  459. # Kernel type
  460. @@ -137,7 +138,6 @@
  461. CONFIG_GENERIC_IRQ_PROBE=y
  462. CONFIG_CPU_SUPPORTS_HIGHMEM=y
  463. CONFIG_SYS_SUPPORTS_HIGHMEM=y
  464. -CONFIG_ARCH_FLATMEM_ENABLE=y
  465. CONFIG_ARCH_POPULATES_NODE_MAP=y
  466. CONFIG_SELECT_MEMORY_MODEL=y
  467. # CONFIG_FLATMEM_MANUAL is not set
  468. @@ -146,17 +146,11 @@
  469. CONFIG_SPARSEMEM=y
  470. CONFIG_HAVE_MEMORY_PRESENT=y
  471. CONFIG_SPARSEMEM_STATIC=y
  472. -
  473. -#
  474. -# Memory hotplug is currently incompatible with Software Suspend
  475. -#
  476. CONFIG_PAGEFLAGS_EXTENDED=y
  477. CONFIG_SPLIT_PTLOCK_CPUS=4
  478. CONFIG_PHYS_ADDR_T_64BIT=y
  479. CONFIG_ZONE_DMA_FLAG=0
  480. CONFIG_VIRT_TO_BUS=y
  481. -CONFIG_HAVE_MLOCK=y
  482. -CONFIG_HAVE_MLOCKED_PAGE_BIT=y
  483. # CONFIG_KSM is not set
  484. CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  485. CONFIG_TICK_ONESHOT=y
  486. @@ -175,7 +169,7 @@
  487. # CONFIG_PREEMPT_NONE is not set
  488. # CONFIG_PREEMPT_VOLUNTARY is not set
  489. CONFIG_PREEMPT=y
  490. -# CONFIG_KEXEC is not set
  491. +CONFIG_KEXEC=y
  492. # CONFIG_SECCOMP is not set
  493. CONFIG_LOCKDEP_SUPPORT=y
  494. CONFIG_STACKTRACE_SUPPORT=y
  495. @@ -194,9 +188,11 @@
  496. CONFIG_HAVE_KERNEL_GZIP=y
  497. CONFIG_HAVE_KERNEL_BZIP2=y
  498. CONFIG_HAVE_KERNEL_LZMA=y
  499. -# CONFIG_KERNEL_GZIP is not set
  500. +CONFIG_HAVE_KERNEL_LZO=y
  501. +CONFIG_KERNEL_GZIP=y
  502. # CONFIG_KERNEL_BZIP2 is not set
  503. -CONFIG_KERNEL_LZMA=y
  504. +# CONFIG_KERNEL_LZMA is not set
  505. +# CONFIG_KERNEL_LZO is not set
  506. CONFIG_SWAP=y
  507. CONFIG_SYSVIPC=y
  508. CONFIG_SYSVIPC_SYSCTL=y
  509. @@ -211,6 +207,7 @@
  510. #
  511. CONFIG_TREE_RCU=y
  512. # CONFIG_TREE_PREEMPT_RCU is not set
  513. +# CONFIG_TINY_RCU is not set
  514. # CONFIG_RCU_TRACE is not set
  515. CONFIG_RCU_FANOUT=64
  516. # CONFIG_RCU_FANOUT_EXACT is not set
  517. @@ -220,11 +217,15 @@
  518. CONFIG_LOG_BUF_SHIFT=15
  519. # CONFIG_GROUP_SCHED is not set
  520. # CONFIG_CGROUPS is not set
  521. -CONFIG_SYSFS_DEPRECATED=y
  522. -CONFIG_SYSFS_DEPRECATED_V2=y
  523. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  524. # CONFIG_RELAY is not set
  525. # CONFIG_NAMESPACES is not set
  526. -# CONFIG_BLK_DEV_INITRD is not set
  527. +CONFIG_BLK_DEV_INITRD=y
  528. +CONFIG_INITRAMFS_SOURCE=""
  529. +CONFIG_RD_GZIP=y
  530. +CONFIG_RD_BZIP2=y
  531. +CONFIG_RD_LZMA=y
  532. +# CONFIG_RD_LZO is not set
  533. # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  534. CONFIG_SYSCTL=y
  535. CONFIG_ANON_INODES=y
  536. @@ -251,21 +252,24 @@
  537. #
  538. CONFIG_VM_EVENT_COUNTERS=y
  539. CONFIG_PCI_QUIRKS=y
  540. -CONFIG_SLUB_DEBUG=y
  541. +# CONFIG_SLUB_DEBUG is not set
  542. CONFIG_COMPAT_BRK=y
  543. # CONFIG_SLAB is not set
  544. CONFIG_SLUB=y
  545. # CONFIG_SLOB is not set
  546. -# CONFIG_PROFILING is not set
  547. +CONFIG_PROFILING=y
  548. +CONFIG_TRACEPOINTS=y
  549. +CONFIG_OPROFILE=m
  550. CONFIG_HAVE_OPROFILE=y
  551. CONFIG_HAVE_SYSCALL_WRAPPERS=y
  552. #
  553. # GCOV-based kernel profiling
  554. #
  555. -# CONFIG_SLOW_WORK is not set
  556. +# CONFIG_GCOV_KERNEL is not set
  557. +CONFIG_SLOW_WORK=y
  558. +# CONFIG_SLOW_WORK_DEBUG is not set
  559. CONFIG_HAVE_GENERIC_DMA_COHERENT=y
  560. -CONFIG_SLABINFO=y
  561. CONFIG_RT_MUTEXES=y
  562. CONFIG_BASE_SMALL=0
  563. CONFIG_MODULES=y
  564. @@ -283,14 +287,41 @@
  565. # IO Schedulers
  566. #
  567. CONFIG_IOSCHED_NOOP=y
  568. -CONFIG_IOSCHED_AS=y
  569. -CONFIG_IOSCHED_DEADLINE=y
  570. +CONFIG_IOSCHED_DEADLINE=m
  571. CONFIG_IOSCHED_CFQ=y
  572. -# CONFIG_DEFAULT_AS is not set
  573. # CONFIG_DEFAULT_DEADLINE is not set
  574. CONFIG_DEFAULT_CFQ=y
  575. # CONFIG_DEFAULT_NOOP is not set
  576. CONFIG_DEFAULT_IOSCHED="cfq"
  577. +# CONFIG_INLINE_SPIN_TRYLOCK is not set
  578. +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
  579. +# CONFIG_INLINE_SPIN_LOCK is not set
  580. +# CONFIG_INLINE_SPIN_LOCK_BH is not set
  581. +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
  582. +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
  583. +# CONFIG_INLINE_SPIN_UNLOCK is not set
  584. +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
  585. +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
  586. +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
  587. +# CONFIG_INLINE_READ_TRYLOCK is not set
  588. +# CONFIG_INLINE_READ_LOCK is not set
  589. +# CONFIG_INLINE_READ_LOCK_BH is not set
  590. +# CONFIG_INLINE_READ_LOCK_IRQ is not set
  591. +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
  592. +# CONFIG_INLINE_READ_UNLOCK is not set
  593. +# CONFIG_INLINE_READ_UNLOCK_BH is not set
  594. +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
  595. +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
  596. +# CONFIG_INLINE_WRITE_TRYLOCK is not set
  597. +# CONFIG_INLINE_WRITE_LOCK is not set
  598. +# CONFIG_INLINE_WRITE_LOCK_BH is not set
  599. +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
  600. +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
  601. +# CONFIG_INLINE_WRITE_UNLOCK is not set
  602. +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
  603. +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
  604. +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
  605. +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
  606. CONFIG_FREEZER=y
  607. #
  608. @@ -300,7 +331,7 @@
  609. CONFIG_PCI=y
  610. CONFIG_PCI_DOMAINS=y
  611. # CONFIG_ARCH_SUPPORTS_MSI is not set
  612. -CONFIG_PCI_LEGACY=y
  613. +# CONFIG_PCI_LEGACY is not set
  614. # CONFIG_PCI_STUB is not set
  615. # CONFIG_PCI_IOV is not set
  616. CONFIG_ISA=y
  617. @@ -314,7 +345,7 @@
  618. CONFIG_BINFMT_ELF=y
  619. # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  620. # CONFIG_HAVE_AOUT is not set
  621. -# CONFIG_BINFMT_MISC is not set
  622. +CONFIG_BINFMT_MISC=m
  623. CONFIG_MIPS32_COMPAT=y
  624. CONFIG_COMPAT=y
  625. CONFIG_SYSVIPC_COMPAT=y
  626. @@ -335,7 +366,33 @@
  627. CONFIG_HIBERNATION_NVS=y
  628. CONFIG_HIBERNATION=y
  629. CONFIG_PM_STD_PARTITION="/dev/hda3"
  630. -# CONFIG_PM_RUNTIME is not set
  631. +CONFIG_PM_RUNTIME=y
  632. +CONFIG_MIPS_EXTERNAL_TIMER=y
  633. +CONFIG_MIPS_CPUFREQ=y
  634. +
  635. +#
  636. +# CPU Frequency scaling
  637. +#
  638. +CONFIG_CPU_FREQ=y
  639. +CONFIG_CPU_FREQ_TABLE=y
  640. +CONFIG_CPU_FREQ_DEBUG=y
  641. +CONFIG_CPU_FREQ_STAT=m
  642. +CONFIG_CPU_FREQ_STAT_DETAILS=y
  643. +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
  644. +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
  645. +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
  646. +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
  647. +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
  648. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  649. +CONFIG_CPU_FREQ_GOV_POWERSAVE=m
  650. +CONFIG_CPU_FREQ_GOV_USERSPACE=m
  651. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  652. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
  653. +
  654. +#
  655. +# CPUFreq processor drivers
  656. +#
  657. +CONFIG_LOONGSON2_CPUFREQ=m
  658. CONFIG_NET=y
  659. CONFIG_COMPAT_NETLINK_MESSAGES=y
  660. @@ -346,11 +403,12 @@
  661. CONFIG_PACKET_MMAP=y
  662. CONFIG_UNIX=y
  663. CONFIG_XFRM=y
  664. -# CONFIG_XFRM_USER is not set
  665. +CONFIG_XFRM_USER=m
  666. # CONFIG_XFRM_SUB_POLICY is not set
  667. # CONFIG_XFRM_MIGRATE is not set
  668. # CONFIG_XFRM_STATISTICS is not set
  669. -# CONFIG_NET_KEY is not set
  670. +CONFIG_NET_KEY=m
  671. +# CONFIG_NET_KEY_MIGRATE is not set
  672. CONFIG_INET=y
  673. CONFIG_IP_MULTICAST=y
  674. CONFIG_IP_ADVANCED_ROUTER=y
  675. @@ -361,12 +419,13 @@
  676. CONFIG_IP_ROUTE_MULTIPATH=y
  677. CONFIG_IP_ROUTE_VERBOSE=y
  678. # CONFIG_IP_PNP is not set
  679. -# CONFIG_NET_IPIP is not set
  680. -# CONFIG_NET_IPGRE is not set
  681. +CONFIG_NET_IPIP=m
  682. +CONFIG_NET_IPGRE=m
  683. +# CONFIG_NET_IPGRE_BROADCAST is not set
  684. CONFIG_IP_MROUTE=y
  685. CONFIG_IP_PIMSM_V1=y
  686. CONFIG_IP_PIMSM_V2=y
  687. -# CONFIG_ARPD is not set
  688. +CONFIG_ARPD=y
  689. CONFIG_SYN_COOKIES=y
  690. # CONFIG_INET_AH is not set
  691. # CONFIG_INET_ESP is not set
  692. @@ -399,30 +458,34 @@
  693. # CONFIG_DEFAULT_WESTWOOD is not set
  694. # CONFIG_DEFAULT_RENO is not set
  695. CONFIG_DEFAULT_TCP_CONG="bic"
  696. -# CONFIG_TCP_MD5SIG is not set
  697. +CONFIG_TCP_MD5SIG=y
  698. CONFIG_IPV6=m
  699. CONFIG_IPV6_PRIVACY=y
  700. -# CONFIG_IPV6_ROUTER_PREF is not set
  701. +CONFIG_IPV6_ROUTER_PREF=y
  702. +# CONFIG_IPV6_ROUTE_INFO is not set
  703. # CONFIG_IPV6_OPTIMISTIC_DAD is not set
  704. # CONFIG_INET6_AH is not set
  705. # CONFIG_INET6_ESP is not set
  706. # CONFIG_INET6_IPCOMP is not set
  707. # CONFIG_IPV6_MIP6 is not set
  708. # CONFIG_INET6_XFRM_TUNNEL is not set
  709. -# CONFIG_INET6_TUNNEL is not set
  710. +CONFIG_INET6_TUNNEL=m
  711. CONFIG_INET6_XFRM_MODE_TRANSPORT=m
  712. CONFIG_INET6_XFRM_MODE_TUNNEL=m
  713. CONFIG_INET6_XFRM_MODE_BEET=m
  714. # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
  715. CONFIG_IPV6_SIT=m
  716. +# CONFIG_IPV6_SIT_6RD is not set
  717. CONFIG_IPV6_NDISC_NODETYPE=y
  718. -# CONFIG_IPV6_TUNNEL is not set
  719. -# CONFIG_IPV6_MULTIPLE_TABLES is not set
  720. +CONFIG_IPV6_TUNNEL=m
  721. +CONFIG_IPV6_MULTIPLE_TABLES=y
  722. +CONFIG_IPV6_SUBTREES=y
  723. # CONFIG_IPV6_MROUTE is not set
  724. CONFIG_NETWORK_SECMARK=y
  725. CONFIG_NETFILTER=y
  726. # CONFIG_NETFILTER_DEBUG is not set
  727. CONFIG_NETFILTER_ADVANCED=y
  728. +CONFIG_BRIDGE_NETFILTER=y
  729. #
  730. # Core Netfilter Configuration
  731. @@ -446,17 +509,22 @@
  732. #
  733. # CONFIG_IP6_NF_QUEUE is not set
  734. # CONFIG_IP6_NF_IPTABLES is not set
  735. +# CONFIG_BRIDGE_NF_EBTABLES is not set
  736. # CONFIG_IP_DCCP is not set
  737. # CONFIG_IP_SCTP is not set
  738. # CONFIG_RDS is not set
  739. # CONFIG_TIPC is not set
  740. # CONFIG_ATM is not set
  741. -# CONFIG_BRIDGE is not set
  742. +CONFIG_STP=m
  743. +CONFIG_BRIDGE=m
  744. # CONFIG_NET_DSA is not set
  745. -# CONFIG_VLAN_8021Q is not set
  746. +CONFIG_VLAN_8021Q=m
  747. +# CONFIG_VLAN_8021Q_GVRP is not set
  748. # CONFIG_DECNET is not set
  749. +CONFIG_LLC=m
  750. # CONFIG_LLC2 is not set
  751. -# CONFIG_IPX is not set
  752. +CONFIG_IPX=m
  753. +# CONFIG_IPX_INTERN is not set
  754. # CONFIG_ATALK is not set
  755. # CONFIG_X25 is not set
  756. # CONFIG_LAPB is not set
  757. @@ -518,26 +586,64 @@
  758. # Network testing
  759. #
  760. # CONFIG_NET_PKTGEN is not set
  761. +# CONFIG_NET_DROP_MONITOR is not set
  762. # CONFIG_HAMRADIO is not set
  763. # CONFIG_CAN is not set
  764. # CONFIG_IRDA is not set
  765. -# CONFIG_BT is not set
  766. +CONFIG_BT=m
  767. +CONFIG_BT_L2CAP=m
  768. +CONFIG_BT_SCO=m
  769. +CONFIG_BT_RFCOMM=m
  770. +CONFIG_BT_RFCOMM_TTY=y
  771. +CONFIG_BT_BNEP=m
  772. +CONFIG_BT_BNEP_MC_FILTER=y
  773. +CONFIG_BT_BNEP_PROTO_FILTER=y
  774. +CONFIG_BT_HIDP=m
  775. +
  776. +#
  777. +# Bluetooth device drivers
  778. +#
  779. +CONFIG_BT_HCIBTUSB=m
  780. +# CONFIG_BT_HCIBTSDIO is not set
  781. +# CONFIG_BT_HCIUART is not set
  782. +# CONFIG_BT_HCIBCM203X is not set
  783. +# CONFIG_BT_HCIBPA10X is not set
  784. +CONFIG_BT_HCIBFUSB=m
  785. +CONFIG_BT_HCIVHCI=m
  786. +# CONFIG_BT_MRVL is not set
  787. +# CONFIG_BT_ATH3K is not set
  788. # CONFIG_AF_RXRPC is not set
  789. CONFIG_FIB_RULES=y
  790. CONFIG_WIRELESS=y
  791. -# CONFIG_CFG80211 is not set
  792. -CONFIG_CFG80211_DEFAULT_PS_VALUE=0
  793. -# CONFIG_WIRELESS_OLD_REGULATORY is not set
  794. CONFIG_WIRELESS_EXT=y
  795. +CONFIG_WEXT_CORE=y
  796. +CONFIG_WEXT_PROC=y
  797. +CONFIG_WEXT_PRIV=y
  798. +CONFIG_CFG80211=m
  799. +# CONFIG_NL80211_TESTMODE is not set
  800. +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
  801. +# CONFIG_CFG80211_REG_DEBUG is not set
  802. +CONFIG_CFG80211_DEFAULT_PS=y
  803. +# CONFIG_CFG80211_DEBUGFS is not set
  804. +# CONFIG_WIRELESS_OLD_REGULATORY is not set
  805. +CONFIG_CFG80211_WEXT=y
  806. CONFIG_WIRELESS_EXT_SYSFS=y
  807. -# CONFIG_LIB80211 is not set
  808. -
  809. -#
  810. -# CFG80211 needs to be enabled for MAC80211
  811. -#
  812. +CONFIG_LIB80211=m
  813. +CONFIG_LIB80211_DEBUG=y
  814. +CONFIG_MAC80211=m
  815. +# CONFIG_MAC80211_RC_PID is not set
  816. +CONFIG_MAC80211_RC_MINSTREL=y
  817. +# CONFIG_MAC80211_RC_DEFAULT_PID is not set
  818. +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
  819. +CONFIG_MAC80211_RC_DEFAULT="minstrel"
  820. +# CONFIG_MAC80211_MESH is not set
  821. +CONFIG_MAC80211_LEDS=y
  822. +# CONFIG_MAC80211_DEBUGFS is not set
  823. +# CONFIG_MAC80211_DEBUG_MENU is not set
  824. # CONFIG_WIMAX is not set
  825. CONFIG_RFKILL=m
  826. -# CONFIG_RFKILL_INPUT is not set
  827. +CONFIG_RFKILL_LEDS=y
  828. +CONFIG_RFKILL_INPUT=y
  829. # CONFIG_NET_9P is not set
  830. #
  831. @@ -555,7 +661,7 @@
  832. CONFIG_FIRMWARE_IN_KERNEL=y
  833. CONFIG_EXTRA_FIRMWARE=""
  834. # CONFIG_SYS_HYPERVISOR is not set
  835. -# CONFIG_CONNECTOR is not set
  836. +CONFIG_CONNECTOR=m
  837. # CONFIG_MTD is not set
  838. # CONFIG_PARPORT is not set
  839. # CONFIG_PNP is not set
  840. @@ -566,7 +672,8 @@
  841. # CONFIG_BLK_DEV_UMEM is not set
  842. # CONFIG_BLK_DEV_COW_COMMON is not set
  843. CONFIG_BLK_DEV_LOOP=y
  844. -CONFIG_BLK_DEV_CRYPTOLOOP=y
  845. +CONFIG_BLK_DEV_CRYPTOLOOP=m
  846. +# CONFIG_BLK_DEV_DRBD is not set
  847. # CONFIG_BLK_DEV_NBD is not set
  848. # CONFIG_BLK_DEV_SX8 is not set
  849. # CONFIG_BLK_DEV_UB is not set
  850. @@ -577,19 +684,7 @@
  851. # CONFIG_CDROM_PKTCDVD is not set
  852. # CONFIG_ATA_OVER_ETH is not set
  853. # CONFIG_BLK_DEV_HD is not set
  854. -CONFIG_MISC_DEVICES=y
  855. -# CONFIG_PHANTOM is not set
  856. -# CONFIG_SGI_IOC4 is not set
  857. -# CONFIG_TIFM_CORE is not set
  858. -# CONFIG_ENCLOSURE_SERVICES is not set
  859. -# CONFIG_HP_ILO is not set
  860. -# CONFIG_C2PORT is not set
  861. -
  862. -#
  863. -# EEPROM support
  864. -#
  865. -# CONFIG_EEPROM_93CX6 is not set
  866. -# CONFIG_CB710_CORE is not set
  867. +# CONFIG_MISC_DEVICES is not set
  868. CONFIG_HAVE_IDE=y
  869. CONFIG_IDE=y
  870. @@ -619,8 +714,7 @@
  871. #
  872. CONFIG_BLK_DEV_IDEPCI=y
  873. # CONFIG_IDEPCI_PCIBUS_ORDER is not set
  874. -# CONFIG_BLK_DEV_OFFBOARD is not set
  875. -CONFIG_BLK_DEV_GENERIC=y
  876. +# CONFIG_BLK_DEV_GENERIC is not set
  877. # CONFIG_BLK_DEV_OPTI621 is not set
  878. CONFIG_BLK_DEV_IDEDMA_PCI=y
  879. # CONFIG_BLK_DEV_AEC62XX is not set
  880. @@ -700,7 +794,29 @@
  881. # CONFIG_SCSI_DH is not set
  882. # CONFIG_SCSI_OSD_INITIATOR is not set
  883. # CONFIG_ATA is not set
  884. -# CONFIG_MD is not set
  885. +CONFIG_MD=y
  886. +CONFIG_BLK_DEV_MD=m
  887. +CONFIG_MD_LINEAR=m
  888. +CONFIG_MD_RAID0=m
  889. +CONFIG_MD_RAID1=m
  890. +CONFIG_MD_RAID10=m
  891. +CONFIG_MD_RAID456=m
  892. +CONFIG_MD_RAID6_PQ=m
  893. +# CONFIG_ASYNC_RAID6_TEST is not set
  894. +CONFIG_MD_MULTIPATH=m
  895. +CONFIG_MD_FAULTY=m
  896. +CONFIG_BLK_DEV_DM=m
  897. +CONFIG_DM_DEBUG=y
  898. +CONFIG_DM_CRYPT=m
  899. +CONFIG_DM_SNAPSHOT=m
  900. +CONFIG_DM_MIRROR=m
  901. +CONFIG_DM_LOG_USERSPACE=m
  902. +CONFIG_DM_ZERO=m
  903. +CONFIG_DM_MULTIPATH=m
  904. +CONFIG_DM_MULTIPATH_QL=m
  905. +CONFIG_DM_MULTIPATH_ST=m
  906. +CONFIG_DM_DELAY=m
  907. +CONFIG_DM_UEVENT=y
  908. # CONFIG_FUSION is not set
  909. #
  910. @@ -712,19 +828,19 @@
  911. #
  912. #
  913. -# See the help texts for more information.
  914. +# The newer stack is recommended.
  915. #
  916. # CONFIG_FIREWIRE is not set
  917. # CONFIG_IEEE1394 is not set
  918. # CONFIG_I2O is not set
  919. CONFIG_NETDEVICES=y
  920. # CONFIG_IFB is not set
  921. -# CONFIG_DUMMY is not set
  922. +CONFIG_DUMMY=m
  923. # CONFIG_BONDING is not set
  924. # CONFIG_MACVLAN is not set
  925. # CONFIG_EQUALIZER is not set
  926. -# CONFIG_TUN is not set
  927. -# CONFIG_VETH is not set
  928. +CONFIG_TUN=m
  929. +CONFIG_VETH=m
  930. # CONFIG_ARCNET is not set
  931. # CONFIG_PHYLIB is not set
  932. CONFIG_NET_ETHERNET=y
  933. @@ -738,6 +854,7 @@
  934. # CONFIG_SMC91X is not set
  935. # CONFIG_DM9000 is not set
  936. # CONFIG_ETHOC is not set
  937. +# CONFIG_SMSC911X is not set
  938. # CONFIG_NET_VENDOR_RACAL is not set
  939. # CONFIG_DNET is not set
  940. # CONFIG_NET_TULIP is not set
  941. @@ -767,9 +884,9 @@
  942. # CONFIG_NATSEMI is not set
  943. # CONFIG_NE2K_PCI is not set
  944. # CONFIG_8139CP is not set
  945. -CONFIG_8139TOO=y
  946. +CONFIG_8139TOO=m
  947. # CONFIG_8139TOO_PIO is not set
  948. -CONFIG_8139TOO_TUNE_TWISTER=y
  949. +# CONFIG_8139TOO_TUNE_TWISTER is not set
  950. # CONFIG_8139TOO_8129 is not set
  951. # CONFIG_8139_OLD_RX_RESET is not set
  952. # CONFIG_R6040 is not set
  953. @@ -794,7 +911,8 @@
  954. # CONFIG_NS83820 is not set
  955. # CONFIG_HAMACHI is not set
  956. # CONFIG_YELLOWFIN is not set
  957. -CONFIG_R8169=y
  958. +CONFIG_R8169=m
  959. +CONFIG_R8169_VLAN=y
  960. # CONFIG_SIS190 is not set
  961. # CONFIG_SKGE is not set
  962. # CONFIG_SKY2 is not set
  963. @@ -810,15 +928,31 @@
  964. # CONFIG_NETDEV_10000 is not set
  965. # CONFIG_TR is not set
  966. CONFIG_WLAN=y
  967. -CONFIG_WLAN_PRE80211=y
  968. -# CONFIG_STRIP is not set
  969. -# CONFIG_WAVELAN is not set
  970. -CONFIG_WLAN_80211=y
  971. -# CONFIG_LIBERTAS is not set
  972. +# CONFIG_LIBERTAS_THINFIRM is not set
  973. # CONFIG_ATMEL is not set
  974. +# CONFIG_AT76C50X_USB is not set
  975. # CONFIG_PRISM54 is not set
  976. # CONFIG_USB_ZD1201 is not set
  977. +# CONFIG_USB_NET_RNDIS_WLAN is not set
  978. +# CONFIG_RTL8180 is not set
  979. +CONFIG_RTL8187B=m
  980. +# CONFIG_ADM8211 is not set
  981. +# CONFIG_MAC80211_HWSIM is not set
  982. +# CONFIG_MWL8K is not set
  983. +# CONFIG_ATH_COMMON is not set
  984. +# CONFIG_B43 is not set
  985. +# CONFIG_B43LEGACY is not set
  986. # CONFIG_HOSTAP is not set
  987. +# CONFIG_IPW2100 is not set
  988. +# CONFIG_IPW2200 is not set
  989. +# CONFIG_IWLWIFI is not set
  990. +# CONFIG_IWM is not set
  991. +# CONFIG_LIBERTAS is not set
  992. +# CONFIG_HERMES is not set
  993. +# CONFIG_P54_COMMON is not set
  994. +# CONFIG_RT2X00 is not set
  995. +# CONFIG_WL12XX is not set
  996. +# CONFIG_ZD1211RW is not set
  997. #
  998. # Enable WiMAX (Networking options) to see the WiMAX drivers
  999. @@ -831,17 +965,39 @@
  1000. # CONFIG_USB_KAWETH is not set
  1001. # CONFIG_USB_PEGASUS is not set
  1002. # CONFIG_USB_RTL8150 is not set
  1003. -# CONFIG_USB_USBNET is not set
  1004. +CONFIG_USB_USBNET=m
  1005. +CONFIG_USB_NET_AX8817X=m
  1006. +CONFIG_USB_NET_CDCETHER=m
  1007. +CONFIG_USB_NET_CDC_EEM=m
  1008. +# CONFIG_USB_NET_DM9601 is not set
  1009. +# CONFIG_USB_NET_SMSC95XX is not set
  1010. +# CONFIG_USB_NET_GL620A is not set
  1011. +CONFIG_USB_NET_NET1080=m
  1012. +# CONFIG_USB_NET_PLUSB is not set
  1013. +# CONFIG_USB_NET_MCS7830 is not set
  1014. +# CONFIG_USB_NET_RNDIS_HOST is not set
  1015. +CONFIG_USB_NET_CDC_SUBSET=m
  1016. +# CONFIG_USB_ALI_M5632 is not set
  1017. +# CONFIG_USB_AN2720 is not set
  1018. +CONFIG_USB_BELKIN=y
  1019. +CONFIG_USB_ARMLINUX=y
  1020. +# CONFIG_USB_EPSON2888 is not set
  1021. +# CONFIG_USB_KC2190 is not set
  1022. +CONFIG_USB_NET_ZAURUS=m
  1023. # CONFIG_USB_HSO is not set
  1024. +# CONFIG_USB_NET_INT51X1 is not set
  1025. # CONFIG_WAN is not set
  1026. # CONFIG_FDDI is not set
  1027. # CONFIG_HIPPI is not set
  1028. # CONFIG_PPP is not set
  1029. # CONFIG_SLIP is not set
  1030. # CONFIG_NET_FC is not set
  1031. -# CONFIG_NETCONSOLE is not set
  1032. -# CONFIG_NETPOLL is not set
  1033. -# CONFIG_NET_POLL_CONTROLLER is not set
  1034. +CONFIG_NETCONSOLE=m
  1035. +CONFIG_NETCONSOLE_DYNAMIC=y
  1036. +CONFIG_NETPOLL=y
  1037. +# CONFIG_NETPOLL_TRAP is not set
  1038. +CONFIG_NET_POLL_CONTROLLER=y
  1039. +# CONFIG_VMXNET3 is not set
  1040. # CONFIG_ISDN is not set
  1041. # CONFIG_PHONE is not set
  1042. @@ -849,25 +1005,26 @@
  1043. # Input device support
  1044. #
  1045. CONFIG_INPUT=y
  1046. -# CONFIG_INPUT_FF_MEMLESS is not set
  1047. -# CONFIG_INPUT_POLLDEV is not set
  1048. +CONFIG_INPUT_FF_MEMLESS=m
  1049. +CONFIG_INPUT_POLLDEV=m
  1050. +CONFIG_INPUT_SPARSEKMAP=m
  1051. #
  1052. # Userland interfaces
  1053. #
  1054. -CONFIG_INPUT_MOUSEDEV=y
  1055. +CONFIG_INPUT_MOUSEDEV=m
  1056. CONFIG_INPUT_MOUSEDEV_PSAUX=y
  1057. CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  1058. CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  1059. # CONFIG_INPUT_JOYDEV is not set
  1060. -CONFIG_INPUT_EVDEV=y
  1061. +CONFIG_INPUT_EVDEV=m
  1062. # CONFIG_INPUT_EVBUG is not set
  1063. #
  1064. # Input Device Drivers
  1065. #
  1066. CONFIG_INPUT_KEYBOARD=y
  1067. -CONFIG_KEYBOARD_ATKBD=y
  1068. +CONFIG_KEYBOARD_ATKBD=m
  1069. # CONFIG_KEYBOARD_LKKBD is not set
  1070. # CONFIG_KEYBOARD_NEWTON is not set
  1071. # CONFIG_KEYBOARD_OPENCORES is not set
  1072. @@ -875,7 +1032,7 @@
  1073. # CONFIG_KEYBOARD_SUNKBD is not set
  1074. # CONFIG_KEYBOARD_XTKBD is not set
  1075. CONFIG_INPUT_MOUSE=y
  1076. -CONFIG_MOUSE_PS2=y
  1077. +CONFIG_MOUSE_PS2=m
  1078. # CONFIG_MOUSE_PS2_ALPS is not set
  1079. # CONFIG_MOUSE_PS2_LOGIPS2PP is not set
  1080. CONFIG_MOUSE_PS2_SYNAPTICS=y
  1081. @@ -884,7 +1041,7 @@
  1082. # CONFIG_MOUSE_PS2_SENTELIC is not set
  1083. # CONFIG_MOUSE_PS2_TOUCHKIT is not set
  1084. # CONFIG_MOUSE_SERIAL is not set
  1085. -# CONFIG_MOUSE_APPLETOUCH is not set
  1086. +CONFIG_MOUSE_APPLETOUCH=m
  1087. # CONFIG_MOUSE_BCM5974 is not set
  1088. # CONFIG_MOUSE_INPORT is not set
  1089. # CONFIG_MOUSE_LOGIBM is not set
  1090. @@ -904,6 +1061,7 @@
  1091. # CONFIG_SERIO_PCIPS2 is not set
  1092. CONFIG_SERIO_LIBPS2=y
  1093. # CONFIG_SERIO_RAW is not set
  1094. +# CONFIG_SERIO_ALTERA_PS2 is not set
  1095. # CONFIG_GAMEPORT is not set
  1096. #
  1097. @@ -915,27 +1073,13 @@
  1098. CONFIG_HW_CONSOLE=y
  1099. # CONFIG_VT_HW_CONSOLE_BINDING is not set
  1100. CONFIG_DEVKMEM=y
  1101. -CONFIG_SERIAL_NONSTANDARD=y
  1102. -# CONFIG_COMPUTONE is not set
  1103. -# CONFIG_ROCKETPORT is not set
  1104. -# CONFIG_CYCLADES is not set
  1105. -# CONFIG_DIGIEPCA is not set
  1106. -# CONFIG_MOXA_INTELLIO is not set
  1107. -# CONFIG_MOXA_SMARTIO is not set
  1108. -# CONFIG_ISI is not set
  1109. -# CONFIG_SYNCLINKMP is not set
  1110. -# CONFIG_SYNCLINK_GT is not set
  1111. -# CONFIG_N_HDLC is not set
  1112. -# CONFIG_RISCOM8 is not set
  1113. -# CONFIG_SPECIALIX is not set
  1114. -# CONFIG_STALDRV is not set
  1115. +# CONFIG_SERIAL_NONSTANDARD is not set
  1116. # CONFIG_NOZOMI is not set
  1117. #
  1118. # Serial drivers
  1119. #
  1120. -CONFIG_SERIAL_8250=y
  1121. -CONFIG_SERIAL_8250_CONSOLE=y
  1122. +CONFIG_SERIAL_8250=m
  1123. # CONFIG_SERIAL_8250_PCI is not set
  1124. CONFIG_SERIAL_8250_NR_UARTS=16
  1125. CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  1126. @@ -953,8 +1097,7 @@
  1127. #
  1128. # Non-8250 serial port support
  1129. #
  1130. -CONFIG_SERIAL_CORE=y
  1131. -CONFIG_SERIAL_CORE_CONSOLE=y
  1132. +CONFIG_SERIAL_CORE=m
  1133. # CONFIG_SERIAL_JSM is not set
  1134. CONFIG_UNIX98_PTYS=y
  1135. # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  1136. @@ -963,7 +1106,6 @@
  1137. # CONFIG_IPMI_HANDLER is not set
  1138. CONFIG_HW_RANDOM=y
  1139. # CONFIG_HW_RANDOM_TIMERIOMEM is not set
  1140. -CONFIG_RTC=y
  1141. # CONFIG_DTLK is not set
  1142. # CONFIG_R3964 is not set
  1143. # CONFIG_APPLICOM is not set
  1144. @@ -978,7 +1120,10 @@
  1145. #
  1146. # CONFIG_PPS is not set
  1147. # CONFIG_W1 is not set
  1148. -# CONFIG_POWER_SUPPLY is not set
  1149. +CONFIG_POWER_SUPPLY=m
  1150. +# CONFIG_POWER_SUPPLY_DEBUG is not set
  1151. +# CONFIG_PDA_POWER is not set
  1152. +# CONFIG_BATTERY_DS2760 is not set
  1153. CONFIG_HWMON=y
  1154. # CONFIG_HWMON_VID is not set
  1155. # CONFIG_HWMON_DEBUG_CHIP is not set
  1156. @@ -1033,14 +1178,18 @@
  1157. #
  1158. # Multimedia drivers
  1159. #
  1160. +CONFIG_IR_CORE=m
  1161. +CONFIG_VIDEO_IR=m
  1162. # CONFIG_MEDIA_ATTACH is not set
  1163. CONFIG_VIDEO_V4L2=m
  1164. CONFIG_VIDEO_V4L1=m
  1165. +CONFIG_VIDEOBUF_GEN=m
  1166. +CONFIG_VIDEOBUF_VMALLOC=m
  1167. CONFIG_VIDEO_CAPTURE_DRIVERS=y
  1168. # CONFIG_VIDEO_ADV_DEBUG is not set
  1169. # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
  1170. CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
  1171. -# CONFIG_VIDEO_VIVI is not set
  1172. +CONFIG_VIDEO_VIVI=m
  1173. # CONFIG_VIDEO_PMS is not set
  1174. # CONFIG_VIDEO_CPIA is not set
  1175. # CONFIG_VIDEO_CPIA2 is not set
  1176. @@ -1049,52 +1198,55 @@
  1177. CONFIG_USB_VIDEO_CLASS=m
  1178. CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
  1179. CONFIG_USB_GSPCA=m
  1180. -# CONFIG_USB_M5602 is not set
  1181. -# CONFIG_USB_STV06XX is not set
  1182. +CONFIG_USB_M5602=m
  1183. +CONFIG_USB_STV06XX=m
  1184. # CONFIG_USB_GL860 is not set
  1185. -# CONFIG_USB_GSPCA_CONEX is not set
  1186. -# CONFIG_USB_GSPCA_ETOMS is not set
  1187. -# CONFIG_USB_GSPCA_FINEPIX is not set
  1188. +CONFIG_USB_GSPCA_CONEX=m
  1189. +CONFIG_USB_GSPCA_ETOMS=m
  1190. +CONFIG_USB_GSPCA_FINEPIX=m
  1191. # CONFIG_USB_GSPCA_JEILINJ is not set
  1192. -# CONFIG_USB_GSPCA_MARS is not set
  1193. -# CONFIG_USB_GSPCA_MR97310A is not set
  1194. -# CONFIG_USB_GSPCA_OV519 is not set
  1195. -# CONFIG_USB_GSPCA_OV534 is not set
  1196. -# CONFIG_USB_GSPCA_PAC207 is not set
  1197. -# CONFIG_USB_GSPCA_PAC7311 is not set
  1198. -# CONFIG_USB_GSPCA_SN9C20X is not set
  1199. -# CONFIG_USB_GSPCA_SONIXB is not set
  1200. -# CONFIG_USB_GSPCA_SONIXJ is not set
  1201. -# CONFIG_USB_GSPCA_SPCA500 is not set
  1202. -# CONFIG_USB_GSPCA_SPCA501 is not set
  1203. -# CONFIG_USB_GSPCA_SPCA505 is not set
  1204. -# CONFIG_USB_GSPCA_SPCA506 is not set
  1205. -# CONFIG_USB_GSPCA_SPCA508 is not set
  1206. -# CONFIG_USB_GSPCA_SPCA561 is not set
  1207. -# CONFIG_USB_GSPCA_SQ905 is not set
  1208. -# CONFIG_USB_GSPCA_SQ905C is not set
  1209. -# CONFIG_USB_GSPCA_STK014 is not set
  1210. -# CONFIG_USB_GSPCA_SUNPLUS is not set
  1211. -# CONFIG_USB_GSPCA_T613 is not set
  1212. -# CONFIG_USB_GSPCA_TV8532 is not set
  1213. -# CONFIG_USB_GSPCA_VC032X is not set
  1214. -# CONFIG_USB_GSPCA_ZC3XX is not set
  1215. +CONFIG_USB_GSPCA_MARS=m
  1216. +CONFIG_USB_GSPCA_MR97310A=m
  1217. +CONFIG_USB_GSPCA_OV519=m
  1218. +CONFIG_USB_GSPCA_OV534=m
  1219. +CONFIG_USB_GSPCA_PAC207=m
  1220. +# CONFIG_USB_GSPCA_PAC7302 is not set
  1221. +CONFIG_USB_GSPCA_PAC7311=m
  1222. +CONFIG_USB_GSPCA_SN9C20X=m
  1223. +CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
  1224. +CONFIG_USB_GSPCA_SONIXB=m
  1225. +CONFIG_USB_GSPCA_SONIXJ=m
  1226. +CONFIG_USB_GSPCA_SPCA500=m
  1227. +CONFIG_USB_GSPCA_SPCA501=m
  1228. +CONFIG_USB_GSPCA_SPCA505=m
  1229. +CONFIG_USB_GSPCA_SPCA506=m
  1230. +CONFIG_USB_GSPCA_SPCA508=m
  1231. +CONFIG_USB_GSPCA_SPCA561=m
  1232. +CONFIG_USB_GSPCA_SQ905=m
  1233. +CONFIG_USB_GSPCA_SQ905C=m
  1234. +CONFIG_USB_GSPCA_STK014=m
  1235. +# CONFIG_USB_GSPCA_STV0680 is not set
  1236. +CONFIG_USB_GSPCA_SUNPLUS=m
  1237. +CONFIG_USB_GSPCA_T613=m
  1238. +CONFIG_USB_GSPCA_TV8532=m
  1239. +CONFIG_USB_GSPCA_VC032X=m
  1240. +CONFIG_USB_GSPCA_ZC3XX=m
  1241. # CONFIG_VIDEO_HDPVR is not set
  1242. # CONFIG_USB_VICAM is not set
  1243. # CONFIG_USB_IBMCAM is not set
  1244. # CONFIG_USB_KONICAWC is not set
  1245. # CONFIG_USB_QUICKCAM_MESSENGER is not set
  1246. -# CONFIG_USB_ET61X251 is not set
  1247. +CONFIG_USB_ET61X251=m
  1248. # CONFIG_USB_OV511 is not set
  1249. # CONFIG_USB_SE401 is not set
  1250. -# CONFIG_USB_SN9C102 is not set
  1251. +CONFIG_USB_SN9C102=m
  1252. # CONFIG_USB_STV680 is not set
  1253. -# CONFIG_USB_ZC0301 is not set
  1254. +CONFIG_USB_ZC0301=m
  1255. # CONFIG_USB_PWC is not set
  1256. CONFIG_USB_PWC_INPUT_EVDEV=y
  1257. -# CONFIG_USB_ZR364XX is not set
  1258. -# CONFIG_USB_STKWEBCAM is not set
  1259. -# CONFIG_USB_S2255 is not set
  1260. +CONFIG_USB_ZR364XX=m
  1261. +CONFIG_USB_STKWEBCAM=m
  1262. +CONFIG_USB_S2255=m
  1263. # CONFIG_RADIO_ADAPTERS is not set
  1264. # CONFIG_DAB is not set
  1265. @@ -1132,6 +1284,7 @@
  1266. # CONFIG_FB_CYBER2000 is not set
  1267. # CONFIG_FB_ASILIANT is not set
  1268. # CONFIG_FB_IMSTT is not set
  1269. +# CONFIG_FB_UVESA is not set
  1270. # CONFIG_FB_S1D13XXX is not set
  1271. # CONFIG_FB_NVIDIA is not set
  1272. # CONFIG_FB_RIVA is not set
  1273. @@ -1161,7 +1314,7 @@
  1274. CONFIG_BACKLIGHT_LCD_SUPPORT=y
  1275. # CONFIG_LCD_CLASS_DEVICE is not set
  1276. CONFIG_BACKLIGHT_CLASS_DEVICE=y
  1277. -CONFIG_BACKLIGHT_GENERIC=y
  1278. +CONFIG_BACKLIGHT_GENERIC=m
  1279. #
  1280. # Display device support
  1281. @@ -1188,33 +1341,45 @@
  1282. CONFIG_FONT_SUN8x16=y
  1283. CONFIG_FONT_SUN12x22=y
  1284. CONFIG_FONT_10x18=y
  1285. -CONFIG_LOGO=y
  1286. -# CONFIG_LOGO_LINUX_MONO is not set
  1287. -# CONFIG_LOGO_LINUX_VGA16 is not set
  1288. -CONFIG_LOGO_LINUX_CLUT224=y
  1289. +# CONFIG_LOGO is not set
  1290. CONFIG_SOUND=m
  1291. -# CONFIG_SOUND_OSS_CORE is not set
  1292. +CONFIG_SOUND_OSS_CORE=y
  1293. +CONFIG_SOUND_OSS_CORE_PRECLAIM=y
  1294. CONFIG_SND=m
  1295. CONFIG_SND_TIMER=m
  1296. CONFIG_SND_PCM=m
  1297. -# CONFIG_SND_SEQUENCER is not set
  1298. -# CONFIG_SND_MIXER_OSS is not set
  1299. -# CONFIG_SND_PCM_OSS is not set
  1300. -# CONFIG_SND_HRTIMER is not set
  1301. -# CONFIG_SND_RTCTIMER is not set
  1302. +CONFIG_SND_HWDEP=m
  1303. +CONFIG_SND_RAWMIDI=m
  1304. +CONFIG_SND_SEQUENCER=m
  1305. +CONFIG_SND_SEQ_DUMMY=m
  1306. +CONFIG_SND_OSSEMUL=y
  1307. +CONFIG_SND_MIXER_OSS=m
  1308. +CONFIG_SND_PCM_OSS=m
  1309. +CONFIG_SND_PCM_OSS_PLUGINS=y
  1310. +CONFIG_SND_SEQUENCER_OSS=y
  1311. +CONFIG_SND_HRTIMER=m
  1312. +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
  1313. # CONFIG_SND_DYNAMIC_MINORS is not set
  1314. -# CONFIG_SND_SUPPORT_OLD_API is not set
  1315. -# CONFIG_SND_VERBOSE_PROCFS is not set
  1316. +CONFIG_SND_SUPPORT_OLD_API=y
  1317. +CONFIG_SND_VERBOSE_PROCFS=y
  1318. # CONFIG_SND_VERBOSE_PRINTK is not set
  1319. # CONFIG_SND_DEBUG is not set
  1320. CONFIG_SND_VMASTER=y
  1321. -# CONFIG_SND_RAWMIDI_SEQ is not set
  1322. +CONFIG_SND_RAWMIDI_SEQ=m
  1323. # CONFIG_SND_OPL3_LIB_SEQ is not set
  1324. # CONFIG_SND_OPL4_LIB_SEQ is not set
  1325. # CONFIG_SND_SBAWE_SEQ is not set
  1326. # CONFIG_SND_EMU10K1_SEQ is not set
  1327. +CONFIG_SND_MPU401_UART=m
  1328. CONFIG_SND_AC97_CODEC=m
  1329. -# CONFIG_SND_DRIVERS is not set
  1330. +CONFIG_SND_DRIVERS=y
  1331. +CONFIG_SND_DUMMY=m
  1332. +CONFIG_SND_VIRMIDI=m
  1333. +# CONFIG_SND_MTPAV is not set
  1334. +CONFIG_SND_SERIAL_U16550=m
  1335. +CONFIG_SND_MPU401=m
  1336. +CONFIG_SND_AC97_POWER_SAVE=y
  1337. +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
  1338. CONFIG_SND_PCI=y
  1339. # CONFIG_SND_AD1889 is not set
  1340. # CONFIG_SND_ALS300 is not set
  1341. @@ -1281,7 +1446,10 @@
  1342. # CONFIG_SND_VX222 is not set
  1343. # CONFIG_SND_YMFPCI is not set
  1344. # CONFIG_SND_MIPS is not set
  1345. -# CONFIG_SND_USB is not set
  1346. +CONFIG_SND_USB=y
  1347. +CONFIG_SND_USB_AUDIO=m
  1348. +CONFIG_SND_USB_CAIAQ=m
  1349. +CONFIG_SND_USB_CAIAQ_INPUT=y
  1350. # CONFIG_SND_SOC is not set
  1351. # CONFIG_SOUND_PRIME is not set
  1352. CONFIG_AC97_BUS=m
  1353. @@ -1299,32 +1467,41 @@
  1354. #
  1355. # Special HID drivers
  1356. #
  1357. -# CONFIG_HID_A4TECH is not set
  1358. -# CONFIG_HID_APPLE is not set
  1359. -# CONFIG_HID_BELKIN is not set
  1360. -# CONFIG_HID_CHERRY is not set
  1361. -# CONFIG_HID_CHICONY is not set
  1362. -# CONFIG_HID_CYPRESS is not set
  1363. -# CONFIG_HID_DRAGONRISE is not set
  1364. -# CONFIG_HID_EZKEY is not set
  1365. -# CONFIG_HID_KYE is not set
  1366. -# CONFIG_HID_GYRATION is not set
  1367. -# CONFIG_HID_TWINHAN is not set
  1368. -# CONFIG_HID_KENSINGTON is not set
  1369. -# CONFIG_HID_LOGITECH is not set
  1370. -# CONFIG_HID_MICROSOFT is not set
  1371. -# CONFIG_HID_MONTEREY is not set
  1372. -# CONFIG_HID_NTRIG is not set
  1373. -# CONFIG_HID_PANTHERLORD is not set
  1374. -# CONFIG_HID_PETALYNX is not set
  1375. -# CONFIG_HID_SAMSUNG is not set
  1376. -# CONFIG_HID_SONY is not set
  1377. -# CONFIG_HID_SUNPLUS is not set
  1378. -# CONFIG_HID_GREENASIA is not set
  1379. -# CONFIG_HID_SMARTJOYPLUS is not set
  1380. -# CONFIG_HID_TOPSEED is not set
  1381. -# CONFIG_HID_THRUSTMASTER is not set
  1382. -# CONFIG_HID_ZEROPLUS is not set
  1383. +CONFIG_HID_A4TECH=m
  1384. +CONFIG_HID_APPLE=m
  1385. +CONFIG_HID_BELKIN=m
  1386. +CONFIG_HID_CHERRY=m
  1387. +CONFIG_HID_CHICONY=m
  1388. +CONFIG_HID_CYPRESS=m
  1389. +CONFIG_HID_DRAGONRISE=m
  1390. +CONFIG_DRAGONRISE_FF=y
  1391. +CONFIG_HID_EZKEY=m
  1392. +CONFIG_HID_KYE=m
  1393. +CONFIG_HID_GYRATION=m
  1394. +CONFIG_HID_TWINHAN=m
  1395. +CONFIG_HID_KENSINGTON=m
  1396. +CONFIG_HID_LOGITECH=m
  1397. +CONFIG_LOGITECH_FF=y
  1398. +CONFIG_LOGIRUMBLEPAD2_FF=y
  1399. +CONFIG_HID_MICROSOFT=m
  1400. +CONFIG_HID_MONTEREY=m
  1401. +CONFIG_HID_NTRIG=m
  1402. +CONFIG_HID_PANTHERLORD=m
  1403. +CONFIG_PANTHERLORD_FF=y
  1404. +CONFIG_HID_PETALYNX=m
  1405. +CONFIG_HID_SAMSUNG=m
  1406. +CONFIG_HID_SONY=m
  1407. +CONFIG_HID_SUNPLUS=m
  1408. +CONFIG_HID_GREENASIA=m
  1409. +CONFIG_GREENASIA_FF=y
  1410. +CONFIG_HID_SMARTJOYPLUS=m
  1411. +CONFIG_SMARTJOYPLUS_FF=y
  1412. +CONFIG_HID_TOPSEED=m
  1413. +CONFIG_HID_THRUSTMASTER=m
  1414. +CONFIG_THRUSTMASTER_FF=y
  1415. +CONFIG_HID_WACOM=m
  1416. +CONFIG_HID_ZEROPLUS=m
  1417. +CONFIG_ZEROPLUS_FF=y
  1418. CONFIG_USB_SUPPORT=y
  1419. CONFIG_USB_ARCH_HAS_HCD=y
  1420. CONFIG_USB_ARCH_HAS_OHCI=y
  1421. @@ -1336,15 +1513,15 @@
  1422. #
  1423. # Miscellaneous USB options
  1424. #
  1425. -CONFIG_USB_DEVICEFS=y
  1426. +# CONFIG_USB_DEVICEFS is not set
  1427. # CONFIG_USB_DEVICE_CLASS is not set
  1428. CONFIG_USB_DYNAMIC_MINORS=y
  1429. CONFIG_USB_SUSPEND=y
  1430. # CONFIG_USB_OTG is not set
  1431. CONFIG_USB_OTG_WHITELIST=y
  1432. # CONFIG_USB_OTG_BLACKLIST_HUB is not set
  1433. -CONFIG_USB_MON=y
  1434. -# CONFIG_USB_WUSB is not set
  1435. +CONFIG_USB_MON=m
  1436. +CONFIG_USB_WUSB=m
  1437. # CONFIG_USB_WUSB_CBAF is not set
  1438. #
  1439. @@ -1366,14 +1543,15 @@
  1440. CONFIG_USB_UHCI_HCD=m
  1441. # CONFIG_USB_SL811_HCD is not set
  1442. # CONFIG_USB_R8A66597_HCD is not set
  1443. -# CONFIG_USB_WHCI_HCD is not set
  1444. -# CONFIG_USB_HWA_HCD is not set
  1445. +CONFIG_USB_WHCI_HCD=m
  1446. +CONFIG_USB_HWA_HCD=m
  1447. +# CONFIG_USB_GADGET_MUSB_HDRC is not set
  1448. #
  1449. # USB Device Class drivers
  1450. #
  1451. CONFIG_USB_ACM=m
  1452. -# CONFIG_USB_PRINTER is not set
  1453. +CONFIG_USB_PRINTER=m
  1454. CONFIG_USB_WDM=m
  1455. # CONFIG_USB_TMC is not set
  1456. @@ -1397,7 +1575,7 @@
  1457. # CONFIG_USB_STORAGE_ONETOUCH is not set
  1458. # CONFIG_USB_STORAGE_KARMA is not set
  1459. # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
  1460. -# CONFIG_USB_LIBUSUAL is not set
  1461. +CONFIG_USB_LIBUSUAL=y
  1462. #
  1463. # USB Imaging devices
  1464. @@ -1467,7 +1645,7 @@
  1465. # CONFIG_USB_LEGOTOWER is not set
  1466. # CONFIG_USB_LCD is not set
  1467. # CONFIG_USB_BERRY_CHARGE is not set
  1468. -# CONFIG_USB_LED is not set
  1469. +CONFIG_USB_LED=m
  1470. # CONFIG_USB_CYPRESS_CY7C63 is not set
  1471. # CONFIG_USB_CYTHERM is not set
  1472. # CONFIG_USB_IDMOUSE is not set
  1473. @@ -1480,19 +1658,136 @@
  1474. # CONFIG_USB_TEST is not set
  1475. # CONFIG_USB_ISIGHTFW is not set
  1476. # CONFIG_USB_VST is not set
  1477. -# CONFIG_USB_GADGET is not set
  1478. +CONFIG_USB_GADGET=m
  1479. +# CONFIG_USB_GADGET_DEBUG_FILES is not set
  1480. +# CONFIG_USB_GADGET_DEBUG_FS is not set
  1481. +CONFIG_USB_GADGET_VBUS_DRAW=2
  1482. +CONFIG_USB_GADGET_SELECTED=y
  1483. +# CONFIG_USB_GADGET_AT91 is not set
  1484. +# CONFIG_USB_GADGET_ATMEL_USBA is not set
  1485. +# CONFIG_USB_GADGET_FSL_USB2 is not set
  1486. +# CONFIG_USB_GADGET_LH7A40X is not set
  1487. +# CONFIG_USB_GADGET_OMAP is not set
  1488. +# CONFIG_USB_GADGET_PXA25X is not set
  1489. +# CONFIG_USB_GADGET_R8A66597 is not set
  1490. +# CONFIG_USB_GADGET_PXA27X is not set
  1491. +# CONFIG_USB_GADGET_S3C_HSOTG is not set
  1492. +# CONFIG_USB_GADGET_IMX is not set
  1493. +# CONFIG_USB_GADGET_S3C2410 is not set
  1494. +CONFIG_USB_GADGET_M66592=y
  1495. +CONFIG_USB_M66592=m
  1496. +# CONFIG_USB_GADGET_AMD5536UDC is not set
  1497. +# CONFIG_USB_GADGET_FSL_QE is not set
  1498. +# CONFIG_USB_GADGET_CI13XXX is not set
  1499. +# CONFIG_USB_GADGET_NET2280 is not set
  1500. +# CONFIG_USB_GADGET_GOKU is not set
  1501. +# CONFIG_USB_GADGET_LANGWELL is not set
  1502. +# CONFIG_USB_GADGET_DUMMY_HCD is not set
  1503. +CONFIG_USB_GADGET_DUALSPEED=y
  1504. +# CONFIG_USB_ZERO is not set
  1505. +# CONFIG_USB_AUDIO is not set
  1506. +# CONFIG_USB_ETH is not set
  1507. +# CONFIG_USB_GADGETFS is not set
  1508. +# CONFIG_USB_FILE_STORAGE is not set
  1509. +# CONFIG_USB_MASS_STORAGE is not set
  1510. +# CONFIG_USB_G_SERIAL is not set
  1511. +# CONFIG_USB_MIDI_GADGET is not set
  1512. +# CONFIG_USB_G_PRINTER is not set
  1513. +# CONFIG_USB_CDC_COMPOSITE is not set
  1514. +# CONFIG_USB_G_MULTI is not set
  1515. #
  1516. # OTG and related infrastructure
  1517. #
  1518. # CONFIG_NOP_USB_XCEIV is not set
  1519. -# CONFIG_UWB is not set
  1520. -# CONFIG_MMC is not set
  1521. +CONFIG_UWB=m
  1522. +CONFIG_UWB_HWA=m
  1523. +CONFIG_UWB_WHCI=m
  1524. +# CONFIG_UWB_WLP is not set
  1525. +# CONFIG_UWB_I1480U is not set
  1526. +CONFIG_MMC=m
  1527. +# CONFIG_MMC_DEBUG is not set
  1528. +# CONFIG_MMC_UNSAFE_RESUME is not set
  1529. +
  1530. +#
  1531. +# MMC/SD/SDIO Card Drivers
  1532. +#
  1533. +CONFIG_MMC_BLOCK=m
  1534. +CONFIG_MMC_BLOCK_BOUNCE=y
  1535. +# CONFIG_SDIO_UART is not set
  1536. +# CONFIG_MMC_TEST is not set
  1537. +
  1538. +#
  1539. +# MMC/SD/SDIO Host Controller Drivers
  1540. +#
  1541. +# CONFIG_MMC_SDHCI is not set
  1542. +# CONFIG_MMC_AT91 is not set
  1543. +# CONFIG_MMC_ATMELMCI is not set
  1544. +# CONFIG_MMC_TIFM_SD is not set
  1545. +# CONFIG_MMC_CB710 is not set
  1546. +# CONFIG_MMC_VIA_SDMMC is not set
  1547. # CONFIG_MEMSTICK is not set
  1548. -# CONFIG_NEW_LEDS is not set
  1549. +CONFIG_NEW_LEDS=y
  1550. +CONFIG_LEDS_CLASS=m
  1551. +
  1552. +#
  1553. +# LED drivers
  1554. +#
  1555. +
  1556. +#
  1557. +# LED Triggers
  1558. +#
  1559. +CONFIG_LEDS_TRIGGERS=y
  1560. +# CONFIG_LEDS_TRIGGER_TIMER is not set
  1561. +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
  1562. +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
  1563. +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
  1564. +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
  1565. +
  1566. +#
  1567. +# iptables trigger is under Netfilter config (LED target)
  1568. +#
  1569. # CONFIG_ACCESSIBILITY is not set
  1570. # CONFIG_INFINIBAND is not set
  1571. -# CONFIG_RTC_CLASS is not set
  1572. +CONFIG_RTC_LIB=y
  1573. +CONFIG_RTC_CLASS=y
  1574. +CONFIG_RTC_HCTOSYS=y
  1575. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  1576. +# CONFIG_RTC_DEBUG is not set
  1577. +
  1578. +#
  1579. +# RTC interfaces
  1580. +#
  1581. +CONFIG_RTC_INTF_SYSFS=y
  1582. +CONFIG_RTC_INTF_PROC=y
  1583. +CONFIG_RTC_INTF_DEV=y
  1584. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  1585. +# CONFIG_RTC_DRV_TEST is not set
  1586. +
  1587. +#
  1588. +# SPI RTC drivers
  1589. +#
  1590. +
  1591. +#
  1592. +# Platform RTC drivers
  1593. +#
  1594. +CONFIG_RTC_DRV_CMOS=y
  1595. +# CONFIG_RTC_DRV_DS1286 is not set
  1596. +# CONFIG_RTC_DRV_DS1511 is not set
  1597. +# CONFIG_RTC_DRV_DS1553 is not set
  1598. +# CONFIG_RTC_DRV_DS1742 is not set
  1599. +# CONFIG_RTC_DRV_STK17TA8 is not set
  1600. +# CONFIG_RTC_DRV_M48T86 is not set
  1601. +# CONFIG_RTC_DRV_M48T35 is not set
  1602. +# CONFIG_RTC_DRV_M48T59 is not set
  1603. +# CONFIG_RTC_DRV_MSM6242 is not set
  1604. +# CONFIG_RTC_DRV_BQ4802 is not set
  1605. +# CONFIG_RTC_DRV_RP5C01 is not set
  1606. +# CONFIG_RTC_DRV_V3020 is not set
  1607. +
  1608. +#
  1609. +# on-CPU RTC drivers
  1610. +#
  1611. # CONFIG_DMADEVICES is not set
  1612. # CONFIG_AUXDISPLAY is not set
  1613. # CONFIG_UIO is not set
  1614. @@ -1504,22 +1799,21 @@
  1615. # CONFIG_STAGING_EXCLUDE_BUILD is not set
  1616. # CONFIG_ET131X is not set
  1617. # CONFIG_USB_IP_COMMON is not set
  1618. +# CONFIG_W35UND is not set
  1619. # CONFIG_PRISM2_USB is not set
  1620. # CONFIG_ECHO is not set
  1621. +# CONFIG_OTUS is not set
  1622. # CONFIG_COMEDI is not set
  1623. # CONFIG_ASUS_OLED is not set
  1624. # CONFIG_ALTERA_PCIE_CHDMA is not set
  1625. -# CONFIG_RTL8187SE is not set
  1626. +# CONFIG_R8187SE is not set
  1627. # CONFIG_RTL8192SU is not set
  1628. +# CONFIG_RTL8192U is not set
  1629. # CONFIG_RTL8192E is not set
  1630. # CONFIG_INPUT_MIMIO is not set
  1631. # CONFIG_TRANZPORT is not set
  1632. #
  1633. -# Android
  1634. -#
  1635. -
  1636. -#
  1637. # Qualcomm MSM Camera And Video
  1638. #
  1639. @@ -1527,7 +1821,6 @@
  1640. # Camera Sensor Selection
  1641. #
  1642. # CONFIG_INPUT_GPIO is not set
  1643. -# CONFIG_DST is not set
  1644. # CONFIG_POHMELFS is not set
  1645. # CONFIG_B3DFG is not set
  1646. # CONFIG_PLAN9AUTH is not set
  1647. @@ -1544,28 +1837,57 @@
  1648. #
  1649. # CONFIG_RAR_REGISTER is not set
  1650. # CONFIG_IIO is not set
  1651. +# CONFIG_RAMZSWAP is not set
  1652. +# CONFIG_BATMAN_ADV is not set
  1653. +# CONFIG_STRIP is not set
  1654. +# CONFIG_WAVELAN is not set
  1655. CONFIG_FB_SM7XX=y
  1656. -CONFIG_FB_SM7XX_ACCEL=y
  1657. +CONFIG_MIPS_PLATFORM_DEVICES=y
  1658. +CONFIG_LEMOTE_YEELOONG2F=m
  1659. +CONFIG_LEMOTE_LYNLOONG2F=m
  1660. #
  1661. # File systems
  1662. #
  1663. -# CONFIG_EXT2_FS is not set
  1664. +CONFIG_EXT2_FS=m
  1665. +# CONFIG_EXT2_FS_XATTR is not set
  1666. +# CONFIG_EXT2_FS_XIP is not set
  1667. CONFIG_EXT3_FS=y
  1668. # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
  1669. CONFIG_EXT3_FS_XATTR=y
  1670. CONFIG_EXT3_FS_POSIX_ACL=y
  1671. CONFIG_EXT3_FS_SECURITY=y
  1672. -# CONFIG_EXT4_FS is not set
  1673. +CONFIG_EXT4_FS=y
  1674. +CONFIG_EXT4_FS_XATTR=y
  1675. +# CONFIG_EXT4_FS_POSIX_ACL is not set
  1676. +# CONFIG_EXT4_FS_SECURITY is not set
  1677. +# CONFIG_EXT4_DEBUG is not set
  1678. CONFIG_JBD=y
  1679. +# CONFIG_JBD_DEBUG is not set
  1680. +CONFIG_JBD2=y
  1681. +# CONFIG_JBD2_DEBUG is not set
  1682. CONFIG_FS_MBCACHE=y
  1683. -# CONFIG_REISERFS_FS is not set
  1684. -# CONFIG_JFS_FS is not set
  1685. +CONFIG_REISERFS_FS=m
  1686. +# CONFIG_REISERFS_CHECK is not set
  1687. +CONFIG_REISERFS_PROC_INFO=y
  1688. +CONFIG_REISERFS_FS_XATTR=y
  1689. +# CONFIG_REISERFS_FS_POSIX_ACL is not set
  1690. +# CONFIG_REISERFS_FS_SECURITY is not set
  1691. +CONFIG_JFS_FS=m
  1692. +CONFIG_JFS_POSIX_ACL=y
  1693. +# CONFIG_JFS_SECURITY is not set
  1694. +# CONFIG_JFS_DEBUG is not set
  1695. +# CONFIG_JFS_STATISTICS is not set
  1696. CONFIG_FS_POSIX_ACL=y
  1697. -# CONFIG_XFS_FS is not set
  1698. +CONFIG_XFS_FS=m
  1699. +CONFIG_XFS_QUOTA=y
  1700. +CONFIG_XFS_POSIX_ACL=y
  1701. +# CONFIG_XFS_RT is not set
  1702. +# CONFIG_XFS_DEBUG is not set
  1703. # CONFIG_GFS2_FS is not set
  1704. # CONFIG_OCFS2_FS is not set
  1705. -# CONFIG_BTRFS_FS is not set
  1706. +CONFIG_BTRFS_FS=m
  1707. +# CONFIG_BTRFS_FS_POSIX_ACL is not set
  1708. # CONFIG_NILFS2_FS is not set
  1709. CONFIG_FILE_LOCKING=y
  1710. CONFIG_FSNOTIFY=y
  1711. @@ -1575,17 +1897,26 @@
  1712. CONFIG_QUOTA=y
  1713. # CONFIG_QUOTA_NETLINK_INTERFACE is not set
  1714. CONFIG_PRINT_QUOTA_WARNING=y
  1715. +CONFIG_QUOTA_TREE=m
  1716. # CONFIG_QFMT_V1 is not set
  1717. -# CONFIG_QFMT_V2 is not set
  1718. +CONFIG_QFMT_V2=m
  1719. CONFIG_QUOTACTL=y
  1720. -# CONFIG_AUTOFS_FS is not set
  1721. -# CONFIG_AUTOFS4_FS is not set
  1722. -# CONFIG_FUSE_FS is not set
  1723. +CONFIG_AUTOFS_FS=m
  1724. +CONFIG_AUTOFS4_FS=m
  1725. +CONFIG_FUSE_FS=m
  1726. +CONFIG_CUSE=m
  1727. #
  1728. # Caches
  1729. #
  1730. -# CONFIG_FSCACHE is not set
  1731. +CONFIG_FSCACHE=m
  1732. +# CONFIG_FSCACHE_STATS is not set
  1733. +# CONFIG_FSCACHE_HISTOGRAM is not set
  1734. +# CONFIG_FSCACHE_DEBUG is not set
  1735. +# CONFIG_FSCACHE_OBJECT_LIST is not set
  1736. +CONFIG_CACHEFILES=m
  1737. +# CONFIG_CACHEFILES_DEBUG is not set
  1738. +# CONFIG_CACHEFILES_HISTOGRAM is not set
  1739. #
  1740. # CD-ROM/DVD Filesystems
  1741. @@ -1599,11 +1930,13 @@
  1742. # DOS/FAT/NT Filesystems
  1743. #
  1744. CONFIG_FAT_FS=m
  1745. -# CONFIG_MSDOS_FS is not set
  1746. +CONFIG_MSDOS_FS=m
  1747. CONFIG_VFAT_FS=m
  1748. CONFIG_FAT_DEFAULT_CODEPAGE=437
  1749. CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
  1750. -# CONFIG_NTFS_FS is not set
  1751. +CONFIG_NTFS_FS=m
  1752. +# CONFIG_NTFS_DEBUG is not set
  1753. +CONFIG_NTFS_RW=y
  1754. #
  1755. # Pseudo filesystems
  1756. @@ -1616,23 +1949,60 @@
  1757. CONFIG_TMPFS=y
  1758. # CONFIG_TMPFS_POSIX_ACL is not set
  1759. # CONFIG_HUGETLB_PAGE is not set
  1760. -# CONFIG_CONFIGFS_FS is not set
  1761. -# CONFIG_MISC_FILESYSTEMS is not set
  1762. +CONFIG_CONFIGFS_FS=m
  1763. +CONFIG_MISC_FILESYSTEMS=y
  1764. +# CONFIG_ADFS_FS is not set
  1765. +# CONFIG_AFFS_FS is not set
  1766. +# CONFIG_ECRYPT_FS is not set
  1767. +# CONFIG_HFS_FS is not set
  1768. +# CONFIG_HFSPLUS_FS is not set
  1769. +# CONFIG_BEFS_FS is not set
  1770. +# CONFIG_BFS_FS is not set
  1771. +# CONFIG_EFS_FS is not set
  1772. +CONFIG_CRAMFS=m
  1773. +CONFIG_SQUASHFS=m
  1774. +CONFIG_SQUASHFS_EMBEDDED=y
  1775. +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
  1776. +# CONFIG_VXFS_FS is not set
  1777. +# CONFIG_MINIX_FS is not set
  1778. +# CONFIG_OMFS_FS is not set
  1779. +# CONFIG_HPFS_FS is not set
  1780. +# CONFIG_QNX4FS_FS is not set
  1781. +CONFIG_ROMFS_FS=m
  1782. +CONFIG_ROMFS_BACKED_BY_BLOCK=y
  1783. +# CONFIG_ROMFS_BACKED_BY_MTD is not set
  1784. +# CONFIG_ROMFS_BACKED_BY_BOTH is not set
  1785. +CONFIG_ROMFS_ON_BLOCK=y
  1786. +# CONFIG_SYSV_FS is not set
  1787. +# CONFIG_UFS_FS is not set
  1788. CONFIG_NETWORK_FILESYSTEMS=y
  1789. CONFIG_NFS_FS=m
  1790. CONFIG_NFS_V3=y
  1791. CONFIG_NFS_V3_ACL=y
  1792. # CONFIG_NFS_V4 is not set
  1793. -# CONFIG_NFSD is not set
  1794. +# CONFIG_NFS_FSCACHE is not set
  1795. +CONFIG_NFSD=m
  1796. +CONFIG_NFSD_V3=y
  1797. +# CONFIG_NFSD_V3_ACL is not set
  1798. +CONFIG_NFSD_V4=y
  1799. CONFIG_LOCKD=m
  1800. CONFIG_LOCKD_V4=y
  1801. +CONFIG_EXPORTFS=m
  1802. CONFIG_NFS_ACL_SUPPORT=m
  1803. CONFIG_NFS_COMMON=y
  1804. CONFIG_SUNRPC=m
  1805. -# CONFIG_RPCSEC_GSS_KRB5 is not set
  1806. +CONFIG_SUNRPC_GSS=m
  1807. +CONFIG_RPCSEC_GSS_KRB5=m
  1808. # CONFIG_RPCSEC_GSS_SPKM3 is not set
  1809. # CONFIG_SMB_FS is not set
  1810. -# CONFIG_CIFS is not set
  1811. +CONFIG_CIFS=m
  1812. +# CONFIG_CIFS_STATS is not set
  1813. +# CONFIG_CIFS_WEAK_PW_HASH is not set
  1814. +# CONFIG_CIFS_UPCALL is not set
  1815. +# CONFIG_CIFS_XATTR is not set
  1816. +# CONFIG_CIFS_DEBUG2 is not set
  1817. +# CONFIG_CIFS_DFS_UPCALL is not set
  1818. +# CONFIG_CIFS_EXPERIMENTAL is not set
  1819. # CONFIG_NCP_FS is not set
  1820. # CONFIG_CODA_FS is not set
  1821. # CONFIG_AFS_FS is not set
  1822. @@ -1643,177 +2013,205 @@
  1823. # CONFIG_PARTITION_ADVANCED is not set
  1824. CONFIG_MSDOS_PARTITION=y
  1825. CONFIG_NLS=y
  1826. -CONFIG_NLS_DEFAULT="utf-8"
  1827. -# CONFIG_NLS_CODEPAGE_437 is not set
  1828. -# CONFIG_NLS_CODEPAGE_737 is not set
  1829. -# CONFIG_NLS_CODEPAGE_775 is not set
  1830. -# CONFIG_NLS_CODEPAGE_850 is not set
  1831. -# CONFIG_NLS_CODEPAGE_852 is not set
  1832. -# CONFIG_NLS_CODEPAGE_855 is not set
  1833. -# CONFIG_NLS_CODEPAGE_857 is not set
  1834. -# CONFIG_NLS_CODEPAGE_860 is not set
  1835. -# CONFIG_NLS_CODEPAGE_861 is not set
  1836. -# CONFIG_NLS_CODEPAGE_862 is not set
  1837. -# CONFIG_NLS_CODEPAGE_863 is not set
  1838. -# CONFIG_NLS_CODEPAGE_864 is not set
  1839. -# CONFIG_NLS_CODEPAGE_865 is not set
  1840. -# CONFIG_NLS_CODEPAGE_866 is not set
  1841. -# CONFIG_NLS_CODEPAGE_869 is not set
  1842. -# CONFIG_NLS_CODEPAGE_936 is not set
  1843. -# CONFIG_NLS_CODEPAGE_950 is not set
  1844. -# CONFIG_NLS_CODEPAGE_932 is not set
  1845. -# CONFIG_NLS_CODEPAGE_949 is not set
  1846. -# CONFIG_NLS_CODEPAGE_874 is not set
  1847. -# CONFIG_NLS_ISO8859_8 is not set
  1848. -# CONFIG_NLS_CODEPAGE_1250 is not set
  1849. -# CONFIG_NLS_CODEPAGE_1251 is not set
  1850. -# CONFIG_NLS_ASCII is not set
  1851. -# CONFIG_NLS_ISO8859_1 is not set
  1852. -# CONFIG_NLS_ISO8859_2 is not set
  1853. -# CONFIG_NLS_ISO8859_3 is not set
  1854. -# CONFIG_NLS_ISO8859_4 is not set
  1855. -# CONFIG_NLS_ISO8859_5 is not set
  1856. -# CONFIG_NLS_ISO8859_6 is not set
  1857. -# CONFIG_NLS_ISO8859_7 is not set
  1858. -# CONFIG_NLS_ISO8859_9 is not set
  1859. -# CONFIG_NLS_ISO8859_13 is not set
  1860. -# CONFIG_NLS_ISO8859_14 is not set
  1861. -# CONFIG_NLS_ISO8859_15 is not set
  1862. -# CONFIG_NLS_KOI8_R is not set
  1863. -# CONFIG_NLS_KOI8_U is not set
  1864. -# CONFIG_NLS_UTF8 is not set
  1865. +CONFIG_NLS_DEFAULT="utf8"
  1866. +CONFIG_NLS_CODEPAGE_437=m
  1867. +CONFIG_NLS_CODEPAGE_737=m
  1868. +CONFIG_NLS_CODEPAGE_775=m
  1869. +CONFIG_NLS_CODEPAGE_850=m
  1870. +CONFIG_NLS_CODEPAGE_852=m
  1871. +CONFIG_NLS_CODEPAGE_855=m
  1872. +CONFIG_NLS_CODEPAGE_857=m
  1873. +CONFIG_NLS_CODEPAGE_860=m
  1874. +CONFIG_NLS_CODEPAGE_861=m
  1875. +CONFIG_NLS_CODEPAGE_862=m
  1876. +CONFIG_NLS_CODEPAGE_863=m
  1877. +CONFIG_NLS_CODEPAGE_864=m
  1878. +CONFIG_NLS_CODEPAGE_865=m
  1879. +CONFIG_NLS_CODEPAGE_866=m
  1880. +CONFIG_NLS_CODEPAGE_869=m
  1881. +CONFIG_NLS_CODEPAGE_936=m
  1882. +CONFIG_NLS_CODEPAGE_950=m
  1883. +CONFIG_NLS_CODEPAGE_932=m
  1884. +CONFIG_NLS_CODEPAGE_949=m
  1885. +CONFIG_NLS_CODEPAGE_874=m
  1886. +CONFIG_NLS_ISO8859_8=m
  1887. +CONFIG_NLS_CODEPAGE_1250=m
  1888. +CONFIG_NLS_CODEPAGE_1251=m
  1889. +CONFIG_NLS_ASCII=m
  1890. +CONFIG_NLS_ISO8859_1=m
  1891. +CONFIG_NLS_ISO8859_2=m
  1892. +CONFIG_NLS_ISO8859_3=m
  1893. +CONFIG_NLS_ISO8859_4=m
  1894. +CONFIG_NLS_ISO8859_5=m
  1895. +CONFIG_NLS_ISO8859_6=m
  1896. +CONFIG_NLS_ISO8859_7=m
  1897. +CONFIG_NLS_ISO8859_9=m
  1898. +CONFIG_NLS_ISO8859_13=m
  1899. +CONFIG_NLS_ISO8859_14=m
  1900. +CONFIG_NLS_ISO8859_15=m
  1901. +CONFIG_NLS_KOI8_R=m
  1902. +CONFIG_NLS_KOI8_U=m
  1903. +CONFIG_NLS_UTF8=y
  1904. # CONFIG_DLM is not set
  1905. #
  1906. # Kernel hacking
  1907. #
  1908. CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  1909. -CONFIG_PRINTK_TIME=y
  1910. +# CONFIG_PRINTK_TIME is not set
  1911. CONFIG_ENABLE_WARN_DEPRECATED=y
  1912. CONFIG_ENABLE_MUST_CHECK=y
  1913. CONFIG_FRAME_WARN=1024
  1914. # CONFIG_MAGIC_SYSRQ is not set
  1915. CONFIG_STRIP_ASM_SYMS=y
  1916. # CONFIG_UNUSED_SYMBOLS is not set
  1917. -# CONFIG_DEBUG_FS is not set
  1918. +CONFIG_DEBUG_FS=y
  1919. # CONFIG_HEADERS_CHECK is not set
  1920. # CONFIG_DEBUG_KERNEL is not set
  1921. -# CONFIG_SLUB_DEBUG_ON is not set
  1922. -# CONFIG_SLUB_STATS is not set
  1923. +CONFIG_STACKTRACE=y
  1924. # CONFIG_DEBUG_MEMORY_INIT is not set
  1925. # CONFIG_RCU_CPU_STALL_DETECTOR is not set
  1926. -CONFIG_SYSCTL_SYSCALL_CHECK=y
  1927. +# CONFIG_SYSCTL_SYSCALL_CHECK is not set
  1928. +CONFIG_NOP_TRACER=y
  1929. +CONFIG_HAVE_FUNCTION_TRACER=y
  1930. +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
  1931. +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
  1932. +CONFIG_HAVE_DYNAMIC_FTRACE=y
  1933. +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
  1934. +CONFIG_RING_BUFFER=y
  1935. +CONFIG_EVENT_TRACING=y
  1936. +CONFIG_CONTEXT_SWITCH_TRACER=y
  1937. +CONFIG_RING_BUFFER_ALLOW_SWAP=y
  1938. +CONFIG_TRACING=y
  1939. CONFIG_TRACING_SUPPORT=y
  1940. # CONFIG_FTRACE is not set
  1941. +# CONFIG_DYNAMIC_DEBUG is not set
  1942. # CONFIG_SAMPLES is not set
  1943. CONFIG_HAVE_ARCH_KGDB=y
  1944. +CONFIG_EARLY_PRINTK=y
  1945. # CONFIG_CMDLINE_BOOL is not set
  1946. #
  1947. # Security options
  1948. #
  1949. -# CONFIG_KEYS is not set
  1950. +CONFIG_KEYS=y
  1951. +CONFIG_KEYS_DEBUG_PROC_KEYS=y
  1952. # CONFIG_SECURITY is not set
  1953. # CONFIG_SECURITYFS is not set
  1954. -# CONFIG_SECURITY_FILE_CAPABILITIES is not set
  1955. +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
  1956. +# CONFIG_DEFAULT_SECURITY_SMACK is not set
  1957. +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
  1958. +CONFIG_DEFAULT_SECURITY_DAC=y
  1959. +CONFIG_DEFAULT_SECURITY=""
  1960. +CONFIG_XOR_BLOCKS=m
  1961. +CONFIG_ASYNC_CORE=m
  1962. +CONFIG_ASYNC_MEMCPY=m
  1963. +CONFIG_ASYNC_XOR=m
  1964. +CONFIG_ASYNC_PQ=m
  1965. +CONFIG_ASYNC_RAID6_RECOV=m
  1966. CONFIG_CRYPTO=y
  1967. #
  1968. # Crypto core or helper
  1969. #
  1970. +CONFIG_CRYPTO_FIPS=y
  1971. CONFIG_CRYPTO_ALGAPI=y
  1972. CONFIG_CRYPTO_ALGAPI2=y
  1973. +CONFIG_CRYPTO_AEAD=m
  1974. CONFIG_CRYPTO_AEAD2=y
  1975. -CONFIG_CRYPTO_BLKCIPHER=y
  1976. +CONFIG_CRYPTO_BLKCIPHER=m
  1977. CONFIG_CRYPTO_BLKCIPHER2=y
  1978. +CONFIG_CRYPTO_HASH=y
  1979. CONFIG_CRYPTO_HASH2=y
  1980. +CONFIG_CRYPTO_RNG=m
  1981. CONFIG_CRYPTO_RNG2=y
  1982. CONFIG_CRYPTO_PCOMP=y
  1983. -CONFIG_CRYPTO_MANAGER=y
  1984. +CONFIG_CRYPTO_MANAGER=m
  1985. CONFIG_CRYPTO_MANAGER2=y
  1986. -# CONFIG_CRYPTO_GF128MUL is not set
  1987. -# CONFIG_CRYPTO_NULL is not set
  1988. +CONFIG_CRYPTO_GF128MUL=m
  1989. +CONFIG_CRYPTO_NULL=m
  1990. CONFIG_CRYPTO_WORKQUEUE=y
  1991. -# CONFIG_CRYPTO_CRYPTD is not set
  1992. -# CONFIG_CRYPTO_AUTHENC is not set
  1993. -# CONFIG_CRYPTO_TEST is not set
  1994. +CONFIG_CRYPTO_CRYPTD=m
  1995. +CONFIG_CRYPTO_AUTHENC=m
  1996. +CONFIG_CRYPTO_TEST=m
  1997. #
  1998. # Authenticated Encryption with Associated Data
  1999. #
  2000. -# CONFIG_CRYPTO_CCM is not set
  2001. -# CONFIG_CRYPTO_GCM is not set
  2002. -# CONFIG_CRYPTO_SEQIV is not set
  2003. +CONFIG_CRYPTO_CCM=m
  2004. +CONFIG_CRYPTO_GCM=m
  2005. +CONFIG_CRYPTO_SEQIV=m
  2006. #
  2007. # Block modes
  2008. #
  2009. -CONFIG_CRYPTO_CBC=y
  2010. -# CONFIG_CRYPTO_CTR is not set
  2011. +CONFIG_CRYPTO_CBC=m
  2012. +CONFIG_CRYPTO_CTR=m
  2013. # CONFIG_CRYPTO_CTS is not set
  2014. -# CONFIG_CRYPTO_ECB is not set
  2015. -# CONFIG_CRYPTO_LRW is not set
  2016. -# CONFIG_CRYPTO_PCBC is not set
  2017. -# CONFIG_CRYPTO_XTS is not set
  2018. +CONFIG_CRYPTO_ECB=m
  2019. +CONFIG_CRYPTO_LRW=m
  2020. +CONFIG_CRYPTO_PCBC=m
  2021. +CONFIG_CRYPTO_XTS=m
  2022. #
  2023. # Hash modes
  2024. #
  2025. -# CONFIG_CRYPTO_HMAC is not set
  2026. -# CONFIG_CRYPTO_XCBC is not set
  2027. +CONFIG_CRYPTO_HMAC=m
  2028. +CONFIG_CRYPTO_XCBC=m
  2029. # CONFIG_CRYPTO_VMAC is not set
  2030. #
  2031. # Digest
  2032. #
  2033. -# CONFIG_CRYPTO_CRC32C is not set
  2034. -# CONFIG_CRYPTO_GHASH is not set
  2035. -# CONFIG_CRYPTO_MD4 is not set
  2036. -# CONFIG_CRYPTO_MD5 is not set
  2037. -# CONFIG_CRYPTO_MICHAEL_MIC is not set
  2038. -# CONFIG_CRYPTO_RMD128 is not set
  2039. -# CONFIG_CRYPTO_RMD160 is not set
  2040. -# CONFIG_CRYPTO_RMD256 is not set
  2041. -# CONFIG_CRYPTO_RMD320 is not set
  2042. -# CONFIG_CRYPTO_SHA1 is not set
  2043. -# CONFIG_CRYPTO_SHA256 is not set
  2044. -# CONFIG_CRYPTO_SHA512 is not set
  2045. -# CONFIG_CRYPTO_TGR192 is not set
  2046. -# CONFIG_CRYPTO_WP512 is not set
  2047. +CONFIG_CRYPTO_CRC32C=m
  2048. +CONFIG_CRYPTO_GHASH=m
  2049. +CONFIG_CRYPTO_MD4=m
  2050. +CONFIG_CRYPTO_MD5=y
  2051. +CONFIG_CRYPTO_MICHAEL_MIC=m
  2052. +CONFIG_CRYPTO_RMD128=m
  2053. +CONFIG_CRYPTO_RMD160=m
  2054. +CONFIG_CRYPTO_RMD256=m
  2055. +CONFIG_CRYPTO_RMD320=m
  2056. +CONFIG_CRYPTO_SHA1=m
  2057. +CONFIG_CRYPTO_SHA256=m
  2058. +CONFIG_CRYPTO_SHA512=m
  2059. +CONFIG_CRYPTO_TGR192=m
  2060. +CONFIG_CRYPTO_WP512=m
  2061. #
  2062. # Ciphers
  2063. #
  2064. -# CONFIG_CRYPTO_AES is not set
  2065. -# CONFIG_CRYPTO_ANUBIS is not set
  2066. -# CONFIG_CRYPTO_ARC4 is not set
  2067. -# CONFIG_CRYPTO_BLOWFISH is not set
  2068. -# CONFIG_CRYPTO_CAMELLIA is not set
  2069. -# CONFIG_CRYPTO_CAST5 is not set
  2070. -# CONFIG_CRYPTO_CAST6 is not set
  2071. -# CONFIG_CRYPTO_DES is not set
  2072. -# CONFIG_CRYPTO_FCRYPT is not set
  2073. -# CONFIG_CRYPTO_KHAZAD is not set
  2074. -# CONFIG_CRYPTO_SALSA20 is not set
  2075. -# CONFIG_CRYPTO_SEED is not set
  2076. -# CONFIG_CRYPTO_SERPENT is not set
  2077. -# CONFIG_CRYPTO_TEA is not set
  2078. -# CONFIG_CRYPTO_TWOFISH is not set
  2079. +CONFIG_CRYPTO_AES=m
  2080. +CONFIG_CRYPTO_ANUBIS=m
  2081. +CONFIG_CRYPTO_ARC4=m
  2082. +CONFIG_CRYPTO_BLOWFISH=m
  2083. +CONFIG_CRYPTO_CAMELLIA=m
  2084. +CONFIG_CRYPTO_CAST5=m
  2085. +CONFIG_CRYPTO_CAST6=m
  2086. +CONFIG_CRYPTO_DES=m
  2087. +CONFIG_CRYPTO_FCRYPT=m
  2088. +CONFIG_CRYPTO_KHAZAD=m
  2089. +CONFIG_CRYPTO_SALSA20=m
  2090. +CONFIG_CRYPTO_SEED=m
  2091. +CONFIG_CRYPTO_SERPENT=m
  2092. +CONFIG_CRYPTO_TEA=m
  2093. +CONFIG_CRYPTO_TWOFISH=m
  2094. +CONFIG_CRYPTO_TWOFISH_COMMON=m
  2095. #
  2096. # Compression
  2097. #
  2098. -# CONFIG_CRYPTO_DEFLATE is not set
  2099. -# CONFIG_CRYPTO_ZLIB is not set
  2100. -# CONFIG_CRYPTO_LZO is not set
  2101. +CONFIG_CRYPTO_DEFLATE=m
  2102. +CONFIG_CRYPTO_ZLIB=m
  2103. +CONFIG_CRYPTO_LZO=m
  2104. #
  2105. # Random Number Generation
  2106. #
  2107. -# CONFIG_CRYPTO_ANSI_CPRNG is not set
  2108. +CONFIG_CRYPTO_ANSI_CPRNG=m
  2109. CONFIG_CRYPTO_HW=y
  2110. # CONFIG_CRYPTO_DEV_HIFN_795X is not set
  2111. -# CONFIG_BINARY_PRINTF is not set
  2112. +CONFIG_BINARY_PRINTF=y
  2113. #
  2114. # Library routines
  2115. @@ -1821,14 +2219,20 @@
  2116. CONFIG_BITREVERSE=y
  2117. CONFIG_GENERIC_FIND_LAST_BIT=y
  2118. # CONFIG_CRC_CCITT is not set
  2119. -# CONFIG_CRC16 is not set
  2120. +CONFIG_CRC16=y
  2121. CONFIG_CRC_T10DIF=y
  2122. # CONFIG_CRC_ITU_T is not set
  2123. CONFIG_CRC32=y
  2124. # CONFIG_CRC7 is not set
  2125. -# CONFIG_LIBCRC32C is not set
  2126. +CONFIG_LIBCRC32C=m
  2127. CONFIG_AUDIT_GENERIC=y
  2128. -CONFIG_ZLIB_INFLATE=m
  2129. +CONFIG_ZLIB_INFLATE=y
  2130. +CONFIG_ZLIB_DEFLATE=m
  2131. +CONFIG_LZO_COMPRESS=m
  2132. +CONFIG_LZO_DECOMPRESS=m
  2133. +CONFIG_DECOMPRESS_GZIP=y
  2134. +CONFIG_DECOMPRESS_BZIP2=y
  2135. +CONFIG_DECOMPRESS_LZMA=y
  2136. CONFIG_HAS_IOMEM=y
  2137. CONFIG_HAS_IOPORT=y
  2138. CONFIG_HAS_DMA=y
  2139. diff -Nur linux-2.6.33/arch/mips/include/asm/ftrace.h linux-lemote/arch/mips/include/asm/ftrace.h
  2140. --- linux-2.6.33/arch/mips/include/asm/ftrace.h 2010-02-24 19:52:17.000000000 +0100
  2141. +++ linux-lemote/arch/mips/include/asm/ftrace.h 2010-03-06 16:43:00.000000000 +0100
  2142. @@ -4,7 +4,7 @@
  2143. * more details.
  2144. *
  2145. * Copyright (C) 2009 DSLab, Lanzhou University, China
  2146. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2147. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2148. */
  2149. #ifndef _ASM_MIPS_FTRACE_H
  2150. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h linux-lemote/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
  2151. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-02-24 19:52:17.000000000 +0100
  2152. +++ linux-lemote/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-03-06 16:43:00.000000000 +0100
  2153. @@ -3,7 +3,7 @@
  2154. * License. See the file "COPYING" in the main directory of this archive
  2155. * for more details.
  2156. *
  2157. - * Copyright (C) 2009 Wu Zhangjin <wuzj@lemote.com>
  2158. + * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
  2159. * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
  2160. * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
  2161. *
  2162. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
  2163. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-02-24 19:52:17.000000000 +0100
  2164. +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-03-06 16:43:00.000000000 +0100
  2165. @@ -301,5 +301,40 @@
  2166. /* GPIO : I/O SPACE; REG : 32BITS */
  2167. #define GPIOL_OUT_VAL 0x00
  2168. #define GPIOL_OUT_EN 0x04
  2169. +#define GPIOL_OUT_AUX1_SEL 0x10
  2170. +/* SMB : I/O SPACE, REG : 8BITS WIDTH */
  2171. +#define SMB_SDA 0x00
  2172. +#define SMB_STS 0x01
  2173. +#define SMB_STS_SLVSTP (1 << 7)
  2174. +#define SMB_STS_SDAST (1 << 6)
  2175. +#define SMB_STS_BER (1 << 5)
  2176. +#define SMB_STS_NEGACK (1 << 4)
  2177. +#define SMB_STS_STASTR (1 << 3)
  2178. +#define SMB_STS_NMATCH (1 << 2)
  2179. +#define SMB_STS_MASTER (1 << 1)
  2180. +#define SMB_STS_XMIT (1 << 0)
  2181. +#define SMB_CTRL_STS 0x02
  2182. +#define SMB_CSTS_TGSTL (1 << 5)
  2183. +#define SMB_CSTS_TSDA (1 << 4)
  2184. +#define SMB_CSTS_GCMTCH (1 << 3)
  2185. +#define SMB_CSTS_MATCH (1 << 2)
  2186. +#define SMB_CSTS_BB (1 << 1)
  2187. +#define SMB_CSTS_BUSY (1 << 0)
  2188. +#define SMB_CTRL1 0x03
  2189. +#define SMB_CTRL1_STASTRE (1 << 7)
  2190. +#define SMB_CTRL1_NMINTE (1 << 6)
  2191. +#define SMB_CTRL1_GCMEN (1 << 5)
  2192. +#define SMB_CTRL1_ACK (1 << 4)
  2193. +#define SMB_CTRL1_RSVD (1 << 3)
  2194. +#define SMB_CTRL1_INTEN (1 << 2)
  2195. +#define SMB_CTRL1_STOP (1 << 1)
  2196. +#define SMB_CTRL1_START (1 << 0)
  2197. +#define SMB_ADDR 0x04
  2198. +#define SMB_ADDR_SAEN (1 << 7)
  2199. +#define SMB_CONTROLLER_ADDR (0xef << 0)
  2200. +#define SMB_CTRL2 0x05
  2201. +#define SMB_FREQ (0x20 << 1)
  2202. +#define SMB_ENABLE (0x01 << 0)
  2203. +#define SMB_CTRL3 0x06
  2204. #endif /* _CS5536_H */
  2205. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
  2206. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-02-24 19:52:17.000000000 +0100
  2207. +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-03-06 16:43:00.000000000 +0100
  2208. @@ -32,4 +32,9 @@
  2209. #define MFGPT0_CNT (MFGPT_BASE + 4)
  2210. #define MFGPT0_SETUP (MFGPT_BASE + 6)
  2211. +#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
  2212. +#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
  2213. +#define MFGPT2_CNT (MFGPT_BASE + 0x14)
  2214. +#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
  2215. +
  2216. #endif /*!_CS5536_MFGPT_H */
  2217. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
  2218. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 2010-02-24 19:52:17.000000000 +0100
  2219. +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 2010-03-06 16:43:00.000000000 +0100
  2220. @@ -2,7 +2,7 @@
  2221. * the read/write interfaces for Virtual Support Module(VSM)
  2222. *
  2223. * Copyright (C) 2009 Lemote, Inc.
  2224. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2225. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2226. */
  2227. #ifndef _CS5536_VSM_H
  2228. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-lemote/arch/mips/include/asm/mach-loongson/ec_kb3310b.h
  2229. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
  2230. +++ linux-lemote/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2010-03-06 16:43:00.000000000 +0100
  2231. @@ -0,0 +1,191 @@
  2232. +/*
  2233. + * KB3310B Embedded Controller
  2234. + *
  2235. + * Copyright (C) 2008 Lemote Inc.
  2236. + * Author: liujl <liujl@lemote.com>, 2008-03-14
  2237. + * Copyright (C) 2009 Lemote Inc.
  2238. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2239. + *
  2240. + * This program is free software; you can redistribute it and/or modify
  2241. + * it under the terms of the GNU General Public License as published by
  2242. + * the Free Software Foundation; either version 2 of the License, or
  2243. + * (at your option) any later version.
  2244. + */
  2245. +
  2246. +#ifndef _EC_KB3310B_H
  2247. +#define _EC_KB3310B_H
  2248. +
  2249. +extern unsigned char ec_read(unsigned short addr);
  2250. +extern void ec_write(unsigned short addr, unsigned char val);
  2251. +extern int ec_query_seq(unsigned char cmd);
  2252. +extern int ec_query_event_num(void);
  2253. +extern int ec_get_event_num(void);
  2254. +
  2255. +typedef int (*sci_handler) (int status);
  2256. +extern sci_handler yeeloong_report_lid_status;
  2257. +
  2258. +#define SCI_IRQ_NUM 0x0A
  2259. +
  2260. +/*
  2261. + * The following registers are determined by the EC index configuration.
  2262. + * 1, fill the PORT_HIGH as EC register high part.
  2263. + * 2, fill the PORT_LOW as EC register low part.
  2264. + * 3, fill the PORT_DATA as EC register write data or get the data from it.
  2265. + */
  2266. +#define EC_IO_PORT_HIGH 0x0381
  2267. +#define EC_IO_PORT_LOW 0x0382
  2268. +#define EC_IO_PORT_DATA 0x0383
  2269. +
  2270. +/*
  2271. + * EC delay time is 500us for register and status access
  2272. + */
  2273. +#define EC_REG_DELAY 500 /* unit : us */
  2274. +#define EC_CMD_TIMEOUT 0x1000
  2275. +
  2276. +/*
  2277. + * EC access port for SCI communication
  2278. + */
  2279. +#define EC_CMD_PORT 0x66
  2280. +#define EC_STS_PORT 0x66
  2281. +#define EC_DAT_PORT 0x62
  2282. +#define CMD_INIT_IDLE_MODE 0xdd
  2283. +#define CMD_EXIT_IDLE_MODE 0xdf
  2284. +#define CMD_INIT_RESET_MODE 0xd8
  2285. +#define CMD_REBOOT_SYSTEM 0x8c
  2286. +#define CMD_GET_EVENT_NUM 0x84
  2287. +#define CMD_PROGRAM_PIECE 0xda
  2288. +
  2289. +/* Temperature & Fan registers */
  2290. +#define REG_TEMPERATURE_VALUE 0xF458
  2291. +#define REG_FAN_AUTO_MAN_SWITCH 0xF459
  2292. +#define BIT_FAN_AUTO 0
  2293. +#define BIT_FAN_MANUAL 1
  2294. +#define REG_FAN_CONTROL 0xF4D2
  2295. +#define BIT_FAN_CONTROL_ON (1 << 0)
  2296. +#define BIT_FAN_CONTROL_OFF (0 << 0)
  2297. +#define REG_FAN_STATUS 0xF4DA
  2298. +#define BIT_FAN_STATUS_ON (1 << 0)
  2299. +#define BIT_FAN_STATUS_OFF (0 << 0)
  2300. +#define REG_FAN_SPEED_HIGH 0xFE22
  2301. +#define REG_FAN_SPEED_LOW 0xFE23
  2302. +#define REG_FAN_SPEED_LEVEL 0xF4CC
  2303. +/* Fan speed divider */
  2304. +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
  2305. +
  2306. +/* Battery registers */
  2307. +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
  2308. +#define REG_BAT_DESIGN_CAP_LOW 0xF77E
  2309. +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
  2310. +#define REG_BAT_FULLCHG_CAP_LOW 0xF781
  2311. +#define REG_BAT_DESIGN_VOL_HIGH 0xF782
  2312. +#define REG_BAT_DESIGN_VOL_LOW 0xF783
  2313. +#define REG_BAT_CURRENT_HIGH 0xF784
  2314. +#define REG_BAT_CURRENT_LOW 0xF785
  2315. +#define REG_BAT_VOLTAGE_HIGH 0xF786
  2316. +#define REG_BAT_VOLTAGE_LOW 0xF787
  2317. +#define REG_BAT_TEMPERATURE_HIGH 0xF788
  2318. +#define REG_BAT_TEMPERATURE_LOW 0xF789
  2319. +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
  2320. +#define REG_BAT_RELATIVE_CAP_LOW 0xF493
  2321. +#define REG_BAT_VENDOR 0xF4C4
  2322. +#define FLAG_BAT_VENDOR_SANYO 0x01
  2323. +#define FLAG_BAT_VENDOR_SIMPLO 0x02
  2324. +#define REG_BAT_CELL_COUNT 0xF4C6
  2325. +#define FLAG_BAT_CELL_3S1P 0x03
  2326. +#define FLAG_BAT_CELL_3S2P 0x06
  2327. +#define REG_BAT_CHARGE 0xF4A2
  2328. +#define FLAG_BAT_CHARGE_DISCHARGE 0x01
  2329. +#define FLAG_BAT_CHARGE_CHARGE 0x02
  2330. +#define FLAG_BAT_CHARGE_ACPOWER 0x00
  2331. +#define REG_BAT_STATUS 0xF4B0
  2332. +#define BIT_BAT_STATUS_LOW (1 << 5)
  2333. +#define BIT_BAT_STATUS_DESTROY (1 << 2)
  2334. +#define BIT_BAT_STATUS_FULL (1 << 1)
  2335. +#define BIT_BAT_STATUS_IN (1 << 0)
  2336. +#define REG_BAT_CHARGE_STATUS 0xF4B1
  2337. +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
  2338. +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
  2339. +#define REG_BAT_STATE 0xF482
  2340. +#define BIT_BAT_STATE_CHARGING (1 << 1)
  2341. +#define BIT_BAT_STATE_DISCHARGING (1 << 0)
  2342. +#define REG_BAT_POWER 0xF440
  2343. +#define BIT_BAT_POWER_S3 (1 << 2)
  2344. +#define BIT_BAT_POWER_ON (1 << 1)
  2345. +#define BIT_BAT_POWER_ACIN (1 << 0)
  2346. +
  2347. +/* Audio: rd/wr */
  2348. +#define REG_AUDIO_VOLUME 0xF46C
  2349. +#define REG_AUDIO_MUTE 0xF4E7
  2350. +#define REG_AUDIO_BEEP 0xF4D0
  2351. +/* USB port power or not: rd/wr */
  2352. +#define REG_USB0_FLAG 0xF461
  2353. +#define REG_USB1_FLAG 0xF462
  2354. +#define REG_USB2_FLAG 0xF463
  2355. +#define BIT_USB_FLAG_ON 1
  2356. +#define BIT_USB_FLAG_OFF 0
  2357. +/* LID */
  2358. +#define REG_LID_DETECT 0xF4BD
  2359. +#define BIT_LID_DETECT_ON 1
  2360. +#define BIT_LID_DETECT_OFF 0
  2361. +/* CRT */
  2362. +#define REG_CRT_DETECT 0xF4AD
  2363. +#define BIT_CRT_DETECT_PLUG 1
  2364. +#define BIT_CRT_DETECT_UNPLUG 0
  2365. +/* LCD backlight brightness adjust: 9 levels */
  2366. +#define REG_DISPLAY_BRIGHTNESS 0xF4F5
  2367. +/* Black screen Status */
  2368. +#define BIT_DISPLAY_LCD_ON 1
  2369. +#define BIT_DISPLAY_LCD_OFF 0
  2370. +/* LCD backlight control: off/restore */
  2371. +#define REG_BACKLIGHT_CTRL 0xF7BD
  2372. +#define BIT_BACKLIGHT_ON 1
  2373. +#define BIT_BACKLIGHT_OFF 0
  2374. +/* Reset the machine auto-clear: rd/wr */
  2375. +#define REG_RESET 0xF4EC
  2376. +#define BIT_RESET_ON 1
  2377. +/* Light the led: rd/wr */
  2378. +#define REG_LED 0xF4C8
  2379. +#define BIT_LED_RED_POWER (1 << 0)
  2380. +#define BIT_LED_ORANGE_POWER (1 << 1)
  2381. +#define BIT_LED_GREEN_CHARGE (1 << 2)
  2382. +#define BIT_LED_RED_CHARGE (1 << 3)
  2383. +#define BIT_LED_NUMLOCK (1 << 4)
  2384. +/* Test led mode, all led on/off */
  2385. +#define REG_LED_TEST 0xF4C2
  2386. +#define BIT_LED_TEST_IN 1
  2387. +#define BIT_LED_TEST_OUT 0
  2388. +/* Camera on/off */
  2389. +#define REG_CAMERA_STATUS 0xF46A
  2390. +#define BIT_CAMERA_STATUS_ON 1
  2391. +#define BIT_CAMERA_STATUS_OFF 0
  2392. +#define REG_CAMERA_CONTROL 0xF7B7
  2393. +#define BIT_CAMERA_CONTROL_OFF 0
  2394. +#define BIT_CAMERA_CONTROL_ON 1
  2395. +/* Wlan Status */
  2396. +#define REG_WLAN 0xF4FA
  2397. +#define BIT_WLAN_ON 1
  2398. +#define BIT_WLAN_OFF 0
  2399. +#define REG_DISPLAY_LCD 0xF79F
  2400. +
  2401. +/* SCI Event Number from EC */
  2402. +enum {
  2403. + EVENT_LID = 0x23, /* Turn on/off LID */
  2404. + EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
  2405. + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
  2406. + EVENT_OVERTEMP, /* Over-temperature happened */
  2407. + EVENT_CRT_DETECT, /* CRT is connected */
  2408. + EVENT_CAMERA, /* Camera on/off */
  2409. + EVENT_USB_OC2, /* USB2 Over Current occurred */
  2410. + EVENT_USB_OC0, /* USB0 Over Current occurred */
  2411. + EVENT_BLACK_SCREEN, /* Turn on/off backlight */
  2412. + EVENT_AUDIO_MUTE, /* Mute on/off */
  2413. + EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
  2414. + EVENT_AC_BAT, /* AC & Battery relative issue */
  2415. + EVENT_AUDIO_VOLUME, /* Volume adjust */
  2416. + EVENT_WLAN, /* Wlan on/off */
  2417. +};
  2418. +
  2419. +#define EVENT_START EVENT_LID
  2420. +#define EVENT_END EVENT_WLAN
  2421. +
  2422. +#endif /* !_EC_KB3310B_H */
  2423. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/loongson.h linux-lemote/arch/mips/include/asm/mach-loongson/loongson.h
  2424. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/loongson.h 2010-02-24 19:52:17.000000000 +0100
  2425. +++ linux-lemote/arch/mips/include/asm/mach-loongson/loongson.h 2010-03-06 16:43:00.000000000 +0100
  2426. @@ -1,12 +1,11 @@
  2427. /*
  2428. * Copyright (C) 2009 Lemote, Inc.
  2429. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2430. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2431. *
  2432. * This program is free software; you can redistribute it and/or modify it
  2433. * under the terms of the GNU General Public License as published by the
  2434. * Free Software Foundation; either version 2 of the License, or (at your
  2435. * option) any later version.
  2436. - *
  2437. */
  2438. #ifndef __ASM_MACH_LOONGSON_LOONGSON_H
  2439. @@ -23,7 +22,7 @@
  2440. extern void mach_prepare_shutdown(void);
  2441. /* environment arguments from bootloader */
  2442. -extern unsigned long bus_clock, cpu_clock_freq;
  2443. +extern unsigned long cpu_clock_freq;
  2444. extern unsigned long memsize, highmemsize;
  2445. /* loongson-specific command line, env and memory initialization */
  2446. @@ -43,6 +42,12 @@
  2447. #endif
  2448. }
  2449. +/*
  2450. + * Copy kernel command line from arcs_cmdline
  2451. + */
  2452. +#include <asm/setup.h>
  2453. +extern char loongson_cmdline[COMMAND_LINE_SIZE];
  2454. +
  2455. /* irq operation functions */
  2456. extern void bonito_irqdispatch(void);
  2457. extern void __init bonito_irq_init(void);
  2458. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/machine.h linux-lemote/arch/mips/include/asm/mach-loongson/machine.h
  2459. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/machine.h 2010-02-24 19:52:17.000000000 +0100
  2460. +++ linux-lemote/arch/mips/include/asm/mach-loongson/machine.h 2010-03-06 16:43:00.000000000 +0100
  2461. @@ -1,6 +1,6 @@
  2462. /*
  2463. - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
  2464. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2465. + * Copyright (C) 2009 Lemote, Inc.
  2466. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2467. *
  2468. * This program is free software; you can redistribute it and/or modify it
  2469. * under the terms of the GNU General Public License as published by the
  2470. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/mem.h linux-lemote/arch/mips/include/asm/mach-loongson/mem.h
  2471. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/mem.h 2010-02-24 19:52:17.000000000 +0100
  2472. +++ linux-lemote/arch/mips/include/asm/mach-loongson/mem.h 2010-03-06 16:43:00.000000000 +0100
  2473. @@ -1,6 +1,6 @@
  2474. /*
  2475. * Copyright (C) 2009 Lemote, Inc.
  2476. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2477. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2478. *
  2479. * This program is free software; you can redistribute it and/or modify it
  2480. * under the terms of the GNU General Public License as published by the
  2481. diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/pci.h linux-lemote/arch/mips/include/asm/mach-loongson/pci.h
  2482. --- linux-2.6.33/arch/mips/include/asm/mach-loongson/pci.h 2010-02-24 19:52:17.000000000 +0100
  2483. +++ linux-lemote/arch/mips/include/asm/mach-loongson/pci.h 2010-03-06 16:43:00.000000000 +0100
  2484. @@ -1,23 +1,12 @@
  2485. /*
  2486. * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
  2487. - * Copyright (c) 2009 Wu Zhangjin <wuzj@lemote.com>
  2488. + * Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
  2489. *
  2490. * This program is free software; you can redistribute it
  2491. * and/or modify it under the terms of the GNU General
  2492. * Public License as published by the Free Software
  2493. * Foundation; either version 2 of the License, or (at your
  2494. * option) any later version.
  2495. - *
  2496. - * This program is distributed in the hope that it will be
  2497. - * useful, but WITHOUT ANY WARRANTY; without even the implied
  2498. - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2499. - * PURPOSE. See the GNU General Public License for more
  2500. - * details.
  2501. - *
  2502. - * You should have received a copy of the GNU General Public
  2503. - * License along with this program; if not, write to the Free
  2504. - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
  2505. - * 02139, USA.
  2506. */
  2507. #ifndef __ASM_MACH_LOONGSON_PCI_H_
  2508. diff -Nur linux-2.6.33/arch/mips/include/asm/stackframe.h linux-lemote/arch/mips/include/asm/stackframe.h
  2509. --- linux-2.6.33/arch/mips/include/asm/stackframe.h 2010-02-24 19:52:17.000000000 +0100
  2510. +++ linux-lemote/arch/mips/include/asm/stackframe.h 2010-03-06 16:43:00.000000000 +0100
  2511. @@ -121,6 +121,25 @@
  2512. .endm
  2513. #else
  2514. .macro get_saved_sp /* Uniprocessor variation */
  2515. + /*
  2516. + * clear BTB(branch target buffer), forbid RAS(row address
  2517. + * strobe) to make cpu execute predictively via
  2518. + * loongson2-specific 64bit diagnostic register
  2519. + */
  2520. +#ifdef CONFIG_CPU_LOONGSON2F
  2521. + move k0, ra
  2522. + jal 1f
  2523. + nop
  2524. +1: jal 1f
  2525. + nop
  2526. +1: jal 1f
  2527. + nop
  2528. +1: jal 1f
  2529. + nop
  2530. +1: move ra, k0
  2531. + li k0, 3
  2532. + mtc0 k0, $22
  2533. +#endif
  2534. #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
  2535. lui k1, %hi(kernelsp)
  2536. #else
  2537. diff -Nur linux-2.6.33/arch/mips/Kconfig linux-lemote/arch/mips/Kconfig
  2538. --- linux-2.6.33/arch/mips/Kconfig 2010-02-24 19:52:17.000000000 +0100
  2539. +++ linux-lemote/arch/mips/Kconfig 2010-03-06 16:42:59.000000000 +0100
  2540. @@ -180,7 +180,7 @@
  2541. config MACH_LOONGSON
  2542. bool "Loongson family of machines"
  2543. - select SYS_SUPPORTS_ZBOOT_UART16550
  2544. + select SYS_SUPPORTS_ZBOOT
  2545. help
  2546. This enables the support of Loongson family of machines.
  2547. @@ -1934,6 +1934,18 @@
  2548. source "kernel/time/Kconfig"
  2549. #
  2550. +# High Resolution sched_clock() Configuration
  2551. +#
  2552. +
  2553. +config CPU_HAS_FIXED_C0_COUNT
  2554. + bool
  2555. +
  2556. +config CPU_SUPPORTS_HR_SCHED_CLOCK
  2557. + bool
  2558. + depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ
  2559. + default y
  2560. +
  2561. +#
  2562. # Timer Interrupt Frequency Configuration
  2563. #
  2564. diff -Nur linux-2.6.33/arch/mips/Kconfig.debug linux-lemote/arch/mips/Kconfig.debug
  2565. --- linux-2.6.33/arch/mips/Kconfig.debug 2010-02-24 19:52:17.000000000 +0100
  2566. +++ linux-lemote/arch/mips/Kconfig.debug 2010-03-06 16:42:59.000000000 +0100
  2567. @@ -102,4 +102,22 @@
  2568. arch/mips/include/asm/debug.h for debugging macros.
  2569. If unsure, say N.
  2570. +config DEBUG_ZBOOT
  2571. + bool "Enable compressed kernel support debugging"
  2572. + depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
  2573. + help
  2574. + If you want to add compressed kernel support to a new board, and the
  2575. + board supports uart16550 compatible serial port, please select
  2576. + SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
  2577. + debug it.
  2578. +
  2579. + If your board doesn't support uart16550 compatible serial port, you
  2580. + can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
  2581. + debug it. for example, add a new serial port support just as
  2582. + arch/mips/boot/compressed/uart-16550.c does.
  2583. +
  2584. + After the compressed kernel support works, please disable this option
  2585. + to reduce the kernel image size and speed up the booting procedure a
  2586. + little.
  2587. +
  2588. endmenu
  2589. diff -Nur linux-2.6.33/arch/mips/kernel/cpufreq/loongson2_clock.c linux-lemote/arch/mips/kernel/cpufreq/loongson2_clock.c
  2590. --- linux-2.6.33/arch/mips/kernel/cpufreq/loongson2_clock.c 2010-02-24 19:52:17.000000000 +0100
  2591. +++ linux-lemote/arch/mips/kernel/cpufreq/loongson2_clock.c 2010-03-06 16:43:01.000000000 +0100
  2592. @@ -164,3 +164,7 @@
  2593. spin_unlock_irqrestore(&loongson2_wait_lock, flags);
  2594. }
  2595. EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
  2596. +
  2597. +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
  2598. +MODULE_DESCRIPTION("cpuclock driver of Loongson2F");
  2599. +MODULE_LICENSE("GPL");
  2600. diff -Nur linux-2.6.33/arch/mips/kernel/csrc-r4k.c linux-lemote/arch/mips/kernel/csrc-r4k.c
  2601. --- linux-2.6.33/arch/mips/kernel/csrc-r4k.c 2010-02-24 19:52:17.000000000 +0100
  2602. +++ linux-lemote/arch/mips/kernel/csrc-r4k.c 2010-03-06 16:43:01.000000000 +0100
  2603. @@ -6,10 +6,66 @@
  2604. * Copyright (C) 2007 by Ralf Baechle
  2605. */
  2606. #include <linux/clocksource.h>
  2607. +#include <linux/cnt32_to_63.h>
  2608. #include <linux/init.h>
  2609. +#include <linux/timer.h>
  2610. #include <asm/time.h>
  2611. +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
  2612. +/*
  2613. + * MIPS sched_clock implementation.
  2614. + *
  2615. + * Because the hardware timer period is quite short and because cnt32_to_63()
  2616. + * needs to be called at least once per half period to work properly, a kernel
  2617. + * timer is set up to ensure this requirement is always met.
  2618. + *
  2619. + * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c
  2620. + */
  2621. +#define CLOCK2NS_SCALE_FACTOR 8
  2622. +
  2623. +static unsigned long clock2ns_scale __read_mostly;
  2624. +
  2625. +unsigned long long notrace sched_clock(void)
  2626. +{
  2627. + unsigned long long v = cnt32_to_63(read_c0_count());
  2628. + return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;
  2629. +}
  2630. +
  2631. +static struct timer_list cnt32_to_63_keepwarm_timer;
  2632. +
  2633. +static void cnt32_to_63_keepwarm(unsigned long data)
  2634. +{
  2635. + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
  2636. + sched_clock();
  2637. +}
  2638. +#endif
  2639. +
  2640. +static inline void setup_hres_sched_clock(unsigned long clock)
  2641. +{
  2642. +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
  2643. + unsigned long long v;
  2644. + unsigned long data;
  2645. +
  2646. + v = NSEC_PER_SEC;
  2647. + v <<= CLOCK2NS_SCALE_FACTOR;
  2648. + v += clock/2;
  2649. + do_div(v, clock);
  2650. + /*
  2651. + * We want an even value to automatically clear the top bit
  2652. + * returned by cnt32_to_63() without an additional run time
  2653. + * instruction. So if the LSB is 1 then round it up.
  2654. + */
  2655. + if (v & 1)
  2656. + v++;
  2657. + clock2ns_scale = v;
  2658. +
  2659. + data = 0x80000000UL / clock * HZ;
  2660. + setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
  2661. + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
  2662. +#endif
  2663. +}
  2664. +
  2665. static cycle_t c0_hpt_read(struct clocksource *cs)
  2666. {
  2667. return read_c0_count();
  2668. @@ -27,6 +83,8 @@
  2669. if (!cpu_has_counter || !mips_hpt_frequency)
  2670. return -ENXIO;
  2671. + setup_hres_sched_clock(mips_hpt_frequency);
  2672. +
  2673. /* Calculate a somewhat reasonable rating value */
  2674. clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
  2675. diff -Nur linux-2.6.33/arch/mips/kernel/ftrace.c linux-lemote/arch/mips/kernel/ftrace.c
  2676. --- linux-2.6.33/arch/mips/kernel/ftrace.c 2010-02-24 19:52:17.000000000 +0100
  2677. +++ linux-lemote/arch/mips/kernel/ftrace.c 2010-03-06 16:43:01.000000000 +0100
  2678. @@ -3,7 +3,7 @@
  2679. *
  2680. * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
  2681. * Copyright (C) 2009 DSLab, Lanzhou University, China
  2682. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2683. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2684. *
  2685. * Thanks goes to Steven Rostedt for writing the original x86 version.
  2686. */
  2687. diff -Nur linux-2.6.33/arch/mips/kernel/mcount.S linux-lemote/arch/mips/kernel/mcount.S
  2688. --- linux-2.6.33/arch/mips/kernel/mcount.S 2010-02-24 19:52:17.000000000 +0100
  2689. +++ linux-lemote/arch/mips/kernel/mcount.S 2010-03-06 16:43:01.000000000 +0100
  2690. @@ -6,7 +6,7 @@
  2691. * more details.
  2692. *
  2693. * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
  2694. - * Author: Wu Zhangjin <wuzj@lemote.com>
  2695. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2696. */
  2697. #include <asm/regdef.h>
  2698. diff -Nur linux-2.6.33/arch/mips/kernel/time.c linux-lemote/arch/mips/kernel/time.c
  2699. --- linux-2.6.33/arch/mips/kernel/time.c 2010-02-24 19:52:17.000000000 +0100
  2700. +++ linux-lemote/arch/mips/kernel/time.c 2010-03-06 16:43:01.000000000 +0100
  2701. @@ -119,6 +119,11 @@
  2702. void __init time_init(void)
  2703. {
  2704. +#ifdef CONFIG_HR_SCHED_CLOCK
  2705. + if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
  2706. + write_c0_count(0);
  2707. +#endif
  2708. +
  2709. plat_time_init();
  2710. if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
  2711. diff -Nur linux-2.6.33/arch/mips/loongson/common/cmdline.c linux-lemote/arch/mips/loongson/common/cmdline.c
  2712. --- linux-2.6.33/arch/mips/loongson/common/cmdline.c 2010-02-24 19:52:17.000000000 +0100
  2713. +++ linux-lemote/arch/mips/loongson/common/cmdline.c 2010-03-06 16:43:01.000000000 +0100
  2714. @@ -10,23 +10,27 @@
  2715. * Author: Fuxin Zhang, zhangfx@lemote.com
  2716. *
  2717. * Copyright (C) 2009 Lemote Inc.
  2718. - * Author: Wu Zhangjin, wuzj@lemote.com
  2719. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2720. *
  2721. * This program is free software; you can redistribute it and/or modify it
  2722. * under the terms of the GNU General Public License as published by the
  2723. * Free Software Foundation; either version 2 of the License, or (at your
  2724. * option) any later version.
  2725. */
  2726. +#include <linux/module.h>
  2727. #include <asm/bootinfo.h>
  2728. #include <loongson.h>
  2729. -int prom_argc;
  2730. -/* pmon passes arguments in 32bit pointers */
  2731. -int *_prom_argv;
  2732. +/* the kernel command line copied from arcs_cmdline */
  2733. +char loongson_cmdline[COMMAND_LINE_SIZE];
  2734. +EXPORT_SYMBOL(loongson_cmdline);
  2735. void __init prom_init_cmdline(void)
  2736. {
  2737. + int prom_argc;
  2738. + /* pmon passes arguments in 32bit pointers */
  2739. + int *_prom_argv;
  2740. int i;
  2741. long l;
  2742. @@ -51,4 +55,26 @@
  2743. strcat(arcs_cmdline, " root=/dev/hda1");
  2744. prom_init_machtype();
  2745. +
  2746. + /* append machine specific command line */
  2747. + switch (mips_machtype) {
  2748. + case MACH_LEMOTE_LL2F:
  2749. + if ((strstr(arcs_cmdline, "video=")) == NULL)
  2750. + strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
  2751. + break;
  2752. + case MACH_LEMOTE_FL2F:
  2753. + if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
  2754. + strcat(arcs_cmdline, " ide_core.ignore_cable=0");
  2755. + break;
  2756. + case MACH_LEMOTE_ML2F7:
  2757. + /* Mengloong-2F has a 800x480 screen */
  2758. + if ((strstr(arcs_cmdline, "vga=")) == NULL)
  2759. + strcat(arcs_cmdline, " vga=0x313");
  2760. + break;
  2761. + default:
  2762. + break;
  2763. + }
  2764. +
  2765. + /* copy arcs_cmdline into loongson_cmdline */
  2766. + strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE);
  2767. }
  2768. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_acc.c
  2769. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-02-24 19:52:17.000000000 +0100
  2770. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-03-06 16:43:01.000000000 +0100
  2771. @@ -5,7 +5,7 @@
  2772. * Author : jlliu, liujl@lemote.com
  2773. *
  2774. * Copyright (C) 2009 Lemote, Inc.
  2775. - * Author: Wu Zhangjin, wuzj@lemote.com
  2776. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2777. *
  2778. * This program is free software; you can redistribute it and/or modify it
  2779. * under the terms of the GNU General Public License as published by the
  2780. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ehci.c
  2781. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-02-24 19:52:17.000000000 +0100
  2782. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-03-06 16:43:01.000000000 +0100
  2783. @@ -5,7 +5,7 @@
  2784. * Author : jlliu, liujl@lemote.com
  2785. *
  2786. * Copyright (C) 2009 Lemote, Inc.
  2787. - * Author: Wu Zhangjin, wuzj@lemote.com
  2788. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2789. *
  2790. * This program is free software; you can redistribute it and/or modify it
  2791. * under the terms of the GNU General Public License as published by the
  2792. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ide.c
  2793. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-02-24 19:52:17.000000000 +0100
  2794. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-03-06 16:43:01.000000000 +0100
  2795. @@ -5,7 +5,7 @@
  2796. * Author : jlliu, liujl@lemote.com
  2797. *
  2798. * Copyright (C) 2009 Lemote, Inc.
  2799. - * Author: Wu Zhangjin, wuzj@lemote.com
  2800. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2801. *
  2802. * This program is free software; you can redistribute it and/or modify it
  2803. * under the terms of the GNU General Public License as published by the
  2804. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_isa.c
  2805. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-02-24 19:52:17.000000000 +0100
  2806. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-03-06 16:43:01.000000000 +0100
  2807. @@ -5,7 +5,7 @@
  2808. * Author : jlliu, liujl@lemote.com
  2809. *
  2810. * Copyright (C) 2009 Lemote, Inc.
  2811. - * Author: Wu Zhangjin, wuzj@lemote.com
  2812. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2813. *
  2814. * This program is free software; you can redistribute it and/or modify it
  2815. * under the terms of the GNU General Public License as published by the
  2816. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
  2817. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 2010-02-24 19:52:17.000000000 +0100
  2818. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 2010-03-06 16:43:01.000000000 +0100
  2819. @@ -5,7 +5,7 @@
  2820. * Author: Yanhua, yanh@lemote.com
  2821. *
  2822. * Copyright (C) 2009 Lemote Inc.
  2823. - * Author: Wu zhangjin, wuzj@lemote.com
  2824. + * Author: Wu zhangjin, wuzhangjin@gmail.com
  2825. *
  2826. * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
  2827. *
  2828. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ohci.c
  2829. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-02-24 19:52:17.000000000 +0100
  2830. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-03-06 16:43:01.000000000 +0100
  2831. @@ -5,7 +5,7 @@
  2832. * Author : jlliu, liujl@lemote.com
  2833. *
  2834. * Copyright (C) 2009 Lemote, Inc.
  2835. - * Author: Wu Zhangjin, wuzj@lemote.com
  2836. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2837. *
  2838. * This program is free software; you can redistribute it and/or modify it
  2839. * under the terms of the GNU General Public License as published by the
  2840. diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_pci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_pci.c
  2841. --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_pci.c 2010-02-24 19:52:17.000000000 +0100
  2842. +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_pci.c 2010-03-06 16:43:01.000000000 +0100
  2843. @@ -5,7 +5,7 @@
  2844. * Author : jlliu, liujl@lemote.com
  2845. *
  2846. * Copyright (C) 2009 Lemote, Inc.
  2847. - * Author: Wu Zhangjin, wuzj@lemote.com
  2848. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2849. *
  2850. * This program is free software; you can redistribute it and/or modify it
  2851. * under the terms of the GNU General Public License as published by the
  2852. diff -Nur linux-2.6.33/arch/mips/loongson/common/early_printk.c linux-lemote/arch/mips/loongson/common/early_printk.c
  2853. --- linux-2.6.33/arch/mips/loongson/common/early_printk.c 2010-02-24 19:52:17.000000000 +0100
  2854. +++ linux-lemote/arch/mips/loongson/common/early_printk.c 2010-03-06 16:43:01.000000000 +0100
  2855. @@ -2,7 +2,7 @@
  2856. *
  2857. * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  2858. * Copyright (c) 2009 Lemote Inc.
  2859. - * Author: Wu Zhangjin, wuzj@lemote.com
  2860. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2861. *
  2862. * This program is free software; you can redistribute it and/or modify it
  2863. * under the terms of the GNU General Public License as published by the
  2864. diff -Nur linux-2.6.33/arch/mips/loongson/common/env.c linux-lemote/arch/mips/loongson/common/env.c
  2865. --- linux-2.6.33/arch/mips/loongson/common/env.c 2010-02-24 19:52:17.000000000 +0100
  2866. +++ linux-lemote/arch/mips/loongson/common/env.c 2010-03-06 16:43:01.000000000 +0100
  2867. @@ -9,8 +9,8 @@
  2868. * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
  2869. * Author: Fuxin Zhang, zhangfx@lemote.com
  2870. *
  2871. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  2872. - * Author: Wu Zhangjin, wuzj@lemote.com
  2873. + * Copyright (C) 2009 Lemote Inc.
  2874. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2875. *
  2876. * This program is free software; you can redistribute it and/or modify it
  2877. * under the terms of the GNU General Public License as published by the
  2878. @@ -23,13 +23,10 @@
  2879. #include <loongson.h>
  2880. -unsigned long bus_clock, cpu_clock_freq;
  2881. +unsigned long cpu_clock_freq;
  2882. EXPORT_SYMBOL(cpu_clock_freq);
  2883. unsigned long memsize, highmemsize;
  2884. -/* pmon passes arguments in 32bit pointers */
  2885. -int *_prom_envp;
  2886. -
  2887. #define parse_even_earlier(res, option, p) \
  2888. do { \
  2889. if (strncmp(option, (char *)p, strlen(option)) == 0) \
  2890. @@ -39,6 +36,10 @@
  2891. void __init prom_init_env(void)
  2892. {
  2893. + /* pmon passes arguments in 32bit pointers */
  2894. + int *_prom_envp;
  2895. + unsigned long bus_clock;
  2896. + unsigned int processor_id;
  2897. long l;
  2898. /* firmware arguments are initialized in head.S */
  2899. @@ -55,6 +56,22 @@
  2900. }
  2901. if (memsize == 0)
  2902. memsize = 256;
  2903. + if (bus_clock == 0)
  2904. + bus_clock = 66000000;
  2905. + if (cpu_clock_freq == 0) {
  2906. + processor_id = (&current_cpu_data)->processor_id;
  2907. + switch (processor_id & PRID_REV_MASK) {
  2908. + case PRID_REV_LOONGSON2E:
  2909. + cpu_clock_freq = 533080000;
  2910. + break;
  2911. + case PRID_REV_LOONGSON2F:
  2912. + cpu_clock_freq = 797000000;
  2913. + break;
  2914. + default:
  2915. + cpu_clock_freq = 100000000;
  2916. + break;
  2917. + }
  2918. + }
  2919. pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
  2920. bus_clock, cpu_clock_freq, memsize, highmemsize);
  2921. diff -Nur linux-2.6.33/arch/mips/loongson/common/init.c linux-lemote/arch/mips/loongson/common/init.c
  2922. --- linux-2.6.33/arch/mips/loongson/common/init.c 2010-02-24 19:52:17.000000000 +0100
  2923. +++ linux-lemote/arch/mips/loongson/common/init.c 2010-03-06 16:43:01.000000000 +0100
  2924. @@ -1,6 +1,6 @@
  2925. /*
  2926. * Copyright (C) 2009 Lemote Inc.
  2927. - * Author: Wu Zhangjin, wuzj@lemote.com
  2928. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2929. *
  2930. * This program is free software; you can redistribute it and/or modify it
  2931. * under the terms of the GNU General Public License as published by the
  2932. diff -Nur linux-2.6.33/arch/mips/loongson/common/machtype.c linux-lemote/arch/mips/loongson/common/machtype.c
  2933. --- linux-2.6.33/arch/mips/loongson/common/machtype.c 2010-02-24 19:52:17.000000000 +0100
  2934. +++ linux-lemote/arch/mips/loongson/common/machtype.c 2010-03-06 16:43:01.000000000 +0100
  2935. @@ -1,6 +1,6 @@
  2936. /*
  2937. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  2938. - * Author: Wu Zhangjin, wuzj@lemote.com
  2939. + * Copyright (C) 2009 Lemote Inc.
  2940. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  2941. *
  2942. * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
  2943. *
  2944. @@ -35,6 +35,10 @@
  2945. return system_types[mips_machtype];
  2946. }
  2947. +void __weak __init mach_prom_init_machtype(void)
  2948. +{
  2949. +}
  2950. +
  2951. void __init prom_init_machtype(void)
  2952. {
  2953. char *p, str[MACHTYPE_LEN];
  2954. @@ -43,8 +47,10 @@
  2955. mips_machtype = LOONGSON_MACHTYPE;
  2956. p = strstr(arcs_cmdline, "machtype=");
  2957. - if (!p)
  2958. + if (!p) {
  2959. + mach_prom_init_machtype();
  2960. return;
  2961. + }
  2962. p += strlen("machtype=");
  2963. strncpy(str, p, MACHTYPE_LEN);
  2964. p = strstr(str, " ");
  2965. diff -Nur linux-2.6.33/arch/mips/loongson/common/Makefile linux-lemote/arch/mips/loongson/common/Makefile
  2966. --- linux-2.6.33/arch/mips/loongson/common/Makefile 2010-02-24 19:52:17.000000000 +0100
  2967. +++ linux-lemote/arch/mips/loongson/common/Makefile 2010-03-06 16:43:01.000000000 +0100
  2968. @@ -23,3 +23,9 @@
  2969. #
  2970. obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
  2971. +
  2972. +# Enable RTC Class support
  2973. +#
  2974. +# please enable CONFIG_RTC_DRV_CMOS
  2975. +#
  2976. +obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o
  2977. diff -Nur linux-2.6.33/arch/mips/loongson/common/mem.c linux-lemote/arch/mips/loongson/common/mem.c
  2978. --- linux-2.6.33/arch/mips/loongson/common/mem.c 2010-02-24 19:52:17.000000000 +0100
  2979. +++ linux-lemote/arch/mips/loongson/common/mem.c 2010-03-06 16:43:01.000000000 +0100
  2980. @@ -16,10 +16,11 @@
  2981. void __init prom_init_memory(void)
  2982. {
  2983. - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
  2984. + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
  2985. +
  2986. + add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
  2987. + 20), BOOT_MEM_RESERVED);
  2988. - add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
  2989. - 20), BOOT_MEM_RESERVED);
  2990. #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
  2991. {
  2992. int bit;
  2993. diff -Nur linux-2.6.33/arch/mips/loongson/common/mtd.c linux-lemote/arch/mips/loongson/common/mtd.c
  2994. --- linux-2.6.33/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
  2995. +++ linux-lemote/arch/mips/loongson/common/mtd.c 2010-03-06 16:43:01.000000000 +0100
  2996. @@ -0,0 +1,91 @@
  2997. +/*
  2998. + * Driver for flushing/dumping ROM of PMON on loongson family machines
  2999. + *
  3000. + * Copyright (C) 2008-2009 Lemote Inc.
  3001. + * Author: Yan Hua <yanh@lemote.com>
  3002. + *
  3003. + * This program is free software; you can redistribute it and/or modify it
  3004. + * under the terms of the GNU General Public License as published by the
  3005. + * Free Software Foundation; either version 2 of the License, or (at your
  3006. + * option) any later version.
  3007. + */
  3008. +
  3009. +#include <linux/module.h>
  3010. +#include <linux/types.h>
  3011. +#include <linux/kernel.h>
  3012. +#include <linux/init.h>
  3013. +#include <linux/mtd/mtd.h>
  3014. +#include <linux/mtd/map.h>
  3015. +#include <linux/mtd/partitions.h>
  3016. +
  3017. +#include <asm/io.h>
  3018. +
  3019. +#include <loongson.h>
  3020. +
  3021. +#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
  3022. +#define FLASH_SIZE 0x080000
  3023. +
  3024. +#define FLASH_PARTITION0_ADDR 0x00000000
  3025. +#define FLASH_PARTITION0_SIZE 0x00080000
  3026. +
  3027. +struct map_info flash_map = {
  3028. + .name = "flash device",
  3029. + .size = FLASH_SIZE,
  3030. + .bankwidth = 1,
  3031. +};
  3032. +
  3033. +struct mtd_partition flash_parts[] = {
  3034. + {
  3035. + .name = "Bootloader",
  3036. + .offset = FLASH_PARTITION0_ADDR,
  3037. + .size = FLASH_PARTITION0_SIZE},
  3038. +};
  3039. +
  3040. +#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
  3041. +
  3042. +static struct mtd_info *mymtd;
  3043. +
  3044. +int __init init_flash(void)
  3045. +{
  3046. + printk(KERN_NOTICE "flash device: %x at %x\n",
  3047. + FLASH_SIZE, FLASH_PHYS_ADDR);
  3048. +
  3049. + flash_map.phys = FLASH_PHYS_ADDR;
  3050. + flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
  3051. +
  3052. + if (!flash_map.virt) {
  3053. + printk(KERN_NOTICE "Failed to ioremap\n");
  3054. + return -EIO;
  3055. + }
  3056. +
  3057. + simple_map_init(&flash_map);
  3058. +
  3059. + mymtd = do_map_probe("cfi_probe", &flash_map);
  3060. + if (mymtd) {
  3061. + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
  3062. + printk(KERN_NOTICE "pmon flash device initialized\n");
  3063. + return 0;
  3064. + }
  3065. +
  3066. + iounmap((void *)flash_map.virt);
  3067. + return -ENXIO;
  3068. +}
  3069. +
  3070. +static void __exit cleanup_flash(void)
  3071. +{
  3072. + if (mymtd) {
  3073. + del_mtd_partitions(mymtd);
  3074. + map_destroy(mymtd);
  3075. + }
  3076. + if (flash_map.virt) {
  3077. + iounmap((void *)flash_map.virt);
  3078. + flash_map.virt = 0;
  3079. + }
  3080. +}
  3081. +
  3082. +module_init(init_flash);
  3083. +module_exit(cleanup_flash);
  3084. +
  3085. +MODULE_LICENSE("GPL");
  3086. +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
  3087. +MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
  3088. diff -Nur linux-2.6.33/arch/mips/loongson/common/platform.c linux-lemote/arch/mips/loongson/common/platform.c
  3089. --- linux-2.6.33/arch/mips/loongson/common/platform.c 2010-02-24 19:52:17.000000000 +0100
  3090. +++ linux-lemote/arch/mips/loongson/common/platform.c 2010-03-06 16:43:01.000000000 +0100
  3091. @@ -1,6 +1,6 @@
  3092. /*
  3093. * Copyright (C) 2009 Lemote Inc.
  3094. - * Author: Wu Zhangjin, wuzj@lemote.com
  3095. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3096. *
  3097. * This program is free software; you can redistribute it and/or modify it
  3098. * under the terms of the GNU General Public License as published by the
  3099. diff -Nur linux-2.6.33/arch/mips/loongson/common/pm.c linux-lemote/arch/mips/loongson/common/pm.c
  3100. --- linux-2.6.33/arch/mips/loongson/common/pm.c 2010-02-24 19:52:17.000000000 +0100
  3101. +++ linux-lemote/arch/mips/loongson/common/pm.c 2010-03-06 16:43:01.000000000 +0100
  3102. @@ -2,7 +2,7 @@
  3103. * loongson-specific suspend support
  3104. *
  3105. * Copyright (C) 2009 Lemote Inc.
  3106. - * Author: Wu Zhangjin <wuzj@lemote.com>
  3107. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3108. *
  3109. * This program is free software; you can redistribute it and/or modify
  3110. * it under the terms of the GNU General Public License as published by
  3111. diff -Nur linux-2.6.33/arch/mips/loongson/common/reset.c linux-lemote/arch/mips/loongson/common/reset.c
  3112. --- linux-2.6.33/arch/mips/loongson/common/reset.c 2010-02-24 19:52:17.000000000 +0100
  3113. +++ linux-lemote/arch/mips/loongson/common/reset.c 2010-03-06 16:43:01.000000000 +0100
  3114. @@ -6,8 +6,8 @@
  3115. *
  3116. * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
  3117. * Author: Fuxin Zhang, zhangfx@lemote.com
  3118. - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
  3119. - * Author: Zhangjin Wu, wuzj@lemote.com
  3120. + * Copyright (C) 2009 Lemote, Inc.
  3121. + * Author: Zhangjin Wu, wuzhangjin@gmail.com
  3122. */
  3123. #include <linux/init.h>
  3124. #include <linux/pm.h>
  3125. @@ -21,22 +21,39 @@
  3126. /* do preparation for reboot */
  3127. mach_prepare_reboot();
  3128. - /* reboot via jumping to boot base address */
  3129. + /* reboot via jumping to boot base address
  3130. + *
  3131. + * ".set noat" and ".set at" are used to ensure the address not
  3132. + * polluted by the binutils patch. the patch will try to change the
  3133. + * jumping address to "addr & 0xcfffffff" via the at register, which is
  3134. + * really wrong for 0xbfc00000:
  3135. + */
  3136. +
  3137. + __asm__ __volatile__(".set noat\n");
  3138. ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
  3139. + __asm__ __volatile__(".set at\n");
  3140. }
  3141. -static void loongson_halt(void)
  3142. +static void loongson_poweroff(void)
  3143. {
  3144. mach_prepare_shutdown();
  3145. - while (1)
  3146. - ;
  3147. + unreachable();
  3148. +}
  3149. +
  3150. +static void loongson_halt(void)
  3151. +{
  3152. + pr_notice("** You can safely turn off the power ** !\n");
  3153. + while (1) {
  3154. + if (cpu_wait)
  3155. + cpu_wait();
  3156. + }
  3157. }
  3158. static int __init mips_reboot_setup(void)
  3159. {
  3160. _machine_restart = loongson_restart;
  3161. _machine_halt = loongson_halt;
  3162. - pm_power_off = loongson_halt;
  3163. + pm_power_off = loongson_poweroff;
  3164. return 0;
  3165. }
  3166. diff -Nur linux-2.6.33/arch/mips/loongson/common/rtc.c linux-lemote/arch/mips/loongson/common/rtc.c
  3167. --- linux-2.6.33/arch/mips/loongson/common/rtc.c 1970-01-01 01:00:00.000000000 +0100
  3168. +++ linux-lemote/arch/mips/loongson/common/rtc.c 2010-03-06 16:43:01.000000000 +0100
  3169. @@ -0,0 +1,43 @@
  3170. +/*
  3171. + * Registration of Loongson RTC platform device.
  3172. + *
  3173. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  3174. + * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
  3175. + *
  3176. + * This program is free software; you can redistribute it and/or modify
  3177. + * it under the terms of the GNU General Public License as published by
  3178. + * the Free Software Foundation; either version 2 of the License, or
  3179. + * (at your option) any later version.
  3180. + */
  3181. +
  3182. +#include <linux/init.h>
  3183. +#include <linux/ioport.h>
  3184. +#include <linux/mc146818rtc.h>
  3185. +#include <linux/platform_device.h>
  3186. +
  3187. +static struct resource rtc_cmos_resource[] = {
  3188. + {
  3189. + .start = RTC_PORT(0),
  3190. + .end = RTC_PORT(1),
  3191. + .flags = IORESOURCE_IO,
  3192. + },
  3193. + {
  3194. + .start = RTC_IRQ,
  3195. + .end = RTC_IRQ,
  3196. + .flags = IORESOURCE_IRQ,
  3197. + },
  3198. +};
  3199. +
  3200. +static struct platform_device rtc_cmos_device = {
  3201. + .name = "rtc_cmos",
  3202. + .id = -1,
  3203. + .num_resources = ARRAY_SIZE(rtc_cmos_resource),
  3204. + .resource = rtc_cmos_resource
  3205. +};
  3206. +
  3207. +static __init int rtc_cmos_init(void)
  3208. +{
  3209. + return platform_device_register(&rtc_cmos_device);
  3210. +}
  3211. +
  3212. +device_initcall(rtc_cmos_init);
  3213. diff -Nur linux-2.6.33/arch/mips/loongson/common/serial.c linux-lemote/arch/mips/loongson/common/serial.c
  3214. --- linux-2.6.33/arch/mips/loongson/common/serial.c 2010-02-24 19:52:17.000000000 +0100
  3215. +++ linux-lemote/arch/mips/loongson/common/serial.c 2010-03-06 16:43:01.000000000 +0100
  3216. @@ -7,7 +7,7 @@
  3217. *
  3218. * Copyright (C) 2009 Lemote, Inc.
  3219. * Author: Yan hua (yanhua@lemote.com)
  3220. - * Author: Wu Zhangjin (wuzj@lemote.com)
  3221. + * Author: Wu Zhangjin (wuzhangjin@gmail.com)
  3222. */
  3223. #include <linux/io.h>
  3224. diff -Nur linux-2.6.33/arch/mips/loongson/common/time.c linux-lemote/arch/mips/loongson/common/time.c
  3225. --- linux-2.6.33/arch/mips/loongson/common/time.c 2010-02-24 19:52:17.000000000 +0100
  3226. +++ linux-lemote/arch/mips/loongson/common/time.c 2010-03-06 16:43:01.000000000 +0100
  3227. @@ -2,8 +2,8 @@
  3228. * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
  3229. * Author: Fuxin Zhang, zhangfx@lemote.com
  3230. *
  3231. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  3232. - * Author: Wu Zhangjin, wuzj@lemote.com
  3233. + * Copyright (C) 2009 Lemote Inc.
  3234. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3235. *
  3236. * This program is free software; you can redistribute it and/or modify it
  3237. * under the terms of the GNU General Public License as published by the
  3238. diff -Nur linux-2.6.33/arch/mips/loongson/common/uart_base.c linux-lemote/arch/mips/loongson/common/uart_base.c
  3239. --- linux-2.6.33/arch/mips/loongson/common/uart_base.c 2010-02-24 19:52:17.000000000 +0100
  3240. +++ linux-lemote/arch/mips/loongson/common/uart_base.c 2010-03-06 16:43:01.000000000 +0100
  3241. @@ -1,6 +1,6 @@
  3242. /*
  3243. * Copyright (C) 2009 Lemote Inc.
  3244. - * Author: Wu Zhangjin, wuzj@lemote.com
  3245. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3246. *
  3247. * This program is free software; you can redistribute it and/or modify it
  3248. * under the terms of the GNU General Public License as published by the
  3249. diff -Nur linux-2.6.33/arch/mips/loongson/fuloong-2e/reset.c linux-lemote/arch/mips/loongson/fuloong-2e/reset.c
  3250. --- linux-2.6.33/arch/mips/loongson/fuloong-2e/reset.c 2010-02-24 19:52:17.000000000 +0100
  3251. +++ linux-lemote/arch/mips/loongson/fuloong-2e/reset.c 2010-03-06 16:43:01.000000000 +0100
  3252. @@ -1,8 +1,8 @@
  3253. /* Board-specific reboot/shutdown routines
  3254. * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  3255. *
  3256. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  3257. - * Author: Wu Zhangjin, wuzj@lemote.com
  3258. + * Copyright (C) 2009 Lemote Inc.
  3259. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3260. *
  3261. * This program is free software; you can redistribute it and/or modify it
  3262. * under the terms of the GNU General Public License as published by the
  3263. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.c
  3264. --- linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-02-24 19:52:17.000000000 +0100
  3265. +++ linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-03-06 16:43:01.000000000 +0100
  3266. @@ -14,7 +14,7 @@
  3267. #include <linux/spinlock.h>
  3268. #include <linux/delay.h>
  3269. -#include "ec_kb3310b.h"
  3270. +#include <ec_kb3310b.h>
  3271. static DEFINE_SPINLOCK(index_access_lock);
  3272. static DEFINE_SPINLOCK(port_access_lock);
  3273. @@ -76,12 +76,9 @@
  3274. }
  3275. if (timeout <= 0) {
  3276. - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
  3277. + pr_err("%s: deadable error : timeout...\n", __func__);
  3278. ret = -EINVAL;
  3279. - } else
  3280. - printk(KERN_INFO
  3281. - "(%x/%d)ec issued command %d status : 0x%x\n",
  3282. - timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
  3283. + }
  3284. spin_unlock_irqrestore(&port_access_lock, flags);
  3285. @@ -118,8 +115,7 @@
  3286. udelay(EC_REG_DELAY);
  3287. }
  3288. if (timeout <= 0) {
  3289. - pr_info("%s: get event number timeout.\n", __func__);
  3290. -
  3291. + pr_err("%s: get event number timeout.\n", __func__);
  3292. return -EINVAL;
  3293. }
  3294. value = inb(EC_DAT_PORT);
  3295. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.h
  3296. --- linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2010-02-24 19:52:17.000000000 +0100
  3297. +++ linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
  3298. @@ -1,188 +0,0 @@
  3299. -/*
  3300. - * KB3310B Embedded Controller
  3301. - *
  3302. - * Copyright (C) 2008 Lemote Inc.
  3303. - * Author: liujl <liujl@lemote.com>, 2008-03-14
  3304. - *
  3305. - * This program is free software; you can redistribute it and/or modify
  3306. - * it under the terms of the GNU General Public License as published by
  3307. - * the Free Software Foundation; either version 2 of the License, or
  3308. - * (at your option) any later version.
  3309. - */
  3310. -
  3311. -#ifndef _EC_KB3310B_H
  3312. -#define _EC_KB3310B_H
  3313. -
  3314. -extern unsigned char ec_read(unsigned short addr);
  3315. -extern void ec_write(unsigned short addr, unsigned char val);
  3316. -extern int ec_query_seq(unsigned char cmd);
  3317. -extern int ec_query_event_num(void);
  3318. -extern int ec_get_event_num(void);
  3319. -
  3320. -typedef int (*sci_handler) (int status);
  3321. -extern sci_handler yeeloong_report_lid_status;
  3322. -
  3323. -#define SCI_IRQ_NUM 0x0A
  3324. -
  3325. -/*
  3326. - * The following registers are determined by the EC index configuration.
  3327. - * 1, fill the PORT_HIGH as EC register high part.
  3328. - * 2, fill the PORT_LOW as EC register low part.
  3329. - * 3, fill the PORT_DATA as EC register write data or get the data from it.
  3330. - */
  3331. -#define EC_IO_PORT_HIGH 0x0381
  3332. -#define EC_IO_PORT_LOW 0x0382
  3333. -#define EC_IO_PORT_DATA 0x0383
  3334. -
  3335. -/*
  3336. - * EC delay time is 500us for register and status access
  3337. - */
  3338. -#define EC_REG_DELAY 500 /* unit : us */
  3339. -#define EC_CMD_TIMEOUT 0x1000
  3340. -
  3341. -/*
  3342. - * EC access port for SCI communication
  3343. - */
  3344. -#define EC_CMD_PORT 0x66
  3345. -#define EC_STS_PORT 0x66
  3346. -#define EC_DAT_PORT 0x62
  3347. -#define CMD_INIT_IDLE_MODE 0xdd
  3348. -#define CMD_EXIT_IDLE_MODE 0xdf
  3349. -#define CMD_INIT_RESET_MODE 0xd8
  3350. -#define CMD_REBOOT_SYSTEM 0x8c
  3351. -#define CMD_GET_EVENT_NUM 0x84
  3352. -#define CMD_PROGRAM_PIECE 0xda
  3353. -
  3354. -/* temperature & fan registers */
  3355. -#define REG_TEMPERATURE_VALUE 0xF458
  3356. -#define REG_FAN_AUTO_MAN_SWITCH 0xF459
  3357. -#define BIT_FAN_AUTO 0
  3358. -#define BIT_FAN_MANUAL 1
  3359. -#define REG_FAN_CONTROL 0xF4D2
  3360. -#define BIT_FAN_CONTROL_ON (1 << 0)
  3361. -#define BIT_FAN_CONTROL_OFF (0 << 0)
  3362. -#define REG_FAN_STATUS 0xF4DA
  3363. -#define BIT_FAN_STATUS_ON (1 << 0)
  3364. -#define BIT_FAN_STATUS_OFF (0 << 0)
  3365. -#define REG_FAN_SPEED_HIGH 0xFE22
  3366. -#define REG_FAN_SPEED_LOW 0xFE23
  3367. -#define REG_FAN_SPEED_LEVEL 0xF4CC
  3368. -/* fan speed divider */
  3369. -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
  3370. -
  3371. -/* battery registers */
  3372. -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
  3373. -#define REG_BAT_DESIGN_CAP_LOW 0xF77E
  3374. -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
  3375. -#define REG_BAT_FULLCHG_CAP_LOW 0xF781
  3376. -#define REG_BAT_DESIGN_VOL_HIGH 0xF782
  3377. -#define REG_BAT_DESIGN_VOL_LOW 0xF783
  3378. -#define REG_BAT_CURRENT_HIGH 0xF784
  3379. -#define REG_BAT_CURRENT_LOW 0xF785
  3380. -#define REG_BAT_VOLTAGE_HIGH 0xF786
  3381. -#define REG_BAT_VOLTAGE_LOW 0xF787
  3382. -#define REG_BAT_TEMPERATURE_HIGH 0xF788
  3383. -#define REG_BAT_TEMPERATURE_LOW 0xF789
  3384. -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
  3385. -#define REG_BAT_RELATIVE_CAP_LOW 0xF493
  3386. -#define REG_BAT_VENDOR 0xF4C4
  3387. -#define FLAG_BAT_VENDOR_SANYO 0x01
  3388. -#define FLAG_BAT_VENDOR_SIMPLO 0x02
  3389. -#define REG_BAT_CELL_COUNT 0xF4C6
  3390. -#define FLAG_BAT_CELL_3S1P 0x03
  3391. -#define FLAG_BAT_CELL_3S2P 0x06
  3392. -#define REG_BAT_CHARGE 0xF4A2
  3393. -#define FLAG_BAT_CHARGE_DISCHARGE 0x01
  3394. -#define FLAG_BAT_CHARGE_CHARGE 0x02
  3395. -#define FLAG_BAT_CHARGE_ACPOWER 0x00
  3396. -#define REG_BAT_STATUS 0xF4B0
  3397. -#define BIT_BAT_STATUS_LOW (1 << 5)
  3398. -#define BIT_BAT_STATUS_DESTROY (1 << 2)
  3399. -#define BIT_BAT_STATUS_FULL (1 << 1)
  3400. -#define BIT_BAT_STATUS_IN (1 << 0)
  3401. -#define REG_BAT_CHARGE_STATUS 0xF4B1
  3402. -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
  3403. -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
  3404. -#define REG_BAT_STATE 0xF482
  3405. -#define BIT_BAT_STATE_CHARGING (1 << 1)
  3406. -#define BIT_BAT_STATE_DISCHARGING (1 << 0)
  3407. -#define REG_BAT_POWER 0xF440
  3408. -#define BIT_BAT_POWER_S3 (1 << 2)
  3409. -#define BIT_BAT_POWER_ON (1 << 1)
  3410. -#define BIT_BAT_POWER_ACIN (1 << 0)
  3411. -
  3412. -/* other registers */
  3413. -/* Audio: rd/wr */
  3414. -#define REG_AUDIO_VOLUME 0xF46C
  3415. -#define REG_AUDIO_MUTE 0xF4E7
  3416. -#define REG_AUDIO_BEEP 0xF4D0
  3417. -/* USB port power or not: rd/wr */
  3418. -#define REG_USB0_FLAG 0xF461
  3419. -#define REG_USB1_FLAG 0xF462
  3420. -#define REG_USB2_FLAG 0xF463
  3421. -#define BIT_USB_FLAG_ON 1
  3422. -#define BIT_USB_FLAG_OFF 0
  3423. -/* LID */
  3424. -#define REG_LID_DETECT 0xF4BD
  3425. -#define BIT_LID_DETECT_ON 1
  3426. -#define BIT_LID_DETECT_OFF 0
  3427. -/* CRT */
  3428. -#define REG_CRT_DETECT 0xF4AD
  3429. -#define BIT_CRT_DETECT_PLUG 1
  3430. -#define BIT_CRT_DETECT_UNPLUG 0
  3431. -/* LCD backlight brightness adjust: 9 levels */
  3432. -#define REG_DISPLAY_BRIGHTNESS 0xF4F5
  3433. -/* Black screen Status */
  3434. -#define BIT_DISPLAY_LCD_ON 1
  3435. -#define BIT_DISPLAY_LCD_OFF 0
  3436. -/* LCD backlight control: off/restore */
  3437. -#define REG_BACKLIGHT_CTRL 0xF7BD
  3438. -#define BIT_BACKLIGHT_ON 1
  3439. -#define BIT_BACKLIGHT_OFF 0
  3440. -/* Reset the machine auto-clear: rd/wr */
  3441. -#define REG_RESET 0xF4EC
  3442. -#define BIT_RESET_ON 1
  3443. -/* Light the led: rd/wr */
  3444. -#define REG_LED 0xF4C8
  3445. -#define BIT_LED_RED_POWER (1 << 0)
  3446. -#define BIT_LED_ORANGE_POWER (1 << 1)
  3447. -#define BIT_LED_GREEN_CHARGE (1 << 2)
  3448. -#define BIT_LED_RED_CHARGE (1 << 3)
  3449. -#define BIT_LED_NUMLOCK (1 << 4)
  3450. -/* Test led mode, all led on/off */
  3451. -#define REG_LED_TEST 0xF4C2
  3452. -#define BIT_LED_TEST_IN 1
  3453. -#define BIT_LED_TEST_OUT 0
  3454. -/* Camera on/off */
  3455. -#define REG_CAMERA_STATUS 0xF46A
  3456. -#define BIT_CAMERA_STATUS_ON 1
  3457. -#define BIT_CAMERA_STATUS_OFF 0
  3458. -#define REG_CAMERA_CONTROL 0xF7B7
  3459. -#define BIT_CAMERA_CONTROL_OFF 0
  3460. -#define BIT_CAMERA_CONTROL_ON 1
  3461. -/* Wlan Status */
  3462. -#define REG_WLAN 0xF4FA
  3463. -#define BIT_WLAN_ON 1
  3464. -#define BIT_WLAN_OFF 0
  3465. -#define REG_DISPLAY_LCD 0xF79F
  3466. -
  3467. -/* SCI Event Number from EC */
  3468. -enum {
  3469. - EVENT_LID = 0x23, /* LID open/close */
  3470. - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
  3471. - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
  3472. - EVENT_OVERTEMP, /* Over-temperature happened */
  3473. - EVENT_CRT_DETECT, /* CRT is connected */
  3474. - EVENT_CAMERA, /* Camera on/off */
  3475. - EVENT_USB_OC2, /* USB2 Over Current occurred */
  3476. - EVENT_USB_OC0, /* USB0 Over Current occurred */
  3477. - EVENT_BLACK_SCREEN, /* Turn on/off backlight */
  3478. - EVENT_AUDIO_MUTE, /* Mute on/off */
  3479. - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
  3480. - EVENT_AC_BAT, /* AC & Battery relative issue */
  3481. - EVENT_AUDIO_VOLUME, /* Volume adjust */
  3482. - EVENT_WLAN, /* Wlan on/off */
  3483. - EVENT_END
  3484. -};
  3485. -
  3486. -#endif /* !_EC_KB3310B_H */
  3487. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/machtype.c linux-lemote/arch/mips/loongson/lemote-2f/machtype.c
  3488. --- linux-2.6.33/arch/mips/loongson/lemote-2f/machtype.c 1970-01-01 01:00:00.000000000 +0100
  3489. +++ linux-lemote/arch/mips/loongson/lemote-2f/machtype.c 2010-03-06 16:43:01.000000000 +0100
  3490. @@ -0,0 +1,45 @@
  3491. +/*
  3492. + * Copyright (C) 2009 Lemote Inc.
  3493. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3494. + *
  3495. + * This program is free software; you can redistribute it and/or modify it
  3496. + * under the terms of the GNU General Public License as published by the
  3497. + * Free Software Foundation; either version 2 of the License, or (at your
  3498. + * option) any later version.
  3499. + */
  3500. +#include <asm/bootinfo.h>
  3501. +
  3502. +#include <loongson.h>
  3503. +
  3504. +void __init mach_prom_init_machtype(void)
  3505. +{
  3506. + /* We share the same kernel image file among Lemote 2F family
  3507. + * of machines, and provide the machtype= kernel command line
  3508. + * to users to indicate their machine, this command line will
  3509. + * be passed by the latest PMON automatically. and fortunately,
  3510. + * up to now, we can get the machine type from the PMON_VER=
  3511. + * commandline directly except the NAS machine, In the old
  3512. + * machines, this will help the users a lot.
  3513. + *
  3514. + * If no "machtype=" passed, get machine type from "PMON_VER=".
  3515. + * PMON_VER=LM8089 Lemote 8.9'' netbook
  3516. + * LM8101 Lemote 10.1'' netbook
  3517. + * (The above two netbooks have the same kernel support)
  3518. + * LM6XXX Lemote FuLoong(2F) box series
  3519. + * LM9XXX Lemote LynLoong PC series
  3520. + */
  3521. + if (strstr(arcs_cmdline, "PMON_VER=LM")) {
  3522. + if (strstr(arcs_cmdline, "PMON_VER=LM8"))
  3523. + mips_machtype = MACH_LEMOTE_YL2F89;
  3524. + else if (strstr(arcs_cmdline, "PMON_VER=LM6"))
  3525. + mips_machtype = MACH_LEMOTE_FL2F;
  3526. + else if (strstr(arcs_cmdline, "PMON_VER=LM9"))
  3527. + mips_machtype = MACH_LEMOTE_LL2F;
  3528. + else
  3529. + mips_machtype = MACH_LEMOTE_NAS;
  3530. +
  3531. + strcat(arcs_cmdline, " machtype=");
  3532. + strcat(arcs_cmdline, get_system_type());
  3533. + strcat(arcs_cmdline, " ");
  3534. + }
  3535. +}
  3536. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/Makefile linux-lemote/arch/mips/loongson/lemote-2f/Makefile
  3537. --- linux-2.6.33/arch/mips/loongson/lemote-2f/Makefile 2010-02-24 19:52:17.000000000 +0100
  3538. +++ linux-lemote/arch/mips/loongson/lemote-2f/Makefile 2010-03-06 16:43:01.000000000 +0100
  3539. @@ -2,7 +2,7 @@
  3540. # Makefile for lemote loongson2f family machines
  3541. #
  3542. -obj-y += irq.o reset.o ec_kb3310b.o
  3543. +obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o
  3544. #
  3545. # Suspend Support
  3546. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/platform.c linux-lemote/arch/mips/loongson/lemote-2f/platform.c
  3547. --- linux-2.6.33/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
  3548. +++ linux-lemote/arch/mips/loongson/lemote-2f/platform.c 2010-03-06 16:43:01.000000000 +0100
  3549. @@ -0,0 +1,48 @@
  3550. +/*
  3551. + * Copyright (C) 2009 Lemote Inc.
  3552. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3553. + *
  3554. + * This program is free software; you can redistribute it and/or modify it
  3555. + * under the terms of the GNU General Public License as published by the
  3556. + * Free Software Foundation; either version 2 of the License, or (at your
  3557. + * option) any later version.
  3558. + */
  3559. +
  3560. +#include <linux/err.h>
  3561. +#include <linux/platform_device.h>
  3562. +
  3563. +#include <asm/bootinfo.h>
  3564. +
  3565. +static struct platform_device yeeloong_pdev = {
  3566. + .name = "yeeloong_laptop",
  3567. + .id = -1,
  3568. +};
  3569. +
  3570. +static struct platform_device lynloong_pdev = {
  3571. + .name = "lynloong_pc",
  3572. + .id = -1,
  3573. +};
  3574. +
  3575. +static int __init lemote2f_platform_init(void)
  3576. +{
  3577. + struct platform_device *pdev = NULL;
  3578. +
  3579. + switch (mips_machtype) {
  3580. + case MACH_LEMOTE_YL2F89:
  3581. + pdev = &yeeloong_pdev;
  3582. + break;
  3583. + case MACH_LEMOTE_LL2F:
  3584. + pdev = &lynloong_pdev;
  3585. + break;
  3586. + default:
  3587. + break;
  3588. +
  3589. + }
  3590. +
  3591. + if (pdev != NULL)
  3592. + return platform_device_register(pdev);
  3593. +
  3594. + return -ENODEV;
  3595. +}
  3596. +
  3597. +arch_initcall(lemote2f_platform_init);
  3598. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/pm.c linux-lemote/arch/mips/loongson/lemote-2f/pm.c
  3599. --- linux-2.6.33/arch/mips/loongson/lemote-2f/pm.c 2010-02-24 19:52:17.000000000 +0100
  3600. +++ linux-lemote/arch/mips/loongson/lemote-2f/pm.c 2010-03-06 16:43:01.000000000 +0100
  3601. @@ -2,7 +2,7 @@
  3602. * Lemote loongson2f family machines' specific suspend support
  3603. *
  3604. * Copyright (C) 2009 Lemote Inc.
  3605. - * Author: Wu Zhangjin <wuzj@lemote.com>
  3606. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3607. *
  3608. * This program is free software; you can redistribute it and/or modify
  3609. * it under the terms of the GNU General Public License as published by
  3610. @@ -23,7 +23,7 @@
  3611. #include <loongson.h>
  3612. #include <cs5536/cs5536_mfgpt.h>
  3613. -#include "ec_kb3310b.h"
  3614. +#include <ec_kb3310b.h>
  3615. #define I8042_KBD_IRQ 1
  3616. #define I8042_CTR_KBDINT 0x01
  3617. @@ -100,7 +100,7 @@
  3618. if (irq < 0)
  3619. return 0;
  3620. - printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
  3621. + pr_info("%s: irq = %d\n", __func__, irq);
  3622. if (irq == I8042_KBD_IRQ)
  3623. return 1;
  3624. diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/reset.c linux-lemote/arch/mips/loongson/lemote-2f/reset.c
  3625. --- linux-2.6.33/arch/mips/loongson/lemote-2f/reset.c 2010-02-24 19:52:17.000000000 +0100
  3626. +++ linux-lemote/arch/mips/loongson/lemote-2f/reset.c 2010-03-06 16:43:01.000000000 +0100
  3627. @@ -3,7 +3,7 @@
  3628. * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
  3629. *
  3630. * Copyright (C) 2009 Lemote Inc.
  3631. - * Author: Wu Zhangjin, wuzj@lemote.com
  3632. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  3633. *
  3634. * This program is free software; you can redistribute it and/or modify it
  3635. * under the terms of the GNU General Public License as published by the
  3636. @@ -20,7 +20,7 @@
  3637. #include <loongson.h>
  3638. #include <cs5536/cs5536.h>
  3639. -#include "ec_kb3310b.h"
  3640. +#include <ec_kb3310b.h>
  3641. static void reset_cpu(void)
  3642. {
  3643. @@ -32,6 +32,7 @@
  3644. }
  3645. /* reset support for fuloong2f */
  3646. +DEFINE_SPINLOCK(msr_lock);
  3647. static void fl2f_reboot(void)
  3648. {
  3649. @@ -46,9 +47,13 @@
  3650. */
  3651. {
  3652. u32 hi, lo;
  3653. + unsigned long flags;
  3654. +
  3655. + spin_lock_irqsave(&msr_lock, flags);
  3656. _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
  3657. lo |= 0x00000001;
  3658. _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
  3659. + spin_unlock_irqrestore(&msr_lock, flags);
  3660. }
  3661. }
  3662. @@ -56,9 +61,13 @@
  3663. {
  3664. u32 hi, lo, val;
  3665. int gpio_base;
  3666. + unsigned long flags;
  3667. /* get gpio base */
  3668. + spin_lock_irqsave(&msr_lock, flags);
  3669. _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
  3670. + spin_unlock_irqrestore(&msr_lock, flags);
  3671. +
  3672. gpio_base = lo & 0xff00;
  3673. /* make cs5536 gpio13 output enable */
  3674. diff -Nur linux-2.6.33/arch/mips/Makefile linux-lemote/arch/mips/Makefile
  3675. --- linux-2.6.33/arch/mips/Makefile 2010-02-24 19:52:17.000000000 +0100
  3676. +++ linux-lemote/arch/mips/Makefile 2010-03-06 16:42:59.000000000 +0100
  3677. @@ -135,7 +135,10 @@
  3678. cflags-$(CONFIG_CPU_LOONGSON2E) += \
  3679. $(call cc-option,-march=loongson2e,-march=r4600)
  3680. cflags-$(CONFIG_CPU_LOONGSON2F) += \
  3681. - $(call cc-option,-march=loongson2f,-march=r4600)
  3682. + $(call cc-option,-march=loongson2f,-march=r4600) \
  3683. + $(call as-option,-Wa$(comma)-mfix-ls2f-kernel,) \
  3684. + $(call as-option,-Wa$(comma)-mfix-loongson2f-nop,) \
  3685. + $(call as-option,-Wa$(comma)-mfix-loongson2f-jump,)
  3686. cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
  3687. -Wa,-mips32 -Wa,--trap
  3688. @@ -332,11 +335,11 @@
  3689. #
  3690. # Loongson family
  3691. #
  3692. -core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
  3693. +core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
  3694. cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
  3695. -mno-branch-likely
  3696. -load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
  3697. -load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
  3698. +load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
  3699. +load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
  3700. #
  3701. # MIPS Malta board
  3702. diff -Nur linux-2.6.33/arch/mips/oprofile/common.c linux-lemote/arch/mips/oprofile/common.c
  3703. --- linux-2.6.33/arch/mips/oprofile/common.c 2010-02-24 19:52:17.000000000 +0100
  3704. +++ linux-lemote/arch/mips/oprofile/common.c 2010-03-06 16:43:01.000000000 +0100
  3705. @@ -14,9 +14,9 @@
  3706. #include "op_impl.h"
  3707. -extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
  3708. -extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
  3709. -extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
  3710. +extern struct op_mips_model op_model_mipsxx_ops __weak;
  3711. +extern struct op_mips_model op_model_rm9000_ops __weak;
  3712. +extern struct op_mips_model op_model_loongson2_ops __weak;
  3713. static struct op_mips_model *model;
  3714. diff -Nur linux-2.6.33/arch/mips/oprofile/op_model_loongson2.c linux-lemote/arch/mips/oprofile/op_model_loongson2.c
  3715. --- linux-2.6.33/arch/mips/oprofile/op_model_loongson2.c 2010-02-24 19:52:17.000000000 +0100
  3716. +++ linux-lemote/arch/mips/oprofile/op_model_loongson2.c 2010-03-06 16:43:01.000000000 +0100
  3717. @@ -3,7 +3,7 @@
  3718. *
  3719. * Copyright (C) 2009 Lemote Inc.
  3720. * Author: Yanhua <yanh@lemote.com>
  3721. - * Author: Wu Zhangjin <wuzj@lemote.com>
  3722. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3723. *
  3724. * This file is subject to the terms and conditions of the GNU General Public
  3725. * License. See the file "COPYING" in the main directory of this archive
  3726. diff -Nur linux-2.6.33/arch/mips/pci/fixup-lemote2f.c linux-lemote/arch/mips/pci/fixup-lemote2f.c
  3727. --- linux-2.6.33/arch/mips/pci/fixup-lemote2f.c 2010-02-24 19:52:17.000000000 +0100
  3728. +++ linux-lemote/arch/mips/pci/fixup-lemote2f.c 2010-03-06 16:43:01.000000000 +0100
  3729. @@ -131,7 +131,7 @@
  3730. /* Serial short detect enable */
  3731. _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
  3732. - _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
  3733. + _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
  3734. /* setting the USB2.0 micro frame length */
  3735. pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
  3736. diff -Nur linux-2.6.33/arch/mips/pci/ops-loongson2.c linux-lemote/arch/mips/pci/ops-loongson2.c
  3737. --- linux-2.6.33/arch/mips/pci/ops-loongson2.c 2010-02-24 19:52:17.000000000 +0100
  3738. +++ linux-lemote/arch/mips/pci/ops-loongson2.c 2010-03-06 16:43:01.000000000 +0100
  3739. @@ -1,13 +1,11 @@
  3740. /*
  3741. - * fuloong2e specific PCI support.
  3742. - *
  3743. * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
  3744. * All rights reserved.
  3745. * Authors: Carsten Langgaard <carstenl@mips.com>
  3746. * Maciej W. Rozycki <macro@mips.com>
  3747. *
  3748. * Copyright (C) 2009 Lemote Inc.
  3749. - * Author: Wu Zhangjin <wuzj@lemote.com>
  3750. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3751. *
  3752. * This program is free software; you can distribute it and/or modify it
  3753. * under the terms of the GNU General Public License (Version 2) as
  3754. diff -Nur linux-2.6.33/arch/mips/power/cpu.c linux-lemote/arch/mips/power/cpu.c
  3755. --- linux-2.6.33/arch/mips/power/cpu.c 2010-02-24 19:52:17.000000000 +0100
  3756. +++ linux-lemote/arch/mips/power/cpu.c 2010-03-06 16:43:01.000000000 +0100
  3757. @@ -3,9 +3,9 @@
  3758. *
  3759. * Licensed under the GPLv2
  3760. *
  3761. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  3762. + * Copyright (C) 2009 Lemote Inc.
  3763. * Author: Hu Hongbing <huhb@lemote.com>
  3764. - * Wu Zhangjin <wuzj@lemote.com>
  3765. + * Wu Zhangjin <wuzhangjin@gmail.com>
  3766. */
  3767. #include <asm/suspend.h>
  3768. #include <asm/fpu.h>
  3769. diff -Nur linux-2.6.33/arch/mips/power/hibernate.S linux-lemote/arch/mips/power/hibernate.S
  3770. --- linux-2.6.33/arch/mips/power/hibernate.S 2010-02-24 19:52:17.000000000 +0100
  3771. +++ linux-lemote/arch/mips/power/hibernate.S 2010-03-06 16:43:01.000000000 +0100
  3772. @@ -3,9 +3,9 @@
  3773. *
  3774. * Licensed under the GPLv2
  3775. *
  3776. - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
  3777. + * Copyright (C) 2009 Lemote Inc.
  3778. * Author: Hu Hongbing <huhb@lemote.com>
  3779. - * Wu Zhangjin <wuzj@lemote.com>
  3780. + * Wu Zhangjin <wuzhangjin@gmail.com>
  3781. */
  3782. #include <asm/asm-offsets.h>
  3783. #include <asm/page.h>
  3784. diff -Nur linux-2.6.33/arch/powerpc/include/asm/prom.h linux-lemote/arch/powerpc/include/asm/prom.h
  3785. --- linux-2.6.33/arch/powerpc/include/asm/prom.h 2010-02-24 19:52:17.000000000 +0100
  3786. +++ linux-lemote/arch/powerpc/include/asm/prom.h 2010-03-06 16:43:03.000000000 +0100
  3787. @@ -23,21 +23,8 @@
  3788. #include <asm/irq.h>
  3789. #include <asm/atomic.h>
  3790. -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
  3791. -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
  3792. -
  3793. -#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
  3794. -#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
  3795. -#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
  3796. -
  3797. -extern struct device_node *of_chosen;
  3798. -
  3799. #define HAVE_ARCH_DEVTREE_FIXUPS
  3800. -/* For updating the device tree at runtime */
  3801. -extern void of_attach_node(struct device_node *);
  3802. -extern void of_detach_node(struct device_node *);
  3803. -
  3804. #ifdef CONFIG_PPC32
  3805. /*
  3806. * PCI <-> OF matching functions
  3807. @@ -52,11 +39,6 @@
  3808. extern void pci_create_OF_bus_map(void);
  3809. #endif
  3810. -extern struct resource *request_OF_resource(struct device_node* node,
  3811. - int index, const char* name_postfix);
  3812. -extern int release_OF_resource(struct device_node* node, int index);
  3813. -
  3814. -
  3815. /*
  3816. * OF address retreival & translation
  3817. */
  3818. diff -Nur linux-2.6.33/drivers/ide/ide-iops.c linux-lemote/drivers/ide/ide-iops.c
  3819. --- linux-2.6.33/drivers/ide/ide-iops.c 2010-02-24 19:52:17.000000000 +0100
  3820. +++ linux-lemote/drivers/ide/ide-iops.c 2010-03-06 16:43:16.000000000 +0100
  3821. @@ -27,6 +27,8 @@
  3822. #include <asm/uaccess.h>
  3823. #include <asm/io.h>
  3824. +#include <asm/bootinfo.h>
  3825. +
  3826. void SELECT_MASK(ide_drive_t *drive, int mask)
  3827. {
  3828. const struct ide_port_ops *port_ops = drive->hwif->port_ops;
  3829. @@ -300,6 +302,9 @@
  3830. {
  3831. const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
  3832. + if (mips_machtype != MACH_LEMOTE_YL2F89)
  3833. + return;
  3834. +
  3835. for (list = nien_quirk_list; *list != NULL; list++)
  3836. if (strstr(m, *list) != NULL) {
  3837. drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
  3838. diff -Nur linux-2.6.33/drivers/net/wireless/Kconfig linux-lemote/drivers/net/wireless/Kconfig
  3839. --- linux-2.6.33/drivers/net/wireless/Kconfig 2010-02-24 19:52:17.000000000 +0100
  3840. +++ linux-lemote/drivers/net/wireless/Kconfig 2010-03-06 16:43:20.000000000 +0100
  3841. @@ -267,7 +267,7 @@
  3842. config RTL8187
  3843. tristate "Realtek 8187 and 8187B USB support"
  3844. - depends on MAC80211 && USB
  3845. + depends on MAC80211 && USB && !LEMOTE_MACH2F
  3846. select EEPROM_93CX6
  3847. ---help---
  3848. This is a driver for RTL8187 and RTL8187B based cards.
  3849. @@ -294,6 +294,19 @@
  3850. depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
  3851. default y
  3852. +config RTL8187B
  3853. + tristate "Realtek 8187B wifi support for yeeloong2f laptop"
  3854. + depends on MAC80211 && USB && LEMOTE_MACH2F
  3855. + depends on RFKILL || !RFKILL
  3856. + select CRYPTO
  3857. + select WIRELESS_EXT
  3858. + select WEXT_PRIV
  3859. + ---help---
  3860. + This is a driver for RTL8187B based cards, this driver is especially
  3861. + for yeeloon2f laptop.
  3862. +
  3863. + Thanks to Realtek for their support!
  3864. +
  3865. config ADM8211
  3866. tristate "ADMtek ADM8211 support"
  3867. depends on MAC80211 && PCI && EXPERIMENTAL
  3868. diff -Nur linux-2.6.33/drivers/net/wireless/Makefile linux-lemote/drivers/net/wireless/Makefile
  3869. --- linux-2.6.33/drivers/net/wireless/Makefile 2010-02-24 19:52:17.000000000 +0100
  3870. +++ linux-lemote/drivers/net/wireless/Makefile 2010-03-06 16:43:20.000000000 +0100
  3871. @@ -24,6 +24,7 @@
  3872. obj-$(CONFIG_ZD1211RW) += zd1211rw/
  3873. obj-$(CONFIG_RTL8180) += rtl818x/
  3874. obj-$(CONFIG_RTL8187) += rtl818x/
  3875. +obj-$(CONFIG_RTL8187B) += rtl8187b/
  3876. # 16-bit wireless PCMCIA client drivers
  3877. obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
  3878. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/dot11d.h linux-lemote/drivers/net/wireless/rtl8187b/dot11d.h
  3879. --- linux-2.6.33/drivers/net/wireless/rtl8187b/dot11d.h 1970-01-01 01:00:00.000000000 +0100
  3880. +++ linux-lemote/drivers/net/wireless/rtl8187b/dot11d.h 2010-03-06 16:43:22.000000000 +0100
  3881. @@ -0,0 +1,102 @@
  3882. +#ifndef __INC_DOT11D_H
  3883. +#define __INC_DOT11D_H
  3884. +
  3885. +#include "ieee80211/ieee80211.h"
  3886. +
  3887. +//#define ENABLE_DOT11D
  3888. +
  3889. +//#define DOT11D_MAX_CHNL_NUM 83
  3890. +
  3891. +typedef struct _CHNL_TXPOWER_TRIPLE {
  3892. + u8 FirstChnl;
  3893. + u8 NumChnls;
  3894. + u8 MaxTxPowerInDbm;
  3895. +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
  3896. +
  3897. +typedef enum _DOT11D_STATE {
  3898. + DOT11D_STATE_NONE = 0,
  3899. + DOT11D_STATE_LEARNED,
  3900. + DOT11D_STATE_DONE,
  3901. +}DOT11D_STATE;
  3902. +
  3903. +typedef struct _RT_DOT11D_INFO {
  3904. + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
  3905. +
  3906. + bool bEnabled; // dot11MultiDomainCapabilityEnabled
  3907. +
  3908. + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
  3909. + u8 CountryIeBuf[MAX_IE_LEN];
  3910. + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
  3911. + u8 CountryIeWatchdog;
  3912. +
  3913. + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
  3914. + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
  3915. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
  3916. + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
  3917. +
  3918. + DOT11D_STATE State;
  3919. +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
  3920. +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
  3921. +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
  3922. +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
  3923. +
  3924. +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
  3925. +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
  3926. +
  3927. +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  3928. +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  3929. +
  3930. +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
  3931. + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
  3932. + FALSE : \
  3933. + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
  3934. +
  3935. +#define CIE_WATCHDOG_TH 1
  3936. +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
  3937. +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
  3938. +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
  3939. +
  3940. +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
  3941. +
  3942. +
  3943. +void
  3944. +Dot11d_Init(
  3945. + struct ieee80211_device *dev
  3946. + );
  3947. +
  3948. +void
  3949. +Dot11d_Reset(
  3950. + struct ieee80211_device *dev
  3951. + );
  3952. +
  3953. +void
  3954. +Dot11d_UpdateCountryIe(
  3955. + struct ieee80211_device *dev,
  3956. + u8 * pTaddr,
  3957. + u16 CoutryIeLen,
  3958. + u8 * pCoutryIe
  3959. + );
  3960. +
  3961. +u8
  3962. +DOT11D_GetMaxTxPwrInDbm(
  3963. + struct ieee80211_device *dev,
  3964. + u8 Channel
  3965. + );
  3966. +
  3967. +void
  3968. +DOT11D_ScanComplete(
  3969. + struct ieee80211_device * dev
  3970. + );
  3971. +
  3972. +int IsLegalChannel(
  3973. + struct ieee80211_device * dev,
  3974. + u8 channel
  3975. +);
  3976. +
  3977. +int ToLegalChannel(
  3978. + struct ieee80211_device * dev,
  3979. + u8 channel
  3980. +);
  3981. +
  3982. +void dump_chnl_map(u8 * channel_map);
  3983. +#endif // #ifndef __INC_DOT11D_H
  3984. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/arc4.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
  3985. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 1970-01-01 01:00:00.000000000 +0100
  3986. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 2010-03-06 16:43:22.000000000 +0100
  3987. @@ -0,0 +1,103 @@
  3988. +/*
  3989. + * Cryptographic API
  3990. + *
  3991. + * ARC4 Cipher Algorithm
  3992. + *
  3993. + * Jon Oberheide <jon@oberheide.org>
  3994. + *
  3995. + * This program is free software; you can redistribute it and/or modify
  3996. + * it under the terms of the GNU General Public License as published by
  3997. + * the Free Software Foundation; either version 2 of the License, or
  3998. + * (at your option) any later version.
  3999. + *
  4000. + */
  4001. +#include <linux/module.h>
  4002. +#include <linux/init.h>
  4003. +#include "rtl_crypto.h"
  4004. +
  4005. +#define ARC4_MIN_KEY_SIZE 1
  4006. +#define ARC4_MAX_KEY_SIZE 256
  4007. +#define ARC4_BLOCK_SIZE 1
  4008. +
  4009. +struct arc4_ctx {
  4010. + u8 S[256];
  4011. + u8 x, y;
  4012. +};
  4013. +
  4014. +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
  4015. +{
  4016. + struct arc4_ctx *ctx = ctx_arg;
  4017. + int i, j = 0, k = 0;
  4018. +
  4019. + ctx->x = 1;
  4020. + ctx->y = 0;
  4021. +
  4022. + for(i = 0; i < 256; i++)
  4023. + ctx->S[i] = i;
  4024. +
  4025. + for(i = 0; i < 256; i++)
  4026. + {
  4027. + u8 a = ctx->S[i];
  4028. + j = (j + in_key[k] + a) & 0xff;
  4029. + ctx->S[i] = ctx->S[j];
  4030. + ctx->S[j] = a;
  4031. + if(++k >= key_len)
  4032. + k = 0;
  4033. + }
  4034. +
  4035. + return 0;
  4036. +}
  4037. +
  4038. +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
  4039. +{
  4040. + struct arc4_ctx *ctx = ctx_arg;
  4041. +
  4042. + u8 *const S = ctx->S;
  4043. + u8 x = ctx->x;
  4044. + u8 y = ctx->y;
  4045. + u8 a, b;
  4046. +
  4047. + a = S[x];
  4048. + y = (y + a) & 0xff;
  4049. + b = S[y];
  4050. + S[x] = b;
  4051. + S[y] = a;
  4052. + x = (x + 1) & 0xff;
  4053. + *out++ = *in ^ S[(a + b) & 0xff];
  4054. +
  4055. + ctx->x = x;
  4056. + ctx->y = y;
  4057. +}
  4058. +
  4059. +static struct crypto_alg arc4_alg = {
  4060. + .cra_name = "arc4",
  4061. + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  4062. + .cra_blocksize = ARC4_BLOCK_SIZE,
  4063. + .cra_ctxsize = sizeof(struct arc4_ctx),
  4064. + .cra_module = THIS_MODULE,
  4065. + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
  4066. + .cra_u = { .cipher = {
  4067. + .cia_min_keysize = ARC4_MIN_KEY_SIZE,
  4068. + .cia_max_keysize = ARC4_MAX_KEY_SIZE,
  4069. + .cia_setkey = arc4_set_key,
  4070. + .cia_encrypt = arc4_crypt,
  4071. + .cia_decrypt = arc4_crypt } }
  4072. +};
  4073. +
  4074. +static int __init arc4_init(void)
  4075. +{
  4076. + return crypto_register_alg(&arc4_alg);
  4077. +}
  4078. +
  4079. +
  4080. +static void __exit arc4_exit(void)
  4081. +{
  4082. + crypto_unregister_alg(&arc4_alg);
  4083. +}
  4084. +
  4085. +module_init(arc4_init);
  4086. +module_exit(arc4_exit);
  4087. +
  4088. +MODULE_LICENSE("GPL");
  4089. +MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
  4090. +MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
  4091. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
  4092. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 1970-01-01 01:00:00.000000000 +0100
  4093. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 2010-03-06 16:43:22.000000000 +0100
  4094. @@ -0,0 +1,244 @@
  4095. +#ifdef ENABLE_DOT11D
  4096. +//-----------------------------------------------------------------------------
  4097. +// File:
  4098. +// Dot11d.c
  4099. +//
  4100. +// Description:
  4101. +// Implement 802.11d.
  4102. +//
  4103. +//-----------------------------------------------------------------------------
  4104. +
  4105. +#include "dot11d.h"
  4106. +
  4107. +void
  4108. +Dot11d_Init(struct ieee80211_device *ieee)
  4109. +{
  4110. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
  4111. +
  4112. + pDot11dInfo->bEnabled = 0;
  4113. +
  4114. + pDot11dInfo->State = DOT11D_STATE_NONE;
  4115. + pDot11dInfo->CountryIeLen = 0;
  4116. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  4117. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  4118. + RESET_CIE_WATCHDOG(ieee);
  4119. +
  4120. + //printk("Dot11d_Init()\n");
  4121. +}
  4122. +
  4123. +//
  4124. +// Description:
  4125. +// Reset to the state as we are just entering a regulatory domain.
  4126. +//
  4127. +void
  4128. +Dot11d_Reset(struct ieee80211_device *ieee)
  4129. +{
  4130. + u32 i;
  4131. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
  4132. +
  4133. + // Clear old channel map
  4134. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  4135. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  4136. + // Set new channel map
  4137. + for (i=1; i<=11; i++) {
  4138. + (pDot11dInfo->channel_map)[i] = 1;
  4139. + }
  4140. + for (i=12; i<=14; i++) {
  4141. + (pDot11dInfo->channel_map)[i] = 2;
  4142. + }
  4143. +
  4144. + pDot11dInfo->State = DOT11D_STATE_NONE;
  4145. + pDot11dInfo->CountryIeLen = 0;
  4146. + RESET_CIE_WATCHDOG(ieee);
  4147. +
  4148. + //printk("Dot11d_Reset()\n");
  4149. +}
  4150. +
  4151. +//
  4152. +// Description:
  4153. +// Update country IE from Beacon or Probe Resopnse
  4154. +// and configure PHY for operation in the regulatory domain.
  4155. +//
  4156. +// TODO:
  4157. +// Configure Tx power.
  4158. +//
  4159. +// Assumption:
  4160. +// 1. IS_DOT11D_ENABLE() is TRUE.
  4161. +// 2. Input IE is an valid one.
  4162. +//
  4163. +void
  4164. +Dot11d_UpdateCountryIe(
  4165. + struct ieee80211_device *dev,
  4166. + u8 * pTaddr,
  4167. + u16 CoutryIeLen,
  4168. + u8 * pCoutryIe
  4169. + )
  4170. +{
  4171. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  4172. + u8 i, j, NumTriples, MaxChnlNum;
  4173. + PCHNL_TXPOWER_TRIPLE pTriple;
  4174. +
  4175. + if((CoutryIeLen - 3)%3 != 0)
  4176. + {
  4177. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
  4178. + Dot11d_Reset(dev);
  4179. + return;
  4180. + }
  4181. +
  4182. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  4183. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  4184. + MaxChnlNum = 0;
  4185. + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
  4186. + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
  4187. + for(i = 0; i < NumTriples; i++)
  4188. + {
  4189. + if(MaxChnlNum >= pTriple->FirstChnl)
  4190. + { // It is not in a monotonically increasing order, so stop processing.
  4191. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
  4192. + Dot11d_Reset(dev);
  4193. + return;
  4194. + }
  4195. + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
  4196. + { // It is not a valid set of channel id, so stop processing.
  4197. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
  4198. + Dot11d_Reset(dev);
  4199. + return;
  4200. + }
  4201. +
  4202. + for(j = 0 ; j < pTriple->NumChnls; j++)
  4203. + {
  4204. + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
  4205. + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
  4206. + MaxChnlNum = pTriple->FirstChnl + j;
  4207. + }
  4208. +
  4209. + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
  4210. + }
  4211. +#if 1
  4212. + //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
  4213. + printk("Channel List:");
  4214. + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
  4215. + if(pDot11dInfo->channel_map[i] > 0)
  4216. + printk(" %d", i);
  4217. + printk("\n");
  4218. +#endif
  4219. +
  4220. + UPDATE_CIE_SRC(dev, pTaddr);
  4221. +
  4222. + pDot11dInfo->CountryIeLen = CoutryIeLen;
  4223. + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
  4224. + pDot11dInfo->State = DOT11D_STATE_LEARNED;
  4225. +}
  4226. +
  4227. +void dump_chnl_map(u8 * channel_map)
  4228. +{
  4229. + int i;
  4230. + printk("Channel List:");
  4231. + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
  4232. + if(channel_map[i] > 0)
  4233. + printk(" %d(%d)", i, channel_map[i]);
  4234. + printk("\n");
  4235. +}
  4236. +
  4237. +u8
  4238. +DOT11D_GetMaxTxPwrInDbm(
  4239. + struct ieee80211_device *dev,
  4240. + u8 Channel
  4241. + )
  4242. +{
  4243. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  4244. + u8 MaxTxPwrInDbm = 255;
  4245. +
  4246. + if(MAX_CHANNEL_NUMBER < Channel)
  4247. + {
  4248. + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
  4249. + return MaxTxPwrInDbm;
  4250. + }
  4251. + if(pDot11dInfo->channel_map[Channel])
  4252. + {
  4253. + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
  4254. + }
  4255. +
  4256. + return MaxTxPwrInDbm;
  4257. +}
  4258. +
  4259. +
  4260. +void
  4261. +DOT11D_ScanComplete(
  4262. + struct ieee80211_device * dev
  4263. + )
  4264. +{
  4265. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  4266. +
  4267. + switch(pDot11dInfo->State)
  4268. + {
  4269. + case DOT11D_STATE_LEARNED:
  4270. + pDot11dInfo->State = DOT11D_STATE_DONE;
  4271. + break;
  4272. +
  4273. + case DOT11D_STATE_DONE:
  4274. + if( GET_CIE_WATCHDOG(dev) == 0 )
  4275. + { // Reset country IE if previous one is gone.
  4276. + Dot11d_Reset(dev);
  4277. + }
  4278. + break;
  4279. + case DOT11D_STATE_NONE:
  4280. + break;
  4281. + }
  4282. +}
  4283. +
  4284. +int IsLegalChannel(
  4285. + struct ieee80211_device * dev,
  4286. + u8 channel
  4287. +)
  4288. +{
  4289. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  4290. +
  4291. + if(MAX_CHANNEL_NUMBER < channel)
  4292. + {
  4293. + printk("IsLegalChannel(): Invalid Channel\n");
  4294. + return 0;
  4295. + }
  4296. + if(pDot11dInfo->channel_map[channel] > 0)
  4297. + return 1;
  4298. + return 0;
  4299. +}
  4300. +
  4301. +int ToLegalChannel(
  4302. + struct ieee80211_device * dev,
  4303. + u8 channel
  4304. +)
  4305. +{
  4306. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  4307. + u8 default_chn = 0;
  4308. + u32 i = 0;
  4309. +
  4310. + for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
  4311. + {
  4312. + if(pDot11dInfo->channel_map[i] > 0)
  4313. + {
  4314. + default_chn = i;
  4315. + break;
  4316. + }
  4317. + }
  4318. +
  4319. + if(MAX_CHANNEL_NUMBER < channel)
  4320. + {
  4321. + printk("IsLegalChannel(): Invalid Channel\n");
  4322. + return default_chn;
  4323. + }
  4324. +
  4325. + if(pDot11dInfo->channel_map[channel] > 0)
  4326. + return channel;
  4327. +
  4328. + return default_chn;
  4329. +}
  4330. +
  4331. +EXPORT_SYMBOL(Dot11d_Init);
  4332. +EXPORT_SYMBOL(Dot11d_Reset);
  4333. +EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
  4334. +EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
  4335. +EXPORT_SYMBOL(DOT11D_ScanComplete);
  4336. +EXPORT_SYMBOL(IsLegalChannel);
  4337. +EXPORT_SYMBOL(ToLegalChannel);
  4338. +#endif
  4339. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
  4340. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 1970-01-01 01:00:00.000000000 +0100
  4341. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 2010-03-06 16:43:22.000000000 +0100
  4342. @@ -0,0 +1,102 @@
  4343. +#ifndef __INC_DOT11D_H
  4344. +#define __INC_DOT11D_H
  4345. +
  4346. +#include "ieee80211.h"
  4347. +
  4348. +//#define ENABLE_DOT11D
  4349. +
  4350. +//#define DOT11D_MAX_CHNL_NUM 83
  4351. +
  4352. +typedef struct _CHNL_TXPOWER_TRIPLE {
  4353. + u8 FirstChnl;
  4354. + u8 NumChnls;
  4355. + u8 MaxTxPowerInDbm;
  4356. +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
  4357. +
  4358. +typedef enum _DOT11D_STATE {
  4359. + DOT11D_STATE_NONE = 0,
  4360. + DOT11D_STATE_LEARNED,
  4361. + DOT11D_STATE_DONE,
  4362. +}DOT11D_STATE;
  4363. +
  4364. +typedef struct _RT_DOT11D_INFO {
  4365. + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
  4366. +
  4367. + bool bEnabled; // dot11MultiDomainCapabilityEnabled
  4368. +
  4369. + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
  4370. + u8 CountryIeBuf[MAX_IE_LEN];
  4371. + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
  4372. + u8 CountryIeWatchdog;
  4373. +
  4374. + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
  4375. + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
  4376. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
  4377. + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
  4378. +
  4379. + DOT11D_STATE State;
  4380. +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
  4381. +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
  4382. +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
  4383. +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
  4384. +
  4385. +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
  4386. +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
  4387. +
  4388. +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  4389. +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  4390. +
  4391. +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
  4392. + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
  4393. + FALSE : \
  4394. + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
  4395. +
  4396. +#define CIE_WATCHDOG_TH 1
  4397. +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
  4398. +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
  4399. +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
  4400. +
  4401. +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
  4402. +
  4403. +
  4404. +void
  4405. +Dot11d_Init(
  4406. + struct ieee80211_device *dev
  4407. + );
  4408. +
  4409. +void
  4410. +Dot11d_Reset(
  4411. + struct ieee80211_device *dev
  4412. + );
  4413. +
  4414. +void
  4415. +Dot11d_UpdateCountryIe(
  4416. + struct ieee80211_device *dev,
  4417. + u8 * pTaddr,
  4418. + u16 CoutryIeLen,
  4419. + u8 * pCoutryIe
  4420. + );
  4421. +
  4422. +u8
  4423. +DOT11D_GetMaxTxPwrInDbm(
  4424. + struct ieee80211_device *dev,
  4425. + u8 Channel
  4426. + );
  4427. +
  4428. +void
  4429. +DOT11D_ScanComplete(
  4430. + struct ieee80211_device * dev
  4431. + );
  4432. +
  4433. +int IsLegalChannel(
  4434. + struct ieee80211_device * dev,
  4435. + u8 channel
  4436. +);
  4437. +
  4438. +int ToLegalChannel(
  4439. + struct ieee80211_device * dev,
  4440. + u8 channel
  4441. +);
  4442. +
  4443. +void dump_chnl_map(u8 * channel_map);
  4444. +#endif // #ifndef __INC_DOT11D_H
  4445. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c
  4446. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 1970-01-01 01:00:00.000000000 +0100
  4447. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 2010-03-06 16:43:22.000000000 +0100
  4448. @@ -0,0 +1,275 @@
  4449. +/*
  4450. + * Host AP crypto routines
  4451. + *
  4452. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  4453. + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
  4454. + *
  4455. + * This program is free software; you can redistribute it and/or modify
  4456. + * it under the terms of the GNU General Public License version 2 as
  4457. + * published by the Free Software Foundation. See README and COPYING for
  4458. + * more details.
  4459. + *
  4460. + */
  4461. +
  4462. +//#include <linux/config.h>
  4463. +#include <linux/version.h>
  4464. +#include <linux/module.h>
  4465. +#include <linux/init.h>
  4466. +#include <linux/slab.h>
  4467. +#include <asm/string.h>
  4468. +#include <asm/errno.h>
  4469. +
  4470. +#include "ieee80211.h"
  4471. +
  4472. +MODULE_AUTHOR("Jouni Malinen");
  4473. +MODULE_DESCRIPTION("HostAP crypto");
  4474. +MODULE_LICENSE("GPL");
  4475. +
  4476. +struct ieee80211_crypto_alg {
  4477. + struct list_head list;
  4478. + struct ieee80211_crypto_ops *ops;
  4479. +};
  4480. +
  4481. +
  4482. +struct ieee80211_crypto {
  4483. + struct list_head algs;
  4484. + spinlock_t lock;
  4485. +};
  4486. +
  4487. +static struct ieee80211_crypto *hcrypt;
  4488. +
  4489. +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
  4490. + int force)
  4491. +{
  4492. + struct list_head *ptr, *n;
  4493. + struct ieee80211_crypt_data *entry;
  4494. +
  4495. + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
  4496. + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
  4497. + entry = list_entry(ptr, struct ieee80211_crypt_data, list);
  4498. +
  4499. + if (atomic_read(&entry->refcnt) != 0 && !force)
  4500. + continue;
  4501. +
  4502. + list_del(ptr);
  4503. +
  4504. + if (entry->ops) {
  4505. + entry->ops->deinit(entry->priv);
  4506. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  4507. + module_put(entry->ops->owner);
  4508. +#else
  4509. + __MOD_DEC_USE_COUNT(entry->ops->owner);
  4510. +#endif
  4511. + }
  4512. + kfree(entry);
  4513. + }
  4514. +}
  4515. +
  4516. +void ieee80211_crypt_deinit_handler(unsigned long data)
  4517. +{
  4518. + struct ieee80211_device *ieee = (struct ieee80211_device *)data;
  4519. + unsigned long flags;
  4520. +
  4521. + spin_lock_irqsave(&ieee->lock, flags);
  4522. + ieee80211_crypt_deinit_entries(ieee, 0);
  4523. + if (!list_empty(&ieee->crypt_deinit_list)) {
  4524. + printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
  4525. + "deletion list\n", ieee->dev->name);
  4526. + ieee->crypt_deinit_timer.expires = jiffies + HZ;
  4527. + add_timer(&ieee->crypt_deinit_timer);
  4528. + }
  4529. + spin_unlock_irqrestore(&ieee->lock, flags);
  4530. +
  4531. +}
  4532. +
  4533. +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
  4534. + struct ieee80211_crypt_data **crypt)
  4535. +{
  4536. + struct ieee80211_crypt_data *tmp;
  4537. + unsigned long flags;
  4538. +
  4539. + if (*crypt == NULL)
  4540. + return;
  4541. +
  4542. + tmp = *crypt;
  4543. + *crypt = NULL;
  4544. +
  4545. + /* must not run ops->deinit() while there may be pending encrypt or
  4546. + * decrypt operations. Use a list of delayed deinits to avoid needing
  4547. + * locking. */
  4548. +
  4549. + spin_lock_irqsave(&ieee->lock, flags);
  4550. + list_add(&tmp->list, &ieee->crypt_deinit_list);
  4551. + if (!timer_pending(&ieee->crypt_deinit_timer)) {
  4552. + ieee->crypt_deinit_timer.expires = jiffies + HZ;
  4553. + add_timer(&ieee->crypt_deinit_timer);
  4554. + }
  4555. + spin_unlock_irqrestore(&ieee->lock, flags);
  4556. +}
  4557. +
  4558. +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
  4559. +{
  4560. + unsigned long flags;
  4561. + struct ieee80211_crypto_alg *alg;
  4562. +
  4563. + if (hcrypt == NULL)
  4564. + return -1;
  4565. +
  4566. + alg = kmalloc(sizeof(*alg), GFP_KERNEL);
  4567. + if (alg == NULL)
  4568. + return -ENOMEM;
  4569. +
  4570. + memset(alg, 0, sizeof(*alg));
  4571. + alg->ops = ops;
  4572. +
  4573. + spin_lock_irqsave(&hcrypt->lock, flags);
  4574. + list_add(&alg->list, &hcrypt->algs);
  4575. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  4576. +
  4577. + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
  4578. + ops->name);
  4579. +
  4580. + return 0;
  4581. +}
  4582. +
  4583. +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
  4584. +{
  4585. + unsigned long flags;
  4586. + struct list_head *ptr;
  4587. + struct ieee80211_crypto_alg *del_alg = NULL;
  4588. +
  4589. + if (hcrypt == NULL)
  4590. + return -1;
  4591. +
  4592. + spin_lock_irqsave(&hcrypt->lock, flags);
  4593. + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
  4594. + struct ieee80211_crypto_alg *alg =
  4595. + (struct ieee80211_crypto_alg *) ptr;
  4596. + if (alg->ops == ops) {
  4597. + list_del(&alg->list);
  4598. + del_alg = alg;
  4599. + break;
  4600. + }
  4601. + }
  4602. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  4603. +
  4604. + if (del_alg) {
  4605. + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
  4606. + "'%s'\n", ops->name);
  4607. + kfree(del_alg);
  4608. + }
  4609. +
  4610. + return del_alg ? 0 : -1;
  4611. +}
  4612. +
  4613. +
  4614. +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
  4615. +{
  4616. + unsigned long flags;
  4617. + struct list_head *ptr;
  4618. + struct ieee80211_crypto_alg *found_alg = NULL;
  4619. +
  4620. + if (hcrypt == NULL)
  4621. + return NULL;
  4622. +
  4623. + spin_lock_irqsave(&hcrypt->lock, flags);
  4624. + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
  4625. + struct ieee80211_crypto_alg *alg =
  4626. + (struct ieee80211_crypto_alg *) ptr;
  4627. + if (strcmp(alg->ops->name, name) == 0) {
  4628. + found_alg = alg;
  4629. + break;
  4630. + }
  4631. + }
  4632. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  4633. +
  4634. + if (found_alg)
  4635. + return found_alg->ops;
  4636. + else
  4637. + return NULL;
  4638. +}
  4639. +
  4640. +
  4641. +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
  4642. +static void ieee80211_crypt_null_deinit(void *priv) {}
  4643. +
  4644. +static struct ieee80211_crypto_ops ieee80211_crypt_null = {
  4645. + .name = "NULL",
  4646. + .init = ieee80211_crypt_null_init,
  4647. + .deinit = ieee80211_crypt_null_deinit,
  4648. + .encrypt_mpdu = NULL,
  4649. + .decrypt_mpdu = NULL,
  4650. + .encrypt_msdu = NULL,
  4651. + .decrypt_msdu = NULL,
  4652. + .set_key = NULL,
  4653. + .get_key = NULL,
  4654. + .extra_prefix_len = 0,
  4655. + .extra_postfix_len = 0,
  4656. + .owner = THIS_MODULE,
  4657. +};
  4658. +
  4659. +
  4660. +int __init ieee80211_crypto_init(void)
  4661. +{
  4662. + int ret = -ENOMEM;
  4663. +
  4664. + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
  4665. + if (!hcrypt)
  4666. + goto out;
  4667. +
  4668. + memset(hcrypt, 0, sizeof(*hcrypt));
  4669. + INIT_LIST_HEAD(&hcrypt->algs);
  4670. + spin_lock_init(&hcrypt->lock);
  4671. +
  4672. + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
  4673. + if (ret < 0) {
  4674. + kfree(hcrypt);
  4675. + hcrypt = NULL;
  4676. + }
  4677. +out:
  4678. + return ret;
  4679. +}
  4680. +
  4681. +
  4682. +void __exit ieee80211_crypto_deinit(void)
  4683. +{
  4684. + struct list_head *ptr, *n;
  4685. +
  4686. + if (hcrypt == NULL)
  4687. + return;
  4688. +
  4689. + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
  4690. + ptr = n, n = ptr->next) {
  4691. + struct ieee80211_crypto_alg *alg =
  4692. + (struct ieee80211_crypto_alg *) ptr;
  4693. + list_del(ptr);
  4694. + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
  4695. + "'%s' (deinit)\n", alg->ops->name);
  4696. + kfree(alg);
  4697. + }
  4698. +
  4699. + kfree(hcrypt);
  4700. +}
  4701. +
  4702. +#if 0
  4703. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  4704. +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
  4705. +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
  4706. +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
  4707. +
  4708. +EXPORT_SYMBOL(ieee80211_register_crypto_ops);
  4709. +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
  4710. +EXPORT_SYMBOL(ieee80211_get_crypto_ops);
  4711. +#else
  4712. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
  4713. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
  4714. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
  4715. +
  4716. +EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
  4717. +EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
  4718. +EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
  4719. +#endif
  4720. +
  4721. +module_init(ieee80211_crypto_init);
  4722. +module_exit(ieee80211_crypto_deinit);
  4723. +#endif
  4724. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c
  4725. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 1970-01-01 01:00:00.000000000 +0100
  4726. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 2010-03-06 16:43:22.000000000 +0100
  4727. @@ -0,0 +1,524 @@
  4728. +/*
  4729. + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
  4730. + *
  4731. + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  4732. + *
  4733. + * This program is free software; you can redistribute it and/or modify
  4734. + * it under the terms of the GNU General Public License version 2 as
  4735. + * published by the Free Software Foundation. See README and COPYING for
  4736. + * more details.
  4737. + */
  4738. +
  4739. +//#include <linux/config.h>
  4740. +#include <linux/version.h>
  4741. +#include <linux/module.h>
  4742. +#include <linux/init.h>
  4743. +#include <linux/slab.h>
  4744. +#include <linux/random.h>
  4745. +#include <linux/skbuff.h>
  4746. +#include <linux/netdevice.h>
  4747. +#include <linux/if_ether.h>
  4748. +#include <linux/if_arp.h>
  4749. +#include <asm/string.h>
  4750. +#include <linux/wireless.h>
  4751. +
  4752. +#include "ieee80211.h"
  4753. +
  4754. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  4755. +#include "rtl_crypto.h"
  4756. +#else
  4757. +#include <linux/crypto.h>
  4758. +#endif
  4759. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  4760. + #include <asm/scatterlist.h>
  4761. +#else
  4762. + #include <linux/scatterlist.h>
  4763. +#endif
  4764. +
  4765. +//#include <asm/scatterlist.h>
  4766. +
  4767. +MODULE_AUTHOR("Jouni Malinen");
  4768. +MODULE_DESCRIPTION("Host AP crypt: CCMP");
  4769. +MODULE_LICENSE("GPL");
  4770. +
  4771. +#define AES_BLOCK_LEN 16
  4772. +#define CCMP_HDR_LEN 8
  4773. +#define CCMP_MIC_LEN 8
  4774. +#define CCMP_TK_LEN 16
  4775. +#define CCMP_PN_LEN 6
  4776. +
  4777. +struct ieee80211_ccmp_data {
  4778. + u8 key[CCMP_TK_LEN];
  4779. + int key_set;
  4780. +
  4781. + u8 tx_pn[CCMP_PN_LEN];
  4782. + u8 rx_pn[CCMP_PN_LEN];
  4783. +
  4784. + u32 dot11RSNAStatsCCMPFormatErrors;
  4785. + u32 dot11RSNAStatsCCMPReplays;
  4786. + u32 dot11RSNAStatsCCMPDecryptErrors;
  4787. +
  4788. + int key_idx;
  4789. +
  4790. + struct crypto_tfm *tfm;
  4791. +
  4792. + /* scratch buffers for virt_to_page() (crypto API) */
  4793. + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
  4794. + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
  4795. + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
  4796. +};
  4797. +
  4798. +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
  4799. + const u8 pt[16], u8 ct[16])
  4800. +{
  4801. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  4802. + struct scatterlist src, dst;
  4803. +
  4804. + src.page = virt_to_page(pt);
  4805. + src.offset = offset_in_page(pt);
  4806. + src.length = AES_BLOCK_LEN;
  4807. +
  4808. + dst.page = virt_to_page(ct);
  4809. + dst.offset = offset_in_page(ct);
  4810. + dst.length = AES_BLOCK_LEN;
  4811. +
  4812. + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
  4813. + #else
  4814. + crypto_cipher_encrypt_one((void*)tfm, ct, pt);
  4815. + #endif
  4816. +}
  4817. +
  4818. +static void * ieee80211_ccmp_init(int key_idx)
  4819. +{
  4820. + struct ieee80211_ccmp_data *priv;
  4821. +
  4822. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  4823. + if (priv == NULL)
  4824. + goto fail;
  4825. + memset(priv, 0, sizeof(*priv));
  4826. + priv->key_idx = key_idx;
  4827. +
  4828. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  4829. + priv->tfm = crypto_alloc_tfm("aes", 0);
  4830. + if (priv->tfm == NULL) {
  4831. + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
  4832. + "crypto API aes\n");
  4833. + goto fail;
  4834. + }
  4835. + #else
  4836. + priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
  4837. + if (IS_ERR(priv->tfm)) {
  4838. + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
  4839. + "crypto API aes\n");
  4840. + priv->tfm = NULL;
  4841. + goto fail;
  4842. + }
  4843. + #endif
  4844. + return priv;
  4845. +
  4846. +fail:
  4847. + if (priv) {
  4848. + if (priv->tfm)
  4849. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  4850. + crypto_free_tfm(priv->tfm);
  4851. + #else
  4852. + crypto_free_cipher((void*)priv->tfm);
  4853. + #endif
  4854. + kfree(priv);
  4855. + }
  4856. +
  4857. + return NULL;
  4858. +}
  4859. +
  4860. +
  4861. +static void ieee80211_ccmp_deinit(void *priv)
  4862. +{
  4863. + struct ieee80211_ccmp_data *_priv = priv;
  4864. + if (_priv && _priv->tfm)
  4865. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  4866. + crypto_free_tfm(_priv->tfm);
  4867. + #else
  4868. + crypto_free_cipher((void*)_priv->tfm);
  4869. + #endif
  4870. + kfree(priv);
  4871. +}
  4872. +
  4873. +
  4874. +static inline void xor_block(u8 *b, u8 *a, size_t len)
  4875. +{
  4876. + int i;
  4877. + for (i = 0; i < len; i++)
  4878. + b[i] ^= a[i];
  4879. +}
  4880. +
  4881. +#ifndef JOHN_CCMP
  4882. +static void ccmp_init_blocks(struct crypto_tfm *tfm,
  4883. + struct ieee80211_hdr *hdr,
  4884. + u8 *pn, size_t dlen, u8 *b0, u8 *auth,
  4885. + u8 *s0)
  4886. +{
  4887. + u8 *pos, qc = 0;
  4888. + size_t aad_len;
  4889. + u16 fc;
  4890. + int a4_included, qc_included;
  4891. + u8 aad[2 * AES_BLOCK_LEN];
  4892. +
  4893. + fc = le16_to_cpu(hdr->frame_ctl);
  4894. + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  4895. + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
  4896. + /*
  4897. + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
  4898. + (WLAN_FC_GET_STYPE(fc) & 0x08));
  4899. + */
  4900. + // fixed by David :2006.9.6
  4901. + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
  4902. + (WLAN_FC_GET_STYPE(fc) & 0x80));
  4903. + aad_len = 22;
  4904. + if (a4_included)
  4905. + aad_len += 6;
  4906. + if (qc_included) {
  4907. + pos = (u8 *) &hdr->addr4;
  4908. + if (a4_included)
  4909. + pos += 6;
  4910. + qc = *pos & 0x0f;
  4911. + aad_len += 2;
  4912. + }
  4913. + /* CCM Initial Block:
  4914. + * Flag (Include authentication header, M=3 (8-octet MIC),
  4915. + * L=1 (2-octet Dlen))
  4916. + * Nonce: 0x00 | A2 | PN
  4917. + * Dlen */
  4918. + b0[0] = 0x59;
  4919. + b0[1] = qc;
  4920. + memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
  4921. + memcpy(b0 + 8, pn, CCMP_PN_LEN);
  4922. + b0[14] = (dlen >> 8) & 0xff;
  4923. + b0[15] = dlen & 0xff;
  4924. +
  4925. + /* AAD:
  4926. + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
  4927. + * A1 | A2 | A3
  4928. + * SC with bits 4..15 (seq#) masked to zero
  4929. + * A4 (if present)
  4930. + * QC (if present)
  4931. + */
  4932. + pos = (u8 *) hdr;
  4933. + aad[0] = 0; /* aad_len >> 8 */
  4934. + aad[1] = aad_len & 0xff;
  4935. + aad[2] = pos[0] & 0x8f;
  4936. + aad[3] = pos[1] & 0xc7;
  4937. + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
  4938. + pos = (u8 *) &hdr->seq_ctl;
  4939. + aad[22] = pos[0] & 0x0f;
  4940. + aad[23] = 0; /* all bits masked */
  4941. + memset(aad + 24, 0, 8);
  4942. + if (a4_included)
  4943. + memcpy(aad + 24, hdr->addr4, ETH_ALEN);
  4944. + if (qc_included) {
  4945. + aad[a4_included ? 30 : 24] = qc;
  4946. + /* rest of QC masked */
  4947. + }
  4948. +
  4949. + /* Start with the first block and AAD */
  4950. + ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
  4951. + xor_block(auth, aad, AES_BLOCK_LEN);
  4952. + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
  4953. + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
  4954. + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
  4955. + b0[0] &= 0x07;
  4956. + b0[14] = b0[15] = 0;
  4957. + ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
  4958. +}
  4959. +#endif
  4960. +
  4961. +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  4962. +{
  4963. + struct ieee80211_ccmp_data *key = priv;
  4964. + int data_len, i;
  4965. + u8 *pos;
  4966. + struct ieee80211_hdr *hdr;
  4967. +#ifndef JOHN_CCMP
  4968. + int blocks, last, len;
  4969. + u8 *mic;
  4970. + u8 *b0 = key->tx_b0;
  4971. + u8 *b = key->tx_b;
  4972. + u8 *e = key->tx_e;
  4973. + u8 *s0 = key->tx_s0;
  4974. +#endif
  4975. + if (skb_headroom(skb) < CCMP_HDR_LEN ||
  4976. + skb_tailroom(skb) < CCMP_MIC_LEN ||
  4977. + skb->len < hdr_len)
  4978. + return -1;
  4979. +
  4980. + data_len = skb->len - hdr_len;
  4981. + pos = skb_push(skb, CCMP_HDR_LEN);
  4982. + memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
  4983. + pos += hdr_len;
  4984. +// mic = skb_put(skb, CCMP_MIC_LEN);
  4985. +
  4986. + i = CCMP_PN_LEN - 1;
  4987. + while (i >= 0) {
  4988. + key->tx_pn[i]++;
  4989. + if (key->tx_pn[i] != 0)
  4990. + break;
  4991. + i--;
  4992. + }
  4993. +
  4994. + *pos++ = key->tx_pn[5];
  4995. + *pos++ = key->tx_pn[4];
  4996. + *pos++ = 0;
  4997. + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
  4998. + *pos++ = key->tx_pn[3];
  4999. + *pos++ = key->tx_pn[2];
  5000. + *pos++ = key->tx_pn[1];
  5001. + *pos++ = key->tx_pn[0];
  5002. +
  5003. + hdr = (struct ieee80211_hdr *) skb->data;
  5004. +#ifndef JOHN_CCMP
  5005. + //mic is moved to here by john
  5006. + mic = skb_put(skb, CCMP_MIC_LEN);
  5007. +
  5008. + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
  5009. +
  5010. + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
  5011. + last = data_len % AES_BLOCK_LEN;
  5012. +
  5013. + for (i = 1; i <= blocks; i++) {
  5014. + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
  5015. + /* Authentication */
  5016. + xor_block(b, pos, len);
  5017. + ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
  5018. + /* Encryption, with counter */
  5019. + b0[14] = (i >> 8) & 0xff;
  5020. + b0[15] = i & 0xff;
  5021. + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
  5022. + xor_block(pos, e, len);
  5023. + pos += len;
  5024. + }
  5025. +
  5026. + for (i = 0; i < CCMP_MIC_LEN; i++)
  5027. + mic[i] = b[i] ^ s0[i];
  5028. +#endif
  5029. + return 0;
  5030. +}
  5031. +
  5032. +
  5033. +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  5034. +{
  5035. + struct ieee80211_ccmp_data *key = priv;
  5036. + u8 keyidx, *pos;
  5037. + struct ieee80211_hdr *hdr;
  5038. + u8 pn[6];
  5039. +#ifndef JOHN_CCMP
  5040. + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
  5041. + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
  5042. + u8 *b0 = key->rx_b0;
  5043. + u8 *b = key->rx_b;
  5044. + u8 *a = key->rx_a;
  5045. + int i, blocks, last, len;
  5046. +#endif
  5047. + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
  5048. + key->dot11RSNAStatsCCMPFormatErrors++;
  5049. + return -1;
  5050. + }
  5051. +
  5052. + hdr = (struct ieee80211_hdr *) skb->data;
  5053. + pos = skb->data + hdr_len;
  5054. + keyidx = pos[3];
  5055. + if (!(keyidx & (1 << 5))) {
  5056. + if (net_ratelimit()) {
  5057. + printk(KERN_DEBUG "CCMP: received packet without ExtIV"
  5058. + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
  5059. + }
  5060. + key->dot11RSNAStatsCCMPFormatErrors++;
  5061. + return -2;
  5062. + }
  5063. + keyidx >>= 6;
  5064. + if (key->key_idx != keyidx) {
  5065. + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
  5066. + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
  5067. + return -6;
  5068. + }
  5069. + if (!key->key_set) {
  5070. + if (net_ratelimit()) {
  5071. + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
  5072. + " with keyid=%d that does not have a configured"
  5073. + " key\n", MAC_ARG(hdr->addr2), keyidx);
  5074. + }
  5075. + return -3;
  5076. + }
  5077. +
  5078. + pn[0] = pos[7];
  5079. + pn[1] = pos[6];
  5080. + pn[2] = pos[5];
  5081. + pn[3] = pos[4];
  5082. + pn[4] = pos[1];
  5083. + pn[5] = pos[0];
  5084. + pos += 8;
  5085. +#if 0
  5086. + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
  5087. + if (net_ratelimit()) {
  5088. + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
  5089. + " previous PN %02x%02x%02x%02x%02x%02x "
  5090. + "received PN %02x%02x%02x%02x%02x%02x\n",
  5091. + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
  5092. + MAC_ARG(pn));
  5093. + }
  5094. + key->dot11RSNAStatsCCMPReplays++;
  5095. + return -4;
  5096. + }
  5097. +#endif
  5098. +#ifndef JOHN_CCMP
  5099. + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
  5100. + xor_block(mic, b, CCMP_MIC_LEN);
  5101. +
  5102. + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
  5103. + last = data_len % AES_BLOCK_LEN;
  5104. +
  5105. + for (i = 1; i <= blocks; i++) {
  5106. + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
  5107. + /* Decrypt, with counter */
  5108. + b0[14] = (i >> 8) & 0xff;
  5109. + b0[15] = i & 0xff;
  5110. + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
  5111. + xor_block(pos, b, len);
  5112. + /* Authentication */
  5113. + xor_block(a, pos, len);
  5114. + ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
  5115. + pos += len;
  5116. + }
  5117. +
  5118. + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
  5119. + if (net_ratelimit()) {
  5120. + printk(KERN_DEBUG "CCMP: decrypt failed: STA="
  5121. + MAC_FMT "\n", MAC_ARG(hdr->addr2));
  5122. + }
  5123. + key->dot11RSNAStatsCCMPDecryptErrors++;
  5124. + return -5;
  5125. + }
  5126. +
  5127. + memcpy(key->rx_pn, pn, CCMP_PN_LEN);
  5128. +
  5129. +#endif
  5130. + /* Remove hdr and MIC */
  5131. + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
  5132. + skb_pull(skb, CCMP_HDR_LEN);
  5133. + skb_trim(skb, skb->len - CCMP_MIC_LEN);
  5134. +
  5135. + return keyidx;
  5136. +}
  5137. +
  5138. +
  5139. +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
  5140. +{
  5141. + struct ieee80211_ccmp_data *data = priv;
  5142. + int keyidx;
  5143. + struct crypto_tfm *tfm = data->tfm;
  5144. +
  5145. + keyidx = data->key_idx;
  5146. + memset(data, 0, sizeof(*data));
  5147. + data->key_idx = keyidx;
  5148. + data->tfm = tfm;
  5149. + if (len == CCMP_TK_LEN) {
  5150. + memcpy(data->key, key, CCMP_TK_LEN);
  5151. + data->key_set = 1;
  5152. + if (seq) {
  5153. + data->rx_pn[0] = seq[5];
  5154. + data->rx_pn[1] = seq[4];
  5155. + data->rx_pn[2] = seq[3];
  5156. + data->rx_pn[3] = seq[2];
  5157. + data->rx_pn[4] = seq[1];
  5158. + data->rx_pn[5] = seq[0];
  5159. + }
  5160. + crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
  5161. + } else if (len == 0)
  5162. + data->key_set = 0;
  5163. + else
  5164. + return -1;
  5165. +
  5166. + return 0;
  5167. +}
  5168. +
  5169. +
  5170. +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
  5171. +{
  5172. + struct ieee80211_ccmp_data *data = priv;
  5173. +
  5174. + if (len < CCMP_TK_LEN)
  5175. + return -1;
  5176. +
  5177. + if (!data->key_set)
  5178. + return 0;
  5179. + memcpy(key, data->key, CCMP_TK_LEN);
  5180. +
  5181. + if (seq) {
  5182. + seq[0] = data->tx_pn[5];
  5183. + seq[1] = data->tx_pn[4];
  5184. + seq[2] = data->tx_pn[3];
  5185. + seq[3] = data->tx_pn[2];
  5186. + seq[4] = data->tx_pn[1];
  5187. + seq[5] = data->tx_pn[0];
  5188. + }
  5189. +
  5190. + return CCMP_TK_LEN;
  5191. +}
  5192. +
  5193. +
  5194. +static char * ieee80211_ccmp_print_stats(char *p, void *priv)
  5195. +{
  5196. + struct ieee80211_ccmp_data *ccmp = priv;
  5197. + p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
  5198. + "tx_pn=%02x%02x%02x%02x%02x%02x "
  5199. + "rx_pn=%02x%02x%02x%02x%02x%02x "
  5200. + "format_errors=%d replays=%d decrypt_errors=%d\n",
  5201. + ccmp->key_idx, ccmp->key_set,
  5202. + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
  5203. + ccmp->dot11RSNAStatsCCMPFormatErrors,
  5204. + ccmp->dot11RSNAStatsCCMPReplays,
  5205. + ccmp->dot11RSNAStatsCCMPDecryptErrors);
  5206. +
  5207. + return p;
  5208. +}
  5209. +
  5210. +void ieee80211_ccmp_null(void)
  5211. +{
  5212. + // printk("============>%s()\n", __FUNCTION__);
  5213. + return;
  5214. +}
  5215. +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
  5216. + .name = "CCMP",
  5217. + .init = ieee80211_ccmp_init,
  5218. + .deinit = ieee80211_ccmp_deinit,
  5219. + .encrypt_mpdu = ieee80211_ccmp_encrypt,
  5220. + .decrypt_mpdu = ieee80211_ccmp_decrypt,
  5221. + .encrypt_msdu = NULL,
  5222. + .decrypt_msdu = NULL,
  5223. + .set_key = ieee80211_ccmp_set_key,
  5224. + .get_key = ieee80211_ccmp_get_key,
  5225. + .print_stats = ieee80211_ccmp_print_stats,
  5226. + .extra_prefix_len = CCMP_HDR_LEN,
  5227. + .extra_postfix_len = CCMP_MIC_LEN,
  5228. + .owner = THIS_MODULE,
  5229. +};
  5230. +
  5231. +
  5232. +int __init ieee80211_crypto_ccmp_init(void)
  5233. +{
  5234. + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
  5235. +}
  5236. +
  5237. +
  5238. +void __exit ieee80211_crypto_ccmp_exit(void)
  5239. +{
  5240. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
  5241. +}
  5242. +#if 0
  5243. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  5244. +EXPORT_SYMBOL(ieee80211_ccmp_null);
  5245. +#else
  5246. +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
  5247. +#endif
  5248. +
  5249. +module_init(ieee80211_crypto_ccmp_init);
  5250. +module_exit(ieee80211_crypto_ccmp_exit);
  5251. +#endif
  5252. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h
  5253. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 1970-01-01 01:00:00.000000000 +0100
  5254. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 2010-03-06 16:43:22.000000000 +0100
  5255. @@ -0,0 +1,91 @@
  5256. +/*
  5257. + * Original code based on Host AP (software wireless LAN access point) driver
  5258. + * for Intersil Prism2/2.5/3.
  5259. + *
  5260. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  5261. + * <jkmaline@cc.hut.fi>
  5262. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  5263. + *
  5264. + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
  5265. + * <jketreno@linux.intel.com>
  5266. + *
  5267. + * Copyright (c) 2004, Intel Corporation
  5268. + *
  5269. + * This program is free software; you can redistribute it and/or modify
  5270. + * it under the terms of the GNU General Public License version 2 as
  5271. + * published by the Free Software Foundation. See README and COPYING for
  5272. + * more details.
  5273. + */
  5274. +
  5275. +/*
  5276. + * This file defines the interface to the ieee80211 crypto module.
  5277. + */
  5278. +#ifndef IEEE80211_CRYPT_H
  5279. +#define IEEE80211_CRYPT_H
  5280. +
  5281. +#include <linux/skbuff.h>
  5282. +
  5283. +struct ieee80211_crypto_ops {
  5284. + const char *name;
  5285. +
  5286. + /* init new crypto context (e.g., allocate private data space,
  5287. + * select IV, etc.); returns NULL on failure or pointer to allocated
  5288. + * private data on success */
  5289. + void * (*init)(int keyidx);
  5290. +
  5291. + /* deinitialize crypto context and free allocated private data */
  5292. + void (*deinit)(void *priv);
  5293. +
  5294. + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
  5295. + * value from decrypt_mpdu is passed as the keyidx value for
  5296. + * decrypt_msdu. skb must have enough head and tail room for the
  5297. + * encryption; if not, error will be returned; these functions are
  5298. + * called for all MPDUs (i.e., fragments).
  5299. + */
  5300. + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
  5301. + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
  5302. +
  5303. + /* These functions are called for full MSDUs, i.e. full frames.
  5304. + * These can be NULL if full MSDU operations are not needed. */
  5305. + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
  5306. + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
  5307. + void *priv);
  5308. +
  5309. + int (*set_key)(void *key, int len, u8 *seq, void *priv);
  5310. + int (*get_key)(void *key, int len, u8 *seq, void *priv);
  5311. +
  5312. + /* procfs handler for printing out key information and possible
  5313. + * statistics */
  5314. + char * (*print_stats)(char *p, void *priv);
  5315. +
  5316. + /* maximum number of bytes added by encryption; encrypt buf is
  5317. + * allocated with extra_prefix_len bytes, copy of in_buf, and
  5318. + * extra_postfix_len; encrypt need not use all this space, but
  5319. + * the result must start at the beginning of the buffer and correct
  5320. + * length must be returned */
  5321. + int extra_prefix_len, extra_postfix_len;
  5322. +
  5323. + struct module *owner;
  5324. +};
  5325. +
  5326. +struct ieee80211_crypt_data {
  5327. + struct list_head list; /* delayed deletion list */
  5328. + struct ieee80211_crypto_ops *ops;
  5329. + void *priv;
  5330. + atomic_t refcnt;
  5331. +};
  5332. +
  5333. +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
  5334. +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
  5335. +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
  5336. +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
  5337. +void ieee80211_crypt_deinit_handler(unsigned long);
  5338. +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
  5339. + struct ieee80211_crypt_data **crypt);
  5340. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  5341. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  5342. +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
  5343. +#define crypto_free_tfm crypto_free_tfm_rtl
  5344. +#endif
  5345. +
  5346. +#endif
  5347. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c
  5348. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 1970-01-01 01:00:00.000000000 +0100
  5349. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 2010-03-06 16:43:22.000000000 +0100
  5350. @@ -0,0 +1,996 @@
  5351. +/*
  5352. + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
  5353. + *
  5354. + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  5355. + *
  5356. + * This program is free software; you can redistribute it and/or modify
  5357. + * it under the terms of the GNU General Public License version 2 as
  5358. + * published by the Free Software Foundation. See README and COPYING for
  5359. + * more details.
  5360. + */
  5361. +
  5362. +//#include <linux/config.h>
  5363. +#include <linux/version.h>
  5364. +#include <linux/module.h>
  5365. +#include <linux/init.h>
  5366. +#include <linux/slab.h>
  5367. +#include <linux/random.h>
  5368. +#include <linux/skbuff.h>
  5369. +#include <linux/netdevice.h>
  5370. +#include <linux/if_ether.h>
  5371. +#include <linux/if_arp.h>
  5372. +#include <asm/string.h>
  5373. +
  5374. +#include "ieee80211.h"
  5375. +
  5376. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  5377. +#include "rtl_crypto.h"
  5378. +#else
  5379. +#include <linux/crypto.h>
  5380. +#endif
  5381. +//#include <asm/scatterlist.h>
  5382. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  5383. + #include <asm/scatterlist.h>
  5384. +#else
  5385. + #include <linux/scatterlist.h>
  5386. +#endif
  5387. +
  5388. +#include <linux/crc32.h>
  5389. +
  5390. +MODULE_AUTHOR("Jouni Malinen");
  5391. +MODULE_DESCRIPTION("Host AP crypt: TKIP");
  5392. +MODULE_LICENSE("GPL");
  5393. +
  5394. +struct ieee80211_tkip_data {
  5395. +#define TKIP_KEY_LEN 32
  5396. + u8 key[TKIP_KEY_LEN];
  5397. + int key_set;
  5398. +
  5399. + u32 tx_iv32;
  5400. + u16 tx_iv16;
  5401. + u16 tx_ttak[5];
  5402. + int tx_phase1_done;
  5403. +
  5404. + u32 rx_iv32;
  5405. + u16 rx_iv16;
  5406. + u16 rx_ttak[5];
  5407. + int rx_phase1_done;
  5408. + u32 rx_iv32_new;
  5409. + u16 rx_iv16_new;
  5410. +
  5411. + u32 dot11RSNAStatsTKIPReplays;
  5412. + u32 dot11RSNAStatsTKIPICVErrors;
  5413. + u32 dot11RSNAStatsTKIPLocalMICFailures;
  5414. +
  5415. + int key_idx;
  5416. +
  5417. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  5418. + struct crypto_blkcipher *rx_tfm_arc4;
  5419. + struct crypto_hash *rx_tfm_michael;
  5420. + struct crypto_blkcipher *tx_tfm_arc4;
  5421. + struct crypto_hash *tx_tfm_michael;
  5422. + #endif
  5423. +
  5424. + struct crypto_tfm *tfm_arc4;
  5425. + struct crypto_tfm *tfm_michael;
  5426. +
  5427. + /* scratch buffers for virt_to_page() (crypto API) */
  5428. + u8 rx_hdr[16], tx_hdr[16];
  5429. +};
  5430. +
  5431. +static void * ieee80211_tkip_init(int key_idx)
  5432. +{
  5433. + struct ieee80211_tkip_data *priv;
  5434. +
  5435. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  5436. + if (priv == NULL)
  5437. + goto fail;
  5438. + memset(priv, 0, sizeof(*priv));
  5439. + priv->key_idx = key_idx;
  5440. +
  5441. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  5442. + priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
  5443. + if (priv->tfm_arc4 == NULL) {
  5444. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5445. + "crypto API arc4\n");
  5446. + goto fail;
  5447. + }
  5448. +
  5449. + priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
  5450. + if (priv->tfm_michael == NULL) {
  5451. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5452. + "crypto API michael_mic\n");
  5453. + goto fail;
  5454. + }
  5455. +
  5456. + #else
  5457. + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
  5458. + CRYPTO_ALG_ASYNC);
  5459. + if (IS_ERR(priv->tx_tfm_arc4)) {
  5460. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5461. + "crypto API arc4\n");
  5462. + priv->tx_tfm_arc4 = NULL;
  5463. + goto fail;
  5464. + }
  5465. +
  5466. + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
  5467. + CRYPTO_ALG_ASYNC);
  5468. + if (IS_ERR(priv->tx_tfm_michael)) {
  5469. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5470. + "crypto API michael_mic\n");
  5471. + priv->tx_tfm_michael = NULL;
  5472. + goto fail;
  5473. + }
  5474. +
  5475. + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
  5476. + CRYPTO_ALG_ASYNC);
  5477. + if (IS_ERR(priv->rx_tfm_arc4)) {
  5478. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5479. + "crypto API arc4\n");
  5480. + priv->rx_tfm_arc4 = NULL;
  5481. + goto fail;
  5482. + }
  5483. +
  5484. + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
  5485. + CRYPTO_ALG_ASYNC);
  5486. + if (IS_ERR(priv->rx_tfm_michael)) {
  5487. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  5488. + "crypto API michael_mic\n");
  5489. + priv->rx_tfm_michael = NULL;
  5490. + goto fail;
  5491. + }
  5492. + #endif
  5493. + return priv;
  5494. +
  5495. +fail:
  5496. + if (priv) {
  5497. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  5498. + if (priv->tfm_michael)
  5499. + crypto_free_tfm(priv->tfm_michael);
  5500. + if (priv->tfm_arc4)
  5501. + crypto_free_tfm(priv->tfm_arc4);
  5502. + #else
  5503. + if (priv->tx_tfm_michael)
  5504. + crypto_free_hash(priv->tx_tfm_michael);
  5505. + if (priv->tx_tfm_arc4)
  5506. + crypto_free_blkcipher(priv->tx_tfm_arc4);
  5507. + if (priv->rx_tfm_michael)
  5508. + crypto_free_hash(priv->rx_tfm_michael);
  5509. + if (priv->rx_tfm_arc4)
  5510. + crypto_free_blkcipher(priv->rx_tfm_arc4);
  5511. + #endif
  5512. + kfree(priv);
  5513. + }
  5514. +
  5515. + return NULL;
  5516. +}
  5517. +
  5518. +
  5519. +static void ieee80211_tkip_deinit(void *priv)
  5520. +{
  5521. + struct ieee80211_tkip_data *_priv = priv;
  5522. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  5523. + if (_priv && _priv->tfm_michael)
  5524. + crypto_free_tfm(_priv->tfm_michael);
  5525. + if (_priv && _priv->tfm_arc4)
  5526. + crypto_free_tfm(_priv->tfm_arc4);
  5527. + #else
  5528. + if (_priv) {
  5529. + if (_priv->tx_tfm_michael)
  5530. + crypto_free_hash(_priv->tx_tfm_michael);
  5531. + if (_priv->tx_tfm_arc4)
  5532. + crypto_free_blkcipher(_priv->tx_tfm_arc4);
  5533. + if (_priv->rx_tfm_michael)
  5534. + crypto_free_hash(_priv->rx_tfm_michael);
  5535. + if (_priv->rx_tfm_arc4)
  5536. + crypto_free_blkcipher(_priv->rx_tfm_arc4);
  5537. + }
  5538. + #endif
  5539. + kfree(priv);
  5540. +}
  5541. +
  5542. +
  5543. +static inline u16 RotR1(u16 val)
  5544. +{
  5545. + return (val >> 1) | (val << 15);
  5546. +}
  5547. +
  5548. +
  5549. +static inline u8 Lo8(u16 val)
  5550. +{
  5551. + return val & 0xff;
  5552. +}
  5553. +
  5554. +
  5555. +static inline u8 Hi8(u16 val)
  5556. +{
  5557. + return val >> 8;
  5558. +}
  5559. +
  5560. +
  5561. +static inline u16 Lo16(u32 val)
  5562. +{
  5563. + return val & 0xffff;
  5564. +}
  5565. +
  5566. +
  5567. +static inline u16 Hi16(u32 val)
  5568. +{
  5569. + return val >> 16;
  5570. +}
  5571. +
  5572. +
  5573. +static inline u16 Mk16(u8 hi, u8 lo)
  5574. +{
  5575. + return lo | (((u16) hi) << 8);
  5576. +}
  5577. +
  5578. +
  5579. +static inline u16 Mk16_le(u16 *v)
  5580. +{
  5581. + return le16_to_cpu(*v);
  5582. +}
  5583. +
  5584. +
  5585. +static const u16 Sbox[256] =
  5586. +{
  5587. + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
  5588. + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
  5589. + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
  5590. + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
  5591. + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
  5592. + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
  5593. + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
  5594. + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
  5595. + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
  5596. + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
  5597. + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
  5598. + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
  5599. + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
  5600. + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
  5601. + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
  5602. + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
  5603. + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
  5604. + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
  5605. + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
  5606. + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
  5607. + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
  5608. + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
  5609. + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
  5610. + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
  5611. + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
  5612. + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
  5613. + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
  5614. + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
  5615. + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
  5616. + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
  5617. + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
  5618. + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
  5619. +};
  5620. +
  5621. +
  5622. +static inline u16 _S_(u16 v)
  5623. +{
  5624. + u16 t = Sbox[Hi8(v)];
  5625. + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
  5626. +}
  5627. +
  5628. +#ifndef JOHN_TKIP
  5629. +#define PHASE1_LOOP_COUNT 8
  5630. +
  5631. +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
  5632. +{
  5633. + int i, j;
  5634. +
  5635. + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
  5636. + TTAK[0] = Lo16(IV32);
  5637. + TTAK[1] = Hi16(IV32);
  5638. + TTAK[2] = Mk16(TA[1], TA[0]);
  5639. + TTAK[3] = Mk16(TA[3], TA[2]);
  5640. + TTAK[4] = Mk16(TA[5], TA[4]);
  5641. +
  5642. + for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
  5643. + j = 2 * (i & 1);
  5644. + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
  5645. + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
  5646. + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
  5647. + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
  5648. + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
  5649. + }
  5650. +}
  5651. +
  5652. +
  5653. +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
  5654. + u16 IV16)
  5655. +{
  5656. + /* Make temporary area overlap WEP seed so that the final copy can be
  5657. + * avoided on little endian hosts. */
  5658. + u16 *PPK = (u16 *) &WEPSeed[4];
  5659. +
  5660. + /* Step 1 - make copy of TTAK and bring in TSC */
  5661. + PPK[0] = TTAK[0];
  5662. + PPK[1] = TTAK[1];
  5663. + PPK[2] = TTAK[2];
  5664. + PPK[3] = TTAK[3];
  5665. + PPK[4] = TTAK[4];
  5666. + PPK[5] = TTAK[4] + IV16;
  5667. +
  5668. + /* Step 2 - 96-bit bijective mixing using S-box */
  5669. + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
  5670. + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
  5671. + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
  5672. + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
  5673. + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
  5674. + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
  5675. +
  5676. + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
  5677. + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
  5678. + PPK[2] += RotR1(PPK[1]);
  5679. + PPK[3] += RotR1(PPK[2]);
  5680. + PPK[4] += RotR1(PPK[3]);
  5681. + PPK[5] += RotR1(PPK[4]);
  5682. +
  5683. + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
  5684. + * WEPSeed[0..2] is transmitted as WEP IV */
  5685. + WEPSeed[0] = Hi8(IV16);
  5686. + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
  5687. + WEPSeed[2] = Lo8(IV16);
  5688. + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
  5689. +
  5690. +#ifdef __BIG_ENDIAN
  5691. + {
  5692. + int i;
  5693. + for (i = 0; i < 6; i++)
  5694. + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
  5695. + }
  5696. +#endif
  5697. +}
  5698. +#endif
  5699. +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  5700. +{
  5701. + struct ieee80211_tkip_data *tkey = priv;
  5702. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  5703. + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
  5704. + #endif
  5705. + int len;
  5706. + u8 *pos;
  5707. + struct ieee80211_hdr *hdr;
  5708. +#ifndef JOHN_TKIP
  5709. + u8 rc4key[16],*icv;
  5710. + u32 crc;
  5711. + struct scatterlist sg;
  5712. +#endif
  5713. + #if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,21))
  5714. + int ret;
  5715. + #endif
  5716. +
  5717. + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
  5718. + skb->len < hdr_len)
  5719. + return -1;
  5720. +
  5721. + hdr = (struct ieee80211_hdr *) skb->data;
  5722. +#if 0
  5723. +printk("@@ tkey\n");
  5724. +printk("%x|", ((u32*)tkey->key)[0]);
  5725. +printk("%x|", ((u32*)tkey->key)[1]);
  5726. +printk("%x|", ((u32*)tkey->key)[2]);
  5727. +printk("%x|", ((u32*)tkey->key)[3]);
  5728. +printk("%x|", ((u32*)tkey->key)[4]);
  5729. +printk("%x|", ((u32*)tkey->key)[5]);
  5730. +printk("%x|", ((u32*)tkey->key)[6]);
  5731. +printk("%x\n", ((u32*)tkey->key)[7]);
  5732. +#endif
  5733. +
  5734. +#ifndef JOHN_TKIP
  5735. + if (!tkey->tx_phase1_done) {
  5736. + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
  5737. + tkey->tx_iv32);
  5738. + tkey->tx_phase1_done = 1;
  5739. + }
  5740. + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
  5741. +
  5742. +#else
  5743. + tkey->tx_phase1_done = 1;
  5744. +#endif /*JOHN_TKIP*/
  5745. +
  5746. + len = skb->len - hdr_len;
  5747. + pos = skb_push(skb, 8);
  5748. + memmove(pos, pos + 8, hdr_len);
  5749. + pos += hdr_len;
  5750. +
  5751. +#ifdef JOHN_TKIP
  5752. + *pos++ = Hi8(tkey->tx_iv16);
  5753. + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
  5754. + *pos++ = Lo8(tkey->tx_iv16);
  5755. +#else
  5756. + *pos++ = rc4key[0];
  5757. + *pos++ = rc4key[1];
  5758. + *pos++ = rc4key[2];
  5759. +#endif
  5760. + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
  5761. + *pos++ = tkey->tx_iv32 & 0xff;
  5762. + *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
  5763. + *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
  5764. + *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
  5765. +#ifndef JOHN_TKIP
  5766. + icv = skb_put(skb, 4);
  5767. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  5768. + crc = ~crc32_le(~0, pos, len);
  5769. +#else
  5770. + crc = ~ether_crc_le(len, pos);
  5771. +#endif
  5772. + icv[0] = crc;
  5773. + icv[1] = crc >> 8;
  5774. + icv[2] = crc >> 16;
  5775. + icv[3] = crc >> 24;
  5776. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  5777. + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
  5778. + sg.page = virt_to_page(pos);
  5779. + sg.offset = offset_in_page(pos);
  5780. + sg.length = len + 4;
  5781. + crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
  5782. + #else
  5783. + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
  5784. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  5785. + sg.page = virt_to_page(pos);
  5786. + sg.offset = offset_in_page(pos);
  5787. + sg.length = len + 4;
  5788. + #else
  5789. + sg_init_one(&sg, pos, len + 4);
  5790. + #endif
  5791. + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
  5792. + #endif
  5793. +#endif
  5794. + tkey->tx_iv16++;
  5795. + if (tkey->tx_iv16 == 0) {
  5796. + tkey->tx_phase1_done = 0;
  5797. + tkey->tx_iv32++;
  5798. + }
  5799. +#ifndef JOHN_TKIP
  5800. + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
  5801. + return 0;
  5802. + #else
  5803. + return ret;
  5804. + #endif
  5805. +#else
  5806. + return 0;
  5807. +#endif
  5808. +}
  5809. +
  5810. +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  5811. +{
  5812. + struct ieee80211_tkip_data *tkey = priv;
  5813. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  5814. + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
  5815. + #endif
  5816. + u8 keyidx, *pos;
  5817. + u32 iv32;
  5818. + u16 iv16;
  5819. + struct ieee80211_hdr *hdr;
  5820. +#ifndef JOHN_TKIP
  5821. + u8 icv[4];
  5822. + u32 crc;
  5823. + struct scatterlist sg;
  5824. + u8 rc4key[16];
  5825. + int plen;
  5826. +#endif
  5827. + if (skb->len < hdr_len + 8 + 4)
  5828. + return -1;
  5829. +
  5830. + hdr = (struct ieee80211_hdr *) skb->data;
  5831. + pos = skb->data + hdr_len;
  5832. + keyidx = pos[3];
  5833. + if (!(keyidx & (1 << 5))) {
  5834. + if (net_ratelimit()) {
  5835. + printk(KERN_DEBUG "TKIP: received packet without ExtIV"
  5836. + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
  5837. + }
  5838. + return -2;
  5839. + }
  5840. + keyidx >>= 6;
  5841. + if (tkey->key_idx != keyidx) {
  5842. + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
  5843. + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
  5844. + return -6;
  5845. + }
  5846. + if (!tkey->key_set) {
  5847. + if (net_ratelimit()) {
  5848. + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
  5849. + " with keyid=%d that does not have a configured"
  5850. + " key\n", MAC_ARG(hdr->addr2), keyidx);
  5851. + }
  5852. + return -3;
  5853. + }
  5854. + iv16 = (pos[0] << 8) | pos[2];
  5855. + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
  5856. + pos += 8;
  5857. +#ifndef JOHN_TKIP
  5858. +#if 0
  5859. + if (iv32 < tkey->rx_iv32 ||
  5860. + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
  5861. + if (net_ratelimit()) {
  5862. + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
  5863. + " previous TSC %08x%04x received TSC "
  5864. + "%08x%04x\n", MAC_ARG(hdr->addr2),
  5865. + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
  5866. + }
  5867. + tkey->dot11RSNAStatsTKIPReplays++;
  5868. + return -4;
  5869. + }
  5870. +#endif
  5871. + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
  5872. + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
  5873. + tkey->rx_phase1_done = 1;
  5874. + }
  5875. + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
  5876. +
  5877. + plen = skb->len - hdr_len - 12;
  5878. + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
  5879. + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
  5880. + sg.page = virt_to_page(pos);
  5881. + sg.offset = offset_in_page(pos);
  5882. + sg.length = plen + 4;
  5883. + crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
  5884. + #else
  5885. + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
  5886. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
  5887. + sg.page = virt_to_page(pos);
  5888. + sg.offset = offset_in_page(pos);
  5889. + sg.length = plen + 4;
  5890. + #else
  5891. + sg_init_one(&sg, pos, plen + 4);
  5892. + #endif
  5893. + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
  5894. + if (net_ratelimit()) {
  5895. + printk(KERN_DEBUG ": TKIP: failed to decrypt "
  5896. + "received packet from " MAC_FMT "\n",
  5897. + MAC_ARG(hdr->addr2));
  5898. + }
  5899. + return -7;
  5900. + }
  5901. + #endif
  5902. +
  5903. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  5904. + crc = ~crc32_le(~0, pos, plen);
  5905. +#else
  5906. + crc = ~ether_crc_le(plen, pos);
  5907. +#endif
  5908. + icv[0] = crc;
  5909. + icv[1] = crc >> 8;
  5910. + icv[2] = crc >> 16;
  5911. + icv[3] = crc >> 24;
  5912. + if (memcmp(icv, pos + plen, 4) != 0) {
  5913. + if (iv32 != tkey->rx_iv32) {
  5914. + /* Previously cached Phase1 result was already lost, so
  5915. + * it needs to be recalculated for the next packet. */
  5916. + tkey->rx_phase1_done = 0;
  5917. + }
  5918. + if (net_ratelimit()) {
  5919. + printk(KERN_DEBUG "TKIP: ICV error detected: STA="
  5920. + MAC_FMT "\n", MAC_ARG(hdr->addr2));
  5921. + }
  5922. + tkey->dot11RSNAStatsTKIPICVErrors++;
  5923. + return -5;
  5924. + }
  5925. +
  5926. +#endif /* JOHN_TKIP */
  5927. +
  5928. + /* Update real counters only after Michael MIC verification has
  5929. + * completed */
  5930. + tkey->rx_iv32_new = iv32;
  5931. + tkey->rx_iv16_new = iv16;
  5932. +
  5933. + /* Remove IV and ICV */
  5934. + memmove(skb->data + 8, skb->data, hdr_len);
  5935. + skb_pull(skb, 8);
  5936. + skb_trim(skb, skb->len - 4);
  5937. +
  5938. +//john's test
  5939. +#ifdef JOHN_DUMP
  5940. +if( ((u16*)skb->data)[0] & 0x4000){
  5941. + printk("@@ rx decrypted skb->data");
  5942. + int i;
  5943. + for(i=0;i<skb->len;i++){
  5944. + if( (i%24)==0 ) printk("\n");
  5945. + printk("%2x ", ((u8*)skb->data)[i]);
  5946. + }
  5947. + printk("\n");
  5948. +}
  5949. +#endif /*JOHN_DUMP*/
  5950. + return keyidx;
  5951. +}
  5952. +
  5953. +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  5954. +static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
  5955. + u8 *data, size_t data_len, u8 *mic)
  5956. +{
  5957. + struct scatterlist sg[2];
  5958. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  5959. + struct hash_desc desc;
  5960. + int ret=0;
  5961. +#endif
  5962. + if (tkey->tfm_michael == NULL) {
  5963. + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
  5964. + return -1;
  5965. + }
  5966. + sg[0].page = virt_to_page(hdr);
  5967. + sg[0].offset = offset_in_page(hdr);
  5968. + sg[0].length = 16;
  5969. +
  5970. + sg[1].page = virt_to_page(data);
  5971. + sg[1].offset = offset_in_page(data);
  5972. + sg[1].length = data_len;
  5973. +
  5974. + //crypto_digest_init(tkey->tfm_michael);
  5975. + //crypto_digest_setkey(tkey->tfm_michael, key, 8);
  5976. + //crypto_digest_update(tkey->tfm_michael, sg, 2);
  5977. + //crypto_digest_final(tkey->tfm_michael, mic);
  5978. +
  5979. + //return 0;
  5980. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  5981. + crypto_digest_init(tkey->tfm_michael);
  5982. + crypto_digest_setkey(tkey->tfm_michael, key, 8);
  5983. + crypto_digest_update(tkey->tfm_michael, sg, 2);
  5984. + crypto_digest_final(tkey->tfm_michael, mic);
  5985. +
  5986. + return 0;
  5987. +#else
  5988. +if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
  5989. + return -1;
  5990. +
  5991. +// return 0;
  5992. + desc.tfm = tkey->tfm_michael;
  5993. + desc.flags = 0;
  5994. + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
  5995. + return ret;
  5996. +#endif
  5997. +}
  5998. +#else
  5999. +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
  6000. + u8 * data, size_t data_len, u8 * mic)
  6001. +{
  6002. + struct hash_desc desc;
  6003. + struct scatterlist sg[2];
  6004. +
  6005. + if (tfm_michael == NULL) {
  6006. + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
  6007. + return -1;
  6008. + }
  6009. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  6010. + sg[0].page = virt_to_page(hdr);
  6011. + sg[0].offset = offset_in_page(hdr);
  6012. + sg[0].length = 16;
  6013. +
  6014. + sg[1].page = virt_to_page(data);
  6015. + sg[1].offset = offset_in_page(data);
  6016. + sg[1].length = data_len;
  6017. +#else
  6018. + sg_init_table(sg, 2);
  6019. + sg_set_buf(&sg[0], hdr, 16);
  6020. + sg_set_buf(&sg[1], data, data_len);
  6021. +#endif
  6022. + if (crypto_hash_setkey(tfm_michael, key, 8))
  6023. + return -1;
  6024. +
  6025. + desc.tfm = tfm_michael;
  6026. + desc.flags = 0;
  6027. + return crypto_hash_digest(&desc, sg, data_len + 16, mic);
  6028. +}
  6029. +#endif
  6030. +
  6031. +
  6032. +
  6033. +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
  6034. +{
  6035. + struct ieee80211_hdr *hdr11;
  6036. +
  6037. + hdr11 = (struct ieee80211_hdr *) skb->data;
  6038. + switch (le16_to_cpu(hdr11->frame_ctl) &
  6039. + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  6040. + case IEEE80211_FCTL_TODS:
  6041. + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
  6042. + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
  6043. + break;
  6044. + case IEEE80211_FCTL_FROMDS:
  6045. + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
  6046. + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
  6047. + break;
  6048. + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
  6049. + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
  6050. + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
  6051. + break;
  6052. + case 0:
  6053. + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
  6054. + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
  6055. + break;
  6056. + }
  6057. +
  6058. + hdr[12] = 0; /* priority */
  6059. +
  6060. + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
  6061. +}
  6062. +
  6063. +
  6064. +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
  6065. +{
  6066. + struct ieee80211_tkip_data *tkey = priv;
  6067. + u8 *pos;
  6068. + struct ieee80211_hdr *hdr;
  6069. +
  6070. + hdr = (struct ieee80211_hdr *) skb->data;
  6071. +
  6072. + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
  6073. + printk(KERN_DEBUG "Invalid packet for Michael MIC add "
  6074. + "(tailroom=%d hdr_len=%d skb->len=%d)\n",
  6075. + skb_tailroom(skb), hdr_len, skb->len);
  6076. + return -1;
  6077. + }
  6078. +
  6079. + michael_mic_hdr(skb, tkey->tx_hdr);
  6080. +
  6081. + // { david, 2006.9.1
  6082. + // fix the wpa process with wmm enabled.
  6083. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
  6084. + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
  6085. + }
  6086. + // }
  6087. + pos = skb_put(skb, 8);
  6088. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6089. + if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
  6090. + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
  6091. + #else
  6092. + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
  6093. + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
  6094. + #endif
  6095. + return -1;
  6096. +
  6097. + return 0;
  6098. +}
  6099. +
  6100. +
  6101. +#if WIRELESS_EXT >= 18
  6102. +static void ieee80211_michael_mic_failure(struct net_device *dev,
  6103. + struct ieee80211_hdr *hdr,
  6104. + int keyidx)
  6105. +{
  6106. + union iwreq_data wrqu;
  6107. + struct iw_michaelmicfailure ev;
  6108. +
  6109. + /* TODO: needed parameters: count, keyid, key type, TSC */
  6110. + memset(&ev, 0, sizeof(ev));
  6111. + ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
  6112. + if (hdr->addr1[0] & 0x01)
  6113. + ev.flags |= IW_MICFAILURE_GROUP;
  6114. + else
  6115. + ev.flags |= IW_MICFAILURE_PAIRWISE;
  6116. + ev.src_addr.sa_family = ARPHRD_ETHER;
  6117. + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
  6118. + memset(&wrqu, 0, sizeof(wrqu));
  6119. + wrqu.data.length = sizeof(ev);
  6120. + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
  6121. +}
  6122. +#elif WIRELESS_EXT >= 15
  6123. +static void ieee80211_michael_mic_failure(struct net_device *dev,
  6124. + struct ieee80211_hdr *hdr,
  6125. + int keyidx)
  6126. +{
  6127. + union iwreq_data wrqu;
  6128. + char buf[128];
  6129. +
  6130. + /* TODO: needed parameters: count, keyid, key type, TSC */
  6131. + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
  6132. + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
  6133. + MAC_ARG(hdr->addr2));
  6134. + memset(&wrqu, 0, sizeof(wrqu));
  6135. + wrqu.data.length = strlen(buf);
  6136. + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
  6137. +}
  6138. +#else /* WIRELESS_EXT >= 15 */
  6139. +static inline void ieee80211_michael_mic_failure(struct net_device *dev,
  6140. + struct ieee80211_hdr *hdr,
  6141. + int keyidx)
  6142. +{
  6143. +}
  6144. +#endif /* WIRELESS_EXT >= 15 */
  6145. +
  6146. +
  6147. +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
  6148. + int hdr_len, void *priv)
  6149. +{
  6150. + struct ieee80211_tkip_data *tkey = priv;
  6151. + u8 mic[8];
  6152. + struct ieee80211_hdr *hdr;
  6153. +
  6154. + hdr = (struct ieee80211_hdr *) skb->data;
  6155. +
  6156. + if (!tkey->key_set)
  6157. + return -1;
  6158. +
  6159. + michael_mic_hdr(skb, tkey->rx_hdr);
  6160. + // { david, 2006.9.1
  6161. + // fix the wpa process with wmm enabled.
  6162. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
  6163. + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
  6164. + }
  6165. + // }
  6166. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6167. + if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
  6168. + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
  6169. + #else
  6170. + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
  6171. + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
  6172. + #endif
  6173. + return -1;
  6174. + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
  6175. + struct ieee80211_hdr *hdr;
  6176. + hdr = (struct ieee80211_hdr *) skb->data;
  6177. + printk(KERN_DEBUG "%s: Michael MIC verification failed for "
  6178. + "MSDU from " MAC_FMT " keyidx=%d\n",
  6179. + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
  6180. + keyidx);
  6181. + if (skb->dev)
  6182. + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
  6183. + tkey->dot11RSNAStatsTKIPLocalMICFailures++;
  6184. + return -1;
  6185. + }
  6186. +
  6187. + /* Update TSC counters for RX now that the packet verification has
  6188. + * completed. */
  6189. + tkey->rx_iv32 = tkey->rx_iv32_new;
  6190. + tkey->rx_iv16 = tkey->rx_iv16_new;
  6191. +
  6192. + skb_trim(skb, skb->len - 8);
  6193. +
  6194. + return 0;
  6195. +}
  6196. +
  6197. +
  6198. +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
  6199. +{
  6200. + struct ieee80211_tkip_data *tkey = priv;
  6201. + int keyidx;
  6202. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6203. + struct crypto_tfm *tfm = tkey->tfm_michael;
  6204. + struct crypto_tfm *tfm2 = tkey->tfm_arc4;
  6205. + #else
  6206. + struct crypto_hash *tfm = tkey->tx_tfm_michael;
  6207. + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
  6208. + struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
  6209. + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
  6210. + #endif
  6211. +
  6212. + keyidx = tkey->key_idx;
  6213. + memset(tkey, 0, sizeof(*tkey));
  6214. + tkey->key_idx = keyidx;
  6215. +
  6216. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6217. + tkey->tfm_michael = tfm;
  6218. + tkey->tfm_arc4 = tfm2;
  6219. + #else
  6220. + tkey->tx_tfm_michael = tfm;
  6221. + tkey->tx_tfm_arc4 = tfm2;
  6222. + tkey->rx_tfm_michael = tfm3;
  6223. + tkey->rx_tfm_arc4 = tfm4;
  6224. + #endif
  6225. +
  6226. + if (len == TKIP_KEY_LEN) {
  6227. + memcpy(tkey->key, key, TKIP_KEY_LEN);
  6228. + tkey->key_set = 1;
  6229. + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
  6230. + if (seq) {
  6231. + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
  6232. + (seq[3] << 8) | seq[2];
  6233. + tkey->rx_iv16 = (seq[1] << 8) | seq[0];
  6234. + }
  6235. + } else if (len == 0)
  6236. + tkey->key_set = 0;
  6237. + else
  6238. + return -1;
  6239. +
  6240. + return 0;
  6241. +}
  6242. +
  6243. +
  6244. +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
  6245. +{
  6246. + struct ieee80211_tkip_data *tkey = priv;
  6247. +
  6248. + if (len < TKIP_KEY_LEN)
  6249. + return -1;
  6250. +
  6251. + if (!tkey->key_set)
  6252. + return 0;
  6253. + memcpy(key, tkey->key, TKIP_KEY_LEN);
  6254. +
  6255. + if (seq) {
  6256. + /* Return the sequence number of the last transmitted frame. */
  6257. + u16 iv16 = tkey->tx_iv16;
  6258. + u32 iv32 = tkey->tx_iv32;
  6259. + if (iv16 == 0)
  6260. + iv32--;
  6261. + iv16--;
  6262. + seq[0] = tkey->tx_iv16;
  6263. + seq[1] = tkey->tx_iv16 >> 8;
  6264. + seq[2] = tkey->tx_iv32;
  6265. + seq[3] = tkey->tx_iv32 >> 8;
  6266. + seq[4] = tkey->tx_iv32 >> 16;
  6267. + seq[5] = tkey->tx_iv32 >> 24;
  6268. + }
  6269. +
  6270. + return TKIP_KEY_LEN;
  6271. +}
  6272. +
  6273. +
  6274. +static char * ieee80211_tkip_print_stats(char *p, void *priv)
  6275. +{
  6276. + struct ieee80211_tkip_data *tkip = priv;
  6277. + p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
  6278. + "tx_pn=%02x%02x%02x%02x%02x%02x "
  6279. + "rx_pn=%02x%02x%02x%02x%02x%02x "
  6280. + "replays=%d icv_errors=%d local_mic_failures=%d\n",
  6281. + tkip->key_idx, tkip->key_set,
  6282. + (tkip->tx_iv32 >> 24) & 0xff,
  6283. + (tkip->tx_iv32 >> 16) & 0xff,
  6284. + (tkip->tx_iv32 >> 8) & 0xff,
  6285. + tkip->tx_iv32 & 0xff,
  6286. + (tkip->tx_iv16 >> 8) & 0xff,
  6287. + tkip->tx_iv16 & 0xff,
  6288. + (tkip->rx_iv32 >> 24) & 0xff,
  6289. + (tkip->rx_iv32 >> 16) & 0xff,
  6290. + (tkip->rx_iv32 >> 8) & 0xff,
  6291. + tkip->rx_iv32 & 0xff,
  6292. + (tkip->rx_iv16 >> 8) & 0xff,
  6293. + tkip->rx_iv16 & 0xff,
  6294. + tkip->dot11RSNAStatsTKIPReplays,
  6295. + tkip->dot11RSNAStatsTKIPICVErrors,
  6296. + tkip->dot11RSNAStatsTKIPLocalMICFailures);
  6297. + return p;
  6298. +}
  6299. +
  6300. +
  6301. +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
  6302. + .name = "TKIP",
  6303. + .init = ieee80211_tkip_init,
  6304. + .deinit = ieee80211_tkip_deinit,
  6305. + .encrypt_mpdu = ieee80211_tkip_encrypt,
  6306. + .decrypt_mpdu = ieee80211_tkip_decrypt,
  6307. + .encrypt_msdu = ieee80211_michael_mic_add,
  6308. + .decrypt_msdu = ieee80211_michael_mic_verify,
  6309. + .set_key = ieee80211_tkip_set_key,
  6310. + .get_key = ieee80211_tkip_get_key,
  6311. + .print_stats = ieee80211_tkip_print_stats,
  6312. + .extra_prefix_len = 4 + 4, /* IV + ExtIV */
  6313. + .extra_postfix_len = 8 + 4, /* MIC + ICV */
  6314. + .owner = THIS_MODULE,
  6315. +};
  6316. +
  6317. +
  6318. +int __init ieee80211_crypto_tkip_init(void)
  6319. +{
  6320. + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
  6321. +}
  6322. +
  6323. +
  6324. +void __exit ieee80211_crypto_tkip_exit(void)
  6325. +{
  6326. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
  6327. +}
  6328. +
  6329. +
  6330. +void ieee80211_tkip_null(void)
  6331. +{
  6332. +// printk("============>%s()\n", __FUNCTION__);
  6333. + return;
  6334. +}
  6335. +
  6336. +#if 0
  6337. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  6338. +EXPORT_SYMBOL(ieee80211_tkip_null);
  6339. +#else
  6340. +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
  6341. +#endif
  6342. +
  6343. +
  6344. +module_init(ieee80211_crypto_tkip_init);
  6345. +module_exit(ieee80211_crypto_tkip_exit);
  6346. +#endif
  6347. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c
  6348. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 1970-01-01 01:00:00.000000000 +0100
  6349. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 2010-03-06 16:43:22.000000000 +0100
  6350. @@ -0,0 +1,383 @@
  6351. +/*
  6352. + * Host AP crypt: host-based WEP encryption implementation for Host AP driver
  6353. + *
  6354. + * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  6355. + *
  6356. + * This program is free software; you can redistribute it and/or modify
  6357. + * it under the terms of the GNU General Public License version 2 as
  6358. + * published by the Free Software Foundation. See README and COPYING for
  6359. + * more details.
  6360. + */
  6361. +
  6362. +//#include <linux/config.h>
  6363. +#include <linux/version.h>
  6364. +#include <linux/module.h>
  6365. +#include <linux/init.h>
  6366. +#include <linux/slab.h>
  6367. +#include <linux/random.h>
  6368. +#include <linux/skbuff.h>
  6369. +#include <asm/string.h>
  6370. +
  6371. +#include "ieee80211.h"
  6372. +
  6373. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  6374. +#include "rtl_crypto.h"
  6375. +#else
  6376. +#include <linux/crypto.h>
  6377. +#endif
  6378. +
  6379. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  6380. + #include <asm/scatterlist.h>
  6381. +#else
  6382. + #include <linux/scatterlist.h>
  6383. +#endif
  6384. +//#include <asm/scatterlist.h>
  6385. +#include <linux/crc32.h>
  6386. +
  6387. +MODULE_AUTHOR("Jouni Malinen");
  6388. +MODULE_DESCRIPTION("Host AP crypt: WEP");
  6389. +MODULE_LICENSE("GPL");
  6390. +
  6391. +
  6392. +struct prism2_wep_data {
  6393. + u32 iv;
  6394. +#define WEP_KEY_LEN 13
  6395. + u8 key[WEP_KEY_LEN + 1];
  6396. + u8 key_len;
  6397. + u8 key_idx;
  6398. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6399. + struct crypto_tfm *tfm;
  6400. + #else
  6401. + struct crypto_blkcipher *tx_tfm;
  6402. + struct crypto_blkcipher *rx_tfm;
  6403. + #endif
  6404. +};
  6405. +
  6406. +
  6407. +static void * prism2_wep_init(int keyidx)
  6408. +{
  6409. + struct prism2_wep_data *priv;
  6410. +
  6411. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  6412. + if (priv == NULL)
  6413. + goto fail;
  6414. + memset(priv, 0, sizeof(*priv));
  6415. + priv->key_idx = keyidx;
  6416. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6417. + priv->tfm = crypto_alloc_tfm("arc4", 0);
  6418. + if (priv->tfm == NULL) {
  6419. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  6420. + "crypto API arc4\n");
  6421. + goto fail;
  6422. + }
  6423. + #else
  6424. + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
  6425. + if (IS_ERR(priv->tx_tfm)) {
  6426. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  6427. + "crypto API arc4\n");
  6428. + priv->tx_tfm = NULL;
  6429. + goto fail;
  6430. + }
  6431. + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
  6432. + if (IS_ERR(priv->rx_tfm)) {
  6433. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  6434. + "crypto API arc4\n");
  6435. + priv->rx_tfm = NULL;
  6436. + goto fail;
  6437. + }
  6438. + #endif
  6439. +
  6440. + /* start WEP IV from a random value */
  6441. + get_random_bytes(&priv->iv, 4);
  6442. +
  6443. + return priv;
  6444. +
  6445. +fail:
  6446. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6447. + if (priv) {
  6448. + if (priv->tfm)
  6449. + crypto_free_tfm(priv->tfm);
  6450. + kfree(priv);
  6451. + }
  6452. + #else
  6453. + if (priv) {
  6454. + if (priv->tx_tfm)
  6455. + crypto_free_blkcipher(priv->tx_tfm);
  6456. + if (priv->rx_tfm)
  6457. + crypto_free_blkcipher(priv->rx_tfm);
  6458. + kfree(priv);
  6459. + }
  6460. + #endif
  6461. + return NULL;
  6462. +}
  6463. +
  6464. +
  6465. +static void prism2_wep_deinit(void *priv)
  6466. +{
  6467. + struct prism2_wep_data *_priv = priv;
  6468. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6469. + if (_priv && _priv->tfm)
  6470. + crypto_free_tfm(_priv->tfm);
  6471. + #else
  6472. + if (_priv) {
  6473. + if (_priv->tx_tfm)
  6474. + crypto_free_blkcipher(_priv->tx_tfm);
  6475. + if (_priv->rx_tfm)
  6476. + crypto_free_blkcipher(_priv->rx_tfm);
  6477. + }
  6478. + #endif
  6479. + kfree(priv);
  6480. +}
  6481. +
  6482. +
  6483. +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
  6484. + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
  6485. + * so the payload length increases with 8 bytes.
  6486. + *
  6487. + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
  6488. + */
  6489. +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  6490. +{
  6491. + struct prism2_wep_data *wep = priv;
  6492. +#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  6493. + struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
  6494. +#endif
  6495. + u32 klen, len;
  6496. + u8 key[WEP_KEY_LEN + 3];
  6497. + u8 *pos;
  6498. +#ifndef JOHN_HWSEC
  6499. + u32 crc;
  6500. + u8 *icv;
  6501. + struct scatterlist sg;
  6502. +#endif
  6503. + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
  6504. + skb->len < hdr_len)
  6505. + return -1;
  6506. +
  6507. + len = skb->len - hdr_len;
  6508. + pos = skb_push(skb, 4);
  6509. + memmove(pos, pos + 4, hdr_len);
  6510. + pos += hdr_len;
  6511. +
  6512. + klen = 3 + wep->key_len;
  6513. +
  6514. + wep->iv++;
  6515. +
  6516. + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
  6517. + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
  6518. + * can be used to speedup attacks, so avoid using them. */
  6519. + if ((wep->iv & 0xff00) == 0xff00) {
  6520. + u8 B = (wep->iv >> 16) & 0xff;
  6521. + if (B >= 3 && B < klen)
  6522. + wep->iv += 0x0100;
  6523. + }
  6524. +
  6525. + /* Prepend 24-bit IV to RC4 key and TX frame */
  6526. + *pos++ = key[0] = (wep->iv >> 16) & 0xff;
  6527. + *pos++ = key[1] = (wep->iv >> 8) & 0xff;
  6528. + *pos++ = key[2] = wep->iv & 0xff;
  6529. + *pos++ = wep->key_idx << 6;
  6530. +
  6531. + /* Copy rest of the WEP key (the secret part) */
  6532. + memcpy(key + 3, wep->key, wep->key_len);
  6533. +
  6534. +#ifndef JOHN_HWSEC
  6535. + /* Append little-endian CRC32 and encrypt it to produce ICV */
  6536. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  6537. + crc = ~crc32_le(~0, pos, len);
  6538. +#else
  6539. + crc = ~ether_crc_le(len, pos);
  6540. +#endif
  6541. + icv = skb_put(skb, 4);
  6542. + icv[0] = crc;
  6543. + icv[1] = crc >> 8;
  6544. + icv[2] = crc >> 16;
  6545. + icv[3] = crc >> 24;
  6546. +
  6547. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6548. + crypto_cipher_setkey(wep->tfm, key, klen);
  6549. + sg.page = virt_to_page(pos);
  6550. + sg.offset = offset_in_page(pos);
  6551. + sg.length = len + 4;
  6552. + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
  6553. +
  6554. + return 0;
  6555. + #else
  6556. + crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
  6557. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
  6558. + sg.page = virt_to_page(pos);
  6559. + sg.offset = offset_in_page(pos);
  6560. + sg.length = len + 4;
  6561. + #else
  6562. + sg_init_one(&sg, pos, len + 4);
  6563. + #endif
  6564. + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
  6565. + #endif
  6566. +#endif /* JOHN_HWSEC */
  6567. + return 0;
  6568. +}
  6569. +
  6570. +
  6571. +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
  6572. + * the frame: IV (4 bytes), encrypted payload (including SNAP header),
  6573. + * ICV (4 bytes). len includes both IV and ICV.
  6574. + *
  6575. + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
  6576. + * failure. If frame is OK, IV and ICV will be removed.
  6577. + */
  6578. +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  6579. +{
  6580. + struct prism2_wep_data *wep = priv;
  6581. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  6582. + struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
  6583. + #endif
  6584. + u32 klen, plen;
  6585. + u8 key[WEP_KEY_LEN + 3];
  6586. + u8 keyidx, *pos;
  6587. +#ifndef JOHN_HWSEC
  6588. + u32 crc;
  6589. + u8 icv[4];
  6590. + struct scatterlist sg;
  6591. +#endif
  6592. + if (skb->len < hdr_len + 8)
  6593. + return -1;
  6594. +
  6595. + pos = skb->data + hdr_len;
  6596. + key[0] = *pos++;
  6597. + key[1] = *pos++;
  6598. + key[2] = *pos++;
  6599. + keyidx = *pos++ >> 6;
  6600. + if (keyidx != wep->key_idx)
  6601. + return -1;
  6602. +
  6603. + klen = 3 + wep->key_len;
  6604. +
  6605. + /* Copy rest of the WEP key (the secret part) */
  6606. + memcpy(key + 3, wep->key, wep->key_len);
  6607. +
  6608. + /* Apply RC4 to data and compute CRC32 over decrypted data */
  6609. + plen = skb->len - hdr_len - 8;
  6610. +#ifndef JOHN_HWSEC
  6611. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  6612. + crypto_cipher_setkey(wep->tfm, key, klen);
  6613. + sg.page = virt_to_page(pos);
  6614. + sg.offset = offset_in_page(pos);
  6615. + sg.length = plen + 4;
  6616. + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
  6617. +#else
  6618. + crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
  6619. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  6620. + sg.page = virt_to_page(pos);
  6621. + sg.offset = offset_in_page(pos);
  6622. + sg.length = plen + 4;
  6623. + #else
  6624. + sg_init_one(&sg, pos, plen + 4);
  6625. + #endif
  6626. + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
  6627. + return -7;
  6628. +#endif
  6629. +
  6630. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  6631. + crc = ~crc32_le(~0, pos, plen);
  6632. +#else
  6633. + crc = ~ether_crc_le(plen, pos);
  6634. +#endif
  6635. + icv[0] = crc;
  6636. + icv[1] = crc >> 8;
  6637. + icv[2] = crc >> 16;
  6638. + icv[3] = crc >> 24;
  6639. +
  6640. + if (memcmp(icv, pos + plen, 4) != 0) {
  6641. + /* ICV mismatch - drop frame */
  6642. + return -2;
  6643. + }
  6644. +#endif /* JOHN_HWSEC */
  6645. +
  6646. + /* Remove IV and ICV */
  6647. + memmove(skb->data + 4, skb->data, hdr_len);
  6648. + skb_pull(skb, 4);
  6649. + skb_trim(skb, skb->len - 4);
  6650. + return 0;
  6651. +}
  6652. +
  6653. +
  6654. +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
  6655. +{
  6656. + struct prism2_wep_data *wep = priv;
  6657. +
  6658. + if (len < 0 || len > WEP_KEY_LEN)
  6659. + return -1;
  6660. +
  6661. + memcpy(wep->key, key, len);
  6662. + wep->key_len = len;
  6663. +
  6664. + return 0;
  6665. +}
  6666. +
  6667. +
  6668. +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
  6669. +{
  6670. + struct prism2_wep_data *wep = priv;
  6671. +
  6672. + if (len < wep->key_len)
  6673. + return -1;
  6674. +
  6675. + memcpy(key, wep->key, wep->key_len);
  6676. +
  6677. + return wep->key_len;
  6678. +}
  6679. +
  6680. +
  6681. +static char * prism2_wep_print_stats(char *p, void *priv)
  6682. +{
  6683. + struct prism2_wep_data *wep = priv;
  6684. + p += sprintf(p, "key[%d] alg=WEP len=%d\n",
  6685. + wep->key_idx, wep->key_len);
  6686. + return p;
  6687. +}
  6688. +
  6689. +
  6690. +static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
  6691. + .name = "WEP",
  6692. + .init = prism2_wep_init,
  6693. + .deinit = prism2_wep_deinit,
  6694. + .encrypt_mpdu = prism2_wep_encrypt,
  6695. + .decrypt_mpdu = prism2_wep_decrypt,
  6696. + .encrypt_msdu = NULL,
  6697. + .decrypt_msdu = NULL,
  6698. + .set_key = prism2_wep_set_key,
  6699. + .get_key = prism2_wep_get_key,
  6700. + .print_stats = prism2_wep_print_stats,
  6701. + .extra_prefix_len = 4, /* IV */
  6702. + .extra_postfix_len = 4, /* ICV */
  6703. + .owner = THIS_MODULE,
  6704. +};
  6705. +
  6706. +
  6707. +int __init ieee80211_crypto_wep_init(void)
  6708. +{
  6709. + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
  6710. +}
  6711. +
  6712. +
  6713. +void __exit ieee80211_crypto_wep_exit(void)
  6714. +{
  6715. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
  6716. +}
  6717. +
  6718. +
  6719. +void ieee80211_wep_null(void)
  6720. +{
  6721. +// printk("============>%s()\n", __FUNCTION__);
  6722. + return;
  6723. +}
  6724. +#if 0
  6725. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  6726. +EXPORT_SYMBOL(ieee80211_wep_null);
  6727. +#else
  6728. +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
  6729. +#endif
  6730. +
  6731. +module_init(ieee80211_crypto_wep_init);
  6732. +module_exit(ieee80211_crypto_wep_exit);
  6733. +#endif
  6734. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
  6735. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 1970-01-01 01:00:00.000000000 +0100
  6736. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 2010-03-06 16:43:22.000000000 +0100
  6737. @@ -0,0 +1,1903 @@
  6738. +/*
  6739. + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
  6740. + * remains copyright by the original authors
  6741. + *
  6742. + * Portions of the merged code are based on Host AP (software wireless
  6743. + * LAN access point) driver for Intersil Prism2/2.5/3.
  6744. + *
  6745. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  6746. + * <jkmaline@cc.hut.fi>
  6747. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  6748. + *
  6749. + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
  6750. + * <jketreno@linux.intel.com>
  6751. + * Copyright (c) 2004, Intel Corporation
  6752. + *
  6753. + * Modified for Realtek's wi-fi cards by Andrea Merello
  6754. + * <andreamrl@tiscali.it>
  6755. + *
  6756. + * This program is free software; you can redistribute it and/or modify
  6757. + * it under the terms of the GNU General Public License version 2 as
  6758. + * published by the Free Software Foundation. See README and COPYING for
  6759. + * more details.
  6760. + */
  6761. +#ifndef IEEE80211_H
  6762. +#define IEEE80211_H
  6763. +#include <linux/if_ether.h> /* ETH_ALEN */
  6764. +#include <linux/kernel.h> /* ARRAY_SIZE */
  6765. +#include <linux/version.h>
  6766. +#include <linux/module.h>
  6767. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  6768. +#include <linux/jiffies.h>
  6769. +#else
  6770. +#include <linux/jffs.h>
  6771. +#include <linux/tqueue.h>
  6772. +#endif
  6773. +#include <linux/timer.h>
  6774. +#include <linux/sched.h>
  6775. +
  6776. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
  6777. +#include <linux/wireless.h>
  6778. +#endif
  6779. +/*
  6780. +#ifndef bool
  6781. +#define bool int
  6782. +#endif
  6783. +
  6784. +#ifndef true
  6785. +#define true 1
  6786. +#endif
  6787. +
  6788. +#ifndef false
  6789. +#define false 0
  6790. +#endif
  6791. +*/
  6792. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
  6793. +#ifndef bool
  6794. +typedef enum{false = 0, true} bool;
  6795. +#endif
  6796. +#endif
  6797. +//#ifdef JOHN_HWSEC
  6798. +#define KEY_TYPE_NA 0x0
  6799. +#define KEY_TYPE_WEP40 0x1
  6800. +#define KEY_TYPE_TKIP 0x2
  6801. +#define KEY_TYPE_CCMP 0x4
  6802. +#define KEY_TYPE_WEP104 0x5
  6803. +//#endif
  6804. +
  6805. +
  6806. +#define aSifsTime 10
  6807. +
  6808. +#define MGMT_QUEUE_NUM 5
  6809. +
  6810. +
  6811. +#define IEEE_CMD_SET_WPA_PARAM 1
  6812. +#define IEEE_CMD_SET_WPA_IE 2
  6813. +#define IEEE_CMD_SET_ENCRYPTION 3
  6814. +#define IEEE_CMD_MLME 4
  6815. +
  6816. +#define IEEE_PARAM_WPA_ENABLED 1
  6817. +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
  6818. +#define IEEE_PARAM_DROP_UNENCRYPTED 3
  6819. +#define IEEE_PARAM_PRIVACY_INVOKED 4
  6820. +#define IEEE_PARAM_AUTH_ALGS 5
  6821. +#define IEEE_PARAM_IEEE_802_1X 6
  6822. +//It should consistent with the driver_XXX.c
  6823. +// David, 2006.9.26
  6824. +#define IEEE_PARAM_WPAX_SELECT 7
  6825. +//Added for notify the encryption type selection
  6826. +// David, 2006.9.26
  6827. +#define IEEE_PROTO_WPA 1
  6828. +#define IEEE_PROTO_RSN 2
  6829. +//Added for notify the encryption type selection
  6830. +// David, 2006.9.26
  6831. +#define IEEE_WPAX_USEGROUP 0
  6832. +#define IEEE_WPAX_WEP40 1
  6833. +#define IEEE_WPAX_TKIP 2
  6834. +#define IEEE_WPAX_WRAP 3
  6835. +#define IEEE_WPAX_CCMP 4
  6836. +#define IEEE_WPAX_WEP104 5
  6837. +
  6838. +#define IEEE_KEY_MGMT_IEEE8021X 1
  6839. +#define IEEE_KEY_MGMT_PSK 2
  6840. +
  6841. +
  6842. +
  6843. +#define IEEE_MLME_STA_DEAUTH 1
  6844. +#define IEEE_MLME_STA_DISASSOC 2
  6845. +
  6846. +
  6847. +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
  6848. +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
  6849. +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
  6850. +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
  6851. +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
  6852. +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
  6853. +
  6854. +
  6855. +#define IEEE_CRYPT_ALG_NAME_LEN 16
  6856. +
  6857. +//#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
  6858. +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
  6859. +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
  6860. +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
  6861. +////////////////////////////////
  6862. +// added for kernel conflict under FC5
  6863. +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
  6864. +#define free_ieee80211 free_ieee80211_rtl
  6865. +#define alloc_ieee80211 alloc_ieee80211_rtl
  6866. +///////////////////////////////
  6867. +//#endif
  6868. +#define ieee80211_rx ieee80211_rx_rtl
  6869. +#define ieee80211_wake_queue ieee80211_wake_queue_rtl
  6870. +#define ieee80211_stop_queue ieee80211_stop_queue_rtl
  6871. +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
  6872. +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
  6873. +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
  6874. +
  6875. +#define ieee80211_start_scan ieee80211_start_scan_rtl
  6876. +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
  6877. +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
  6878. +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
  6879. +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
  6880. +typedef struct ieee_param {
  6881. + u32 cmd;
  6882. + u8 sta_addr[ETH_ALEN];
  6883. + union {
  6884. + struct {
  6885. + u8 name;
  6886. + u32 value;
  6887. + } wpa_param;
  6888. + struct {
  6889. + u32 len;
  6890. + u8 reserved[32];
  6891. + u8 data[0];
  6892. + } wpa_ie;
  6893. + struct{
  6894. + int command;
  6895. + int reason_code;
  6896. + } mlme;
  6897. + struct {
  6898. + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
  6899. + u8 set_tx;
  6900. + u32 err;
  6901. + u8 idx;
  6902. + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
  6903. + u16 key_len;
  6904. + u8 key[0];
  6905. + } crypt;
  6906. +
  6907. + } u;
  6908. +}ieee_param;
  6909. +
  6910. +
  6911. +#if WIRELESS_EXT < 17
  6912. +#define IW_QUAL_QUAL_INVALID 0x10
  6913. +#define IW_QUAL_LEVEL_INVALID 0x20
  6914. +#define IW_QUAL_NOISE_INVALID 0x40
  6915. +#define IW_QUAL_QUAL_UPDATED 0x1
  6916. +#define IW_QUAL_LEVEL_UPDATED 0x2
  6917. +#define IW_QUAL_NOISE_UPDATED 0x4
  6918. +#endif
  6919. +
  6920. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  6921. +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
  6922. +{
  6923. + task->routine = func;
  6924. + task->data = data;
  6925. + //task->next = NULL;
  6926. + INIT_LIST_HEAD(&task->list);
  6927. + task->sync = 0;
  6928. +}
  6929. +#endif
  6930. +
  6931. +// linux under 2.6.9 release may not support it, so modify it for common use
  6932. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
  6933. +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
  6934. +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
  6935. +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
  6936. +{
  6937. + unsigned long timeout = MSECS(msecs) + 1;
  6938. +
  6939. + while (timeout) {
  6940. + set_current_state(TASK_UNINTERRUPTIBLE);
  6941. + timeout = schedule_timeout(timeout);
  6942. + }
  6943. + return timeout;
  6944. +}
  6945. +#else
  6946. +#define MSECS(t) msecs_to_jiffies(t)
  6947. +#define msleep_interruptible_rtl msleep_interruptible
  6948. +#endif
  6949. +
  6950. +#define IEEE80211_DATA_LEN 2304
  6951. +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
  6952. + 6.2.1.1.2.
  6953. +
  6954. + The figure in section 7.1.2 suggests a body size of up to 2312
  6955. + bytes is allowed, which is a bit confusing, I suspect this
  6956. + represents the 2304 bytes of real data, plus a possible 8 bytes of
  6957. + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
  6958. +
  6959. +
  6960. +#define IEEE80211_HLEN 30
  6961. +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
  6962. +
  6963. +/* this is stolen and modified from the madwifi driver*/
  6964. +#define IEEE80211_FC0_TYPE_MASK 0x0c
  6965. +#define IEEE80211_FC0_TYPE_DATA 0x08
  6966. +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
  6967. +#define IEEE80211_FC0_SUBTYPE_QOS 0x80
  6968. +
  6969. +#define IEEE80211_QOS_HAS_SEQ(fc) \
  6970. + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
  6971. + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
  6972. +
  6973. +/* this is stolen from ipw2200 driver */
  6974. +#define IEEE_IBSS_MAC_HASH_SIZE 31
  6975. +#define IEEE_MESH_MAC_HASH_SIZE 31
  6976. +struct ieee_ibss_seq {
  6977. + u8 mac[ETH_ALEN];
  6978. + u16 seq_num[17];
  6979. + u16 frag_num[17];
  6980. + unsigned long packet_time[17];
  6981. + struct list_head list;
  6982. +};
  6983. +
  6984. +struct ieee_mesh_seq {
  6985. + u8 mac[ETH_ALEN];
  6986. + u16 seq_num;
  6987. + u16 frag_num;
  6988. + unsigned long packet_time;
  6989. + struct list_head list;
  6990. +};
  6991. +
  6992. +struct ieee80211_hdr {
  6993. + u16 frame_ctl;
  6994. + u16 duration_id;
  6995. + u8 addr1[ETH_ALEN];
  6996. + u8 addr2[ETH_ALEN];
  6997. + u8 addr3[ETH_ALEN];
  6998. + u16 seq_ctl;
  6999. + u8 addr4[ETH_ALEN];
  7000. +} __attribute__ ((packed));
  7001. +
  7002. +struct ieee80211_hdr_QOS {
  7003. + u16 frame_ctl;
  7004. + u16 duration_id;
  7005. + u8 addr1[ETH_ALEN];
  7006. + u8 addr2[ETH_ALEN];
  7007. + u8 addr3[ETH_ALEN];
  7008. + u16 seq_ctl;
  7009. + u8 addr4[ETH_ALEN];
  7010. + u16 QOS_ctl;
  7011. +} __attribute__ ((packed));
  7012. +
  7013. +struct ieee80211_hdr_3addr {
  7014. + u16 frame_ctl;
  7015. + u16 duration_id;
  7016. + u8 addr1[ETH_ALEN];
  7017. + u8 addr2[ETH_ALEN];
  7018. + u8 addr3[ETH_ALEN];
  7019. + u16 seq_ctl;
  7020. +} __attribute__ ((packed));
  7021. +
  7022. +struct ieee80211_hdr_3addr_QOS {
  7023. + u16 frame_ctl;
  7024. + u16 duration_id;
  7025. + u8 addr1[ETH_ALEN];
  7026. + u8 addr2[ETH_ALEN];
  7027. + u8 addr3[ETH_ALEN];
  7028. + u16 seq_ctl;
  7029. + u16 QOS_ctl;
  7030. +} __attribute__ ((packed));
  7031. +
  7032. +enum eap_type {
  7033. + EAP_PACKET = 0,
  7034. + EAPOL_START,
  7035. + EAPOL_LOGOFF,
  7036. + EAPOL_KEY,
  7037. + EAPOL_ENCAP_ASF_ALERT
  7038. +};
  7039. +
  7040. +//by lizhaoming for LED 2008.6.23 from r8187_led.h
  7041. +#ifdef LED
  7042. +typedef enum _LED_CTL_MODE {
  7043. + LED_CTL_POWER_ON,
  7044. + LED_CTL_POWER_OFF,
  7045. + LED_CTL_LINK,
  7046. + LED_CTL_NO_LINK,
  7047. + LED_CTL_TX,
  7048. + LED_CTL_RX,
  7049. + LED_CTL_SITE_SURVEY,
  7050. +} LED_CTL_MODE;
  7051. +#endif
  7052. +
  7053. +static const char *eap_types[] = {
  7054. + [EAP_PACKET] = "EAP-Packet",
  7055. + [EAPOL_START] = "EAPOL-Start",
  7056. + [EAPOL_LOGOFF] = "EAPOL-Logoff",
  7057. + [EAPOL_KEY] = "EAPOL-Key",
  7058. + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
  7059. +};
  7060. +
  7061. +static inline const char *eap_get_type(int type)
  7062. +{
  7063. + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
  7064. +}
  7065. +
  7066. +struct eapol {
  7067. + u8 snap[6];
  7068. + u16 ethertype;
  7069. + u8 version;
  7070. + u8 type;
  7071. + u16 length;
  7072. +} __attribute__ ((packed));
  7073. +
  7074. +#define IEEE80211_3ADDR_LEN 24
  7075. +#define IEEE80211_4ADDR_LEN 30
  7076. +#define IEEE80211_FCS_LEN 4
  7077. +
  7078. +#define MIN_FRAG_THRESHOLD 256U
  7079. +#define MAX_FRAG_THRESHOLD 2346U
  7080. +
  7081. +/* Frame control field constants */
  7082. +#define IEEE80211_FCTL_VERS 0x0002
  7083. +#define IEEE80211_FCTL_FTYPE 0x000c
  7084. +#define IEEE80211_FCTL_STYPE 0x00f0
  7085. +#define IEEE80211_FCTL_TODS 0x0100
  7086. +#define IEEE80211_FCTL_FROMDS 0x0200
  7087. +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
  7088. +#define IEEE80211_FCTL_MOREFRAGS 0x0400
  7089. +#define IEEE80211_FCTL_RETRY 0x0800
  7090. +#define IEEE80211_FCTL_PM 0x1000
  7091. +#define IEEE80211_FCTL_MOREDATA 0x2000
  7092. +#define IEEE80211_FCTL_WEP 0x4000
  7093. +#define IEEE80211_FCTL_ORDER 0x8000
  7094. +
  7095. +#define IEEE80211_FTYPE_MGMT 0x0000
  7096. +#define IEEE80211_FTYPE_CTL 0x0004
  7097. +#define IEEE80211_FTYPE_DATA 0x0008
  7098. +
  7099. +/* management */
  7100. +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
  7101. +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
  7102. +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
  7103. +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
  7104. +#define IEEE80211_STYPE_PROBE_REQ 0x0040
  7105. +#define IEEE80211_STYPE_PROBE_RESP 0x0050
  7106. +#define IEEE80211_STYPE_BEACON 0x0080
  7107. +#define IEEE80211_STYPE_ATIM 0x0090
  7108. +#define IEEE80211_STYPE_DISASSOC 0x00A0
  7109. +#define IEEE80211_STYPE_AUTH 0x00B0
  7110. +#define IEEE80211_STYPE_DEAUTH 0x00C0
  7111. +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
  7112. +
  7113. +/* control */
  7114. +#define IEEE80211_STYPE_PSPOLL 0x00A0
  7115. +#define IEEE80211_STYPE_RTS 0x00B0
  7116. +#define IEEE80211_STYPE_CTS 0x00C0
  7117. +#define IEEE80211_STYPE_ACK 0x00D0
  7118. +#define IEEE80211_STYPE_CFEND 0x00E0
  7119. +#define IEEE80211_STYPE_CFENDACK 0x00F0
  7120. +
  7121. +/* data */
  7122. +#define IEEE80211_STYPE_DATA 0x0000
  7123. +#define IEEE80211_STYPE_DATA_CFACK 0x0010
  7124. +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
  7125. +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
  7126. +#define IEEE80211_STYPE_NULLFUNC 0x0040
  7127. +#define IEEE80211_STYPE_CFACK 0x0050
  7128. +#define IEEE80211_STYPE_CFPOLL 0x0060
  7129. +#define IEEE80211_STYPE_CFACKPOLL 0x0070
  7130. +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
  7131. +#define IEEE80211_STYPE_QOS_NULL 0x00C0
  7132. +
  7133. +
  7134. +#define IEEE80211_SCTL_FRAG 0x000F
  7135. +#define IEEE80211_SCTL_SEQ 0xFFF0
  7136. +
  7137. +
  7138. +/* debug macros */
  7139. +
  7140. +#ifdef CONFIG_IEEE80211_DEBUG
  7141. +extern u32 ieee80211_debug_level;
  7142. +#define IEEE80211_DEBUG(level, fmt, args...) \
  7143. +do { if (ieee80211_debug_level & (level)) \
  7144. + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
  7145. + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
  7146. +#else
  7147. +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
  7148. +#endif /* CONFIG_IEEE80211_DEBUG */
  7149. +
  7150. +/*
  7151. + * To use the debug system;
  7152. + *
  7153. + * If you are defining a new debug classification, simply add it to the #define
  7154. + * list here in the form of:
  7155. + *
  7156. + * #define IEEE80211_DL_xxxx VALUE
  7157. + *
  7158. + * shifting value to the left one bit from the previous entry. xxxx should be
  7159. + * the name of the classification (for example, WEP)
  7160. + *
  7161. + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
  7162. + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
  7163. + * to send output to that classification.
  7164. + *
  7165. + * To add your debug level to the list of levels seen when you perform
  7166. + *
  7167. + * % cat /proc/net/ipw/debug_level
  7168. + *
  7169. + * you simply need to add your entry to the ipw_debug_levels array.
  7170. + *
  7171. + * If you do not see debug_level in /proc/net/ipw then you do not have
  7172. + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
  7173. + *
  7174. + */
  7175. +
  7176. +#define IEEE80211_DL_INFO (1<<0)
  7177. +#define IEEE80211_DL_WX (1<<1)
  7178. +#define IEEE80211_DL_SCAN (1<<2)
  7179. +#define IEEE80211_DL_STATE (1<<3)
  7180. +#define IEEE80211_DL_MGMT (1<<4)
  7181. +#define IEEE80211_DL_FRAG (1<<5)
  7182. +#define IEEE80211_DL_EAP (1<<6)
  7183. +#define IEEE80211_DL_DROP (1<<7)
  7184. +
  7185. +#define IEEE80211_DL_TX (1<<8)
  7186. +#define IEEE80211_DL_RX (1<<9)
  7187. +
  7188. +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
  7189. +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
  7190. +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
  7191. +
  7192. +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
  7193. +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
  7194. +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
  7195. +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
  7196. +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
  7197. +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
  7198. +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
  7199. +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
  7200. +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
  7201. +#include <linux/netdevice.h>
  7202. +#include <linux/wireless.h>
  7203. +#include <linux/if_arp.h> /* ARPHRD_ETHER */
  7204. +
  7205. +#ifndef WIRELESS_SPY
  7206. +#define WIRELESS_SPY // enable iwspy support
  7207. +#endif
  7208. +#include <net/iw_handler.h> // new driver API
  7209. +
  7210. +#ifndef ETH_P_PAE
  7211. +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
  7212. +#endif /* ETH_P_PAE */
  7213. +
  7214. +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
  7215. +
  7216. +#ifndef ETH_P_80211_RAW
  7217. +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
  7218. +#endif
  7219. +
  7220. +/* IEEE 802.11 defines */
  7221. +
  7222. +#define P80211_OUI_LEN 3
  7223. +
  7224. +struct ieee80211_snap_hdr {
  7225. +
  7226. + u8 dsap; /* always 0xAA */
  7227. + u8 ssap; /* always 0xAA */
  7228. + u8 ctrl; /* always 0x03 */
  7229. + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
  7230. +
  7231. +} __attribute__ ((packed));
  7232. +
  7233. +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
  7234. +
  7235. +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
  7236. +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
  7237. +
  7238. +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
  7239. +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
  7240. +
  7241. +/* Authentication algorithms */
  7242. +#define WLAN_AUTH_OPEN 0
  7243. +#define WLAN_AUTH_SHARED_KEY 1
  7244. +
  7245. +#define WLAN_AUTH_CHALLENGE_LEN 128
  7246. +
  7247. +#define WLAN_CAPABILITY_BSS (1<<0)
  7248. +#define WLAN_CAPABILITY_IBSS (1<<1)
  7249. +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
  7250. +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
  7251. +#define WLAN_CAPABILITY_PRIVACY (1<<4)
  7252. +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
  7253. +#define WLAN_CAPABILITY_PBCC (1<<6)
  7254. +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
  7255. +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
  7256. +
  7257. +/* Status codes */
  7258. +#define WLAN_STATUS_SUCCESS 0
  7259. +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
  7260. +#define WLAN_STATUS_CAPS_UNSUPPORTED 10
  7261. +#define WLAN_STATUS_REASSOC_NO_ASSOC 11
  7262. +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
  7263. +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
  7264. +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
  7265. +#define WLAN_STATUS_CHALLENGE_FAIL 15
  7266. +#define WLAN_STATUS_AUTH_TIMEOUT 16
  7267. +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
  7268. +#define WLAN_STATUS_ASSOC_DENIED_RATES 18
  7269. +/* 802.11b */
  7270. +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
  7271. +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
  7272. +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
  7273. +
  7274. +/* Reason codes */
  7275. +#define WLAN_REASON_UNSPECIFIED 1
  7276. +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
  7277. +#define WLAN_REASON_DEAUTH_LEAVING 3
  7278. +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
  7279. +#define WLAN_REASON_DISASSOC_AP_BUSY 5
  7280. +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
  7281. +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
  7282. +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
  7283. +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
  7284. +
  7285. +
  7286. +/* Information Element IDs */
  7287. +#define WLAN_EID_SSID 0
  7288. +#define WLAN_EID_SUPP_RATES 1
  7289. +#define WLAN_EID_FH_PARAMS 2
  7290. +#define WLAN_EID_DS_PARAMS 3
  7291. +#define WLAN_EID_CF_PARAMS 4
  7292. +#define WLAN_EID_TIM 5
  7293. +#define WLAN_EID_IBSS_PARAMS 6
  7294. +#define WLAN_EID_CHALLENGE 16
  7295. +#define WLAN_EID_RSN 48
  7296. +#define WLAN_EID_GENERIC 221
  7297. +
  7298. +#define IEEE80211_MGMT_HDR_LEN 24
  7299. +#define IEEE80211_DATA_HDR3_LEN 24
  7300. +#define IEEE80211_DATA_HDR4_LEN 30
  7301. +
  7302. +
  7303. +#define IEEE80211_STATMASK_SIGNAL (1<<0)
  7304. +#define IEEE80211_STATMASK_RSSI (1<<1)
  7305. +#define IEEE80211_STATMASK_NOISE (1<<2)
  7306. +#define IEEE80211_STATMASK_RATE (1<<3)
  7307. +#define IEEE80211_STATMASK_WEMASK 0x7
  7308. +
  7309. +
  7310. +#define IEEE80211_CCK_MODULATION (1<<0)
  7311. +#define IEEE80211_OFDM_MODULATION (1<<1)
  7312. +
  7313. +#define IEEE80211_24GHZ_BAND (1<<0)
  7314. +#define IEEE80211_52GHZ_BAND (1<<1)
  7315. +
  7316. +#define IEEE80211_CCK_RATE_LEN 4
  7317. +#define IEEE80211_CCK_RATE_1MB 0x02
  7318. +#define IEEE80211_CCK_RATE_2MB 0x04
  7319. +#define IEEE80211_CCK_RATE_5MB 0x0B
  7320. +#define IEEE80211_CCK_RATE_11MB 0x16
  7321. +#define IEEE80211_OFDM_RATE_LEN 8
  7322. +#define IEEE80211_OFDM_RATE_6MB 0x0C
  7323. +#define IEEE80211_OFDM_RATE_9MB 0x12
  7324. +#define IEEE80211_OFDM_RATE_12MB 0x18
  7325. +#define IEEE80211_OFDM_RATE_18MB 0x24
  7326. +#define IEEE80211_OFDM_RATE_24MB 0x30
  7327. +#define IEEE80211_OFDM_RATE_36MB 0x48
  7328. +#define IEEE80211_OFDM_RATE_48MB 0x60
  7329. +#define IEEE80211_OFDM_RATE_54MB 0x6C
  7330. +#define IEEE80211_BASIC_RATE_MASK 0x80
  7331. +
  7332. +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
  7333. +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
  7334. +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
  7335. +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
  7336. +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
  7337. +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
  7338. +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
  7339. +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
  7340. +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
  7341. +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
  7342. +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
  7343. +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
  7344. +
  7345. +#define IEEE80211_CCK_RATES_MASK 0x0000000F
  7346. +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
  7347. + IEEE80211_CCK_RATE_2MB_MASK)
  7348. +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
  7349. + IEEE80211_CCK_RATE_5MB_MASK | \
  7350. + IEEE80211_CCK_RATE_11MB_MASK)
  7351. +
  7352. +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
  7353. +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
  7354. + IEEE80211_OFDM_RATE_12MB_MASK | \
  7355. + IEEE80211_OFDM_RATE_24MB_MASK)
  7356. +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
  7357. + IEEE80211_OFDM_RATE_9MB_MASK | \
  7358. + IEEE80211_OFDM_RATE_18MB_MASK | \
  7359. + IEEE80211_OFDM_RATE_36MB_MASK | \
  7360. + IEEE80211_OFDM_RATE_48MB_MASK | \
  7361. + IEEE80211_OFDM_RATE_54MB_MASK)
  7362. +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
  7363. + IEEE80211_CCK_DEFAULT_RATES_MASK)
  7364. +
  7365. +#define IEEE80211_NUM_OFDM_RATES 8
  7366. +#define IEEE80211_NUM_CCK_RATES 4
  7367. +#define IEEE80211_OFDM_SHIFT_MASK_A 4
  7368. +
  7369. +
  7370. +
  7371. +
  7372. +/* NOTE: This data is for statistical purposes; not all hardware provides this
  7373. + * information for frames received. Not setting these will not cause
  7374. + * any adverse affects. */
  7375. +struct ieee80211_rx_stats {
  7376. + u32 mac_time[2];
  7377. + u8 signalstrength;
  7378. + s8 rssi;
  7379. + u8 signal;
  7380. + u8 noise;
  7381. + u16 rate; /* in 100 kbps */
  7382. + u8 received_channel;
  7383. + u8 control;
  7384. + u8 mask;
  7385. + u8 freq;
  7386. + u16 len;
  7387. + u8 nic_type;
  7388. +};
  7389. +
  7390. +/* IEEE 802.11 requires that STA supports concurrent reception of at least
  7391. + * three fragmented frames. This define can be increased to support more
  7392. + * concurrent frames, but it should be noted that each entry can consume about
  7393. + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
  7394. +#define IEEE80211_FRAG_CACHE_LEN 4
  7395. +
  7396. +struct ieee80211_frag_entry {
  7397. + unsigned long first_frag_time;
  7398. + unsigned int seq;
  7399. + unsigned int last_frag;
  7400. + struct sk_buff *skb;
  7401. + u8 src_addr[ETH_ALEN];
  7402. + u8 dst_addr[ETH_ALEN];
  7403. +};
  7404. +
  7405. +struct ieee80211_stats {
  7406. + unsigned int tx_unicast_frames;
  7407. + unsigned int tx_multicast_frames;
  7408. + unsigned int tx_fragments;
  7409. + unsigned int tx_unicast_octets;
  7410. + unsigned int tx_multicast_octets;
  7411. + unsigned int tx_deferred_transmissions;
  7412. + unsigned int tx_single_retry_frames;
  7413. + unsigned int tx_multiple_retry_frames;
  7414. + unsigned int tx_retry_limit_exceeded;
  7415. + unsigned int tx_discards;
  7416. + unsigned int rx_unicast_frames;
  7417. + unsigned int rx_multicast_frames;
  7418. + unsigned int rx_fragments;
  7419. + unsigned int rx_unicast_octets;
  7420. + unsigned int rx_multicast_octets;
  7421. + unsigned int rx_fcs_errors;
  7422. + unsigned int rx_discards_no_buffer;
  7423. + unsigned int tx_discards_wrong_sa;
  7424. + unsigned int rx_discards_undecryptable;
  7425. + unsigned int rx_message_in_msg_fragments;
  7426. + unsigned int rx_message_in_bad_msg_fragments;
  7427. +};
  7428. +
  7429. +struct ieee80211_softmac_stats{
  7430. + unsigned int rx_ass_ok;
  7431. + unsigned int rx_ass_err;
  7432. + unsigned int rx_probe_rq;
  7433. + unsigned int tx_probe_rs;
  7434. + unsigned int tx_beacons;
  7435. + unsigned int rx_auth_rq;
  7436. + unsigned int rx_auth_rs_ok;
  7437. + unsigned int rx_auth_rs_err;
  7438. + unsigned int tx_auth_rq;
  7439. + unsigned int no_auth_rs;
  7440. + unsigned int no_ass_rs;
  7441. + unsigned int tx_ass_rq;
  7442. + unsigned int rx_ass_rq;
  7443. + unsigned int tx_probe_rq;
  7444. + unsigned int reassoc;
  7445. + unsigned int swtxstop;
  7446. + unsigned int swtxawake;
  7447. +};
  7448. +
  7449. +struct ieee80211_device;
  7450. +
  7451. +#include "ieee80211_crypt.h"
  7452. +
  7453. +#define SEC_KEY_1 (1<<0)
  7454. +#define SEC_KEY_2 (1<<1)
  7455. +#define SEC_KEY_3 (1<<2)
  7456. +#define SEC_KEY_4 (1<<3)
  7457. +#define SEC_ACTIVE_KEY (1<<4)
  7458. +#define SEC_AUTH_MODE (1<<5)
  7459. +#define SEC_UNICAST_GROUP (1<<6)
  7460. +#define SEC_LEVEL (1<<7)
  7461. +#define SEC_ENABLED (1<<8)
  7462. +
  7463. +#define SEC_LEVEL_0 0 /* None */
  7464. +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
  7465. +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
  7466. +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
  7467. +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
  7468. +
  7469. +#define WEP_KEYS 4
  7470. +#define WEP_KEY_LEN 13
  7471. +#define ALG_KEY_LEN 32
  7472. +
  7473. +#ifdef _RTL8187_EXT_PATCH_
  7474. +#define MAX_MP 16
  7475. +#endif
  7476. +struct ieee80211_security {
  7477. + u16 active_key:2,
  7478. + enabled:1,
  7479. + auth_mode:2,
  7480. + auth_algo:4,
  7481. + unicast_uses_group:1;
  7482. + u8 key_sizes[WEP_KEYS];
  7483. + u8 keys[WEP_KEYS][ALG_KEY_LEN];
  7484. + u8 level;
  7485. + u16 flags;
  7486. +} __attribute__ ((packed));
  7487. +
  7488. +
  7489. +/*
  7490. +
  7491. + 802.11 data frame from AP
  7492. +
  7493. + ,-------------------------------------------------------------------.
  7494. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
  7495. + |------|------|---------|---------|---------|------|---------|------|
  7496. +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
  7497. + | | tion | (BSSID) | | | ence | data | |
  7498. + `-------------------------------------------------------------------'
  7499. +
  7500. +Total: 28-2340 bytes
  7501. +
  7502. +*/
  7503. +
  7504. +struct ieee80211_header_data {
  7505. + u16 frame_ctl;
  7506. + u16 duration_id;
  7507. + u8 addr1[6];
  7508. + u8 addr2[6];
  7509. + u8 addr3[6];
  7510. + u16 seq_ctrl;
  7511. +};
  7512. +
  7513. +#define BEACON_PROBE_SSID_ID_POSITION 12
  7514. +
  7515. +/* Management Frame Information Element Types */
  7516. +#define MFIE_TYPE_SSID 0
  7517. +#define MFIE_TYPE_RATES 1
  7518. +#define MFIE_TYPE_FH_SET 2
  7519. +#define MFIE_TYPE_DS_SET 3
  7520. +#define MFIE_TYPE_CF_SET 4
  7521. +#define MFIE_TYPE_TIM 5
  7522. +#define MFIE_TYPE_IBSS_SET 6
  7523. +#define MFIE_TYPE_COUNTRY 7
  7524. +#define MFIE_TYPE_CHALLENGE 16
  7525. +#define MFIE_TYPE_ERP 42
  7526. +#define MFIE_TYPE_RSN 48
  7527. +#define MFIE_TYPE_RATES_EX 50
  7528. +#define MFIE_TYPE_GENERIC 221
  7529. +
  7530. +#ifdef ENABLE_DOT11D
  7531. +typedef enum
  7532. +{
  7533. + COUNTRY_CODE_FCC = 0,
  7534. + COUNTRY_CODE_IC = 1,
  7535. + COUNTRY_CODE_ETSI = 2,
  7536. + COUNTRY_CODE_SPAIN = 3,
  7537. + COUNTRY_CODE_FRANCE = 4,
  7538. + COUNTRY_CODE_MKK = 5,
  7539. + COUNTRY_CODE_MKK1 = 6,
  7540. + COUNTRY_CODE_ISRAEL = 7,
  7541. + COUNTRY_CODE_TELEC = 8,
  7542. + COUNTRY_CODE_GLOBAL_DOMAIN = 9,
  7543. + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
  7544. +}country_code_type_t;
  7545. +#endif
  7546. +
  7547. +
  7548. +struct ieee80211_info_element_hdr {
  7549. + u8 id;
  7550. + u8 len;
  7551. +} __attribute__ ((packed));
  7552. +
  7553. +struct ieee80211_info_element {
  7554. + u8 id;
  7555. + u8 len;
  7556. + u8 data[0];
  7557. +} __attribute__ ((packed));
  7558. +
  7559. +/*
  7560. + * These are the data types that can make up management packets
  7561. + *
  7562. + u16 auth_algorithm;
  7563. + u16 auth_sequence;
  7564. + u16 beacon_interval;
  7565. + u16 capability;
  7566. + u8 current_ap[ETH_ALEN];
  7567. + u16 listen_interval;
  7568. + struct {
  7569. + u16 association_id:14, reserved:2;
  7570. + } __attribute__ ((packed));
  7571. + u32 time_stamp[2];
  7572. + u16 reason;
  7573. + u16 status;
  7574. +*/
  7575. +
  7576. +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
  7577. +#define IEEE80211_DEFAULT_BASIC_RATE 10
  7578. +#define IEEE80211_DEFAULT_MESHID "802.11s"
  7579. +#define IEEE80211_DEFAULT_MESH_CHAN 1
  7580. +
  7581. +struct ieee80211_authentication {
  7582. + struct ieee80211_header_data header;
  7583. + u16 algorithm;
  7584. + u16 transaction;
  7585. + u16 status;
  7586. + //struct ieee80211_info_element_hdr info_element;
  7587. +} __attribute__ ((packed));
  7588. +
  7589. +
  7590. +struct ieee80211_probe_response {
  7591. + struct ieee80211_header_data header;
  7592. + u32 time_stamp[2];
  7593. + u16 beacon_interval;
  7594. + u16 capability;
  7595. + struct ieee80211_info_element info_element;
  7596. +} __attribute__ ((packed));
  7597. +
  7598. +struct ieee80211_probe_request {
  7599. + struct ieee80211_header_data header;
  7600. + /*struct ieee80211_info_element info_element;*/
  7601. +} __attribute__ ((packed));
  7602. +
  7603. +struct ieee80211_assoc_request_frame {
  7604. + struct ieee80211_hdr_3addr header;
  7605. + u16 capability;
  7606. + u16 listen_interval;
  7607. + //u8 current_ap[ETH_ALEN];
  7608. + struct ieee80211_info_element_hdr info_element;
  7609. +} __attribute__ ((packed));
  7610. +
  7611. +struct ieee80211_assoc_response_frame {
  7612. + struct ieee80211_hdr_3addr header;
  7613. + u16 capability;
  7614. + u16 status;
  7615. + u16 aid;
  7616. + struct ieee80211_info_element info_element; /* supported rates */
  7617. +} __attribute__ ((packed));
  7618. +
  7619. +
  7620. +struct ieee80211_txb {
  7621. + u8 nr_frags;
  7622. + u8 encrypted;
  7623. + u16 reserved;
  7624. + u16 frag_size;
  7625. + u16 payload_size;
  7626. + struct sk_buff *fragments[0];
  7627. +};
  7628. +
  7629. +struct ieee80211_wmm_ac_param {
  7630. + u8 ac_aci_acm_aifsn;
  7631. + u8 ac_ecwmin_ecwmax;
  7632. + u16 ac_txop_limit;
  7633. +};
  7634. +
  7635. +struct ieee80211_wmm_ts_info {
  7636. + u8 ac_dir_tid;
  7637. + u8 ac_up_psb;
  7638. + u8 reserved;
  7639. +} __attribute__ ((packed));
  7640. +
  7641. +struct ieee80211_wmm_tspec_elem {
  7642. + struct ieee80211_wmm_ts_info ts_info;
  7643. + u16 norm_msdu_size;
  7644. + u16 max_msdu_size;
  7645. + u32 min_serv_inter;
  7646. + u32 max_serv_inter;
  7647. + u32 inact_inter;
  7648. + u32 suspen_inter;
  7649. + u32 serv_start_time;
  7650. + u32 min_data_rate;
  7651. + u32 mean_data_rate;
  7652. + u32 peak_data_rate;
  7653. + u32 max_burst_size;
  7654. + u32 delay_bound;
  7655. + u32 min_phy_rate;
  7656. + u16 surp_band_allow;
  7657. + u16 medium_time;
  7658. +}__attribute__((packed));
  7659. +
  7660. +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
  7661. +#define MAX_SP_Len (WMM_all_frame << 4)
  7662. +#define IEEE80211_QOS_TID 0x0f
  7663. +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
  7664. +
  7665. +/* SWEEP TABLE ENTRIES NUMBER*/
  7666. +#define MAX_SWEEP_TAB_ENTRIES 42
  7667. +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
  7668. +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
  7669. + * only use 8, and then use extended rates for the remaining supported
  7670. + * rates. Other APs, however, stick all of their supported rates on the
  7671. + * main rates information element... */
  7672. +#define MAX_RATES_LENGTH ((u8)12)
  7673. +#define MAX_RATES_EX_LENGTH ((u8)16)
  7674. +#define MAX_NETWORK_COUNT 128
  7675. +#ifdef ENABLE_DOT11D
  7676. +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
  7677. +#define MAX_IE_LEN 0xFF //+YJ,080625
  7678. +#else
  7679. +#define MAX_CHANNEL_NUMBER 161
  7680. +#endif
  7681. +
  7682. +//#define IEEE80211_SOFTMAC_SCAN_TIME 400
  7683. +#define IEEE80211_SOFTMAC_SCAN_TIME 100//lzm mod 081209
  7684. +//(HZ / 2)
  7685. +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
  7686. +
  7687. +#define CRC_LENGTH 4U
  7688. +
  7689. +#define MAX_WPA_IE_LEN 64
  7690. +
  7691. +#define NETWORK_EMPTY_ESSID (1<<0)
  7692. +#define NETWORK_HAS_OFDM (1<<1)
  7693. +#define NETWORK_HAS_CCK (1<<2)
  7694. +
  7695. +#define IEEE80211_DTIM_MBCAST 4
  7696. +#define IEEE80211_DTIM_UCAST 2
  7697. +#define IEEE80211_DTIM_VALID 1
  7698. +#define IEEE80211_DTIM_INVALID 0
  7699. +
  7700. +#define IEEE80211_PS_DISABLED 0
  7701. +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
  7702. +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
  7703. +
  7704. +//added by David for QoS 2006/6/30
  7705. +//#define WMM_Hang_8187
  7706. +#ifdef WMM_Hang_8187
  7707. +#undef WMM_Hang_8187
  7708. +#endif
  7709. +
  7710. +#define WME_AC_BE 0x00
  7711. +#define WME_AC_BK 0x01
  7712. +#define WME_AC_VI 0x02
  7713. +#define WME_AC_VO 0x03
  7714. +#define WME_ACI_MASK 0x03
  7715. +#define WME_AIFSN_MASK 0x03
  7716. +#define WME_AC_PRAM_LEN 16
  7717. +
  7718. +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
  7719. +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
  7720. +#define UP2AC(up) ( \
  7721. + ((up) < 1) ? WME_AC_BE : \
  7722. + ((up) < 3) ? WME_AC_BK : \
  7723. + ((up) < 4) ? WME_AC_BE : \
  7724. + ((up) < 6) ? WME_AC_VI : \
  7725. + WME_AC_VO)
  7726. +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
  7727. +#define AC2UP(_ac) ( \
  7728. + ((_ac) == WME_AC_VO) ? 6 : \
  7729. + ((_ac) == WME_AC_VI) ? 5 : \
  7730. + ((_ac) == WME_AC_BK) ? 1 : \
  7731. + 0)
  7732. +
  7733. +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
  7734. +struct ether_header {
  7735. + u8 ether_dhost[ETHER_ADDR_LEN];
  7736. + u8 ether_shost[ETHER_ADDR_LEN];
  7737. + u16 ether_type;
  7738. +} __attribute__((packed));
  7739. +
  7740. +#ifndef ETHERTYPE_PAE
  7741. +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
  7742. +#endif
  7743. +#ifndef ETHERTYPE_IP
  7744. +#define ETHERTYPE_IP 0x0800 /* IP protocol */
  7745. +#endif
  7746. +
  7747. +struct ieee80211_network {
  7748. + /* These entries are used to identify a unique network */
  7749. + u8 bssid[ETH_ALEN];
  7750. + u8 channel;
  7751. + /* Ensure null-terminated for any debug msgs */
  7752. + u8 ssid[IW_ESSID_MAX_SIZE + 1];
  7753. + u8 ssid_len;
  7754. +
  7755. + /* These are network statistics */
  7756. + struct ieee80211_rx_stats stats;
  7757. + u16 capability;
  7758. + u8 rates[MAX_RATES_LENGTH];
  7759. + u8 rates_len;
  7760. + u8 rates_ex[MAX_RATES_EX_LENGTH];
  7761. + u8 rates_ex_len;
  7762. + unsigned long last_scanned;
  7763. + u8 mode;
  7764. + u8 flags;
  7765. + u32 last_associate;
  7766. + u32 time_stamp[2];
  7767. + u16 beacon_interval;
  7768. + u16 listen_interval;
  7769. + u16 atim_window;
  7770. + u8 wpa_ie[MAX_WPA_IE_LEN];
  7771. + size_t wpa_ie_len;
  7772. + u8 rsn_ie[MAX_WPA_IE_LEN];
  7773. + size_t rsn_ie_len;
  7774. + u8 dtim_period;
  7775. + u8 dtim_data;
  7776. + u32 last_dtim_sta_time[2];
  7777. +#ifdef _RTL8187_EXT_PATCH_
  7778. + void *ext_entry;
  7779. +#endif
  7780. + struct list_head list;
  7781. + //appeded for QoS
  7782. + u8 wmm_info;
  7783. + struct ieee80211_wmm_ac_param wmm_param[4];
  7784. + u8 QoS_Enable;
  7785. + u8 SignalStrength;
  7786. +#ifdef THOMAS_TURBO
  7787. + u8 Turbo_Enable;//enable turbo mode, added by thomas
  7788. +#endif
  7789. +
  7790. +#ifdef ENABLE_DOT11D
  7791. + u16 CountryIeLen;
  7792. + u8 CountryIeBuf[MAX_IE_LEN];
  7793. +#endif
  7794. +
  7795. +};
  7796. +
  7797. +enum ieee80211_state {
  7798. +
  7799. + /* the card is not linked at all */
  7800. + IEEE80211_NOLINK = 0,
  7801. +
  7802. + /* IEEE80211_ASSOCIATING* are for BSS client mode
  7803. + * the driver shall not perform RX filtering unless
  7804. + * the state is LINKED.
  7805. + * The driver shall just check for the state LINKED and
  7806. + * defaults to NOLINK for ALL the other states (including
  7807. + * LINKED_SCANNING)
  7808. + */
  7809. +
  7810. + /* the association procedure will start (wq scheduling)*/
  7811. + IEEE80211_ASSOCIATING,
  7812. + IEEE80211_ASSOCIATING_RETRY,
  7813. +
  7814. + /* the association procedure is sending AUTH request*/
  7815. + IEEE80211_ASSOCIATING_AUTHENTICATING,
  7816. +
  7817. + /* the association procedure has successfully authentcated
  7818. + * and is sending association request
  7819. + */
  7820. + IEEE80211_ASSOCIATING_AUTHENTICATED,
  7821. +
  7822. + /* the link is ok. the card associated to a BSS or linked
  7823. + * to a ibss cell or acting as an AP and creating the bss
  7824. + */
  7825. + IEEE80211_LINKED,
  7826. +
  7827. + /* same as LINKED, but the driver shall apply RX filter
  7828. + * rules as we are in NO_LINK mode. As the card is still
  7829. + * logically linked, but it is doing a syncro site survey
  7830. + * then it will be back to LINKED state.
  7831. + */
  7832. + IEEE80211_LINKED_SCANNING,
  7833. +//by amy for mesh
  7834. + IEEE80211_MESH_SCANNING,
  7835. + IEEE80211_MESH_LINKED,
  7836. +//by amy for mesh
  7837. +
  7838. +};
  7839. +
  7840. +#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
  7841. +#define DEFAULT_FTS 2346
  7842. +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
  7843. +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
  7844. +
  7845. +
  7846. +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
  7847. +extern inline int is_multicast_ether_addr(const u8 *addr)
  7848. +{
  7849. + return ((addr[0] != 0xff) && (0x01 & addr[0]));
  7850. +}
  7851. +#endif
  7852. +
  7853. +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
  7854. +extern inline int is_broadcast_ether_addr(const u8 *addr)
  7855. +{
  7856. + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
  7857. + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
  7858. +}
  7859. +#endif
  7860. +
  7861. +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
  7862. +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
  7863. +
  7864. +typedef struct tx_pending_t{
  7865. + int frag;
  7866. + struct ieee80211_txb *txb;
  7867. +}tx_pending_t;
  7868. +
  7869. +#ifdef _RTL8187_EXT_PATCH_
  7870. +struct ieee80211_crypt_data_list{
  7871. + u8 used;
  7872. + u8 mac_addr[ETH_ALEN]; //record mac_add
  7873. + struct ieee80211_crypt_data *crypt[WEP_KEYS];
  7874. +}__attribute__((packed));
  7875. +
  7876. +#endif
  7877. +
  7878. +struct ieee80211_device {
  7879. + struct net_device *dev;
  7880. +
  7881. + /* Bookkeeping structures */
  7882. + struct net_device_stats stats;
  7883. + struct ieee80211_stats ieee_stats;
  7884. + struct ieee80211_softmac_stats softmac_stats;
  7885. +
  7886. + /* Probe / Beacon management */
  7887. + struct list_head network_free_list;
  7888. + struct list_head network_list;
  7889. + struct ieee80211_network *networks;
  7890. + int scans;
  7891. + int scan_age;
  7892. +
  7893. + int iw_mode; /* operating mode (IW_MODE_*) */
  7894. +#ifdef _RTL8187_EXT_PATCH_
  7895. + int iw_ext_mode; // if iw_mode == iw_ext_mode, do ext_patch_**();
  7896. +#endif
  7897. +
  7898. + spinlock_t lock;
  7899. + spinlock_t wpax_suitlist_lock;
  7900. +
  7901. + int tx_headroom; /* Set to size of any additional room needed at front
  7902. + * of allocated Tx SKBs */
  7903. + u32 config;
  7904. +
  7905. + /* WEP and other encryption related settings at the device level */
  7906. + int open_wep; /* Set to 1 to allow unencrypted frames */
  7907. +
  7908. + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
  7909. + * WEP key changes */
  7910. +
  7911. + /* If the host performs {en,de}cryption, then set to 1 */
  7912. + int host_encrypt;
  7913. + int host_decrypt;
  7914. + int ieee802_1x; /* is IEEE 802.1X used */
  7915. +
  7916. + /* WPA data */
  7917. + int wpa_enabled;
  7918. + int drop_unencrypted;
  7919. + int tkip_countermeasures;
  7920. + int privacy_invoked;
  7921. + size_t wpa_ie_len;
  7922. + u8 *wpa_ie;
  7923. +
  7924. +//#ifdef JOHN_TKIP
  7925. + u8 ap_mac_addr[6];
  7926. + u16 pairwise_key_type;
  7927. + u16 broadcast_key_type;
  7928. +//#endif
  7929. + struct list_head crypt_deinit_list;
  7930. +#ifdef _RTL8187_EXT_PATCH_
  7931. + struct ieee80211_crypt_data_list* cryptlist[MAX_MP];
  7932. +#else
  7933. + struct ieee80211_crypt_data *crypt[WEP_KEYS];
  7934. +#endif
  7935. + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
  7936. + struct timer_list crypt_deinit_timer;
  7937. +
  7938. + int bcrx_sta_key; /* use individual keys to override default keys even
  7939. + * with RX of broad/multicast frames */
  7940. +
  7941. + /* Fragmentation structures */
  7942. + // each streaming contain a entry
  7943. + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
  7944. + unsigned int frag_next_idx[17];
  7945. + u16 fts; /* Fragmentation Threshold */
  7946. +
  7947. + /* This stores infos for the current network.
  7948. + * Either the network we are associated in INFRASTRUCTURE
  7949. + * or the network that we are creating in MASTER mode.
  7950. + * ad-hoc is a mixture ;-).
  7951. + * Note that in infrastructure mode, even when not associated,
  7952. + * fields bssid and essid may be valid (if wpa_set and essid_set
  7953. + * are true) as thy carry the value set by the user via iwconfig
  7954. + */
  7955. + struct ieee80211_network current_network;
  7956. +
  7957. +
  7958. + enum ieee80211_state state;
  7959. +
  7960. + int short_slot;
  7961. + int mode; /* A, B, G */
  7962. + int modulation; /* CCK, OFDM */
  7963. + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
  7964. + int abg_true; /* ABG flag */
  7965. +
  7966. + /* used for forcing the ibss workqueue to terminate
  7967. + * without wait for the syncro scan to terminate
  7968. + */
  7969. + short sync_scan_hurryup;
  7970. +
  7971. +#ifdef ENABLE_DOT11D
  7972. + void * pDot11dInfo;
  7973. + bool bGlobalDomain;
  7974. + bool bWorldWide13;//lzm add 20081205
  7975. +
  7976. + // For Liteon Ch12~13 passive scan
  7977. + u8 MinPassiveChnlNum;
  7978. + u8 IbssStartChnl;
  7979. +#else
  7980. + /* map of allowed channels. 0 is dummy */
  7981. + // FIXME: remeber to default to a basic channel plan depending of the PHY type
  7982. + int channel_map[MAX_CHANNEL_NUMBER+1];
  7983. +#endif
  7984. +
  7985. + int rate; /* current rate */
  7986. + int basic_rate;
  7987. + //FIXME: pleace callback, see if redundant with softmac_features
  7988. + short active_scan;
  7989. +
  7990. +#ifdef _RTL8187_EXT_PATCH_
  7991. +// short ch_lock;
  7992. + short meshScanMode;
  7993. +#endif
  7994. + /* this contains flags for selectively enable softmac support */
  7995. + u16 softmac_features;
  7996. +
  7997. + /* if the sequence control field is not filled by HW */
  7998. + u16 seq_ctrl[5];
  7999. +
  8000. + /* association procedure transaction sequence number */
  8001. + u16 associate_seq;
  8002. +
  8003. + /* AID for RTXed association responses */
  8004. + u16 assoc_id;
  8005. +
  8006. + /* power save mode related*/
  8007. + short ps;
  8008. + short sta_sleep;
  8009. + int ps_timeout;
  8010. + struct tasklet_struct ps_task;
  8011. + u32 ps_th;
  8012. + u32 ps_tl;
  8013. +
  8014. + short raw_tx;
  8015. + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
  8016. + short queue_stop;
  8017. + short scanning;
  8018. + short scan_watchdog;//lzm add 081215 for roaming
  8019. + short proto_started;
  8020. +
  8021. + struct semaphore wx_sem;
  8022. + struct semaphore scan_sem;
  8023. + struct semaphore ips_sem;
  8024. + spinlock_t mgmt_tx_lock;
  8025. + spinlock_t beacon_lock;
  8026. + spinlock_t beaconflag_lock;
  8027. + short beacon_txing;
  8028. +
  8029. + short wap_set;
  8030. + short ssid_set;
  8031. +
  8032. + u8 wpax_type_set; //{added by David, 2006.9.28}
  8033. + u32 wpax_type_notify; //{added by David, 2006.9.26}
  8034. +
  8035. + /* QoS related flag */
  8036. + char init_wmmparam_flag;
  8037. +
  8038. + /* for discarding duplicated packets in IBSS */
  8039. + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
  8040. +
  8041. + /* for discarding duplicated packets in Mesh */ //added by david 2008.2.28/
  8042. + struct list_head mesh_mac_hash[IEEE_MESH_MAC_HASH_SIZE];
  8043. +
  8044. + /* for discarding duplicated packets in BSS */
  8045. + u16 last_rxseq_num[17]; /* rx seq previous per-tid */
  8046. + u16 last_rxfrag_num[17];/* tx frag previous per-tid */
  8047. + unsigned long last_packet_time[17];
  8048. +
  8049. + /* for PS mode */
  8050. + unsigned long last_rx_ps_time;
  8051. +
  8052. + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
  8053. + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
  8054. + int mgmt_queue_head;
  8055. + int mgmt_queue_tail;
  8056. +//by amy for ps
  8057. + bool bInactivePs;
  8058. + bool actscanning;
  8059. + u16 ListenInterval;
  8060. + u32 NumRxData;
  8061. + unsigned long NumRxDataInPeriod; //YJ,add,080828
  8062. + unsigned long NumRxBcnInPeriod; //YJ,add,080828
  8063. +//by amy for ps
  8064. + short meshid_set;
  8065. + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
  8066. + struct tx_pending_t tx_pending;
  8067. +
  8068. + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
  8069. + struct timer_list associate_timer;
  8070. +
  8071. + /* used if IEEE_SOFTMAC_BEACONS is set */
  8072. + struct timer_list beacon_timer;
  8073. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  8074. + struct work_struct associate_complete_wq;
  8075. +// struct work_struct associate_retry_wq;
  8076. +// struct work_struct start_ibss_wq;
  8077. + struct work_struct associate_procedure_wq;
  8078. + struct work_struct ips_leave_wq; //YJ,add,081230,for IPS
  8079. + bool bHwRadioOff;//by lizhaoming
  8080. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  8081. + struct delayed_work softmac_scan_wq;
  8082. + struct delayed_work start_ibss_wq;
  8083. + struct delayed_work associate_retry_wq;
  8084. +//by amy for rate adaptive
  8085. + struct delayed_work rate_adapter_wq;
  8086. +//by amy for rate adaptive
  8087. + struct delayed_work watch_dog_wq;
  8088. + struct delayed_work hw_dig_wq;
  8089. + struct delayed_work tx_pw_wq;
  8090. +
  8091. +#ifdef SW_ANTE_DIVERSITY
  8092. + struct delayed_work SwAntennaWorkItem;
  8093. +#endif
  8094. +
  8095. +#else
  8096. + struct work_struct softmac_scan_wq;
  8097. + struct work_struct start_ibss_wq;
  8098. + struct work_struct associate_retry_wq;
  8099. +//by amy for rate adaptive
  8100. + struct work_struct rate_adapter_wq;
  8101. +//by amy for rate adaptive
  8102. + struct work_struct watch_dog_wq;
  8103. + struct work_struct hw_dig_wq;
  8104. + struct work_struct tx_pw_wq;
  8105. +
  8106. +#ifdef SW_ANTE_DIVERSITY
  8107. + struct work_struct SwAntennaWorkItem;
  8108. +#endif
  8109. +
  8110. +#endif
  8111. +
  8112. +//struct work_struct softmac_scan_wq;
  8113. + struct work_struct wx_sync_scan_wq;
  8114. + struct work_struct wmm_param_update_wq;
  8115. +#ifdef _RTL8187_EXT_PATCH_
  8116. + struct work_struct ext_stop_scan_wq;
  8117. + struct work_struct ext_send_beacon_wq;
  8118. +#endif
  8119. + struct workqueue_struct *wq;
  8120. +#else
  8121. + /* used for periodly scan */
  8122. + struct timer_list scan_timer;
  8123. +
  8124. + struct tq_struct associate_complete_wq;
  8125. + struct tq_struct associate_retry_wq;
  8126. + struct tq_struct start_ibss_wq;
  8127. + struct tq_struct associate_procedure_wq;
  8128. + struct tq_struct ips_leave_wq; //YJ,add,081230,for IPS
  8129. + struct tq_struct softmac_scan_wq;
  8130. + struct tq_struct wx_sync_scan_wq;
  8131. + struct tq_struct wmm_param_update_wq;
  8132. +#ifdef _RTL8187_EXT_PATCH_
  8133. + struct tq_struct ext_stop_scan_wq;
  8134. + struct tq_struct ext_send_beacon_wq;
  8135. +#endif
  8136. +#endif
  8137. +
  8138. + /* Callback functions */
  8139. + void (*set_security)(struct net_device *dev,
  8140. + struct ieee80211_security *sec);
  8141. +
  8142. + /* Used to TX data frame by using txb structs.
  8143. + * this is not used if in the softmac_features
  8144. + * is set the flag IEEE_SOFTMAC_TX_QUEUE
  8145. + */
  8146. + int (*hard_start_xmit)(struct ieee80211_txb *txb,
  8147. + struct net_device *dev);
  8148. +
  8149. + int (*reset_port)(struct net_device *dev);
  8150. +
  8151. + /* Softmac-generated frames (mamagement) are TXed via this
  8152. + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
  8153. + * not set. As some cards may have different HW queues that
  8154. + * one might want to use for data and management frames
  8155. + * the option to have two callbacks might be useful.
  8156. + * This fucntion can't sleep.
  8157. + */
  8158. + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
  8159. + struct net_device *dev);
  8160. +
  8161. + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
  8162. + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
  8163. + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
  8164. + * then also management frames are sent via this callback.
  8165. + * This function can't sleep.
  8166. + */
  8167. + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
  8168. + struct net_device *dev,int rate);
  8169. +
  8170. + /* stops the HW queue for DATA frames. Useful to avoid
  8171. + * waste time to TX data frame when we are reassociating
  8172. + * This function can sleep.
  8173. + */
  8174. + void (*data_hard_stop)(struct net_device *dev);
  8175. +
  8176. + /* OK this is complementar to data_poll_hard_stop */
  8177. + void (*data_hard_resume)(struct net_device *dev);
  8178. +
  8179. + /* ask to the driver to retune the radio .
  8180. + * This function can sleep. the driver should ensure
  8181. + * the radio has been swithced before return.
  8182. + */
  8183. + void (*set_chan)(struct net_device *dev,short ch);
  8184. +
  8185. + /* These are not used if the ieee stack takes care of
  8186. + * scanning (IEEE_SOFTMAC_SCAN feature set).
  8187. + * In this case only the set_chan is used.
  8188. + *
  8189. + * The syncro version is similar to the start_scan but
  8190. + * does not return until all channels has been scanned.
  8191. + * this is called in user context and should sleep,
  8192. + * it is called in a work_queue when swithcing to ad-hoc mode
  8193. + * or in behalf of iwlist scan when the card is associated
  8194. + * and root user ask for a scan.
  8195. + * the fucntion stop_scan should stop both the syncro and
  8196. + * background scanning and can sleep.
  8197. + * The fucntion start_scan should initiate the background
  8198. + * scanning and can't sleep.
  8199. + */
  8200. + void (*scan_syncro)(struct net_device *dev);
  8201. + void (*start_scan)(struct net_device *dev);
  8202. + void (*stop_scan)(struct net_device *dev);
  8203. +
  8204. + /* indicate the driver that the link state is changed
  8205. + * for example it may indicate the card is associated now.
  8206. + * Driver might be interested in this to apply RX filter
  8207. + * rules or simply light the LINK led
  8208. + */
  8209. + void (*link_change)(struct net_device *dev);
  8210. +
  8211. + /* these two function indicates to the HW when to start
  8212. + * and stop to send beacons. This is used when the
  8213. + * IEEE_SOFTMAC_BEACONS is not set. For now the
  8214. + * stop_send_bacons is NOT guaranteed to be called only
  8215. + * after start_send_beacons.
  8216. + */
  8217. + void (*start_send_beacons) (struct net_device *dev);
  8218. + void (*stop_send_beacons) (struct net_device *dev);
  8219. +
  8220. + /* power save mode related */
  8221. + void (*sta_wake_up) (struct net_device *dev);
  8222. + void (*ps_request_tx_ack) (struct net_device *dev);
  8223. + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
  8224. + short (*ps_is_queue_empty) (struct net_device *dev);
  8225. +
  8226. +//by lizhaoming for LED 2008.6.23
  8227. +#ifdef LED
  8228. + void (*ieee80211_led_contorl) (struct net_device *dev, LED_CTL_MODE LedAction);
  8229. +#endif
  8230. +#ifdef CONFIG_IPS
  8231. + void (*ieee80211_ips_leave) (struct net_device *dev);
  8232. +#endif
  8233. + /* QoS related */
  8234. + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
  8235. + //void (*wmm_param_update) (struct ieee80211_device *ieee);
  8236. +
  8237. +
  8238. +#ifdef _RTL8187_EXT_PATCH_
  8239. +
  8240. + /// ieee80211_softmac.c
  8241. + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
  8242. +
  8243. + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
  8244. + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
  8245. +
  8246. + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
  8247. +
  8248. + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
  8249. + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  8250. +
  8251. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
  8252. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
  8253. +
  8254. + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
  8255. + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  8256. +
  8257. + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
  8258. +
  8259. + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
  8260. +
  8261. + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  8262. + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  8263. +//by amy for mesh
  8264. + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
  8265. +//by amy for mesh
  8266. + // ieee80211_rx.c
  8267. + // rz
  8268. + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  8269. + unsigned int(*ext_patch_ieee80211_process_probe_response_1)(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  8270. +
  8271. + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
  8272. + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  8273. +
  8274. + // success(return 0) is responsible to free skb
  8275. + int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
  8276. +
  8277. + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
  8278. +
  8279. + // Check whether or not accept the incoming frame. return 0: not accept, >0: accept
  8280. + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  8281. +
  8282. + // return > 0 is success. 0 when failed
  8283. + // success(return >0) is responsible to free skb
  8284. + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  8285. +
  8286. + /* added by david for setting acl dynamically */
  8287. + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
  8288. +
  8289. + // int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  8290. +
  8291. + // ieee80211_tx.c
  8292. +
  8293. + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  8294. + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
  8295. +
  8296. +
  8297. +#endif // _RTL8187_EXT_PATCH_
  8298. +
  8299. + /* This must be the last item so that it points to the data
  8300. + * allocated beyond this structure by alloc_ieee80211 */
  8301. + u8 priv[0];
  8302. +};
  8303. +
  8304. +#define IEEE_A (1<<0)
  8305. +#define IEEE_B (1<<1)
  8306. +#define IEEE_G (1<<2)
  8307. +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
  8308. +
  8309. +/* Generate a 802.11 header */
  8310. +
  8311. +/* Uses the channel change callback directly
  8312. + * instead of [start/stop] scan callbacks
  8313. + */
  8314. +#define IEEE_SOFTMAC_SCAN (1<<2)
  8315. +
  8316. +/* Perform authentication and association handshake */
  8317. +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
  8318. +
  8319. +/* Generate probe requests */
  8320. +#define IEEE_SOFTMAC_PROBERQ (1<<4)
  8321. +
  8322. +/* Generate respones to probe requests */
  8323. +#define IEEE_SOFTMAC_PROBERS (1<<5)
  8324. +
  8325. +/* The ieee802.11 stack will manages the netif queue
  8326. + * wake/stop for the driver, taking care of 802.11
  8327. + * fragmentation. See softmac.c for details. */
  8328. +#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
  8329. +
  8330. +/* Uses only the softmac_data_hard_start_xmit
  8331. + * even for TX management frames.
  8332. + */
  8333. +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
  8334. +
  8335. +/* Generate beacons. The stack will enqueue beacons
  8336. + * to the card
  8337. + */
  8338. +#define IEEE_SOFTMAC_BEACONS (1<<6)
  8339. +#ifdef _RTL8187_EXT_PATCH_
  8340. +extern inline int ieee80211_find_MP(struct ieee80211_device* ieee, const u8* addr, u8 set)
  8341. +{
  8342. + int i=0;
  8343. + for (i=1; i<MAX_MP; i++)
  8344. + {
  8345. + if ((ieee->cryptlist[i]->used == 0)&&set)
  8346. + {//entry is empty
  8347. + memcpy(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN);
  8348. + ieee->cryptlist[i]->used = 1;
  8349. + return i;
  8350. + }
  8351. + else if (0 == memcmp(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN)) //find matched entry
  8352. + {
  8353. + return i;
  8354. + }
  8355. + }
  8356. + return -1;
  8357. +}
  8358. +#endif
  8359. +
  8360. +
  8361. +
  8362. +static inline void *ieee80211_priv(struct net_device *dev)
  8363. +{
  8364. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  8365. + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
  8366. +#else
  8367. + return ((struct ieee80211_device *)dev->priv)->priv;
  8368. +#endif
  8369. +}
  8370. +
  8371. +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
  8372. +{
  8373. + /* Single white space is for Linksys APs */
  8374. + if (essid_len == 1 && essid[0] == ' ')
  8375. + return 1;
  8376. +
  8377. + /* Otherwise, if the entire essid is 0, we assume it is hidden */
  8378. + while (essid_len) {
  8379. + essid_len--;
  8380. + if (essid[essid_len] != '\0')
  8381. + return 0;
  8382. + }
  8383. +
  8384. + return 1;
  8385. +}
  8386. +
  8387. +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
  8388. +{
  8389. + /*
  8390. + * It is possible for both access points and our device to support
  8391. + * combinations of modes, so as long as there is one valid combination
  8392. + * of ap/device supported modes, then return success
  8393. + *
  8394. + */
  8395. + if ((mode & IEEE_A) &&
  8396. + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
  8397. + (ieee->freq_band & IEEE80211_52GHZ_BAND))
  8398. + return 1;
  8399. +
  8400. + if ((mode & IEEE_G) &&
  8401. + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
  8402. + (ieee->freq_band & IEEE80211_24GHZ_BAND))
  8403. + return 1;
  8404. +
  8405. + if ((mode & IEEE_B) &&
  8406. + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
  8407. + (ieee->freq_band & IEEE80211_24GHZ_BAND))
  8408. + return 1;
  8409. +
  8410. + return 0;
  8411. +}
  8412. +
  8413. +extern inline int ieee80211_get_hdrlen(u16 fc)
  8414. +{
  8415. + int hdrlen = 24;
  8416. +
  8417. + switch (WLAN_FC_GET_TYPE(fc)) {
  8418. + case IEEE80211_FTYPE_DATA:
  8419. + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
  8420. + hdrlen = 30; /* Addr4 */
  8421. + if(IEEE80211_QOS_HAS_SEQ(fc))
  8422. + hdrlen += 2; /* QOS ctrl*/
  8423. + break;
  8424. + case IEEE80211_FTYPE_CTL:
  8425. + switch (WLAN_FC_GET_STYPE(fc)) {
  8426. + case IEEE80211_STYPE_CTS:
  8427. + case IEEE80211_STYPE_ACK:
  8428. + hdrlen = 10;
  8429. + break;
  8430. + default:
  8431. + hdrlen = 16;
  8432. + break;
  8433. + }
  8434. + break;
  8435. + }
  8436. +
  8437. + return hdrlen;
  8438. +}
  8439. +
  8440. +
  8441. +
  8442. +/* ieee80211.c */
  8443. +extern void free_ieee80211(struct net_device *dev);
  8444. +extern struct net_device *alloc_ieee80211(int sizeof_priv);
  8445. +
  8446. +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
  8447. +
  8448. +/* ieee80211_tx.c */
  8449. +
  8450. +extern int ieee80211_encrypt_fragment(
  8451. + struct ieee80211_device *ieee,
  8452. + struct sk_buff *frag,
  8453. + int hdr_len);
  8454. +
  8455. +extern int ieee80211_xmit(struct sk_buff *skb,
  8456. + struct net_device *dev);
  8457. +extern void ieee80211_txb_free(struct ieee80211_txb *);
  8458. +
  8459. +
  8460. +/* ieee80211_rx.c */
  8461. +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
  8462. + struct ieee80211_rx_stats *rx_stats);
  8463. +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
  8464. + struct ieee80211_hdr *header,
  8465. + struct ieee80211_rx_stats *stats);
  8466. +
  8467. +/* ieee80211_wx.c */
  8468. +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
  8469. + struct iw_request_info *info,
  8470. + union iwreq_data *wrqu, char *key);
  8471. +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
  8472. + struct iw_request_info *info,
  8473. + union iwreq_data *wrqu, char *key);
  8474. +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
  8475. + struct iw_request_info *info,
  8476. + union iwreq_data *wrqu, char *key);
  8477. +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
  8478. + struct iw_request_info *info,
  8479. + union iwreq_data* wrqu, char *extra);
  8480. +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
  8481. + struct iw_request_info *info,
  8482. + struct iw_param *data, char *extra);
  8483. +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
  8484. + struct iw_request_info *info,
  8485. + union iwreq_data *wrqu, char *extra);
  8486. +
  8487. +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
  8488. +/* ieee80211_softmac.c */
  8489. +extern short ieee80211_is_54g(struct ieee80211_network net);
  8490. +extern short ieee80211_is_shortslot(struct ieee80211_network net);
  8491. +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
  8492. + struct ieee80211_rx_stats *rx_stats, u16 type,
  8493. + u16 stype);
  8494. +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
  8495. +
  8496. +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
  8497. +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
  8498. +extern void ieee80211_start_bss(struct ieee80211_device *ieee);
  8499. +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
  8500. +extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
  8501. +extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
  8502. +extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
  8503. +extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
  8504. +extern void ieee80211_disassociate(struct ieee80211_device *ieee);
  8505. +extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
  8506. +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
  8507. +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
  8508. +extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
  8509. +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
  8510. +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
  8511. +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
  8512. +extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
  8513. +extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
  8514. +extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
  8515. +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
  8516. +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
  8517. +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
  8518. +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
  8519. +extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
  8520. +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
  8521. +extern void ieee80211_start_scan(struct ieee80211_device *ieee);
  8522. +
  8523. +#ifdef _RTL8187_EXT_PATCH_
  8524. +extern void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb);
  8525. +extern void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat);
  8526. +extern void ieee80211_associate_step1(struct ieee80211_device *ieee);
  8527. +extern void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason);
  8528. +extern void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type);
  8529. +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
  8530. +extern struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  8531. +extern int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, struct ieee80211_rx_stats *stats);
  8532. +extern struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, int gfp_mask);
  8533. +extern void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee);
  8534. +extern struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt);
  8535. +extern struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt);
  8536. +extern int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src);
  8537. +#endif
  8538. +
  8539. +/* ieee80211_crypt_ccmp&tkip&wep.c */
  8540. +extern void ieee80211_tkip_null(void);
  8541. +extern void ieee80211_wep_null(void);
  8542. +extern void ieee80211_ccmp_null(void);
  8543. +/* ieee80211_softmac_wx.c */
  8544. +
  8545. +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
  8546. + struct iw_request_info *info,
  8547. + union iwreq_data *wrqu, char *ext);
  8548. +
  8549. +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
  8550. + struct iw_request_info *info,
  8551. + union iwreq_data *awrq,
  8552. + char *extra);
  8553. +
  8554. +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
  8555. +
  8556. +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
  8557. + struct iw_request_info *info,
  8558. + union iwreq_data *wrqu, char *extra);
  8559. +
  8560. +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
  8561. + struct iw_request_info *info,
  8562. + union iwreq_data *wrqu, char *extra);
  8563. +
  8564. +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  8565. + union iwreq_data *wrqu, char *b);
  8566. +
  8567. +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
  8568. + union iwreq_data *wrqu, char *b);
  8569. +
  8570. +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
  8571. + struct iw_request_info *a,
  8572. + union iwreq_data *wrqu, char *extra);
  8573. +
  8574. +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  8575. + union iwreq_data *wrqu, char *b);
  8576. +
  8577. +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  8578. + union iwreq_data *wrqu, char *b);
  8579. +
  8580. +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  8581. + union iwreq_data *wrqu, char *b);
  8582. +
  8583. +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  8584. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  8585. +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
  8586. +#else
  8587. + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  8588. +#endif
  8589. +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
  8590. + struct iw_request_info *info,
  8591. + union iwreq_data *wrqu, char *extra);
  8592. +
  8593. +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
  8594. + struct iw_request_info *info,
  8595. + union iwreq_data *wrqu, char *extra);
  8596. +
  8597. +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
  8598. + struct iw_request_info *info,
  8599. + union iwreq_data *wrqu, char *extra);
  8600. +
  8601. +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
  8602. + struct iw_request_info *info,
  8603. + union iwreq_data *wrqu, char *extra);
  8604. +
  8605. +extern const long ieee80211_wlan_frequencies[];
  8606. +
  8607. +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
  8608. +{
  8609. + ieee->scans++;
  8610. +}
  8611. +
  8612. +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
  8613. +{
  8614. + return ieee->scans;
  8615. +}
  8616. +
  8617. +static inline const char *escape_essid(const char *essid, u8 essid_len) {
  8618. + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
  8619. + const char *s = essid;
  8620. + char *d = escaped;
  8621. +
  8622. + if (ieee80211_is_empty_essid(essid, essid_len)) {
  8623. + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
  8624. + return escaped;
  8625. + }
  8626. +
  8627. + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
  8628. + while (essid_len--) {
  8629. + if (*s == '\0') {
  8630. + *d++ = '\\';
  8631. + *d++ = '0';
  8632. + s++;
  8633. + } else {
  8634. + *d++ = *s++;
  8635. + }
  8636. + }
  8637. + *d = '\0';
  8638. + return escaped;
  8639. +}
  8640. +#endif /* IEEE80211_H */
  8641. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c
  8642. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 1970-01-01 01:00:00.000000000 +0100
  8643. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 2010-03-06 16:43:22.000000000 +0100
  8644. @@ -0,0 +1,385 @@
  8645. +/*******************************************************************************
  8646. +
  8647. + Copyright(c) 2004 Intel Corporation. All rights reserved.
  8648. +
  8649. + Portions of this file are based on the WEP enablement code provided by the
  8650. + Host AP project hostap-drivers v0.1.3
  8651. + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  8652. + <jkmaline@cc.hut.fi>
  8653. + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  8654. +
  8655. + This program is free software; you can redistribute it and/or modify it
  8656. + under the terms of version 2 of the GNU General Public License as
  8657. + published by the Free Software Foundation.
  8658. +
  8659. + This program is distributed in the hope that it will be useful, but WITHOUT
  8660. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  8661. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  8662. + more details.
  8663. +
  8664. + You should have received a copy of the GNU General Public License along with
  8665. + this program; if not, write to the Free Software Foundation, Inc., 59
  8666. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  8667. +
  8668. + The full GNU General Public License is included in this distribution in the
  8669. + file called LICENSE.
  8670. +
  8671. + Contact Information:
  8672. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  8673. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  8674. +
  8675. +*******************************************************************************/
  8676. +
  8677. +#include <linux/compiler.h>
  8678. +//#include <linux/config.h>
  8679. +#include <linux/errno.h>
  8680. +#include <linux/if_arp.h>
  8681. +#include <linux/in6.h>
  8682. +#include <linux/in.h>
  8683. +#include <linux/ip.h>
  8684. +#include <linux/kernel.h>
  8685. +#include <linux/module.h>
  8686. +#include <linux/netdevice.h>
  8687. +#include <linux/pci.h>
  8688. +#include <linux/proc_fs.h>
  8689. +#include <linux/skbuff.h>
  8690. +#include <linux/slab.h>
  8691. +#include <linux/tcp.h>
  8692. +#include <linux/types.h>
  8693. +#include <linux/version.h>
  8694. +#include <linux/wireless.h>
  8695. +#include <linux/etherdevice.h>
  8696. +#include <asm/uaccess.h>
  8697. +#include <net/arp.h>
  8698. +
  8699. +#include "ieee80211.h"
  8700. +
  8701. +MODULE_DESCRIPTION("802.11 data/management/control stack");
  8702. +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
  8703. +MODULE_LICENSE("GPL");
  8704. +
  8705. +#define DRV_NAME "ieee80211"
  8706. +
  8707. +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
  8708. +{
  8709. + if (ieee->networks)
  8710. + return 0;
  8711. +
  8712. + ieee->networks = kmalloc(
  8713. + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
  8714. + GFP_KERNEL);
  8715. + if (!ieee->networks) {
  8716. + printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
  8717. + ieee->dev->name);
  8718. + return -ENOMEM;
  8719. + }
  8720. +
  8721. + memset(ieee->networks, 0,
  8722. + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
  8723. +
  8724. + return 0;
  8725. +}
  8726. +
  8727. +static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
  8728. +{
  8729. + if (!ieee->networks)
  8730. + return;
  8731. + kfree(ieee->networks);
  8732. + ieee->networks = NULL;
  8733. +}
  8734. +
  8735. +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
  8736. +{
  8737. + int i;
  8738. +
  8739. + INIT_LIST_HEAD(&ieee->network_free_list);
  8740. + INIT_LIST_HEAD(&ieee->network_list);
  8741. + for (i = 0; i < MAX_NETWORK_COUNT; i++)
  8742. + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
  8743. +}
  8744. +
  8745. +
  8746. +struct net_device *alloc_ieee80211(int sizeof_priv)
  8747. +{
  8748. + struct ieee80211_device *ieee;
  8749. + struct net_device *dev;
  8750. + int i,err;
  8751. +
  8752. + IEEE80211_DEBUG_INFO("Initializing...\n");
  8753. +
  8754. + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
  8755. + if (!dev) {
  8756. + IEEE80211_ERROR("Unable to network device.\n");
  8757. + goto failed;
  8758. + }
  8759. +
  8760. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  8761. + ieee = netdev_priv(dev);
  8762. +#else
  8763. + ieee = (struct ieee80211_device *)dev->priv;
  8764. +#endif
  8765. +
  8766. + ieee->dev = dev;
  8767. +
  8768. + err = ieee80211_networks_allocate(ieee);
  8769. + if (err) {
  8770. + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
  8771. + err);
  8772. + goto failed;
  8773. + }
  8774. + ieee80211_networks_initialize(ieee);
  8775. +
  8776. + /* Default fragmentation threshold is maximum payload size */
  8777. + ieee->fts = DEFAULT_FTS;
  8778. + ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
  8779. + ieee->open_wep = 1;
  8780. +
  8781. + /* Default to enabling full open WEP with host based encrypt/decrypt */
  8782. + ieee->host_encrypt = 1;
  8783. + ieee->host_decrypt = 1;
  8784. + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
  8785. +
  8786. + INIT_LIST_HEAD(&ieee->crypt_deinit_list);
  8787. + init_timer(&ieee->crypt_deinit_timer);
  8788. + ieee->crypt_deinit_timer.data = (unsigned long)ieee;
  8789. + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
  8790. +
  8791. + spin_lock_init(&ieee->lock);
  8792. + spin_lock_init(&ieee->wpax_suitlist_lock);
  8793. +
  8794. + ieee->wpax_type_set = 0;
  8795. + ieee->wpa_enabled = 0;
  8796. + ieee->tkip_countermeasures = 0;
  8797. + ieee->drop_unencrypted = 0;
  8798. + ieee->privacy_invoked = 0;
  8799. + ieee->ieee802_1x = 1;
  8800. + ieee->raw_tx = 0;
  8801. +#ifdef _RTL8187_EXT_PATCH_
  8802. + for (i=0; i<MAX_MP; i++)
  8803. + {
  8804. + ieee->cryptlist[i] = (struct ieee80211_crypt_data_list*) kmalloc(sizeof(struct ieee80211_crypt_data_list), GFP_KERNEL);
  8805. + if (NULL == ieee->cryptlist[i])
  8806. + {
  8807. + printk("error kmalloc cryptlist\n");
  8808. + goto failed;
  8809. + }
  8810. + memset(ieee->cryptlist[i], 0, sizeof(struct ieee80211_crypt_data_list));
  8811. +
  8812. + }
  8813. +#endif
  8814. + ieee80211_softmac_init(ieee);
  8815. +
  8816. + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
  8817. + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
  8818. +
  8819. + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++)
  8820. + INIT_LIST_HEAD(&ieee->mesh_mac_hash[i]);
  8821. +
  8822. + for (i = 0; i < 17; i++) {
  8823. + ieee->last_rxseq_num[i] = -1;
  8824. + ieee->last_rxfrag_num[i] = -1;
  8825. + ieee->last_packet_time[i] = 0;
  8826. + }
  8827. +#if 1 //added these to autoload encryption module. WB
  8828. + ieee80211_tkip_null();
  8829. + ieee80211_wep_null();
  8830. + ieee80211_ccmp_null();
  8831. +#endif
  8832. + return dev;
  8833. +
  8834. + failed:
  8835. +#ifdef _RTL8187_EXT_PATCH_
  8836. + for (i=0; i<MAX_MP; i++)
  8837. + {
  8838. + if (ieee->cryptlist[i]==NULL){
  8839. + continue;
  8840. + }
  8841. + kfree(ieee->cryptlist[i]);
  8842. + ieee->cryptlist[i] = NULL;
  8843. +
  8844. + }
  8845. +#endif
  8846. + if (dev)
  8847. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  8848. + free_netdev(dev);
  8849. +#else
  8850. + kfree(dev);
  8851. +#endif
  8852. + return NULL;
  8853. +}
  8854. +
  8855. +
  8856. +void free_ieee80211(struct net_device *dev)
  8857. +{
  8858. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  8859. + struct ieee80211_device *ieee = netdev_priv(dev);
  8860. +#else
  8861. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  8862. +#endif
  8863. + int i;//,j;
  8864. + struct list_head *p, *q;
  8865. +
  8866. +
  8867. + ieee80211_softmac_free(ieee);
  8868. + del_timer_sync(&ieee->crypt_deinit_timer);
  8869. + ieee80211_crypt_deinit_entries(ieee, 1);
  8870. +#if 1
  8871. + ieee80211_tkip_null();
  8872. + ieee80211_wep_null();
  8873. + ieee80211_ccmp_null();
  8874. +#endif
  8875. + for (i = 0; i < WEP_KEYS; i++) {
  8876. +#ifdef _RTL8187_EXT_PATCH_
  8877. +{
  8878. + // int j;
  8879. + for (j=0;j<MAX_MP; j++){
  8880. + if (ieee->cryptlist[j] == NULL)
  8881. + continue;
  8882. + struct ieee80211_crypt_data *crypt = ieee->cryptlist[j]->crypt[i];
  8883. +#else
  8884. + struct ieee80211_crypt_data *crypt = ieee->crypt[i];
  8885. +#endif
  8886. + if (crypt) {
  8887. + if (crypt->ops) {
  8888. + crypt->ops->deinit(crypt->priv);
  8889. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  8890. + module_put(crypt->ops->owner);
  8891. +#else
  8892. + __MOD_DEC_USE_COUNT(crypt->ops->owner);
  8893. +#endif
  8894. + }
  8895. + kfree(crypt);
  8896. +#ifdef _RTL8187_EXT_PATCH_
  8897. + ieee->cryptlist[j]->crypt[i] = NULL;
  8898. + //kfree(ieee->cryptlist[j]);
  8899. + //ieee->cryptlist[j] = NULL;
  8900. +#else
  8901. + ieee->crypt[i] = NULL;
  8902. +#endif
  8903. + }
  8904. +#ifdef _RTL8187_EXT_PATCH_
  8905. + }
  8906. + }
  8907. +#endif
  8908. +}
  8909. +#ifdef _RTL8187_EXT_PATCH_
  8910. +for(j=0;j<MAX_MP;j++)
  8911. + {
  8912. + if (ieee->cryptlist[j])
  8913. + {
  8914. + kfree(ieee->cryptlist[j]);
  8915. + ieee->cryptlist[j] = NULL;
  8916. + }
  8917. + }
  8918. +
  8919. + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) {
  8920. + list_for_each_safe(p, q, &ieee->mesh_mac_hash[i]) {
  8921. + kfree(list_entry(p, struct ieee_mesh_seq, list));
  8922. + list_del(p);
  8923. + }
  8924. + }
  8925. +#endif
  8926. + ieee80211_networks_free(ieee);
  8927. +
  8928. + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
  8929. + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
  8930. + kfree(list_entry(p, struct ieee_ibss_seq, list));
  8931. + list_del(p);
  8932. + }
  8933. + }
  8934. +
  8935. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  8936. + free_netdev(dev);
  8937. +#else
  8938. + kfree(dev);
  8939. +#endif
  8940. +}
  8941. +
  8942. +#ifdef CONFIG_IEEE80211_DEBUG
  8943. +
  8944. +static int debug = 0;
  8945. +u32 ieee80211_debug_level = 0;
  8946. +struct proc_dir_entry *ieee80211_proc = NULL;
  8947. +
  8948. +static int show_debug_level(char *page, char **start, off_t offset,
  8949. + int count, int *eof, void *data)
  8950. +{
  8951. + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
  8952. +}
  8953. +
  8954. +static int store_debug_level(struct file *file, const char *buffer,
  8955. + unsigned long count, void *data)
  8956. +{
  8957. + char buf[] = "0x00000000";
  8958. + unsigned long len = min(sizeof(buf) - 1, (u32)count);
  8959. + char *p = (char *)buf;
  8960. + unsigned long val;
  8961. +
  8962. + if (copy_from_user(buf, buffer, len))
  8963. + return count;
  8964. + buf[len] = 0;
  8965. + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
  8966. + p++;
  8967. + if (p[0] == 'x' || p[0] == 'X')
  8968. + p++;
  8969. + val = simple_strtoul(p, &p, 16);
  8970. + } else
  8971. + val = simple_strtoul(p, &p, 10);
  8972. + if (p == buf)
  8973. + printk(KERN_INFO DRV_NAME
  8974. + ": %s is not in hex or decimal form.\n", buf);
  8975. + else
  8976. + ieee80211_debug_level = val;
  8977. +
  8978. + return strnlen(buf, count);
  8979. +}
  8980. +
  8981. +static int __init ieee80211_init(void)
  8982. +{
  8983. + struct proc_dir_entry *e;
  8984. +
  8985. + ieee80211_debug_level = debug;
  8986. + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
  8987. + if (ieee80211_proc == NULL) {
  8988. + IEEE80211_ERROR("Unable to create " DRV_NAME
  8989. + " proc directory\n");
  8990. + return -EIO;
  8991. + }
  8992. + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
  8993. + ieee80211_proc);
  8994. + if (!e) {
  8995. + remove_proc_entry(DRV_NAME, proc_net);
  8996. + ieee80211_proc = NULL;
  8997. + return -EIO;
  8998. + }
  8999. + e->read_proc = show_debug_level;
  9000. + e->write_proc = store_debug_level;
  9001. + e->data = NULL;
  9002. +
  9003. + return 0;
  9004. +}
  9005. +
  9006. +static void __exit ieee80211_exit(void)
  9007. +{
  9008. + if (ieee80211_proc) {
  9009. + remove_proc_entry("debug_level", ieee80211_proc);
  9010. + remove_proc_entry(DRV_NAME, proc_net);
  9011. + ieee80211_proc = NULL;
  9012. + }
  9013. +}
  9014. +
  9015. +#include <linux/moduleparam.h>
  9016. +module_param(debug, int, 0444);
  9017. +MODULE_PARM_DESC(debug, "debug output mask");
  9018. +
  9019. +
  9020. +module_exit(ieee80211_exit);
  9021. +module_init(ieee80211_init);
  9022. +#endif
  9023. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  9024. +EXPORT_SYMBOL(alloc_ieee80211);
  9025. +EXPORT_SYMBOL(free_ieee80211);
  9026. +#else
  9027. +EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
  9028. +EXPORT_SYMBOL_NOVERS(free_ieee80211);
  9029. +#endif
  9030. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c
  9031. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 1970-01-01 01:00:00.000000000 +0100
  9032. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 2010-03-06 16:43:22.000000000 +0100
  9033. @@ -0,0 +1,2074 @@
  9034. +/*
  9035. + * Original code based Host AP (software wireless LAN access point) driver
  9036. + * for Intersil Prism2/2.5/3 - hostap.o module, common routines
  9037. + *
  9038. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  9039. + * <jkmaline@cc.hut.fi>
  9040. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  9041. + * Copyright (c) 2004, Intel Corporation
  9042. + *
  9043. + * This program is free software; you can redistribute it and/or modify
  9044. + * it under the terms of the GNU General Public License version 2 as
  9045. + * published by the Free Software Foundation. See README and COPYING for
  9046. + * more details.
  9047. + ******************************************************************************
  9048. +
  9049. + Few modifications for Realtek's Wi-Fi drivers by
  9050. + Andrea Merello <andreamrl@tiscali.it>
  9051. +
  9052. + A special thanks goes to Realtek for their support !
  9053. +
  9054. +******************************************************************************/
  9055. +
  9056. +
  9057. +#include <linux/compiler.h>
  9058. +//#include <linux/config.h>
  9059. +#include <linux/errno.h>
  9060. +#include <linux/if_arp.h>
  9061. +#include <linux/in6.h>
  9062. +#include <linux/in.h>
  9063. +#include <linux/ip.h>
  9064. +#include <linux/kernel.h>
  9065. +#include <linux/module.h>
  9066. +#include <linux/netdevice.h>
  9067. +#include <linux/pci.h>
  9068. +#include <linux/proc_fs.h>
  9069. +#include <linux/skbuff.h>
  9070. +#include <linux/slab.h>
  9071. +#include <linux/tcp.h>
  9072. +#include <linux/types.h>
  9073. +#include <linux/version.h>
  9074. +#include <linux/wireless.h>
  9075. +#include <linux/etherdevice.h>
  9076. +#include <asm/uaccess.h>
  9077. +#include <linux/ctype.h>
  9078. +
  9079. +#include "ieee80211.h"
  9080. +#ifdef ENABLE_DOT11D
  9081. +#include "dot11d.h"
  9082. +#endif
  9083. +
  9084. +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
  9085. + struct sk_buff *skb,
  9086. + struct ieee80211_rx_stats *rx_stats)
  9087. +{
  9088. + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  9089. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  9090. +
  9091. + skb->dev = ieee->dev;
  9092. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
  9093. + skb_reset_mac_header(skb);
  9094. +#else
  9095. + skb->mac.raw = skb->data;
  9096. +#endif
  9097. +
  9098. + //skb->mac.raw = skb->data;
  9099. + skb_pull(skb, ieee80211_get_hdrlen(fc));
  9100. + skb->pkt_type = PACKET_OTHERHOST;
  9101. + skb->protocol = __constant_htons(ETH_P_80211_RAW);
  9102. + memset(skb->cb, 0, sizeof(skb->cb));
  9103. + netif_rx(skb);
  9104. +}
  9105. +
  9106. +
  9107. +/* Called only as a tasklet (software IRQ) */
  9108. +static struct ieee80211_frag_entry *
  9109. +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
  9110. + unsigned int frag, u8 tid,u8 *src, u8 *dst)
  9111. +{
  9112. + struct ieee80211_frag_entry *entry;
  9113. + int i;
  9114. +
  9115. + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
  9116. + entry = &ieee->frag_cache[tid][i];
  9117. + if (entry->skb != NULL &&
  9118. + time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
  9119. + IEEE80211_DEBUG_FRAG(
  9120. + "expiring fragment cache entry "
  9121. + "seq=%u last_frag=%u\n",
  9122. + entry->seq, entry->last_frag);
  9123. + dev_kfree_skb_any(entry->skb);
  9124. + entry->skb = NULL;
  9125. + }
  9126. +
  9127. + if (entry->skb != NULL && entry->seq == seq &&
  9128. + (entry->last_frag + 1 == frag || frag == -1) &&
  9129. + memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
  9130. + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
  9131. + return entry;
  9132. + }
  9133. +
  9134. + return NULL;
  9135. +}
  9136. +
  9137. +/* Called only as a tasklet (software IRQ) */
  9138. +static struct sk_buff *
  9139. +ieee80211_frag_cache_get(struct ieee80211_device *ieee,
  9140. + struct ieee80211_hdr *hdr)
  9141. +{
  9142. + struct sk_buff *skb = NULL;
  9143. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  9144. + u16 sc = le16_to_cpu(hdr->seq_ctl);
  9145. + unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
  9146. + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  9147. + struct ieee80211_frag_entry *entry;
  9148. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  9149. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  9150. + u8 tid;
  9151. +
  9152. +#ifdef _RTL8187_EXT_PATCH_
  9153. + if(ieee->iw_mode == ieee->iw_ext_mode)
  9154. + {
  9155. + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  9156. + }
  9157. + else
  9158. +#endif
  9159. + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  9160. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
  9161. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9162. + tid = UP2AC(tid);
  9163. + tid ++;
  9164. + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  9165. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
  9166. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9167. + tid = UP2AC(tid);
  9168. + tid ++;
  9169. + } else {
  9170. + tid = 0;
  9171. + }
  9172. +
  9173. + if (frag == 0) {
  9174. + /* Reserve enough space to fit maximum frame length */
  9175. + skb = dev_alloc_skb(ieee->dev->mtu +
  9176. + sizeof(struct ieee80211_hdr) +
  9177. + 8 /* LLC */ +
  9178. + 2 /* alignment */ +
  9179. + 8 /* WEP */ +
  9180. + ETH_ALEN /* WDS */ +
  9181. + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
  9182. + if (skb == NULL)
  9183. + return NULL;
  9184. +
  9185. + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
  9186. + ieee->frag_next_idx[tid]++;
  9187. + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
  9188. + ieee->frag_next_idx[tid] = 0;
  9189. +
  9190. + if (entry->skb != NULL)
  9191. + dev_kfree_skb_any(entry->skb);
  9192. +
  9193. + entry->first_frag_time = jiffies;
  9194. + entry->seq = seq;
  9195. + entry->last_frag = frag;
  9196. + entry->skb = skb;
  9197. + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
  9198. + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
  9199. + } else {
  9200. + /* received a fragment of a frame for which the head fragment
  9201. + * should have already been received */
  9202. + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
  9203. + hdr->addr1);
  9204. + if (entry != NULL) {
  9205. + entry->last_frag = frag;
  9206. + skb = entry->skb;
  9207. + }
  9208. + }
  9209. +
  9210. + return skb;
  9211. +}
  9212. +
  9213. +
  9214. +/* Called only as a tasklet (software IRQ) */
  9215. +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
  9216. + struct ieee80211_hdr *hdr)
  9217. +{
  9218. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  9219. + u16 sc = le16_to_cpu(hdr->seq_ctl);
  9220. + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  9221. + struct ieee80211_frag_entry *entry;
  9222. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  9223. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  9224. + u8 tid;
  9225. +
  9226. +#ifdef _RTL8187_EXT_PATCH_
  9227. + if(ieee->iw_mode == ieee->iw_ext_mode)
  9228. + {
  9229. + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  9230. + }
  9231. + else
  9232. +#endif
  9233. + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  9234. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
  9235. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9236. + tid = UP2AC(tid);
  9237. + tid ++;
  9238. + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  9239. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
  9240. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9241. + tid = UP2AC(tid);
  9242. + tid ++;
  9243. + } else {
  9244. + tid = 0;
  9245. + }
  9246. +
  9247. + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
  9248. + hdr->addr1);
  9249. +
  9250. + if (entry == NULL) {
  9251. + IEEE80211_DEBUG_FRAG(
  9252. + "could not invalidate fragment cache "
  9253. + "entry (seq=%u)\n", seq);
  9254. + return -1;
  9255. + }
  9256. +
  9257. + entry->skb = NULL;
  9258. + return 0;
  9259. +}
  9260. +
  9261. +
  9262. +
  9263. +/* ieee80211_rx_frame_mgtmt
  9264. + *
  9265. + * Responsible for handling management control frames
  9266. + *
  9267. + * Called by ieee80211_rx */
  9268. +static inline int
  9269. +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
  9270. + struct ieee80211_rx_stats *rx_stats, u16 type,
  9271. + u16 stype)
  9272. +{
  9273. + /* On the struct stats definition there is written that
  9274. + * this is not mandatory.... but seems that the probe
  9275. + * response parser uses it
  9276. + */
  9277. + struct ieee80211_hdr * hdr = (struct ieee80211_hdr*)skb->data;
  9278. + rx_stats->len = skb->len;
  9279. + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
  9280. +
  9281. + if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
  9282. + {
  9283. + dev_kfree_skb_any(skb);
  9284. + return 0;
  9285. + }
  9286. +
  9287. + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
  9288. +
  9289. + dev_kfree_skb_any(skb);
  9290. +
  9291. + return 0;
  9292. +
  9293. + #ifdef NOT_YET
  9294. + if (ieee->iw_mode == IW_MODE_MASTER) {
  9295. + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
  9296. + ieee->dev->name);
  9297. + return 0;
  9298. +/*
  9299. + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
  9300. + skb->data);*/
  9301. + }
  9302. +
  9303. + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
  9304. + if (stype == WLAN_FC_STYPE_BEACON &&
  9305. + ieee->iw_mode == IW_MODE_MASTER) {
  9306. + struct sk_buff *skb2;
  9307. + /* Process beacon frames also in kernel driver to
  9308. + * update STA(AP) table statistics */
  9309. + skb2 = skb_clone(skb, GFP_ATOMIC);
  9310. + if (skb2)
  9311. + hostap_rx(skb2->dev, skb2, rx_stats);
  9312. + }
  9313. +
  9314. + /* send management frames to the user space daemon for
  9315. + * processing */
  9316. + ieee->apdevstats.rx_packets++;
  9317. + ieee->apdevstats.rx_bytes += skb->len;
  9318. + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
  9319. + return 0;
  9320. + }
  9321. +
  9322. + if (ieee->iw_mode == IW_MODE_MASTER) {
  9323. + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
  9324. + printk(KERN_DEBUG "%s: unknown management frame "
  9325. + "(type=0x%02x, stype=0x%02x) dropped\n",
  9326. + skb->dev->name, type, stype);
  9327. + return -1;
  9328. + }
  9329. +
  9330. + hostap_rx(skb->dev, skb, rx_stats);
  9331. + return 0;
  9332. + }
  9333. +
  9334. + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
  9335. + "received in non-Host AP mode\n", skb->dev->name);
  9336. + return -1;
  9337. + #endif
  9338. +}
  9339. +
  9340. +
  9341. +
  9342. +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
  9343. +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
  9344. +static unsigned char rfc1042_header[] =
  9345. +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
  9346. +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
  9347. +static unsigned char bridge_tunnel_header[] =
  9348. +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
  9349. +/* No encapsulation header if EtherType < 0x600 (=length) */
  9350. +
  9351. +/* Called by ieee80211_rx_frame_decrypt */
  9352. +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
  9353. + struct sk_buff *skb, size_t hdrlen)
  9354. +{
  9355. + struct net_device *dev = ieee->dev;
  9356. + u16 fc, ethertype;
  9357. + struct ieee80211_hdr *hdr;
  9358. + u8 *pos;
  9359. +
  9360. + if (skb->len < 24)
  9361. + return 0;
  9362. +
  9363. + hdr = (struct ieee80211_hdr *) skb->data;
  9364. + fc = le16_to_cpu(hdr->frame_ctl);
  9365. +
  9366. + /* check that the frame is unicast frame to us */
  9367. + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  9368. + IEEE80211_FCTL_TODS &&
  9369. + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
  9370. + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
  9371. + /* ToDS frame with own addr BSSID and DA */
  9372. + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  9373. + IEEE80211_FCTL_FROMDS &&
  9374. + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
  9375. + /* FromDS frame with own addr as DA */
  9376. + } else
  9377. + return 0;
  9378. +
  9379. + if (skb->len < 24 + 8)
  9380. + return 0;
  9381. +
  9382. + /* check for port access entity Ethernet type */
  9383. +// pos = skb->data + 24;
  9384. + pos = skb->data + hdrlen;
  9385. + ethertype = (pos[6] << 8) | pos[7];
  9386. + if (ethertype == ETH_P_PAE)
  9387. + return 1;
  9388. +
  9389. + return 0;
  9390. +}
  9391. +
  9392. +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
  9393. +static inline int
  9394. +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
  9395. + struct ieee80211_crypt_data *crypt)
  9396. +{
  9397. + struct ieee80211_hdr *hdr;
  9398. + int res, hdrlen;
  9399. +
  9400. + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
  9401. + return 0;
  9402. +
  9403. + hdr = (struct ieee80211_hdr *) skb->data;
  9404. +#ifdef _RTL8187_EXT_PATCH_
  9405. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  9406. + {
  9407. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  9408. + }
  9409. + else
  9410. +#endif
  9411. + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  9412. +
  9413. +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
  9414. + if (ieee->tkip_countermeasures &&
  9415. + strcmp(crypt->ops->name, "TKIP") == 0) {
  9416. + if (net_ratelimit()) {
  9417. + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
  9418. + "received packet from " MAC_FMT "\n",
  9419. + ieee->dev->name, MAC_ARG(hdr->addr2));
  9420. + }
  9421. + return -1;
  9422. + }
  9423. +#endif
  9424. +
  9425. + atomic_inc(&crypt->refcnt);
  9426. + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
  9427. + atomic_dec(&crypt->refcnt);
  9428. + if (res < 0) {
  9429. + IEEE80211_DEBUG_DROP(
  9430. + "decryption failed (SA=" MAC_FMT
  9431. + ") res=%d\n", MAC_ARG(hdr->addr2), res);
  9432. + if (res == -2)
  9433. + IEEE80211_DEBUG_DROP("Decryption failed ICV "
  9434. + "mismatch (key %d)\n",
  9435. + skb->data[hdrlen + 3] >> 6);
  9436. + ieee->ieee_stats.rx_discards_undecryptable++;
  9437. + return -1;
  9438. + }
  9439. +
  9440. + return res;
  9441. +}
  9442. +
  9443. +
  9444. +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
  9445. +static inline int
  9446. +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
  9447. + int keyidx, struct ieee80211_crypt_data *crypt)
  9448. +{
  9449. + struct ieee80211_hdr *hdr;
  9450. + int res, hdrlen;
  9451. +
  9452. + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
  9453. + return 0;
  9454. +
  9455. + hdr = (struct ieee80211_hdr *) skb->data;
  9456. +#ifdef _RTL8187_EXT_PATCH_
  9457. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  9458. + {
  9459. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  9460. + }
  9461. + else
  9462. +#endif
  9463. + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  9464. +
  9465. + atomic_inc(&crypt->refcnt);
  9466. + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
  9467. + atomic_dec(&crypt->refcnt);
  9468. + if (res < 0) {
  9469. + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
  9470. + " (SA=" MAC_FMT " keyidx=%d)\n",
  9471. + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
  9472. + return -1;
  9473. + }
  9474. +
  9475. + return 0;
  9476. +}
  9477. +
  9478. +
  9479. +/* this function is stolen from ipw2200 driver*/
  9480. +#define IEEE_PACKET_RETRY_TIME (5*HZ)
  9481. +static int is_duplicate_packet(struct ieee80211_device *ieee,
  9482. + struct ieee80211_hdr *header)
  9483. +{
  9484. + u16 fc = le16_to_cpu(header->frame_ctl);
  9485. + u16 sc = le16_to_cpu(header->seq_ctl);
  9486. + u16 seq = WLAN_GET_SEQ_SEQ(sc);
  9487. + u16 frag = WLAN_GET_SEQ_FRAG(sc);
  9488. + u16 *last_seq, *last_frag;
  9489. + unsigned long *last_time;
  9490. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  9491. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  9492. + u8 tid;
  9493. +
  9494. +#ifdef _RTL8187_EXT_PATCH_
  9495. + if(ieee->iw_mode == ieee->iw_ext_mode)
  9496. + {
  9497. + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  9498. + }
  9499. + else
  9500. +#endif
  9501. + //TO2DS and QoS
  9502. + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  9503. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
  9504. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9505. + tid = UP2AC(tid);
  9506. + tid ++;
  9507. + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
  9508. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
  9509. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  9510. + tid = UP2AC(tid);
  9511. + tid ++;
  9512. + } else { // no QoS
  9513. + tid = 0;
  9514. + }
  9515. +
  9516. + switch (ieee->iw_mode) {
  9517. + case IW_MODE_ADHOC:
  9518. + {
  9519. + struct list_head *p;
  9520. + struct ieee_ibss_seq *entry = NULL;
  9521. + u8 *mac = header->addr2;
  9522. + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
  9523. + //for (pos = (head)->next; pos != (head); pos = pos->next)
  9524. + __list_for_each(p, &ieee->ibss_mac_hash[index]) {
  9525. + entry = list_entry(p, struct ieee_ibss_seq, list);
  9526. + if (!memcmp(entry->mac, mac, ETH_ALEN))
  9527. + break;
  9528. + }
  9529. + // if (memcmp(entry->mac, mac, ETH_ALEN)){
  9530. + if (p == &ieee->ibss_mac_hash[index]) {
  9531. + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
  9532. + if (!entry) {
  9533. + printk(KERN_WARNING "Cannot malloc new mac entry\n");
  9534. + return 0;
  9535. + }
  9536. + memcpy(entry->mac, mac, ETH_ALEN);
  9537. + entry->seq_num[tid] = seq;
  9538. + entry->frag_num[tid] = frag;
  9539. + entry->packet_time[tid] = jiffies;
  9540. + list_add(&entry->list, &ieee->ibss_mac_hash[index]);
  9541. + return 0;
  9542. + }
  9543. + last_seq = &entry->seq_num[tid];
  9544. + last_frag = &entry->frag_num[tid];
  9545. + last_time = &entry->packet_time[tid];
  9546. + break;
  9547. + }
  9548. +
  9549. + case IW_MODE_INFRA:
  9550. + last_seq = &ieee->last_rxseq_num[tid];
  9551. + last_frag = &ieee->last_rxfrag_num[tid];
  9552. + last_time = &ieee->last_packet_time[tid];
  9553. +
  9554. + break;
  9555. + default:
  9556. +#ifdef _RTL8187_EXT_PATCH_
  9557. + if(ieee->iw_mode == ieee->iw_ext_mode)
  9558. + {
  9559. +#if 0
  9560. + printk("==============> tid = %d\n", tid);
  9561. + last_seq = &ieee->last_rxseq_num[tid];
  9562. + last_frag = &ieee->last_rxfrag_num[tid];
  9563. + last_time = &ieee->last_packet_time[tid];
  9564. +#else
  9565. + struct list_head *p;
  9566. + struct ieee_mesh_seq *entry = NULL;
  9567. + u8 *mac = header->addr2;
  9568. + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
  9569. +
  9570. + __list_for_each(p, &ieee->mesh_mac_hash[index]) {
  9571. + entry = list_entry(p, struct ieee_mesh_seq, list);
  9572. + if (!memcmp(entry->mac, mac, ETH_ALEN))
  9573. + break;
  9574. + }
  9575. + if (p == &ieee->mesh_mac_hash[index]) {
  9576. + entry = kmalloc(sizeof(struct ieee_mesh_seq), GFP_ATOMIC);
  9577. + if (!entry) {
  9578. + printk(KERN_WARNING "Cannot malloc new mac entry for mesh\n");
  9579. + return 0;
  9580. + }
  9581. + memcpy(entry->mac, mac, ETH_ALEN);
  9582. + entry->seq_num = seq;
  9583. + entry->frag_num = frag;
  9584. + entry->packet_time = jiffies;
  9585. + list_add(&entry->list, &ieee->mesh_mac_hash[index]);
  9586. + return 0;
  9587. + }
  9588. + last_seq = &entry->seq_num;
  9589. + last_frag = &entry->frag_num;
  9590. + last_time = &entry->packet_time;
  9591. +#endif
  9592. + break;
  9593. + }
  9594. + else
  9595. +#endif
  9596. + return 0;
  9597. + }
  9598. +
  9599. +// if(tid != 0) {
  9600. +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
  9601. +// }
  9602. + if ((*last_seq == seq) &&
  9603. + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
  9604. + if (*last_frag == frag){
  9605. + //printk(KERN_WARNING "[1] go drop!\n");
  9606. + goto drop;
  9607. +
  9608. + }
  9609. + if (*last_frag + 1 != frag)
  9610. + /* out-of-order fragment */
  9611. + //printk(KERN_WARNING "[2] go drop!\n");
  9612. + goto drop;
  9613. + } else
  9614. + *last_seq = seq;
  9615. +
  9616. + *last_frag = frag;
  9617. + *last_time = jiffies;
  9618. + return 0;
  9619. +
  9620. +drop:
  9621. +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
  9622. +// printk("DUP\n");
  9623. +
  9624. + return 1;
  9625. +}
  9626. +#ifdef JUST_FOR_87SEMESH
  9627. +#define ActionHeadLen 30
  9628. +#define WIFI_MESH_TYPE IEEE80211_FTYPE_DATA
  9629. +#define WIFI_11S_MESH_ACTION 0x00A0
  9630. +#endif
  9631. +
  9632. +/* All received frames are sent to this function. @skb contains the frame in
  9633. + * IEEE 802.11 format, i.e., in the format it was sent over air.
  9634. + * This function is called only as a tasklet (software IRQ). */
  9635. +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
  9636. + struct ieee80211_rx_stats *rx_stats)
  9637. +{
  9638. + struct net_device *dev = ieee->dev;
  9639. + struct ieee80211_hdr *hdr;
  9640. + //struct ieee80211_hdr_3addr_QOS *hdr;
  9641. +
  9642. + size_t hdrlen;
  9643. + u16 fc, type, stype, sc;
  9644. + struct net_device_stats *stats;
  9645. + unsigned int frag;
  9646. + u8 *payload;
  9647. + u16 ethertype;
  9648. +#ifdef NOT_YET
  9649. + struct net_device *wds = NULL;
  9650. + struct sk_buff *skb2 = NULL;
  9651. + struct net_device *wds = NULL;
  9652. + int frame_authorized = 0;
  9653. + int from_assoc_ap = 0;
  9654. + void *sta = NULL;
  9655. +#endif
  9656. +// u16 QOS_ctl = 0;
  9657. + u8 dst[ETH_ALEN];
  9658. + u8 src[ETH_ALEN];
  9659. + u8 bssid[ETH_ALEN];
  9660. + struct ieee80211_crypt_data *crypt = NULL;
  9661. + int keyidx = 0;
  9662. +
  9663. + //Added for mesh by Lawrence.
  9664. + //u8 status;
  9665. + //u32 flags;
  9666. +
  9667. + // cheat the the hdr type
  9668. + hdr = (struct ieee80211_hdr *)skb->data;
  9669. + stats = &ieee->stats;
  9670. +
  9671. + if (skb->len < 10) {
  9672. + printk(KERN_INFO "%s: SKB length < 10\n",
  9673. + dev->name);
  9674. + goto rx_dropped;
  9675. + }
  9676. +#if 0
  9677. +//{added by david for filter the packet listed in the filter table
  9678. +#ifdef _RTL8187_EXT_PATCH_
  9679. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
  9680. + {
  9681. + if(!ieee->ext_patch_ieee80211_acl_query(ieee, hdr->addr2))
  9682. + goto rx_dropped;
  9683. + }
  9684. +#endif
  9685. +//}
  9686. +#endif
  9687. + fc = le16_to_cpu(hdr->frame_ctl);
  9688. + type = WLAN_FC_GET_TYPE(fc);
  9689. + stype = WLAN_FC_GET_STYPE(fc);
  9690. +
  9691. + //Because 87se's bad feature,do more handle.
  9692. +#ifdef JUST_FOR_87SEMESH
  9693. +
  9694. +u8 tmphead[ActionHeadLen];
  9695. + if(type ==WIFI_MESH_TYPE && stype== WIFI_11S_MESH_ACTION )
  9696. + //head=sizeof(struct ieee80211_hdr)=30
  9697. + {
  9698. + memset(tmphead,0,ActionHeadLen);
  9699. + memcpy(tmphead,skb->data,ActionHeadLen);
  9700. +
  9701. + skb_pull(skb,ActionHeadLen+2);
  9702. + memcpy(skb_push(skb,ActionHeadLen),tmphead,ActionHeadLen);
  9703. + hdr = (struct ieee80211_hdr *)skb->data;
  9704. + }
  9705. +
  9706. +#endif
  9707. + sc = le16_to_cpu(hdr->seq_ctl);
  9708. +
  9709. + frag = WLAN_GET_SEQ_FRAG(sc);
  9710. +#ifdef _RTL8187_EXT_PATCH_
  9711. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  9712. + {
  9713. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  9714. + if(skb->len < hdrlen)
  9715. + goto rx_dropped;
  9716. + }
  9717. + else
  9718. +#endif
  9719. + hdrlen = ieee80211_get_hdrlen(fc);
  9720. +
  9721. +#ifdef NOT_YET
  9722. +#if WIRELESS_EXT > 15
  9723. + /* Put this code here so that we avoid duplicating it in all
  9724. + * Rx paths. - Jean II */
  9725. +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
  9726. + /* If spy monitoring on */
  9727. + if (iface->spy_data.spy_number > 0) {
  9728. + struct iw_quality wstats;
  9729. + wstats.level = rx_stats->signal;
  9730. + wstats.noise = rx_stats->noise;
  9731. + wstats.updated = 6; /* No qual value */
  9732. + /* Update spy records */
  9733. + wireless_spy_update(dev, hdr->addr2, &wstats);
  9734. + }
  9735. +#endif /* IW_WIRELESS_SPY */
  9736. +#endif /* WIRELESS_EXT > 15 */
  9737. + hostap_update_rx_stats(local->ap, hdr, rx_stats);
  9738. +#endif
  9739. +
  9740. +#if WIRELESS_EXT > 15
  9741. + if (ieee->iw_mode == IW_MODE_MONITOR) {
  9742. + ieee80211_monitor_rx(ieee, skb, rx_stats);
  9743. + stats->rx_packets++;
  9744. + stats->rx_bytes += skb->len;
  9745. + return 1;
  9746. + }
  9747. +#endif
  9748. + if (ieee->host_decrypt) {
  9749. + int idx = 0;
  9750. + if (skb->len >= hdrlen + 3)
  9751. + idx = skb->data[hdrlen + 3] >> 6;
  9752. +#ifdef _RTL8187_EXT_PATCH_
  9753. +
  9754. + crypt = ieee->cryptlist[0]->crypt[idx];
  9755. +#if 0
  9756. + {
  9757. + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2);
  9758. + if (i == -1)
  9759. + {
  9760. + printk("error find entry in entry list\n");
  9761. + goto rx_dropped;
  9762. + }
  9763. + //printk("%s():"MAC_FMT", find in index:%d", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
  9764. + crypt = ieee->cryptlist[i]->crypt[idx];
  9765. + }
  9766. +#endif
  9767. +#else
  9768. + crypt = ieee->crypt[idx];
  9769. +#endif
  9770. +
  9771. +#ifdef NOT_YET
  9772. + sta = NULL;
  9773. +
  9774. + /* Use station specific key to override default keys if the
  9775. + * receiver address is a unicast address ("individual RA"). If
  9776. + * bcrx_sta_key parameter is set, station specific key is used
  9777. + * even with broad/multicast targets (this is against IEEE
  9778. + * 802.11, but makes it easier to use different keys with
  9779. + * stations that do not support WEP key mapping). */
  9780. +
  9781. + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
  9782. + (void) hostap_handle_sta_crypto(local, hdr, &crypt,
  9783. + &sta);
  9784. +#endif
  9785. +
  9786. + /* allow NULL decrypt to indicate an station specific override
  9787. + * for default encryption */
  9788. + if (crypt && (crypt->ops == NULL ||
  9789. + crypt->ops->decrypt_mpdu == NULL))
  9790. + crypt = NULL;
  9791. +
  9792. + if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
  9793. + /* This seems to be triggered by some (multicast?)
  9794. + * frames from other than current BSS, so just drop the
  9795. + * frames silently instead of filling system log with
  9796. + * these reports. */
  9797. + IEEE80211_DEBUG_DROP("Decryption failed (not set)"
  9798. + " (SA=" MAC_FMT ")\n",
  9799. + MAC_ARG(hdr->addr2));
  9800. + ieee->ieee_stats.rx_discards_undecryptable++;
  9801. + goto rx_dropped;
  9802. + }
  9803. + }
  9804. +
  9805. + if (skb->len < IEEE80211_DATA_HDR3_LEN)
  9806. + goto rx_dropped;
  9807. +
  9808. + // if QoS enabled, should check the sequence for each of the AC
  9809. + if (is_duplicate_packet(ieee, hdr))
  9810. + goto rx_dropped;
  9811. +
  9812. +#ifdef _RTL8187_EXT_PATCH_
  9813. + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
  9814. + ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
  9815. +#endif
  9816. +
  9817. + if (type == IEEE80211_FTYPE_MGMT) {
  9818. +
  9819. + #if 0
  9820. + if ( stype == IEEE80211_STYPE_AUTH &&
  9821. + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
  9822. + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
  9823. + {
  9824. + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
  9825. + "from " MAC_FMT "\n", dev->name,
  9826. + MAC_ARG(hdr->addr2));
  9827. + /* TODO: could inform hostapd about this so that it
  9828. + * could send auth failure report */
  9829. + goto rx_dropped;
  9830. + }
  9831. + #endif
  9832. +
  9833. +
  9834. + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
  9835. + goto rx_dropped;
  9836. + else
  9837. + goto rx_exit;
  9838. + }
  9839. +
  9840. +#ifdef _RTL8187_EXT_PATCH_
  9841. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
  9842. + {
  9843. + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
  9844. + {
  9845. + goto rx_exit;
  9846. + }
  9847. + }
  9848. +#endif
  9849. +
  9850. + /* Data frame - extract src/dst addresses */
  9851. + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  9852. + case IEEE80211_FCTL_FROMDS:
  9853. + memcpy(dst, hdr->addr1, ETH_ALEN);
  9854. + memcpy(src, hdr->addr3, ETH_ALEN);
  9855. + memcpy(bssid, hdr->addr2, ETH_ALEN);
  9856. + break;
  9857. + case IEEE80211_FCTL_TODS:
  9858. + memcpy(dst, hdr->addr3, ETH_ALEN);
  9859. + memcpy(src, hdr->addr2, ETH_ALEN);
  9860. + memcpy(bssid, hdr->addr1, ETH_ALEN);
  9861. + break;
  9862. + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
  9863. + if (skb->len < IEEE80211_DATA_HDR4_LEN)
  9864. + goto rx_dropped;
  9865. + memcpy(dst, hdr->addr3, ETH_ALEN);
  9866. + memcpy(src, hdr->addr4, ETH_ALEN);
  9867. + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
  9868. + break;
  9869. + case 0:
  9870. + memcpy(dst, hdr->addr1, ETH_ALEN);
  9871. + memcpy(src, hdr->addr2, ETH_ALEN);
  9872. + memcpy(bssid, hdr->addr3, ETH_ALEN);
  9873. + break;
  9874. + }
  9875. +
  9876. +#ifdef NOT_YET
  9877. + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
  9878. + goto rx_dropped;
  9879. + if (wds) {
  9880. + skb->dev = dev = wds;
  9881. + stats = hostap_get_stats(dev);
  9882. + }
  9883. +
  9884. + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
  9885. + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
  9886. + ieee->stadev &&
  9887. + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
  9888. + /* Frame from BSSID of the AP for which we are a client */
  9889. + skb->dev = dev = ieee->stadev;
  9890. + stats = hostap_get_stats(dev);
  9891. + from_assoc_ap = 1;
  9892. + }
  9893. +#endif
  9894. +
  9895. + dev->last_rx = jiffies;
  9896. +
  9897. +#ifdef NOT_YET
  9898. + if ((ieee->iw_mode == IW_MODE_MASTER ||
  9899. + ieee->iw_mode == IW_MODE_REPEAT) &&
  9900. + !from_assoc_ap) {
  9901. + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
  9902. + wds != NULL)) {
  9903. + case AP_RX_CONTINUE_NOT_AUTHORIZED:
  9904. + frame_authorized = 0;
  9905. + break;
  9906. + case AP_RX_CONTINUE:
  9907. + frame_authorized = 1;
  9908. + break;
  9909. + case AP_RX_DROP:
  9910. + goto rx_dropped;
  9911. + case AP_RX_EXIT:
  9912. + goto rx_exit;
  9913. + }
  9914. + }
  9915. +#endif
  9916. +
  9917. +#ifdef _RTL8187_EXT_PATCH_
  9918. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
  9919. + {
  9920. + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
  9921. + goto rx_dropped;
  9922. + }
  9923. + else
  9924. +#endif
  9925. + /* Nullfunc frames may have PS-bit set, so they must be passed to
  9926. + * hostap_handle_sta_rx() before being dropped here. */
  9927. + if (stype != IEEE80211_STYPE_DATA &&
  9928. + stype != IEEE80211_STYPE_DATA_CFACK &&
  9929. + stype != IEEE80211_STYPE_DATA_CFPOLL &&
  9930. + stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
  9931. + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
  9932. + ) {
  9933. + if (stype != IEEE80211_STYPE_NULLFUNC)
  9934. + IEEE80211_DEBUG_DROP(
  9935. + "RX: dropped data frame "
  9936. + "with no data (type=0x%02x, "
  9937. + "subtype=0x%02x, len=%d)\n",
  9938. + type, stype, skb->len);
  9939. + goto rx_dropped;
  9940. + }
  9941. +
  9942. + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
  9943. + goto rx_dropped;
  9944. +
  9945. + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
  9946. +#ifdef _RTL8187_EXT_PATCH_
  9947. + if (ieee->host_decrypt && crypt) {
  9948. + int idx = 0;
  9949. + if (skb->len >= hdrlen + 3)
  9950. + idx = skb->data[hdrlen + 3] >> 6;
  9951. + if (ieee->iw_ext_mode == ieee->iw_mode) //if in mesh mode
  9952. + {
  9953. + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2, 0);
  9954. + if (i == -1)
  9955. + {
  9956. + printk("error find entry in entry list\n");
  9957. + goto rx_dropped;
  9958. + }
  9959. + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
  9960. + if (ieee->cryptlist[i]&&ieee->cryptlist[i]->crypt[idx])
  9961. + crypt = ieee->cryptlist[i]->crypt[idx];
  9962. +
  9963. + else
  9964. + crypt = NULL;
  9965. + }
  9966. + else
  9967. + crypt = ieee->cryptlist[0]->crypt[idx];
  9968. + }
  9969. +#endif
  9970. +
  9971. + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  9972. + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
  9973. + goto rx_dropped;
  9974. +
  9975. + hdr = (struct ieee80211_hdr *) skb->data;
  9976. +
  9977. + /* skb: hdr + (possibly fragmented) plaintext payload */
  9978. + // PR: FIXME: hostap has additional conditions in the "if" below:
  9979. + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  9980. + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
  9981. + int flen;
  9982. + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
  9983. + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
  9984. +
  9985. + if (!frag_skb) {
  9986. + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
  9987. + "Rx cannot get skb from fragment "
  9988. + "cache (morefrag=%d seq=%u frag=%u)\n",
  9989. + (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
  9990. + WLAN_GET_SEQ_SEQ(sc), frag);
  9991. + goto rx_dropped;
  9992. + }
  9993. + flen = skb->len;
  9994. + if (frag != 0)
  9995. + flen -= hdrlen;
  9996. +
  9997. + if (frag_skb->tail + flen > frag_skb->end) {
  9998. + printk(KERN_WARNING "%s: host decrypted and "
  9999. + "reassembled frame did not fit skb\n",
  10000. + dev->name);
  10001. + ieee80211_frag_cache_invalidate(ieee, hdr);
  10002. + goto rx_dropped;
  10003. + }
  10004. +
  10005. + if (frag == 0) {
  10006. + /* copy first fragment (including full headers) into
  10007. + * beginning of the fragment cache skb */
  10008. + memcpy(skb_put(frag_skb, flen), skb->data, flen);
  10009. + } else {
  10010. + /* append frame payload to the end of the fragment
  10011. + * cache skb */
  10012. + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
  10013. + flen);
  10014. + }
  10015. + dev_kfree_skb_any(skb);
  10016. + skb = NULL;
  10017. +
  10018. + if (fc & IEEE80211_FCTL_MOREFRAGS) {
  10019. + /* more fragments expected - leave the skb in fragment
  10020. + * cache for now; it will be delivered to upper layers
  10021. + * after all fragments have been received */
  10022. + goto rx_exit;
  10023. + }
  10024. +
  10025. + /* this was the last fragment and the frame will be
  10026. + * delivered, so remove skb from fragment cache */
  10027. + skb = frag_skb;
  10028. + hdr = (struct ieee80211_hdr *) skb->data;
  10029. + ieee80211_frag_cache_invalidate(ieee, hdr);
  10030. + }
  10031. +
  10032. + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
  10033. + * encrypted/authenticated */
  10034. + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  10035. + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
  10036. + goto rx_dropped;
  10037. +
  10038. + hdr = (struct ieee80211_hdr *) skb->data;
  10039. + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
  10040. + if (/*ieee->ieee802_1x &&*/
  10041. + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  10042. +
  10043. +#ifdef CONFIG_IEEE80211_DEBUG
  10044. + /* pass unencrypted EAPOL frames even if encryption is
  10045. + * configured */
  10046. + struct eapol *eap = (struct eapol *)(skb->data +
  10047. + 24);
  10048. + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  10049. + eap_get_type(eap->type));
  10050. +#endif
  10051. + } else {
  10052. + IEEE80211_DEBUG_DROP(
  10053. + "encryption configured, but RX "
  10054. + "frame not encrypted (SA=" MAC_FMT ")\n",
  10055. + MAC_ARG(hdr->addr2));
  10056. + goto rx_dropped;
  10057. + }
  10058. + }
  10059. +
  10060. +#ifdef CONFIG_IEEE80211_DEBUG
  10061. + if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
  10062. + ieee80211_is_eapol_frame(ieee, skb)) {
  10063. + struct eapol *eap = (struct eapol *)(skb->data +
  10064. + 24);
  10065. + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  10066. + eap_get_type(eap->type));
  10067. + }
  10068. +#endif
  10069. +
  10070. + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
  10071. + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  10072. + IEEE80211_DEBUG_DROP(
  10073. + "dropped unencrypted RX data "
  10074. + "frame from " MAC_FMT
  10075. + " (drop_unencrypted=1)\n",
  10076. + MAC_ARG(hdr->addr2));
  10077. + goto rx_dropped;
  10078. + }
  10079. +/*
  10080. + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  10081. + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
  10082. + }
  10083. +*/
  10084. + /* skb: hdr + (possible reassembled) full plaintext payload */
  10085. + payload = skb->data + hdrlen;
  10086. + ethertype = (payload[6] << 8) | payload[7];
  10087. +
  10088. +#ifdef NOT_YET
  10089. + /* If IEEE 802.1X is used, check whether the port is authorized to send
  10090. + * the received frame. */
  10091. + if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
  10092. + if (ethertype == ETH_P_PAE) {
  10093. + printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
  10094. + dev->name);
  10095. + if (ieee->hostapd && ieee->apdev) {
  10096. + /* Send IEEE 802.1X frames to the user
  10097. + * space daemon for processing */
  10098. + prism2_rx_80211(ieee->apdev, skb, rx_stats,
  10099. + PRISM2_RX_MGMT);
  10100. + ieee->apdevstats.rx_packets++;
  10101. + ieee->apdevstats.rx_bytes += skb->len;
  10102. + goto rx_exit;
  10103. + }
  10104. + } else if (!frame_authorized) {
  10105. + printk(KERN_DEBUG "%s: dropped frame from "
  10106. + "unauthorized port (IEEE 802.1X): "
  10107. + "ethertype=0x%04x\n",
  10108. + dev->name, ethertype);
  10109. + goto rx_dropped;
  10110. + }
  10111. + }
  10112. +#endif
  10113. +
  10114. +#ifdef _RTL8187_EXT_PATCH_
  10115. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
  10116. + {
  10117. + if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
  10118. + {
  10119. + stats->rx_packets++;
  10120. + stats->rx_bytes += skb->len;
  10121. + goto rx_exit;
  10122. + }
  10123. + else
  10124. + goto rx_dropped;
  10125. + }
  10126. +#endif
  10127. + ieee->NumRxDataInPeriod++;
  10128. +// ieee->NumRxOkTotal++;
  10129. + /* convert hdr + possible LLC headers into Ethernet header */
  10130. + if (skb->len - hdrlen >= 8 &&
  10131. + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
  10132. + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
  10133. + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
  10134. + /* remove RFC1042 or Bridge-Tunnel encapsulation and
  10135. + * replace EtherType */
  10136. + skb_pull(skb, hdrlen + SNAP_SIZE);
  10137. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  10138. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  10139. + } else {
  10140. + u16 len;
  10141. + /* Leave Ethernet header part of hdr and full payload */
  10142. + skb_pull(skb, hdrlen);
  10143. + len = htons(skb->len);
  10144. + memcpy(skb_push(skb, 2), &len, 2);
  10145. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  10146. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  10147. + }
  10148. +
  10149. +#ifdef NOT_YET
  10150. + if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  10151. + IEEE80211_FCTL_TODS) &&
  10152. + skb->len >= ETH_HLEN + ETH_ALEN) {
  10153. + /* Non-standard frame: get addr4 from its bogus location after
  10154. + * the payload */
  10155. + memcpy(skb->data + ETH_ALEN,
  10156. + skb->data + skb->len - ETH_ALEN, ETH_ALEN);
  10157. + skb_trim(skb, skb->len - ETH_ALEN);
  10158. + }
  10159. +#endif
  10160. +
  10161. + stats->rx_packets++;
  10162. + stats->rx_bytes += skb->len;
  10163. +
  10164. +#ifdef NOT_YET
  10165. + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
  10166. + ieee->ap->bridge_packets) {
  10167. + if (dst[0] & 0x01) {
  10168. + /* copy multicast frame both to the higher layers and
  10169. + * to the wireless media */
  10170. + ieee->ap->bridged_multicast++;
  10171. + skb2 = skb_clone(skb, GFP_ATOMIC);
  10172. + if (skb2 == NULL)
  10173. + printk(KERN_DEBUG "%s: skb_clone failed for "
  10174. + "multicast frame\n", dev->name);
  10175. + } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
  10176. + /* send frame directly to the associated STA using
  10177. + * wireless media and not passing to higher layers */
  10178. + ieee->ap->bridged_unicast++;
  10179. + skb2 = skb;
  10180. + skb = NULL;
  10181. + }
  10182. + }
  10183. +
  10184. + if (skb2 != NULL) {
  10185. + /* send to wireless media */
  10186. + skb2->protocol = __constant_htons(ETH_P_802_3);
  10187. + skb2->mac.raw = skb2->nh.raw = skb2->data;
  10188. + /* skb2->nh.raw = skb2->data + ETH_HLEN; */
  10189. + skb2->dev = dev;
  10190. + dev_queue_xmit(skb2);
  10191. + }
  10192. +
  10193. +#endif
  10194. + if (skb) {
  10195. + //printk("0skb_len(%d)\n", skb->len);
  10196. + skb->protocol = eth_type_trans(skb, dev);
  10197. + memset(skb->cb, 0, sizeof(skb->cb));
  10198. + skb->dev = dev;
  10199. + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
  10200. + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
  10201. + ieee->last_rx_ps_time = jiffies;
  10202. + //printk("1skb_len(%d)\n", skb->len);
  10203. + netif_rx(skb);
  10204. + }
  10205. +
  10206. +//by lizhaoming for LED_RX 2008.6.23
  10207. +#ifdef LED_SHIN
  10208. +// printk("==================>data rcvd\n");
  10209. + ieee->ieee80211_led_contorl(dev,LED_CTL_RX);
  10210. +#endif
  10211. +
  10212. + rx_exit:
  10213. +#ifdef NOT_YET
  10214. + if (sta)
  10215. + hostap_handle_sta_release(sta);
  10216. +#endif
  10217. + return 1;
  10218. +
  10219. + rx_dropped:
  10220. + stats->rx_dropped++;
  10221. +#if 0
  10222. + int i;
  10223. + printk("======>dropped: %s():addr2:"MAC_FMT",addr1:"MAC_FMT",skb->len:%d, hdrlen:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr1), skb->len, hdrlen);
  10224. + for (i = 0; i < skb->len; i++) {
  10225. + if (i % 16 == 0) printk("\n\t");
  10226. + printk("%2x ", *(skb->data+i));
  10227. + }
  10228. +
  10229. + printk("\n");
  10230. +#endif
  10231. + /* Returning 0 indicates to caller that we have not handled the SKB--
  10232. + * so it is still allocated and can be used again by underlying
  10233. + * hardware as a DMA target */
  10234. + return 0;
  10235. +}
  10236. +
  10237. +#ifdef _RTL8187_EXT_PATCH_
  10238. +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
  10239. +{
  10240. + u8 *payload;
  10241. + u16 ethertype;
  10242. +
  10243. + /* skb: hdr + (possible reassembled) full plaintext payload */
  10244. + payload = skb->data + hdrlen;
  10245. + ethertype = (payload[6] << 8) | payload[7];
  10246. +
  10247. + /* convert hdr + possible LLC headers into Ethernet header */
  10248. + if (skb->len - hdrlen >= 8 &&
  10249. + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
  10250. + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
  10251. + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
  10252. + /* remove RFC1042 or Bridge-Tunnel encapsulation and
  10253. + * replace EtherType */
  10254. + skb_pull(skb, hdrlen + SNAP_SIZE);
  10255. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  10256. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  10257. + } else {
  10258. + u16 len;
  10259. + /* Leave Ethernet header part of hdr and full payload */
  10260. + skb_pull(skb, hdrlen);
  10261. + len = htons(skb->len);
  10262. + memcpy(skb_push(skb, 2), &len, 2);
  10263. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  10264. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  10265. + }
  10266. +
  10267. + return 1;
  10268. +}
  10269. +#endif // _RTL8187_EXT_PATCH_
  10270. +
  10271. +
  10272. +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
  10273. +
  10274. +static inline int ieee80211_is_ofdm_rate(u8 rate)
  10275. +{
  10276. + switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
  10277. + case IEEE80211_OFDM_RATE_6MB:
  10278. + case IEEE80211_OFDM_RATE_9MB:
  10279. + case IEEE80211_OFDM_RATE_12MB:
  10280. + case IEEE80211_OFDM_RATE_18MB:
  10281. + case IEEE80211_OFDM_RATE_24MB:
  10282. + case IEEE80211_OFDM_RATE_36MB:
  10283. + case IEEE80211_OFDM_RATE_48MB:
  10284. + case IEEE80211_OFDM_RATE_54MB:
  10285. + return 1;
  10286. + }
  10287. + return 0;
  10288. +}
  10289. +
  10290. +
  10291. +//
  10292. +// Description:
  10293. +// Translate 0-100 signal strength index into dBm.
  10294. +//
  10295. +int
  10296. +TranslateToDbm8187(
  10297. + unsigned char SignalStrengthIndex // 0-100 index.
  10298. + )
  10299. +{
  10300. + unsigned char SignalPower; // in dBm.
  10301. +
  10302. + // Translate to dBm (x=0.5y-95).
  10303. + //SignalPower = (int)((SignalStrengthIndex + 1) >> 1);
  10304. + SignalPower = (int)SignalStrengthIndex * 7 / 10;
  10305. + SignalPower -= 95;
  10306. +// printk("==>SignalPower:%d\n", SignalPower);
  10307. + return SignalPower;
  10308. +}
  10309. +
  10310. +static inline int ieee80211_SignalStrengthTranslate(
  10311. + int CurrSS
  10312. + )
  10313. +{
  10314. + int RetSS;
  10315. +
  10316. + // Step 1. Scale mapping.
  10317. + if(CurrSS >= 71 && CurrSS <= 100)
  10318. + {
  10319. + RetSS = 95 + (((CurrSS - 70) / 6 == 5) ? 5 : ((CurrSS - 70) / 6 + 1));
  10320. + }
  10321. + else if(CurrSS >= 41 && CurrSS <= 70)
  10322. + {
  10323. + RetSS = 83 + ((CurrSS - 40) / 3);
  10324. + }
  10325. + else if(CurrSS >= 31 && CurrSS <= 40)
  10326. + {
  10327. + RetSS = 71 + (CurrSS - 30);
  10328. + }
  10329. + else if(CurrSS >= 21 && CurrSS <= 30)
  10330. + {
  10331. + RetSS = 59 + (CurrSS - 20);
  10332. + }
  10333. + else if(CurrSS >= 5 && CurrSS <= 20)
  10334. + {
  10335. + RetSS = 47 + (((CurrSS - 5) * 2) / 3);
  10336. + }
  10337. + else if(CurrSS == 4)
  10338. + {
  10339. + RetSS = 37;
  10340. + }
  10341. + else if(CurrSS == 3)
  10342. + {
  10343. + RetSS = 27;
  10344. + }
  10345. + else if(CurrSS == 2)
  10346. + {
  10347. + RetSS = 18;
  10348. + }
  10349. + else if(CurrSS == 1)
  10350. + {
  10351. + RetSS = 9;
  10352. + }
  10353. + else
  10354. + {
  10355. + RetSS = CurrSS;
  10356. + }
  10357. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  10358. +
  10359. + // Step 2. Smoothing.
  10360. +
  10361. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  10362. +
  10363. + return RetSS;
  10364. +}
  10365. +
  10366. +#ifdef ENABLE_DOT11D
  10367. +static inline void ieee80211_extract_country_ie(
  10368. + struct ieee80211_device *ieee,
  10369. + struct ieee80211_info_element *info_element,
  10370. + struct ieee80211_network *network,
  10371. + u8 * addr2
  10372. +)
  10373. +{
  10374. +#if 0
  10375. + u32 i = 0;
  10376. + u8 * p = (u8*)info_element->data;
  10377. + printk("-----------------------\n");
  10378. + printk("%s Country IE:", network->ssid);
  10379. + for(i=0; i<info_element->len; i++)
  10380. + printk("\t%2.2x", *(p+i));
  10381. + printk("\n-----------------------\n");
  10382. +#endif
  10383. + if(IS_DOT11D_ENABLE(ieee))
  10384. + {
  10385. + if(info_element->len!= 0)
  10386. + {
  10387. + memcpy(network->CountryIeBuf, info_element->data, info_element->len);
  10388. + network->CountryIeLen = info_element->len;
  10389. +
  10390. + if(!IS_COUNTRY_IE_VALID(ieee))
  10391. + {
  10392. + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
  10393. + }
  10394. + }
  10395. +
  10396. + //
  10397. + // 070305, rcnjko: I update country IE watch dog here because
  10398. + // some AP (e.g. Cisco 1242) don't include country IE in their
  10399. + // probe response frame.
  10400. + //
  10401. + if(IS_EQUAL_CIE_SRC(ieee, addr2) )
  10402. + {
  10403. + UPDATE_CIE_WATCHDOG(ieee);
  10404. + }
  10405. + }
  10406. +
  10407. +}
  10408. +#endif
  10409. +
  10410. +
  10411. + inline int ieee80211_network_init(
  10412. + struct ieee80211_device *ieee,
  10413. + struct ieee80211_probe_response *beacon,
  10414. + struct ieee80211_network *network,
  10415. + struct ieee80211_rx_stats *stats)
  10416. +{
  10417. +#ifdef CONFIG_IEEE80211_DEBUG
  10418. + char rates_str[64];
  10419. + char *p;
  10420. +#endif
  10421. + struct ieee80211_info_element *info_element;
  10422. + u16 left;
  10423. + u8 i;
  10424. + short offset;
  10425. +
  10426. + /* Pull out fixed field data */
  10427. + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
  10428. + network->capability = beacon->capability;
  10429. + network->last_scanned = jiffies;
  10430. + network->time_stamp[0] = beacon->time_stamp[0];
  10431. + network->time_stamp[1] = beacon->time_stamp[1];
  10432. + network->beacon_interval = beacon->beacon_interval;
  10433. + /* Where to pull this? beacon->listen_interval;*/
  10434. + network->listen_interval = 0x0A;
  10435. + network->rates_len = network->rates_ex_len = 0;
  10436. + network->last_associate = 0;
  10437. + network->ssid_len = 0;
  10438. + network->flags = 0;
  10439. + network->atim_window = 0;
  10440. + network->QoS_Enable = 0;
  10441. +#ifdef THOMAS_TURBO
  10442. + network->Turbo_Enable = 0;
  10443. +#endif
  10444. +#ifdef ENABLE_DOT11D
  10445. + network->CountryIeLen = 0;
  10446. + memset(network->CountryIeBuf, 0, MAX_IE_LEN);
  10447. +#endif
  10448. +
  10449. + if (stats->freq == IEEE80211_52GHZ_BAND) {
  10450. + /* for A band (No DS info) */
  10451. + network->channel = stats->received_channel;
  10452. + } else
  10453. + network->flags |= NETWORK_HAS_CCK;
  10454. +
  10455. + network->wpa_ie_len = 0;
  10456. + network->rsn_ie_len = 0;
  10457. +
  10458. + info_element = &beacon->info_element;
  10459. + left = stats->len - ((void *)info_element - (void *)beacon);
  10460. + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
  10461. + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
  10462. + IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
  10463. + info_element->len + sizeof(struct ieee80211_info_element),
  10464. + left);
  10465. + return 1;
  10466. + }
  10467. +
  10468. + switch (info_element->id) {
  10469. + case MFIE_TYPE_SSID:
  10470. + if (ieee80211_is_empty_essid(info_element->data,
  10471. + info_element->len)) {
  10472. + network->flags |= NETWORK_EMPTY_ESSID;
  10473. + break;
  10474. + }
  10475. +
  10476. + network->ssid_len = min(info_element->len,
  10477. + (u8)IW_ESSID_MAX_SIZE);
  10478. + memcpy(network->ssid, info_element->data, network->ssid_len);
  10479. + if (network->ssid_len < IW_ESSID_MAX_SIZE)
  10480. + memset(network->ssid + network->ssid_len, 0,
  10481. + IW_ESSID_MAX_SIZE - network->ssid_len);
  10482. +
  10483. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
  10484. + network->ssid, network->ssid_len);
  10485. + break;
  10486. +
  10487. + case MFIE_TYPE_RATES:
  10488. +#ifdef CONFIG_IEEE80211_DEBUG
  10489. + p = rates_str;
  10490. +#endif
  10491. + network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
  10492. + for (i = 0; i < network->rates_len; i++) {
  10493. + network->rates[i] = info_element->data[i];
  10494. +#ifdef CONFIG_IEEE80211_DEBUG
  10495. + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  10496. +#endif
  10497. + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  10498. + network->flags |= NETWORK_HAS_OFDM;
  10499. + if (info_element->data[i] &
  10500. + IEEE80211_BASIC_RATE_MASK)
  10501. + network->flags &=
  10502. + ~NETWORK_HAS_CCK;
  10503. + }
  10504. + }
  10505. +
  10506. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
  10507. + rates_str, network->rates_len);
  10508. + break;
  10509. +
  10510. + case MFIE_TYPE_RATES_EX:
  10511. +#ifdef CONFIG_IEEE80211_DEBUG
  10512. + p = rates_str;
  10513. +#endif
  10514. + network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
  10515. + for (i = 0; i < network->rates_ex_len; i++) {
  10516. + network->rates_ex[i] = info_element->data[i];
  10517. +#ifdef CONFIG_IEEE80211_DEBUG
  10518. + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  10519. +#endif
  10520. + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  10521. + network->flags |= NETWORK_HAS_OFDM;
  10522. + if (info_element->data[i] &
  10523. + IEEE80211_BASIC_RATE_MASK)
  10524. + network->flags &=
  10525. + ~NETWORK_HAS_CCK;
  10526. + }
  10527. + }
  10528. +
  10529. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
  10530. + rates_str, network->rates_ex_len);
  10531. + break;
  10532. +
  10533. + case MFIE_TYPE_DS_SET:
  10534. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
  10535. + info_element->data[0]);
  10536. + if (stats->freq == IEEE80211_24GHZ_BAND)
  10537. + network->channel = info_element->data[0];
  10538. + break;
  10539. +
  10540. + case MFIE_TYPE_FH_SET:
  10541. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
  10542. + break;
  10543. +
  10544. + case MFIE_TYPE_CF_SET:
  10545. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
  10546. + break;
  10547. +
  10548. + case MFIE_TYPE_TIM:
  10549. +
  10550. + if(info_element->len < 4)
  10551. + break;
  10552. +
  10553. + network->dtim_period = info_element->data[1];
  10554. +
  10555. + if(ieee->state != IEEE80211_LINKED)
  10556. + break;
  10557. +
  10558. + network->last_dtim_sta_time[0] = stats->mac_time[0];
  10559. + network->last_dtim_sta_time[1] = stats->mac_time[1];
  10560. +
  10561. + network->dtim_data = IEEE80211_DTIM_VALID;
  10562. +
  10563. + if(info_element->data[0] != 0)
  10564. + break;
  10565. +
  10566. + if(info_element->data[2] & 1)
  10567. + network->dtim_data |= IEEE80211_DTIM_MBCAST;
  10568. +
  10569. + offset = (info_element->data[2] >> 1)*2;
  10570. +
  10571. + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
  10572. +
  10573. + if(ieee->assoc_id < offset ||
  10574. + ieee->assoc_id > 8*(offset + info_element->len -3))
  10575. +
  10576. + break;
  10577. +
  10578. +
  10579. + offset = offset + ieee->assoc_id / 8;// + ((aid % 8)? 0 : 1) ;
  10580. +
  10581. + // printk("offset:%x data:%x, ucast:%d\n", offset,
  10582. + // info_element->data[3+offset] ,
  10583. + // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
  10584. +
  10585. + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
  10586. + network->dtim_data |= IEEE80211_DTIM_UCAST;
  10587. +
  10588. + break;
  10589. +
  10590. + case MFIE_TYPE_IBSS_SET:
  10591. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
  10592. + break;
  10593. +
  10594. + case MFIE_TYPE_CHALLENGE:
  10595. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
  10596. + break;
  10597. +
  10598. + case MFIE_TYPE_GENERIC:
  10599. + //nic is 87B
  10600. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
  10601. + info_element->len);
  10602. + if (info_element->len >= 4 &&
  10603. + info_element->data[0] == 0x00 &&
  10604. + info_element->data[1] == 0x50 &&
  10605. + info_element->data[2] == 0xf2 &&
  10606. + info_element->data[3] == 0x01) {
  10607. + network->wpa_ie_len = min(info_element->len + 2,
  10608. + MAX_WPA_IE_LEN);
  10609. + memcpy(network->wpa_ie, info_element,
  10610. + network->wpa_ie_len);
  10611. + }
  10612. +
  10613. +#ifdef THOMAS_TURBO
  10614. + if (info_element->len == 7 &&
  10615. + info_element->data[0] == 0x00 &&
  10616. + info_element->data[1] == 0xe0 &&
  10617. + info_element->data[2] == 0x4c &&
  10618. + info_element->data[3] == 0x01 &&
  10619. + info_element->data[4] == 0x02) {
  10620. + network->Turbo_Enable = 1;
  10621. + }
  10622. +#endif
  10623. + if (1 == stats->nic_type) {//nic 87
  10624. + break;
  10625. + }
  10626. +
  10627. + if (info_element->len >= 5 &&
  10628. + info_element->data[0] == 0x00 &&
  10629. + info_element->data[1] == 0x50 &&
  10630. + info_element->data[2] == 0xf2 &&
  10631. + info_element->data[3] == 0x02 &&
  10632. + info_element->data[4] == 0x00) {
  10633. + //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
  10634. + //WMM Information Element
  10635. + network->wmm_info = info_element->data[6];
  10636. + network->QoS_Enable = 1;
  10637. + }
  10638. +
  10639. + if (info_element->len >= 8 &&
  10640. + info_element->data[0] == 0x00 &&
  10641. + info_element->data[1] == 0x50 &&
  10642. + info_element->data[2] == 0xf2 &&
  10643. + info_element->data[3] == 0x02 &&
  10644. + info_element->data[4] == 0x01) {
  10645. + // Not care about version at present.
  10646. + //WMM Information Element
  10647. + //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
  10648. + network->wmm_info = info_element->data[6];
  10649. + //WMM Parameter Element
  10650. + memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
  10651. + network->QoS_Enable = 1;
  10652. + }
  10653. + break;
  10654. +
  10655. + case MFIE_TYPE_RSN:
  10656. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
  10657. + info_element->len);
  10658. + network->rsn_ie_len = min(info_element->len + 2,
  10659. + MAX_WPA_IE_LEN);
  10660. + memcpy(network->rsn_ie, info_element,
  10661. + network->rsn_ie_len);
  10662. + break;
  10663. +
  10664. +#ifdef ENABLE_DOT11D
  10665. + case MFIE_TYPE_COUNTRY:
  10666. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
  10667. + info_element->len);
  10668. +// printk("=====>Receive <%s> Country IE\n",network->ssid);
  10669. + ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
  10670. + break;
  10671. +#endif
  10672. +
  10673. + default:
  10674. + IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
  10675. + info_element->id);
  10676. + break;
  10677. + }
  10678. +
  10679. + left -= sizeof(struct ieee80211_info_element_hdr) +
  10680. + info_element->len;
  10681. + info_element = (struct ieee80211_info_element *)
  10682. + &info_element->data[info_element->len];
  10683. + }
  10684. +
  10685. + network->mode = 0;
  10686. + if (stats->freq == IEEE80211_52GHZ_BAND)
  10687. + network->mode = IEEE_A;
  10688. + else {
  10689. + if (network->flags & NETWORK_HAS_OFDM)
  10690. + network->mode |= IEEE_G;
  10691. + if (network->flags & NETWORK_HAS_CCK)
  10692. + network->mode |= IEEE_B;
  10693. + }
  10694. +
  10695. + if (network->mode == 0) {
  10696. + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
  10697. + "network.\n",
  10698. + escape_essid(network->ssid,
  10699. + network->ssid_len),
  10700. + MAC_ARG(network->bssid));
  10701. + return 1;
  10702. + }
  10703. +
  10704. + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
  10705. + network->flags |= NETWORK_EMPTY_ESSID;
  10706. +
  10707. +#if 1
  10708. + //if(strcmp(network->ssid, "linksys_lzm000") == 0)
  10709. + // printk("----signalstrength = %d ", stats->signalstrength);
  10710. + stats->signal = TranslateToDbm8187(stats->signalstrength);
  10711. + //stats->noise = stats->signal - stats->noise;
  10712. + stats->noise = TranslateToDbm8187(100 - stats->signalstrength) - 25;
  10713. +#endif
  10714. + memcpy(&network->stats, stats, sizeof(network->stats));
  10715. +
  10716. + //YJ,test,080611
  10717. + //if(strcmp(network->ssid, "ZyXEL") == 0)
  10718. + // IEEE_NET_DUMP(network);
  10719. +
  10720. + return 0;
  10721. +}
  10722. +
  10723. +static inline int is_same_network(struct ieee80211_network *src,
  10724. + struct ieee80211_network *dst,
  10725. + struct ieee80211_device * ieee)
  10726. +{
  10727. + /* A network is only a duplicate if the channel, BSSID, ESSID
  10728. + * and the capability field (in particular IBSS and BSS) all match.
  10729. + * We treat all <hidden> with the same BSSID and channel
  10730. + * as one network */
  10731. + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  10732. + //((src->ssid_len == dst->ssid_len) &&
  10733. + (src->channel == dst->channel) &&
  10734. + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
  10735. + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  10736. + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
  10737. + ((src->capability & WLAN_CAPABILITY_IBSS) ==
  10738. + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
  10739. + ((src->capability & WLAN_CAPABILITY_BSS) ==
  10740. + (dst->capability & WLAN_CAPABILITY_BSS)));
  10741. +}
  10742. +
  10743. +inline void update_network(struct ieee80211_network *dst,
  10744. + struct ieee80211_network *src)
  10745. +{
  10746. + unsigned char quality = src->stats.signalstrength;
  10747. + unsigned char signal = 0;
  10748. + unsigned char noise = 0;
  10749. + if(dst->stats.signalstrength > 0) {
  10750. + quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
  10751. + }
  10752. + signal = TranslateToDbm8187(quality);
  10753. + //noise = signal - src->stats.noise;
  10754. + if(dst->stats.noise > 0)
  10755. + noise = (dst->stats.noise * 5 + src->stats.noise)/6;
  10756. + //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
  10757. +// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
  10758. + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
  10759. + dst->stats.signalstrength = quality;
  10760. + dst->stats.signal = signal;
  10761. + dst->stats.noise = noise;
  10762. + dst->capability = src->capability;
  10763. + memcpy(dst->rates, src->rates, src->rates_len);
  10764. + dst->rates_len = src->rates_len;
  10765. + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
  10766. + dst->rates_ex_len = src->rates_ex_len;
  10767. +
  10768. + //YJ,add,080819,for hidden ap
  10769. + if(src->ssid_len > 0)
  10770. + {
  10771. + //if(src->ssid_len == 13)
  10772. + // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
  10773. + memset(dst->ssid, 0, dst->ssid_len);
  10774. + dst->ssid_len = src->ssid_len;
  10775. + memcpy(dst->ssid, src->ssid, src->ssid_len);
  10776. + }
  10777. + //YJ,add,080819,for hidden ap,end
  10778. + dst->channel = src->channel;
  10779. + dst->mode = src->mode;
  10780. + dst->flags = src->flags;
  10781. + dst->time_stamp[0] = src->time_stamp[0];
  10782. + dst->time_stamp[1] = src->time_stamp[1];
  10783. +
  10784. + dst->beacon_interval = src->beacon_interval;
  10785. + dst->listen_interval = src->listen_interval;
  10786. + dst->atim_window = src->atim_window;
  10787. + dst->dtim_period = src->dtim_period;
  10788. + dst->dtim_data = src->dtim_data;
  10789. + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
  10790. + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
  10791. +
  10792. + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
  10793. + dst->wpa_ie_len = src->wpa_ie_len;
  10794. + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
  10795. + dst->rsn_ie_len = src->rsn_ie_len;
  10796. +
  10797. + dst->last_scanned = jiffies;
  10798. + /* dst->last_associate is not overwritten */
  10799. +#if 1
  10800. + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
  10801. +/*
  10802. + if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
  10803. + memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
  10804. + }
  10805. +*/
  10806. + if(src->wmm_param[0].ac_aci_acm_aifsn|| \
  10807. + src->wmm_param[1].ac_aci_acm_aifsn|| \
  10808. + src->wmm_param[2].ac_aci_acm_aifsn|| \
  10809. + src->wmm_param[1].ac_aci_acm_aifsn) {
  10810. + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
  10811. + }
  10812. + dst->QoS_Enable = src->QoS_Enable;
  10813. +#else
  10814. + dst->QoS_Enable = 1;//for Rtl8187 simulation
  10815. +#endif
  10816. + dst->SignalStrength = src->SignalStrength;
  10817. +#ifdef THOMAS_TURBO
  10818. + dst->Turbo_Enable = src->Turbo_Enable;
  10819. +#endif
  10820. +#ifdef ENABLE_DOT11D
  10821. + dst->CountryIeLen = src->CountryIeLen;
  10822. + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
  10823. +#endif
  10824. +
  10825. +}
  10826. +
  10827. +inline void ieee80211_process_probe_response(
  10828. + struct ieee80211_device *ieee,
  10829. + struct ieee80211_probe_response *beacon,
  10830. + struct ieee80211_rx_stats *stats)
  10831. +{
  10832. + struct ieee80211_network network;
  10833. + struct ieee80211_network *target;
  10834. + struct ieee80211_network *oldest = NULL;
  10835. +#ifdef CONFIG_IEEE80211_DEBUG
  10836. + struct ieee80211_info_element *info_element = &beacon->info_element;
  10837. +#endif
  10838. + unsigned long flags;
  10839. + short renew;
  10840. + u8 wmm_info;
  10841. + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;
  10842. +
  10843. + memset(&network, 0, sizeof(struct ieee80211_network));
  10844. +//rz
  10845. +#ifdef _RTL8187_EXT_PATCH_
  10846. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
  10847. + ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
  10848. + return;
  10849. + }
  10850. +#endif
  10851. + IEEE80211_DEBUG_SCAN(
  10852. + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
  10853. + escape_essid(info_element->data, info_element->len),
  10854. + MAC_ARG(beacon->header.addr3),
  10855. + (beacon->capability & (1<<0xf)) ? '1' : '0',
  10856. + (beacon->capability & (1<<0xe)) ? '1' : '0',
  10857. + (beacon->capability & (1<<0xd)) ? '1' : '0',
  10858. + (beacon->capability & (1<<0xc)) ? '1' : '0',
  10859. + (beacon->capability & (1<<0xb)) ? '1' : '0',
  10860. + (beacon->capability & (1<<0xa)) ? '1' : '0',
  10861. + (beacon->capability & (1<<0x9)) ? '1' : '0',
  10862. + (beacon->capability & (1<<0x8)) ? '1' : '0',
  10863. + (beacon->capability & (1<<0x7)) ? '1' : '0',
  10864. + (beacon->capability & (1<<0x6)) ? '1' : '0',
  10865. + (beacon->capability & (1<<0x5)) ? '1' : '0',
  10866. + (beacon->capability & (1<<0x4)) ? '1' : '0',
  10867. + (beacon->capability & (1<<0x3)) ? '1' : '0',
  10868. + (beacon->capability & (1<<0x2)) ? '1' : '0',
  10869. + (beacon->capability & (1<<0x1)) ? '1' : '0',
  10870. + (beacon->capability & (1<<0x0)) ? '1' : '0');
  10871. +
  10872. + if (ieee80211_network_init(ieee, beacon, &network, stats)) {
  10873. + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
  10874. + escape_essid(info_element->data,
  10875. + info_element->len),
  10876. + MAC_ARG(beacon->header.addr3),
  10877. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  10878. + IEEE80211_STYPE_PROBE_RESP ?
  10879. + "PROBE RESPONSE" : "BEACON");
  10880. + return;
  10881. + }
  10882. +
  10883. +#ifdef ENABLE_DOT11D
  10884. + // For Asus EeePc request,
  10885. + // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
  10886. + // wireless adapter should follow the country code.
  10887. + // (2) If there is no any country code in beacon,
  10888. + // then wireless adapter should do active scan from ch1~11 and
  10889. + // passive scan from ch12~14
  10890. + if(ieee->bGlobalDomain)
  10891. + {
  10892. + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
  10893. + {
  10894. + // Case 1: Country code
  10895. + if(IS_COUNTRY_IE_VALID(ieee) )
  10896. + {
  10897. + if( !IsLegalChannel(ieee, network.channel) )
  10898. + {
  10899. + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
  10900. + return;
  10901. + }
  10902. + }
  10903. + // Case 2: No any country code.
  10904. + else
  10905. + {
  10906. + // Filter over channel ch12~14
  10907. + if(network.channel > 11)
  10908. + {
  10909. + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
  10910. + return;
  10911. + }
  10912. + }
  10913. + }
  10914. + else
  10915. + {
  10916. + // Case 1: Country code
  10917. + if(IS_COUNTRY_IE_VALID(ieee) )
  10918. + {
  10919. + if( !IsLegalChannel(ieee, network.channel) )
  10920. + {
  10921. + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
  10922. + return;
  10923. + }
  10924. + }
  10925. + // Case 2: No any country code.
  10926. + else
  10927. + {
  10928. + // Filter over channel ch12~14
  10929. + if(network.channel > 14)
  10930. + {
  10931. + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
  10932. + return;
  10933. + }
  10934. + }
  10935. + }
  10936. + }
  10937. +
  10938. + //lzm add 081205
  10939. + // for Toshiba request, we use channel_plan COUNTRY_CODE_WORLD_WIDE_13_INDEX,
  10940. + // For Liteon "World Wide 13" Domain name:ch1~11 active scan & ch12~13 passive scan
  10941. + // So we shoud only rcv beacon in 12-13, and filter probe resp in 12-13.
  10942. + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
  10943. + {
  10944. + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
  10945. + {
  10946. + // Filter over channel ch12~13
  10947. + if(network.channel >= ieee->MinPassiveChnlNum)
  10948. + {
  10949. + printk("GetScanInfo(): passive scan, filter probe resp at channel(%d).\n", network.channel);
  10950. + return;
  10951. + }
  10952. + }
  10953. + }
  10954. +#endif
  10955. +
  10956. +
  10957. + /* The network parsed correctly -- so now we scan our known networks
  10958. + * to see if we can find it in our list.
  10959. + *
  10960. + * NOTE: This search is definitely not optimized. Once its doing
  10961. + * the "right thing" we'll optimize it for efficiency if
  10962. + * necessary */
  10963. +
  10964. + /* Search for this entry in the list and update it if it is
  10965. + * already there. */
  10966. +
  10967. + spin_lock_irqsave(&ieee->lock, flags);
  10968. +
  10969. + if(is_same_network(&ieee->current_network, &network, ieee)) {
  10970. + //YJ,add,080819,for hidden ap
  10971. + if(is_beacon == 0)
  10972. + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
  10973. + if ((ieee->state == IEEE80211_LINKED) && is_beacon)
  10974. + ieee->NumRxBcnInPeriod++;
  10975. + wmm_info = ieee->current_network.wmm_info;
  10976. + update_network(&ieee->current_network, &network);
  10977. + }
  10978. +
  10979. + list_for_each_entry(target, &ieee->network_list, list) {
  10980. + if (is_same_network(target, &network, ieee))
  10981. + break;
  10982. + if ((oldest == NULL) ||
  10983. + (target->last_scanned < oldest->last_scanned))
  10984. + oldest = target;
  10985. + }
  10986. +
  10987. + /* If we didn't find a match, then get a new network slot to initialize
  10988. + * with this beacon's information */
  10989. + if (&target->list == &ieee->network_list) {
  10990. + if (list_empty(&ieee->network_free_list)) {
  10991. + /* If there are no more slots, expire the oldest */
  10992. + list_del(&oldest->list);
  10993. + target = oldest;
  10994. + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
  10995. + "network list.\n",
  10996. + escape_essid(target->ssid,
  10997. + target->ssid_len),
  10998. + MAC_ARG(target->bssid));
  10999. + } else {
  11000. + /* Otherwise just pull from the free list */
  11001. + target = list_entry(ieee->network_free_list.next,
  11002. + struct ieee80211_network, list);
  11003. + list_del(ieee->network_free_list.next);
  11004. + }
  11005. +
  11006. +
  11007. +#ifdef CONFIG_IEEE80211_DEBUG
  11008. + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
  11009. + escape_essid(network.ssid,
  11010. + network.ssid_len),
  11011. + MAC_ARG(network.bssid),
  11012. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  11013. + IEEE80211_STYPE_PROBE_RESP ?
  11014. + "PROBE RESPONSE" : "BEACON");
  11015. +#endif
  11016. +
  11017. +#ifdef _RTL8187_EXT_PATCH_
  11018. + network.ext_entry = target->ext_entry;
  11019. +#endif
  11020. + memcpy(target, &network, sizeof(*target));
  11021. + list_add_tail(&target->list, &ieee->network_list);
  11022. + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
  11023. + ieee80211_softmac_new_net(ieee,&network);
  11024. + } else {
  11025. + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
  11026. + escape_essid(target->ssid,
  11027. + target->ssid_len),
  11028. + MAC_ARG(target->bssid),
  11029. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  11030. + IEEE80211_STYPE_PROBE_RESP ?
  11031. + "PROBE RESPONSE" : "BEACON");
  11032. +
  11033. + /* we have an entry and we are going to update it. But this entry may
  11034. + * be already expired. In this case we do the same as we found a new
  11035. + * net and call the new_net handler
  11036. + */
  11037. + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
  11038. + //YJ,add,080819,for hidden ap
  11039. + if(is_beacon == 0)
  11040. + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
  11041. + //if(strncmp(network.ssid, "linksys-c",9) == 0)
  11042. + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
  11043. + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
  11044. + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
  11045. + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
  11046. + renew = 1;
  11047. + //YJ,add,080819,for hidden ap,end
  11048. + update_network(target, &network);
  11049. + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
  11050. + ieee80211_softmac_new_net(ieee,&network);
  11051. + }
  11052. +
  11053. + spin_unlock_irqrestore(&ieee->lock, flags);
  11054. +}
  11055. +
  11056. +void ieee80211_rx_mgt(struct ieee80211_device *ieee,
  11057. + struct ieee80211_hdr *header,
  11058. + struct ieee80211_rx_stats *stats)
  11059. +{
  11060. + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  11061. +
  11062. + case IEEE80211_STYPE_BEACON:
  11063. + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
  11064. + WLAN_FC_GET_STYPE(header->frame_ctl));
  11065. + IEEE80211_DEBUG_SCAN("Beacon\n");
  11066. + ieee80211_process_probe_response(
  11067. + ieee, (struct ieee80211_probe_response *)header, stats);
  11068. + break;
  11069. +
  11070. + case IEEE80211_STYPE_PROBE_RESP:
  11071. + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
  11072. + WLAN_FC_GET_STYPE(header->frame_ctl));
  11073. + IEEE80211_DEBUG_SCAN("Probe response\n");
  11074. + ieee80211_process_probe_response(
  11075. + ieee, (struct ieee80211_probe_response *)header, stats);
  11076. + break;
  11077. +//rz
  11078. +#ifdef _RTL8187_EXT_PATCH_
  11079. + case IEEE80211_STYPE_PROBE_REQ:
  11080. + IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
  11081. + WLAN_FC_GET_STYPE(header->frame_ctl));
  11082. + IEEE80211_DEBUG_SCAN("Probe request\n");
  11083. + ///
  11084. + //printk("Probe request\n");
  11085. + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
  11086. + ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
  11087. + break;
  11088. +#endif // _RTL8187_EXT_PATCH_
  11089. +
  11090. + }
  11091. +}
  11092. +
  11093. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  11094. +EXPORT_SYMBOL(ieee80211_rx_mgt);
  11095. +EXPORT_SYMBOL(ieee80211_rx);
  11096. +EXPORT_SYMBOL(ieee80211_network_init);
  11097. +#ifdef _RTL8187_EXT_PATCH_
  11098. +EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
  11099. +#endif
  11100. +#else
  11101. +EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
  11102. +EXPORT_SYMBOL_NOVERS(ieee80211_rx);
  11103. +EXPORT_SYMBOL_NOVERS(ieee80211_network_init);
  11104. +#ifdef _RTL8187_EXT_PATCH_
  11105. +EXPORT_SYMBOL_NOVERS(ieee_ext_skb_p80211_to_ether);
  11106. +#endif
  11107. +#endif
  11108. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c
  11109. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 1970-01-01 01:00:00.000000000 +0100
  11110. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 2010-03-06 16:43:22.000000000 +0100
  11111. @@ -0,0 +1,4083 @@
  11112. +/* IEEE 802.11 SoftMAC layer
  11113. + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  11114. + *
  11115. + * Mostly extracted from the rtl8180-sa2400 driver for the
  11116. + * in-kernel generic ieee802.11 stack.
  11117. + *
  11118. + * Few lines might be stolen from other part of the ieee80211
  11119. + * stack. Copyright who own it's copyright
  11120. + *
  11121. + * WPA code stolen from the ipw2200 driver.
  11122. + * Copyright who own it's copyright.
  11123. + *
  11124. + * released under the GPL
  11125. + */
  11126. +
  11127. +
  11128. +#include "ieee80211.h"
  11129. +
  11130. +#include <linux/random.h>
  11131. +#include <linux/delay.h>
  11132. +#include <linux/version.h>
  11133. +#include <asm/uaccess.h>
  11134. +
  11135. +#ifdef ENABLE_DOT11D
  11136. +#include "dot11d.h"
  11137. +#endif
  11138. +
  11139. +
  11140. +u8 rsn_authen_cipher_suite[16][4] = {
  11141. + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
  11142. + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
  11143. + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
  11144. + {0x00,0x0F,0xAC,0x03}, //WRAP-historical
  11145. + {0x00,0x0F,0xAC,0x04}, //CCMP
  11146. + {0x00,0x0F,0xAC,0x05}, //WEP-104
  11147. +};
  11148. +
  11149. +short ieee80211_is_54g(struct ieee80211_network net)
  11150. +{
  11151. + return ((net.rates_ex_len > 0) || (net.rates_len > 4));
  11152. +}
  11153. +
  11154. +short ieee80211_is_shortslot(struct ieee80211_network net)
  11155. +{
  11156. + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
  11157. +}
  11158. +
  11159. +/* returns the total length needed for pleacing the RATE MFIE
  11160. + * tag and the EXTENDED RATE MFIE tag if needed.
  11161. + * It encludes two bytes per tag for the tag itself and its len
  11162. + */
  11163. +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
  11164. +{
  11165. + unsigned int rate_len = 0;
  11166. +
  11167. + if (ieee->modulation & IEEE80211_CCK_MODULATION)
  11168. + rate_len = IEEE80211_CCK_RATE_LEN + 2;
  11169. +
  11170. + if (ieee->modulation & IEEE80211_OFDM_MODULATION)
  11171. +
  11172. + rate_len += IEEE80211_OFDM_RATE_LEN + 2;
  11173. +
  11174. + return rate_len;
  11175. +}
  11176. +
  11177. +/* pleace the MFIE rate, tag to the memory (double) poined.
  11178. + * Then it updates the pointer so that
  11179. + * it points after the new MFIE tag added.
  11180. + */
  11181. +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
  11182. +{
  11183. + u8 *tag = *tag_p;
  11184. +
  11185. + if (ieee->modulation & IEEE80211_CCK_MODULATION){
  11186. + *tag++ = MFIE_TYPE_RATES;
  11187. + *tag++ = 7;
  11188. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  11189. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  11190. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  11191. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  11192. + //added for basic rate set
  11193. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  11194. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  11195. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  11196. + }
  11197. +
  11198. + /* We may add an option for custom rates that specific HW might support */
  11199. + *tag_p = tag;
  11200. +}
  11201. +
  11202. +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
  11203. +{
  11204. + u8 *tag = *tag_p;
  11205. +
  11206. + if (ieee->modulation & IEEE80211_OFDM_MODULATION){
  11207. +
  11208. + *tag++ = MFIE_TYPE_RATES_EX;
  11209. + *tag++ = 5;
  11210. + *tag++ = IEEE80211_OFDM_RATE_9MB;
  11211. + *tag++ = IEEE80211_OFDM_RATE_18MB;
  11212. + *tag++ = IEEE80211_OFDM_RATE_36MB;
  11213. + *tag++ = IEEE80211_OFDM_RATE_48MB;
  11214. + *tag++ = IEEE80211_OFDM_RATE_54MB;
  11215. +
  11216. + }
  11217. +
  11218. + /* We may add an option for custom rates that specific HW might support */
  11219. + *tag_p = tag;
  11220. +}
  11221. +
  11222. +
  11223. +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
  11224. + u8 *tag = *tag_p;
  11225. +
  11226. + *tag++ = MFIE_TYPE_GENERIC; //0
  11227. + *tag++ = 7;
  11228. + *tag++ = 0x00;
  11229. + *tag++ = 0x50;
  11230. + *tag++ = 0xf2;
  11231. + *tag++ = 0x02;//5
  11232. + *tag++ = 0x00;
  11233. + *tag++ = 0x01;
  11234. +#ifdef SUPPORT_USPD
  11235. + if(ieee->current_network.wmm_info & 0x80) {
  11236. + *tag++ = 0x0f|MAX_SP_Len;
  11237. + } else {
  11238. + *tag++ = MAX_SP_Len;
  11239. + }
  11240. +#else
  11241. + *tag++ = MAX_SP_Len;
  11242. +#endif
  11243. + *tag_p = tag;
  11244. +}
  11245. +
  11246. +#ifdef THOMAS_TURBO
  11247. +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
  11248. + u8 *tag = *tag_p;
  11249. +
  11250. + *tag++ = MFIE_TYPE_GENERIC; //0
  11251. + *tag++ = 7;
  11252. + *tag++ = 0x00;
  11253. + *tag++ = 0xe0;
  11254. + *tag++ = 0x4c;
  11255. + *tag++ = 0x01;//5
  11256. + *tag++ = 0x02;
  11257. + *tag++ = 0x11;
  11258. + *tag++ = 0x00;
  11259. +
  11260. + *tag_p = tag;
  11261. + printk(KERN_ALERT "This is enable turbo mode IE process\n");
  11262. +}
  11263. +#endif
  11264. +
  11265. +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
  11266. +{
  11267. + int nh;
  11268. + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
  11269. +
  11270. +/*
  11271. + * if the queue is full but we have newer frames then
  11272. + * just overwrites the oldest.
  11273. + *
  11274. + * if (nh == ieee->mgmt_queue_tail)
  11275. + * return -1;
  11276. + */
  11277. + ieee->mgmt_queue_head = nh;
  11278. + ieee->mgmt_queue_ring[nh] = skb;
  11279. +
  11280. + //return 0;
  11281. +}
  11282. +
  11283. +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
  11284. +{
  11285. + struct sk_buff *ret;
  11286. +
  11287. + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
  11288. + return NULL;
  11289. +
  11290. + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
  11291. +
  11292. + ieee->mgmt_queue_tail =
  11293. + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
  11294. +
  11295. + return ret;
  11296. +}
  11297. +
  11298. +void init_mgmt_queue(struct ieee80211_device *ieee)
  11299. +{
  11300. + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
  11301. +}
  11302. +
  11303. +
  11304. +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
  11305. +
  11306. +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  11307. +{
  11308. + unsigned long flags;
  11309. + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  11310. + struct ieee80211_hdr_3addr *header=
  11311. + (struct ieee80211_hdr_3addr *) skb->data;
  11312. +
  11313. +
  11314. + spin_lock_irqsave(&ieee->lock, flags);
  11315. +
  11316. + /* called with 2nd param 0, no mgmt lock required */
  11317. + ieee80211_sta_wakeup(ieee,0);
  11318. +
  11319. + if(single){
  11320. + if(ieee->queue_stop){
  11321. +
  11322. + enqueue_mgmt(ieee,skb);
  11323. + }else{
  11324. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
  11325. +
  11326. + if (ieee->seq_ctrl[0] == 0xFFF)
  11327. + ieee->seq_ctrl[0] = 0;
  11328. + else
  11329. + ieee->seq_ctrl[0]++;
  11330. +
  11331. + /* avoid watchdog triggers */
  11332. + ieee->dev->trans_start = jiffies;
  11333. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  11334. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  11335. +// dev_kfree_skb_any(skb);//edit by thomas //'cause this function will cause Oops called in interrupt context in old version 101907
  11336. +#endif
  11337. + }
  11338. +
  11339. + spin_unlock_irqrestore(&ieee->lock, flags);
  11340. + }else{
  11341. + spin_unlock_irqrestore(&ieee->lock, flags);
  11342. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
  11343. +
  11344. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  11345. +
  11346. + if (ieee->seq_ctrl[0] == 0xFFF)
  11347. + ieee->seq_ctrl[0] = 0;
  11348. + else
  11349. + ieee->seq_ctrl[0]++;
  11350. +
  11351. + ieee->softmac_hard_start_xmit(skb,ieee->dev);
  11352. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  11353. +// dev_kfree_skb_any(skb);//edit by thomas
  11354. +#endif
  11355. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
  11356. + }
  11357. +}
  11358. +
  11359. +
  11360. +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  11361. +{
  11362. +
  11363. + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  11364. + struct ieee80211_hdr_3addr *header =
  11365. + (struct ieee80211_hdr_3addr *) skb->data;
  11366. +
  11367. +
  11368. + if(single){
  11369. +
  11370. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  11371. +
  11372. + if (ieee->seq_ctrl[0] == 0xFFF)
  11373. + ieee->seq_ctrl[0] = 0;
  11374. + else
  11375. + ieee->seq_ctrl[0]++;
  11376. +
  11377. + /* avoid watchdog triggers */
  11378. + ieee->dev->trans_start = jiffies;
  11379. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  11380. +
  11381. + }else{
  11382. +
  11383. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  11384. +
  11385. + if (ieee->seq_ctrl[0] == 0xFFF)
  11386. + ieee->seq_ctrl[0] = 0;
  11387. + else
  11388. + ieee->seq_ctrl[0]++;
  11389. +
  11390. + ieee->softmac_hard_start_xmit(skb,ieee->dev);
  11391. +
  11392. + }
  11393. + dev_kfree_skb_any(skb);//edit by thomas
  11394. +}
  11395. +
  11396. +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
  11397. +{
  11398. + unsigned int len,rate_len;
  11399. + u8 *tag;
  11400. + struct sk_buff *skb;
  11401. + struct ieee80211_probe_request *req;
  11402. +
  11403. +#ifdef _RTL8187_EXT_PATCH_
  11404. + short extMore = 0;
  11405. + if(ieee->ext_patch_ieee80211_probe_req_1)
  11406. + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
  11407. +#endif
  11408. +
  11409. + len = ieee->current_network.ssid_len;
  11410. +
  11411. + rate_len = ieee80211_MFIE_rate_len(ieee);
  11412. +
  11413. +#ifdef _RTL8187_EXT_PATCH_
  11414. + if(!extMore)
  11415. +#endif
  11416. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  11417. + 2 + len + rate_len);
  11418. +#ifdef _RTL8187_EXT_PATCH_
  11419. + else
  11420. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  11421. + 2 + len + rate_len+128); // MESHID + CAP
  11422. +#endif
  11423. +
  11424. + if (!skb)
  11425. + return NULL;
  11426. +
  11427. + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
  11428. + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  11429. + req->header.duration_id = 0; //FIXME: is this OK ?
  11430. +
  11431. + memset(req->header.addr1, 0xff, ETH_ALEN);
  11432. + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  11433. + memset(req->header.addr3, 0xff, ETH_ALEN);
  11434. +
  11435. + tag = (u8 *) skb_put(skb,len+2+rate_len);
  11436. +
  11437. + *tag++ = MFIE_TYPE_SSID;
  11438. + *tag++ = len;
  11439. + memcpy(tag, ieee->current_network.ssid, len);
  11440. + tag += len;
  11441. +
  11442. + ieee80211_MFIE_Brate(ieee,&tag);
  11443. + ieee80211_MFIE_Grate(ieee,&tag);
  11444. +
  11445. +#ifdef _RTL8187_EXT_PATCH_
  11446. + if(extMore)
  11447. + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
  11448. +#endif
  11449. + return skb;
  11450. +}
  11451. +
  11452. +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
  11453. +
  11454. +#ifdef _RTL8187_EXT_PATCH_
  11455. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  11456. +void ext_ieee80211_send_beacon_wq(struct work_struct *work)
  11457. +{
  11458. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
  11459. +#else
  11460. +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
  11461. +{
  11462. +#endif
  11463. +
  11464. + struct sk_buff *skb;
  11465. +
  11466. + //unsigned long flags;
  11467. +// printk("=========>%s()\n", __FUNCTION__);
  11468. + skb = ieee80211_get_beacon_(ieee);
  11469. +
  11470. + if (skb){
  11471. + softmac_mgmt_xmit(skb, ieee);
  11472. + ieee->softmac_stats.tx_beacons++;
  11473. + dev_kfree_skb_any(skb);//edit by thomas
  11474. + }
  11475. +
  11476. +
  11477. + //printk(KERN_WARNING "[1] beacon sending!\n");
  11478. +// ieee->beacon_timer.expires = jiffies +
  11479. +// (MSECS( ieee->current_network.beacon_interval -5));
  11480. +
  11481. + //spin_lock_irqsave(&ieee->beacon_lock,flags);
  11482. +// if(ieee->beacon_txing)
  11483. +// add_timer(&ieee->beacon_timer);
  11484. + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  11485. +}
  11486. +#endif
  11487. +
  11488. +void ieee80211_send_beacon(struct ieee80211_device *ieee)
  11489. +{
  11490. + struct sk_buff *skb;
  11491. +
  11492. + //unsigned long flags;
  11493. +// printk("=========>%s()\n", __FUNCTION__);
  11494. + skb = ieee80211_get_beacon_(ieee);
  11495. +
  11496. + if (skb){
  11497. + softmac_mgmt_xmit(skb, ieee);
  11498. + ieee->softmac_stats.tx_beacons++;
  11499. + dev_kfree_skb_any(skb);//edit by thomas
  11500. + }
  11501. +
  11502. +
  11503. + //printk(KERN_WARNING "[1] beacon sending!\n");
  11504. + ieee->beacon_timer.expires = jiffies +
  11505. + (MSECS( ieee->current_network.beacon_interval -5));
  11506. +
  11507. + //spin_lock_irqsave(&ieee->beacon_lock,flags);
  11508. + if(ieee->beacon_txing)
  11509. + add_timer(&ieee->beacon_timer);
  11510. + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  11511. +}
  11512. +
  11513. +
  11514. +void ieee80211_send_beacon_cb(unsigned long _ieee)
  11515. +{
  11516. + struct ieee80211_device *ieee =
  11517. + (struct ieee80211_device *) _ieee;
  11518. + unsigned long flags;
  11519. +
  11520. + spin_lock_irqsave(&ieee->beacon_lock, flags);
  11521. + ieee80211_send_beacon(ieee);
  11522. + spin_unlock_irqrestore(&ieee->beacon_lock, flags);
  11523. +}
  11524. +
  11525. +#ifdef _RTL8187_EXT_PATCH_
  11526. +
  11527. +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
  11528. +{
  11529. + unsigned int len,rate_len;
  11530. + u8 *tag;
  11531. + struct sk_buff *skb;
  11532. + struct ieee80211_probe_request *req;
  11533. +
  11534. +#ifdef _RTL8187_EXT_PATCH_
  11535. + short extMore = 0;
  11536. + if(ieee->ext_patch_ieee80211_probe_req_1)
  11537. + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
  11538. +#endif
  11539. +
  11540. + len = len_ssid;
  11541. +
  11542. + rate_len = ieee80211_MFIE_rate_len(ieee);
  11543. +
  11544. +#ifdef _RTL8187_EXT_PATCH_
  11545. + if(!extMore)
  11546. +#endif
  11547. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  11548. + 2 + len + rate_len);
  11549. +#ifdef _RTL8187_EXT_PATCH_
  11550. + else
  11551. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  11552. + 2 + len + rate_len+128); // MESHID + CAP
  11553. +#endif
  11554. +
  11555. + if (!skb)
  11556. + return NULL;
  11557. +
  11558. + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
  11559. + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  11560. + req->header.duration_id = 0; //FIXME: is this OK ?
  11561. +
  11562. + memset(req->header.addr1, 0xff, ETH_ALEN);
  11563. + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  11564. + memset(req->header.addr3, 0xff, ETH_ALEN);
  11565. +
  11566. + tag = (u8 *) skb_put(skb,len+2+rate_len);
  11567. +
  11568. + *tag++ = MFIE_TYPE_SSID;
  11569. + *tag++ = len;
  11570. + if(len)
  11571. + {
  11572. + memcpy(tag, ssid, len);
  11573. + tag += len;
  11574. + }
  11575. +
  11576. + ieee80211_MFIE_Brate(ieee,&tag);
  11577. + ieee80211_MFIE_Grate(ieee,&tag);
  11578. +
  11579. +#ifdef _RTL8187_EXT_PATCH_
  11580. + if(extMore)
  11581. + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
  11582. +#endif
  11583. + return skb;
  11584. +}
  11585. +
  11586. +#endif // _RTL8187_EXT_PATCH_
  11587. +
  11588. +
  11589. +void ieee80211_send_probe(struct ieee80211_device *ieee)
  11590. +{
  11591. + struct sk_buff *skb;
  11592. +
  11593. +#ifdef _RTL8187_EXT_PATCH_
  11594. + if(ieee->iw_mode == ieee->iw_ext_mode)
  11595. + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
  11596. + else
  11597. +#endif
  11598. + skb = ieee80211_probe_req(ieee);
  11599. + if (skb){
  11600. + softmac_mgmt_xmit(skb, ieee);
  11601. + ieee->softmac_stats.tx_probe_rq++;
  11602. + dev_kfree_skb_any(skb);//edit by thomas
  11603. + }
  11604. +}
  11605. +
  11606. +void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
  11607. +{
  11608. + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
  11609. + ieee80211_send_probe(ieee);
  11610. + ieee80211_send_probe(ieee);
  11611. + }
  11612. +}
  11613. +
  11614. +/* this performs syncro scan blocking the caller until all channels
  11615. + * in the allowed channel map has been checked.
  11616. + */
  11617. +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
  11618. +{
  11619. + short ch = 0;
  11620. +#ifdef ENABLE_DOT11D
  11621. + u8 channel_map[MAX_CHANNEL_NUMBER+1];
  11622. + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  11623. +#endif
  11624. +
  11625. +
  11626. + down(&ieee->scan_sem);
  11627. +
  11628. + while(1)
  11629. + {
  11630. +
  11631. + do{
  11632. + ch++;
  11633. + if (ch > MAX_CHANNEL_NUMBER)
  11634. + goto out; /* scan completed */
  11635. +
  11636. +#ifdef ENABLE_DOT11D
  11637. + }while(!channel_map[ch]);
  11638. +#else
  11639. + }while(!ieee->channel_map[ch]);
  11640. +#endif
  11641. +
  11642. + //printk("=>current channel is %d\n",ch);
  11643. +
  11644. + /* this fuction can be called in two situations
  11645. + * 1- We have switched to ad-hoc mode and we are
  11646. + * performing a complete syncro scan before conclude
  11647. + * there are no interesting cell and to create a
  11648. + * new one. In this case the link state is
  11649. + * IEEE80211_NOLINK until we found an interesting cell.
  11650. + * If so the ieee8021_new_net, called by the RX path
  11651. + * will set the state to IEEE80211_LINKED, so we stop
  11652. + * scanning
  11653. + * 2- We are linked and the root uses run iwlist scan.
  11654. + * So we switch to IEEE80211_LINKED_SCANNING to remember
  11655. + * that we are still logically linked (not interested in
  11656. + * new network events, despite for updating the net list,
  11657. + * but we are temporarly 'unlinked' as the driver shall
  11658. + * not filter RX frames and the channel is changing.
  11659. + * So the only situation in witch are interested is to check
  11660. + * if the state become LINKED because of the #1 situation
  11661. + */
  11662. +
  11663. + if (ieee->state == IEEE80211_LINKED)
  11664. + goto out;
  11665. +
  11666. + //printk("---->%s: chan %d\n", __func__, ch);
  11667. + ieee->set_chan(ieee->dev, ch);
  11668. +#ifdef ENABLE_DOT11D
  11669. + if(channel_map[ch] == 1)
  11670. +#endif
  11671. + {
  11672. + ieee80211_send_probe_requests(ieee);
  11673. + }
  11674. +
  11675. + /* this prevent excessive time wait when we
  11676. + * need to wait for a syncro scan to end..
  11677. + */
  11678. + if (ieee->sync_scan_hurryup)
  11679. + goto out;
  11680. +
  11681. +
  11682. + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
  11683. +
  11684. + }
  11685. +out:
  11686. + ieee->sync_scan_hurryup = 0;
  11687. + up(&ieee->scan_sem);
  11688. +#ifdef ENABLE_DOT11D
  11689. + if(IS_DOT11D_ENABLE(ieee))
  11690. + DOT11D_ScanComplete(ieee);
  11691. +#endif
  11692. +
  11693. +}
  11694. +
  11695. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  11696. +/* called both by wq with ieee->lock held */
  11697. +void ieee80211_softmac_scan(struct ieee80211_device *ieee)
  11698. +{
  11699. +#if 0
  11700. + short watchdog = 0;
  11701. + do{
  11702. + ieee->current_network.channel =
  11703. + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
  11704. + if (watchdog++ > MAX_CHANNEL_NUMBER)
  11705. + return; /* no good chans */
  11706. +
  11707. + }while(!ieee->channel_map[ieee->current_network.channel]);
  11708. +#endif
  11709. +
  11710. + schedule_task(&ieee->softmac_scan_wq);
  11711. +}
  11712. +#endif
  11713. +
  11714. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  11715. +void ieee80211_softmac_scan_wq(struct work_struct *work)
  11716. +{
  11717. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  11718. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
  11719. +#else
  11720. +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
  11721. +{
  11722. +#endif
  11723. + //static short watchdog = 0;
  11724. + //short watchdog = 0;//lzm move into ieee->scan_watchdog 081215 for roaming
  11725. + u8 channel_bak = ieee->current_network.channel;//lzm for channel+1
  11726. +#ifdef ENABLE_DOT11D
  11727. + u8 channel_map[MAX_CHANNEL_NUMBER+1];
  11728. + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  11729. +#endif
  11730. + down(&ieee->scan_sem);
  11731. +
  11732. + do{
  11733. + ieee->current_network.channel =
  11734. + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
  11735. + if (ieee->scan_watchdog++ > MAX_CHANNEL_NUMBER)
  11736. + goto out; /* no good chans */
  11737. +#ifdef ENABLE_DOT11D
  11738. + }while(!channel_map[ieee->current_network.channel]);
  11739. +#else
  11740. + }while(!ieee->channel_map[ieee->current_network.channel]);
  11741. +#endif
  11742. +
  11743. + if (ieee->scanning == 0 )
  11744. + goto out;
  11745. +
  11746. + //printk("current channel is %d\n",ieee->current_network.channel);
  11747. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  11748. +#ifdef ENABLE_DOT11D
  11749. + if(channel_map[ieee->current_network.channel] == 1)
  11750. +#endif
  11751. + {
  11752. + ieee80211_send_probe_requests(ieee);
  11753. + }
  11754. +
  11755. +
  11756. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  11757. + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
  11758. +#else
  11759. + ieee->scan_timer.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME);
  11760. + if (ieee->scanning == 1)
  11761. + add_timer(&ieee->scan_timer);
  11762. +#endif
  11763. +
  11764. + up(&ieee->scan_sem);
  11765. + return;
  11766. +out:
  11767. + //printk("%s():Stop scan now\n",__FUNCTION__);
  11768. + ieee->actscanning = false;
  11769. + ieee->scan_watchdog = 0;
  11770. + ieee->scanning = 0;
  11771. + ieee->current_network.channel = channel_bak;
  11772. + up(&ieee->scan_sem);
  11773. +#ifdef ENABLE_DOT11D
  11774. + if(IS_DOT11D_ENABLE(ieee))
  11775. + DOT11D_ScanComplete(ieee);
  11776. +#endif
  11777. +
  11778. + return;
  11779. +}
  11780. +
  11781. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  11782. +void ieee80211_softmac_scan_cb(unsigned long _dev)
  11783. +{
  11784. + unsigned long flags;
  11785. + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
  11786. +
  11787. + spin_lock_irqsave(&ieee->lock, flags);
  11788. + ieee80211_softmac_scan(ieee);
  11789. + spin_unlock_irqrestore(&ieee->lock, flags);
  11790. +}
  11791. +#endif
  11792. +
  11793. +
  11794. +void ieee80211_beacons_start(struct ieee80211_device *ieee)
  11795. +{
  11796. + unsigned long flags;
  11797. +
  11798. + spin_lock_irqsave(&ieee->beacon_lock,flags);
  11799. +
  11800. + ieee->beacon_txing = 1;
  11801. + ieee80211_send_beacon(ieee);
  11802. +
  11803. + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  11804. +}
  11805. +
  11806. +void ieee80211_beacons_stop(struct ieee80211_device *ieee)
  11807. +{
  11808. + unsigned long flags;
  11809. +
  11810. + spin_lock_irqsave(&ieee->beacon_lock,flags);
  11811. +
  11812. + ieee->beacon_txing = 0;
  11813. + del_timer_sync(&ieee->beacon_timer);
  11814. +
  11815. + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  11816. +
  11817. +}
  11818. +
  11819. +
  11820. +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
  11821. +{
  11822. + if(ieee->stop_send_beacons)
  11823. + ieee->stop_send_beacons(ieee->dev);
  11824. + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  11825. + ieee80211_beacons_stop(ieee);
  11826. +}
  11827. +
  11828. +
  11829. +void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
  11830. +{
  11831. + if(ieee->start_send_beacons)
  11832. + ieee->start_send_beacons(ieee->dev);
  11833. + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  11834. + ieee80211_beacons_start(ieee);
  11835. +}
  11836. +
  11837. +
  11838. +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
  11839. +{
  11840. +// unsigned long flags;
  11841. +
  11842. + ieee->sync_scan_hurryup = 1;
  11843. +
  11844. + down(&ieee->scan_sem);
  11845. +// spin_lock_irqsave(&ieee->lock, flags);
  11846. +
  11847. + if (ieee->scanning == 1){
  11848. + //printk("%s():Stop scan now\n",__FUNCTION__);
  11849. + ieee->scanning = 0;
  11850. + //lzm add for softmac_scan_wq can't return from out
  11851. + //example: rcv probe_response
  11852. + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
  11853. + ieee->actscanning = false;
  11854. +
  11855. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  11856. + cancel_delayed_work(&ieee->softmac_scan_wq);
  11857. +#else
  11858. + del_timer_sync(&ieee->scan_timer);
  11859. +#endif
  11860. + }
  11861. +
  11862. +// spin_unlock_irqrestore(&ieee->lock, flags);
  11863. + up(&ieee->scan_sem);
  11864. +}
  11865. +
  11866. +void ieee80211_stop_scan(struct ieee80211_device *ieee)
  11867. +{
  11868. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  11869. + ieee80211_softmac_stop_scan(ieee);
  11870. + else
  11871. + ieee->stop_scan(ieee->dev);
  11872. +}
  11873. +
  11874. +/* called with ieee->lock held */
  11875. +void ieee80211_start_scan(struct ieee80211_device *ieee)
  11876. +{
  11877. + ieee->actscanning = true;
  11878. +#ifdef CONFIG_IPS
  11879. + ieee->ieee80211_ips_leave(ieee->dev);
  11880. +#endif
  11881. +
  11882. +#ifdef ENABLE_DOT11D
  11883. + if(IS_DOT11D_ENABLE(ieee) )
  11884. + {
  11885. + if(IS_COUNTRY_IE_VALID(ieee))
  11886. + {
  11887. + RESET_CIE_WATCHDOG(ieee);
  11888. + }
  11889. + }
  11890. +#endif
  11891. +
  11892. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
  11893. + if (ieee->scanning == 0){
  11894. + ieee->scanning = 1;
  11895. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  11896. + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
  11897. +#else
  11898. + ieee80211_softmac_scan(ieee);
  11899. +#endif
  11900. + }
  11901. + }else
  11902. + ieee->start_scan(ieee->dev);
  11903. +
  11904. +}
  11905. +
  11906. +/* called with wx_sem held */
  11907. +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
  11908. +{
  11909. + //printk("====>%s()\n", __func__);
  11910. +#ifdef CONFIG_IPS
  11911. + ieee->ieee80211_ips_leave(ieee->dev);
  11912. +#endif
  11913. + ieee->actscanning = true;
  11914. +
  11915. +#ifdef ENABLE_DOT11D
  11916. + if(IS_DOT11D_ENABLE(ieee) )
  11917. + {
  11918. + if(IS_COUNTRY_IE_VALID(ieee))
  11919. + {
  11920. + RESET_CIE_WATCHDOG(ieee);
  11921. + }
  11922. + }
  11923. +#endif
  11924. +
  11925. + ieee->sync_scan_hurryup = 0;
  11926. +
  11927. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  11928. + ieee80211_softmac_scan_syncro(ieee);
  11929. + else
  11930. + ieee->scan_syncro(ieee->dev);
  11931. +
  11932. + ieee->actscanning = false;
  11933. + //printk("<====%s()\n", __func__);
  11934. +}
  11935. +
  11936. +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
  11937. + struct ieee80211_device *ieee, int challengelen)
  11938. +{
  11939. + struct sk_buff *skb;
  11940. + struct ieee80211_authentication *auth;
  11941. +
  11942. + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
  11943. +
  11944. + if (!skb) return NULL;
  11945. +
  11946. + auth = (struct ieee80211_authentication *)
  11947. + skb_put(skb, sizeof(struct ieee80211_authentication));
  11948. +
  11949. + auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
  11950. + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
  11951. +
  11952. + auth->header.duration_id = 0x013a; //FIXME
  11953. +
  11954. + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
  11955. + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  11956. + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
  11957. +
  11958. + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
  11959. +
  11960. + auth->transaction = cpu_to_le16(ieee->associate_seq);
  11961. + ieee->associate_seq++;
  11962. +
  11963. + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
  11964. +
  11965. + return skb;
  11966. +
  11967. +}
  11968. +
  11969. +u8 WPA_OUI[3] = {0x00, 0x50, 0xf2};
  11970. +
  11971. +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
  11972. +{
  11973. + u8 *tag;
  11974. + int beacon_size;
  11975. + struct ieee80211_probe_response *beacon_buf;
  11976. + struct sk_buff *skb;
  11977. + int encrypt;
  11978. + int atim_len,erp_len;
  11979. + struct ieee80211_crypt_data* crypt;
  11980. +
  11981. + char *ssid = ieee->current_network.ssid;
  11982. + int ssid_len = ieee->current_network.ssid_len;
  11983. + int rate_len = ieee->current_network.rates_len+2;
  11984. + int rate_ex_len = ieee->current_network.rates_ex_len;
  11985. +
  11986. + int wpa_ie_len = 0, wpa_type=0;
  11987. + if(rate_ex_len > 0) rate_ex_len+=2;
  11988. +
  11989. + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
  11990. + atim_len = 4;
  11991. + else
  11992. + atim_len = 0;
  11993. +
  11994. + if(ieee80211_is_54g(ieee->current_network))
  11995. + erp_len = 3;
  11996. + else
  11997. + erp_len = 0;
  11998. + if (ieee->wpa_enabled)
  11999. + {
  12000. + // printk("hoho wpa_enalbe\n");
  12001. + wpa_ie_len = ieee->wpa_ie_len; //24-2
  12002. + }
  12003. + beacon_size = sizeof(struct ieee80211_probe_response)+
  12004. + ssid_len
  12005. + +3 //channel
  12006. + +rate_len
  12007. + +rate_ex_len
  12008. + +atim_len
  12009. + +erp_len
  12010. + +wpa_ie_len;
  12011. +
  12012. + skb = dev_alloc_skb(beacon_size);
  12013. +
  12014. + if (!skb)
  12015. + return NULL;
  12016. +
  12017. + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
  12018. +
  12019. + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
  12020. + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12021. + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
  12022. +
  12023. + beacon_buf->header.duration_id = 0; //FIXME
  12024. + beacon_buf->beacon_interval =
  12025. + cpu_to_le16(ieee->current_network.beacon_interval);
  12026. + beacon_buf->capability =
  12027. + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
  12028. +
  12029. + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
  12030. + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
  12031. +#ifdef _RTL8187_EXT_PATCH_
  12032. +{
  12033. +/* struct ieee80211_crypt_data_list* cryptlist = ieee->cryptlist[1];
  12034. + u8 i = cryptlist->used;
  12035. + crypt = cryptlist ->crypt[ieee->tx_keyidx];
  12036. +*/
  12037. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  12038. +}
  12039. +#else
  12040. +
  12041. + crypt = ieee->crypt[ieee->tx_keyidx];
  12042. +#endif
  12043. + if (crypt)
  12044. + wpa_type = strcmp(crypt->ops->name, "TKIP");
  12045. +
  12046. +
  12047. + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
  12048. + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
  12049. +
  12050. + if (encrypt)
  12051. + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  12052. +
  12053. +
  12054. + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
  12055. +
  12056. + beacon_buf->info_element.id = MFIE_TYPE_SSID;
  12057. + beacon_buf->info_element.len = ssid_len;
  12058. +
  12059. + tag = (u8*) beacon_buf->info_element.data;
  12060. +
  12061. + memcpy(tag, ssid, ssid_len);
  12062. +
  12063. + tag += ssid_len;
  12064. +
  12065. + *(tag++) = MFIE_TYPE_RATES;
  12066. + *(tag++) = rate_len-2;
  12067. + memcpy(tag,ieee->current_network.rates,rate_len-2);
  12068. + tag+=rate_len-2;
  12069. +
  12070. + *(tag++) = MFIE_TYPE_DS_SET;
  12071. + *(tag++) = 1;
  12072. + *(tag++) = ieee->current_network.channel;
  12073. +
  12074. + if(atim_len){
  12075. + u16 val16;
  12076. + *(tag++) = MFIE_TYPE_IBSS_SET;
  12077. + *(tag++) = 2;
  12078. + val16 = cpu_to_le16(ieee->current_network.atim_window);
  12079. + //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
  12080. + memcpy((u8 *)tag,(u8 *)&val16,2);
  12081. + tag+=2;
  12082. + }
  12083. +
  12084. + if(erp_len){
  12085. + *(tag++) = MFIE_TYPE_ERP;
  12086. + *(tag++) = 1;
  12087. + *(tag++) = 0;
  12088. + }
  12089. +
  12090. + if(rate_ex_len){
  12091. + *(tag++) = MFIE_TYPE_RATES_EX;
  12092. + *(tag++) = rate_ex_len-2;
  12093. + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
  12094. + tag+=rate_ex_len-2;
  12095. + }
  12096. + if (wpa_ie_len)
  12097. + {
  12098. +#if 0
  12099. + *(tag++) = 0xdd;
  12100. + *(tag++) = wpa_ie_len-2;
  12101. + memcpy(tag, WPA_OUI, 3);
  12102. + tag += 3;
  12103. + *(tag++) = 1;
  12104. + *(tag++) = 1;
  12105. + *(tag++) = 0;
  12106. +
  12107. + memcpy(tag, WPA_OUI, 3);
  12108. + tag += 3;
  12109. + *(tag++) = wpa_type ? 4:2;
  12110. + *(tag++) = 1;
  12111. + *(tag++) = 0;
  12112. +
  12113. +
  12114. + memcpy(tag, WPA_OUI, 3);
  12115. + tag += 3;
  12116. + *(tag++) = wpa_type ? 4:0;
  12117. + *(tag++) = 1;
  12118. + *(tag++) = 0;
  12119. +
  12120. + memcpy(tag, WPA_OUI, 3);
  12121. + tag += 3;
  12122. + *(tag++) = 0;
  12123. +#else
  12124. + if (ieee->iw_mode == IW_MODE_ADHOC)
  12125. + {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
  12126. + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
  12127. + }
  12128. +
  12129. + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  12130. +
  12131. +#endif
  12132. + }
  12133. +
  12134. +
  12135. + skb->dev = ieee->dev;
  12136. + return skb;
  12137. +}
  12138. +
  12139. +
  12140. +#ifdef _RTL8187_EXT_PATCH_
  12141. +struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
  12142. +{
  12143. + u8 *tag;
  12144. + int beacon_size;
  12145. + struct ieee80211_probe_response *beacon_buf;
  12146. + struct sk_buff *skb;
  12147. + int encrypt;
  12148. + int atim_len,erp_len;
  12149. + struct ieee80211_crypt_data* crypt;
  12150. + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
  12151. +
  12152. + char *ssid = net->ssid;
  12153. + int ssid_len = net->ssid_len;
  12154. +
  12155. + int rate_len = ieee->current_network.rates_len+2;
  12156. + int rate_ex_len = ieee->current_network.rates_ex_len;
  12157. + int wpa_ie_len = 0, wpa_type=0;
  12158. + if(rate_ex_len > 0) rate_ex_len+=2;
  12159. +
  12160. + if( ieee->meshScanMode&4)
  12161. + ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
  12162. + if( ieee->meshScanMode&6)
  12163. + {
  12164. +
  12165. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  12166. + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
  12167. +#else
  12168. + schedule_task(&ieee->ext_stop_scan_wq);
  12169. +#endif
  12170. + }
  12171. + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
  12172. + atim_len = 4;
  12173. + else
  12174. + atim_len = 0;
  12175. +
  12176. + if(ieee80211_is_54g(*net))
  12177. + erp_len = 3;
  12178. + else
  12179. + erp_len = 0;
  12180. +
  12181. + if (ieee->wpa_enabled &&(ieee->iw_ext_mode==ieee->iw_mode))
  12182. + {
  12183. +// printk("hoho wpa_enalbe\n");
  12184. + wpa_ie_len = ieee->wpa_ie_len; //24-2
  12185. + }
  12186. +
  12187. + beacon_size = sizeof(struct ieee80211_probe_response)+
  12188. + ssid_len
  12189. + +3 //channel
  12190. + +rate_len
  12191. + +rate_ex_len
  12192. + +atim_len
  12193. + +erp_len
  12194. + +wpa_ie_len;
  12195. +//b
  12196. + skb = dev_alloc_skb(beacon_size+196);
  12197. +
  12198. + if (!skb)
  12199. + return NULL;
  12200. +
  12201. + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
  12202. +
  12203. + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
  12204. + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12205. + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
  12206. +
  12207. + beacon_buf->header.duration_id = 0; //FIXME
  12208. +
  12209. + beacon_buf->beacon_interval =
  12210. + cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
  12211. + beacon_buf->capability =
  12212. + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
  12213. +
  12214. + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
  12215. + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
  12216. +#ifdef _RTL8187_EXT_PATCH_
  12217. +
  12218. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  12219. +#else
  12220. +
  12221. + crypt = ieee->crypt[ieee->tx_keyidx];
  12222. +#endif
  12223. +
  12224. +// crypt = ieee->crypt[ieee->tx_keyidx];
  12225. + if (crypt)
  12226. + wpa_type = strcmp(crypt->ops->name, "TKIP");
  12227. +
  12228. + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
  12229. + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
  12230. +
  12231. + if (encrypt)
  12232. + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  12233. +
  12234. +
  12235. + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
  12236. +
  12237. + beacon_buf->info_element.id = MFIE_TYPE_SSID;
  12238. + beacon_buf->info_element.len = ssid_len;
  12239. +
  12240. + tag = (u8*) beacon_buf->info_element.data;
  12241. +
  12242. + // brocad cast / probe rsp
  12243. + if(memcmp(dest, broadcast_addr, ETH_ALEN ))
  12244. + memcpy(tag, ssid, ssid_len);
  12245. + else
  12246. + ssid_len=0;
  12247. +
  12248. + tag += ssid_len;
  12249. +
  12250. +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
  12251. +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
  12252. +
  12253. + *(tag++) = MFIE_TYPE_RATES;
  12254. + *(tag++) = rate_len-2;
  12255. + memcpy(tag,ieee->current_network.rates,rate_len-2);
  12256. + tag+=rate_len-2;
  12257. +
  12258. + *(tag++) = MFIE_TYPE_DS_SET;
  12259. + *(tag++) = 1;
  12260. + *(tag++) = ieee->current_network.channel; // use current_network here
  12261. +
  12262. +
  12263. + if(atim_len){
  12264. + *(tag++) = MFIE_TYPE_IBSS_SET;
  12265. + *(tag++) = 2;
  12266. + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
  12267. + tag+=2;
  12268. + }
  12269. +
  12270. + if(erp_len){
  12271. + *(tag++) = MFIE_TYPE_ERP;
  12272. + *(tag++) = 1;
  12273. + *(tag++) = 0;
  12274. + }
  12275. +
  12276. + if(rate_ex_len){
  12277. + *(tag++) = MFIE_TYPE_RATES_EX;
  12278. + *(tag++) = rate_ex_len-2;
  12279. + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
  12280. + tag+=rate_ex_len-2;
  12281. + }
  12282. +
  12283. + if (wpa_ie_len)
  12284. + {
  12285. +#if 0
  12286. + *(tag++) = 0xdd;
  12287. + *(tag++) = wpa_ie_len-2;
  12288. + memcpy(tag, WPA_OUI, 3);
  12289. + tag += 3;
  12290. + *(tag++) = 1;
  12291. + *(tag++) = 1;
  12292. + *(tag++) = 0;
  12293. +
  12294. + memcpy(tag, WPA_OUI, 3);
  12295. + tag += 3;
  12296. + *(tag++) = wpa_type ? 4:2;
  12297. + *(tag++) = 1;
  12298. + *(tag++) = 0;
  12299. +
  12300. +
  12301. + memcpy(tag, WPA_OUI, 3);
  12302. + tag += 3;
  12303. + *(tag++) = wpa_type ? 4:0;
  12304. + *(tag++) = 1;
  12305. + *(tag++) = 0;
  12306. +
  12307. + memcpy(tag, WPA_OUI, 3);
  12308. + tag += 3;
  12309. + *(tag++) = 0;
  12310. +#else
  12311. + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  12312. +#endif
  12313. + }
  12314. +
  12315. +
  12316. + skb->dev = ieee->dev;
  12317. + return skb;
  12318. +}
  12319. +#endif // _RTL8187_EXT_PATCH_
  12320. +
  12321. +
  12322. +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
  12323. +{
  12324. + struct sk_buff *skb;
  12325. + u8* tag;
  12326. +
  12327. + struct ieee80211_crypt_data* crypt;
  12328. + struct ieee80211_assoc_response_frame *assoc;
  12329. + short encrypt;
  12330. +
  12331. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  12332. + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
  12333. +
  12334. + skb = dev_alloc_skb(len);
  12335. +
  12336. + if (!skb)
  12337. + return NULL;
  12338. +
  12339. + assoc = (struct ieee80211_assoc_response_frame *)
  12340. + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
  12341. +
  12342. + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
  12343. + memcpy(assoc->header.addr1, dest,ETH_ALEN);
  12344. + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  12345. + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12346. + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
  12347. + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
  12348. +
  12349. +
  12350. + if(ieee->short_slot)
  12351. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  12352. +
  12353. + if (ieee->host_encrypt){
  12354. +#ifdef _RTL8187_EXT_PATCH_
  12355. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  12356. +#else
  12357. + crypt = ieee->crypt[ieee->tx_keyidx];
  12358. +#endif
  12359. + }
  12360. + else crypt = NULL;
  12361. +
  12362. + encrypt = ( crypt && crypt->ops);
  12363. +
  12364. + if (encrypt)
  12365. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  12366. +
  12367. + assoc->status = 0;
  12368. + assoc->aid = cpu_to_le16(ieee->assoc_id);
  12369. + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
  12370. + else ieee->assoc_id++;
  12371. +
  12372. + tag = (u8*) skb_put(skb, rate_len);
  12373. +
  12374. + ieee80211_MFIE_Brate(ieee, &tag);
  12375. + ieee80211_MFIE_Grate(ieee, &tag);
  12376. +
  12377. + return skb;
  12378. +}
  12379. +
  12380. +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
  12381. +{
  12382. + struct sk_buff *skb;
  12383. + struct ieee80211_authentication *auth;
  12384. +
  12385. + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
  12386. +
  12387. + if (!skb)
  12388. + return NULL;
  12389. +
  12390. + skb->len = sizeof(struct ieee80211_authentication);
  12391. +
  12392. + auth = (struct ieee80211_authentication *)skb->data;
  12393. +
  12394. + auth->status = cpu_to_le16(status);
  12395. + auth->transaction = cpu_to_le16(2);
  12396. + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
  12397. +
  12398. +#ifdef _RTL8187_EXT_PATCH_
  12399. + if(ieee->iw_mode == ieee->iw_ext_mode)
  12400. + memcpy(auth->header.addr3, dest, ETH_ALEN);
  12401. +#else
  12402. + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  12403. +#endif
  12404. + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12405. + memcpy(auth->header.addr1, dest, ETH_ALEN);
  12406. + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
  12407. + return skb;
  12408. +
  12409. +
  12410. +}
  12411. +
  12412. +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
  12413. +{
  12414. + struct sk_buff *skb;
  12415. + struct ieee80211_hdr_3addr* hdr;
  12416. +
  12417. + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
  12418. +
  12419. + if (!skb)
  12420. + return NULL;
  12421. +
  12422. + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
  12423. +
  12424. + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
  12425. + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
  12426. + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
  12427. +
  12428. + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
  12429. + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
  12430. + (pwr ? IEEE80211_FCTL_PM:0));
  12431. +
  12432. + return skb;
  12433. +
  12434. +
  12435. +}
  12436. +
  12437. +
  12438. +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
  12439. +{
  12440. + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
  12441. +
  12442. + if (buf){
  12443. + softmac_mgmt_xmit(buf, ieee);
  12444. + dev_kfree_skb_any(buf);//edit by thomas
  12445. + }
  12446. +}
  12447. +
  12448. +
  12449. +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
  12450. +{
  12451. + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
  12452. +
  12453. + if (buf){
  12454. + softmac_mgmt_xmit(buf, ieee);
  12455. + dev_kfree_skb_any(buf);//edit by thomas
  12456. + }
  12457. +}
  12458. +
  12459. +
  12460. +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
  12461. +{
  12462. +
  12463. + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
  12464. +
  12465. + if (buf) {
  12466. + softmac_mgmt_xmit(buf, ieee);
  12467. + dev_kfree_skb_any(buf);//edit by thomas
  12468. + }
  12469. +}
  12470. +
  12471. +
  12472. +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
  12473. +{
  12474. + struct sk_buff *skb;
  12475. +
  12476. + struct ieee80211_assoc_request_frame *hdr;
  12477. + u8 *tag;
  12478. + //int i;
  12479. + unsigned int wpa_len = beacon->wpa_ie_len;
  12480. +#if 1
  12481. + // for testing purpose
  12482. + unsigned int rsn_len = beacon->rsn_ie_len;
  12483. +#else
  12484. + unsigned int rsn_len = beacon->rsn_ie_len - 4;
  12485. +#endif
  12486. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  12487. + unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
  12488. +#ifdef THOMAS_TURBO
  12489. + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
  12490. +#endif
  12491. +
  12492. + u8 encry_proto = ieee->wpax_type_notify & 0xff;
  12493. +
  12494. +
  12495. + int len = 0;
  12496. +
  12497. + //[0] Notify type of encryption: WPA/WPA2
  12498. + //[1] pair wise type
  12499. + //[2] authen type
  12500. + if(ieee->wpax_type_set) {
  12501. + if (IEEE_PROTO_WPA == encry_proto) {
  12502. + rsn_len = 0;
  12503. + } else if (IEEE_PROTO_RSN == encry_proto) {
  12504. + wpa_len = 0;
  12505. + }
  12506. + }
  12507. +#ifdef THOMAS_TURBO
  12508. + len = sizeof(struct ieee80211_assoc_request_frame)+
  12509. + + beacon->ssid_len//essid tagged val
  12510. + + rate_len//rates tagged val
  12511. + + wpa_len
  12512. + + rsn_len
  12513. + + wmm_info_len
  12514. + + turbo_info_len;
  12515. +#else
  12516. + len = sizeof(struct ieee80211_assoc_request_frame)+
  12517. + + beacon->ssid_len//essid tagged val
  12518. + + rate_len//rates tagged val
  12519. + + wpa_len
  12520. + + rsn_len
  12521. + + wmm_info_len;
  12522. +#endif
  12523. +
  12524. +#ifdef _RTL8187_EXT_PATCH_
  12525. + if(ieee->iw_mode == ieee->iw_ext_mode)
  12526. + skb = dev_alloc_skb(len+256); // stanley
  12527. + else
  12528. +#endif
  12529. + skb = dev_alloc_skb(len);
  12530. +
  12531. + if (!skb)
  12532. + return NULL;
  12533. +
  12534. + hdr = (struct ieee80211_assoc_request_frame *)
  12535. + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
  12536. +
  12537. +
  12538. + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
  12539. + hdr->header.duration_id= 37; //FIXME
  12540. + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
  12541. + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12542. + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
  12543. + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
  12544. +
  12545. + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
  12546. + if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
  12547. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  12548. +
  12549. + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
  12550. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
  12551. +
  12552. + if(ieee->short_slot)
  12553. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  12554. +
  12555. +#ifdef _RTL8187_EXT_PATCH_
  12556. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
  12557. + ieee->ext_patch_ieee80211_association_req_1(hdr);
  12558. +#endif
  12559. +
  12560. + hdr->listen_interval = 0xa; //FIXME
  12561. +
  12562. + hdr->info_element.id = MFIE_TYPE_SSID;
  12563. +
  12564. + hdr->info_element.len = beacon->ssid_len;
  12565. + tag = skb_put(skb, beacon->ssid_len);
  12566. + memcpy(tag, beacon->ssid, beacon->ssid_len);
  12567. +
  12568. + tag = skb_put(skb, rate_len);
  12569. +
  12570. + ieee80211_MFIE_Brate(ieee, &tag);
  12571. + ieee80211_MFIE_Grate(ieee, &tag);
  12572. +
  12573. + //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
  12574. + //choose AES encryption as default algorithm while using mixed mode
  12575. +#if 0
  12576. + if(rsn_len == 0){
  12577. +
  12578. + tag = skb_put(skb,wpa_len);
  12579. +
  12580. + if(wpa_len) {
  12581. +
  12582. +
  12583. + //{add by david. 2006.8.31
  12584. + //fix linksys compatibility bug
  12585. + //}
  12586. + if(wpa_len > 24) {//22+2, mean include the capability
  12587. + beacon->wpa_ie[wpa_len - 2] = 0;
  12588. + }
  12589. + //multicast cipher OUI
  12590. + if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
  12591. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  12592. + }
  12593. + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
  12594. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  12595. + }
  12596. + //unicast cipher OUI
  12597. + if( beacon->wpa_ie[14]==0
  12598. + && beacon->wpa_ie[15]==0x50
  12599. + && beacon->wpa_ie[16]==0xf2
  12600. + && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
  12601. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  12602. + }
  12603. +
  12604. + else if( beacon->wpa_ie[14]==0
  12605. + && beacon->wpa_ie[15]==0x50
  12606. + && beacon->wpa_ie[16]==0xf2
  12607. + && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
  12608. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  12609. + }
  12610. + //indicate the wpa_ie content to WPA_SUPPLICANT
  12611. + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
  12612. + memset(buff, 0, IW_CUSTOM_MAX);
  12613. + p=buff;
  12614. + p += sprintf(p, "ASSOCINFO(ReqIEs=");
  12615. + for(i=0;i<wpa_len;i++){
  12616. + p += sprintf(p, "%02x", beacon->wpa_ie[i]);
  12617. + }
  12618. + p += sprintf(p, ")");
  12619. + memset(&wrqu, 0, sizeof(wrqu) );
  12620. + wrqu.data.length = p - buff;
  12621. +
  12622. + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
  12623. + memcpy(tag,beacon->wpa_ie,wpa_len);
  12624. + }
  12625. +
  12626. + }
  12627. +
  12628. + if(rsn_len > 22) {
  12629. +
  12630. + if( beacon->rsn_ie[4]==0x0 &&
  12631. + beacon->rsn_ie[5]==0xf &&
  12632. + beacon->rsn_ie[6]==0xac){
  12633. +
  12634. + switch(beacon->rsn_ie[7]){
  12635. + case 0x1:
  12636. + ieee->broadcast_key_type = KEY_TYPE_WEP40;
  12637. + break;
  12638. + case 0x2:
  12639. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  12640. + break;
  12641. + case 0x4:
  12642. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  12643. + break;
  12644. + case 0x5:
  12645. + ieee->broadcast_key_type = KEY_TYPE_WEP104;
  12646. + break;
  12647. + default:
  12648. + printk("fault suite type in RSN broadcast key\n");
  12649. + break;
  12650. + }
  12651. + }
  12652. +
  12653. + if( beacon->rsn_ie[10]==0x0 &&
  12654. + beacon->rsn_ie[11]==0xf &&
  12655. + beacon->rsn_ie[12]==0xac){
  12656. + if(beacon->rsn_ie[8]==1){//not mixed mode
  12657. + switch(beacon->rsn_ie[13]){
  12658. + case 0x2:
  12659. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  12660. + break;
  12661. + case 0x4:
  12662. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  12663. + break;
  12664. + default:
  12665. + printk("fault suite type in RSN pairwise key\n");
  12666. + break;
  12667. + }
  12668. + }
  12669. + else if(beacon->rsn_ie[8]==2){//mixed mode
  12670. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  12671. + }
  12672. + }
  12673. +
  12674. +
  12675. +
  12676. + tag = skb_put(skb,22);
  12677. + memcpy(tag,(beacon->rsn_ie + info_addr),8);
  12678. + tag[1] = 20;
  12679. + tag += 8;
  12680. + info_addr += 8;
  12681. +
  12682. + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
  12683. + for (i = 0; i < 2; i++) {
  12684. + tag[0] = 1;
  12685. + tag[1] = 0;
  12686. + tag += 2;
  12687. + suite_count = beacon->rsn_ie[info_addr] + \
  12688. + (beacon->rsn_ie[info_addr + 1] << 8);
  12689. + info_addr += 2;
  12690. + if(1 == suite_count) {
  12691. + memcpy(tag,(beacon->rsn_ie + info_addr),4);
  12692. + info_addr += 4;
  12693. + } else {
  12694. + // if the wpax_type_notify has been set by the application,
  12695. + // just use it, otherwise just use the default one.
  12696. + if(ieee->wpax_type_set) {
  12697. + suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
  12698. + memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
  12699. + } else {
  12700. + //default set as ccmp, or none authentication
  12701. + if(i == 0) {
  12702. + memcpy(tag,rsn_authen_cipher_suite[4],4);
  12703. + } else {
  12704. + memcpy(tag,rsn_authen_cipher_suite[2],4);
  12705. + }
  12706. +
  12707. + }
  12708. +
  12709. + info_addr += (suite_count * 4);
  12710. + }
  12711. + tag += 4;
  12712. + }
  12713. + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
  12714. +
  12715. + tag[0] = 0;
  12716. + tag[1] = beacon->rsn_ie[info_addr+1];
  12717. +
  12718. +
  12719. +
  12720. + } else {
  12721. + tag = skb_put(skb,rsn_len);
  12722. + if(rsn_len) {
  12723. +
  12724. +
  12725. + if( beacon->rsn_ie[4]==0x0 &&
  12726. + beacon->rsn_ie[5]==0xf &&
  12727. + beacon->rsn_ie[6]==0xac){
  12728. + switch(beacon->rsn_ie[7]){
  12729. + case 0x1:
  12730. + ieee->broadcast_key_type = KEY_TYPE_WEP40;
  12731. + break;
  12732. + case 0x2:
  12733. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  12734. + break;
  12735. + case 0x4:
  12736. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  12737. + break;
  12738. + case 0x5:
  12739. + ieee->broadcast_key_type = KEY_TYPE_WEP104;
  12740. + break;
  12741. + default:
  12742. + printk("fault suite type in RSN broadcast key\n");
  12743. + break;
  12744. + }
  12745. + }
  12746. + if( beacon->rsn_ie[10]==0x0 &&
  12747. + beacon->rsn_ie[11]==0xf &&
  12748. + beacon->rsn_ie[12]==0xac){
  12749. + if(beacon->rsn_ie[8]==1){//not mixed mode
  12750. + switch(beacon->rsn_ie[13]){
  12751. + case 0x2:
  12752. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  12753. + break;
  12754. + case 0x4:
  12755. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  12756. + break;
  12757. + default:
  12758. + printk("fault suite type in RSN pairwise key\n");
  12759. + break;
  12760. + }
  12761. +
  12762. + }
  12763. + else if(beacon->rsn_ie[8]==2){//mixed mode
  12764. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  12765. + }
  12766. + }
  12767. +
  12768. +
  12769. + beacon->rsn_ie[rsn_len - 2] = 0;
  12770. + memcpy(tag,beacon->rsn_ie,rsn_len);
  12771. + }
  12772. + }
  12773. +#else
  12774. + if (ieee->wpa_ie){
  12775. + tag = skb_put(skb,ieee->wpa_ie_len);
  12776. + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
  12777. + }
  12778. +#endif
  12779. + tag = skb_put(skb,wmm_info_len);
  12780. + if(wmm_info_len) {
  12781. + ieee80211_WMM_Info(ieee, &tag);
  12782. + }
  12783. +#ifdef THOMAS_TURBO
  12784. + tag = skb_put(skb,turbo_info_len);
  12785. + if(turbo_info_len) {
  12786. + ieee80211_TURBO_Info(ieee, &tag);
  12787. + }
  12788. +#endif
  12789. +
  12790. +#ifdef _RTL8187_EXT_PATCH_
  12791. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
  12792. + ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
  12793. +#endif
  12794. +
  12795. + return skb;
  12796. +}
  12797. +
  12798. +void ieee80211_associate_abort(struct ieee80211_device *ieee)
  12799. +{
  12800. +
  12801. + unsigned long flags;
  12802. + spin_lock_irqsave(&ieee->lock, flags);
  12803. +
  12804. + ieee->associate_seq++;
  12805. +
  12806. + /* don't scan, and avoid to have the RX path possibily
  12807. + * try again to associate. Even do not react to AUTH or
  12808. + * ASSOC response. Just wait for the retry wq to be scheduled.
  12809. + * Here we will check if there are good nets to associate
  12810. + * with, so we retry or just get back to NO_LINK and scanning
  12811. + */
  12812. + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
  12813. + IEEE80211_DEBUG_MGMT("Authentication failed\n");
  12814. + ieee->softmac_stats.no_auth_rs++;
  12815. + }else{
  12816. + IEEE80211_DEBUG_MGMT("Association failed\n");
  12817. + ieee->softmac_stats.no_ass_rs++;
  12818. + }
  12819. +
  12820. + ieee->state = IEEE80211_ASSOCIATING_RETRY;
  12821. +
  12822. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  12823. + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
  12824. + IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
  12825. +#else
  12826. + schedule_task(&ieee->associate_retry_wq);
  12827. +#endif
  12828. +
  12829. + spin_unlock_irqrestore(&ieee->lock, flags);
  12830. +}
  12831. +
  12832. +void ieee80211_associate_abort_cb(unsigned long dev)
  12833. +{
  12834. + ieee80211_associate_abort((struct ieee80211_device *) dev);
  12835. +}
  12836. +
  12837. +
  12838. +void ieee80211_associate_step1(struct ieee80211_device *ieee)
  12839. +{
  12840. + struct ieee80211_network *beacon = &ieee->current_network;
  12841. + struct sk_buff *skb;
  12842. +
  12843. + IEEE80211_DEBUG_MGMT("Stopping scan\n");
  12844. +
  12845. + ieee->softmac_stats.tx_auth_rq++;
  12846. + skb=ieee80211_authentication_req(beacon, ieee, 0);
  12847. +
  12848. +#ifdef _RTL8187_EXT_PATCH_
  12849. + if(ieee->iw_mode == ieee->iw_ext_mode ) {
  12850. + if(skb)
  12851. + softmac_mgmt_xmit(skb, ieee);
  12852. + return;
  12853. + }else
  12854. +#endif
  12855. + if (!skb)
  12856. + ieee80211_associate_abort(ieee);
  12857. + else{
  12858. + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
  12859. + IEEE80211_DEBUG_MGMT("Sending authentication request\n");
  12860. + //printk(KERN_WARNING "Sending authentication request\n");
  12861. + softmac_mgmt_xmit(skb, ieee);
  12862. + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
  12863. + if(!timer_pending(&ieee->associate_timer)){
  12864. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  12865. + add_timer(&ieee->associate_timer);
  12866. + }
  12867. + dev_kfree_skb_any(skb);//edit by thomas
  12868. + }
  12869. +}
  12870. +
  12871. +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
  12872. +{
  12873. + u8 *c;
  12874. + struct sk_buff *skb;
  12875. + struct ieee80211_network *beacon = &ieee->current_network;
  12876. +// int hlen = sizeof(struct ieee80211_authentication);
  12877. +
  12878. + ieee->associate_seq++;
  12879. + ieee->softmac_stats.tx_auth_rq++;
  12880. +
  12881. + skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
  12882. + if (!skb)
  12883. + ieee80211_associate_abort(ieee);
  12884. + else{
  12885. + c = skb_put(skb, chlen+2);
  12886. + *(c++) = MFIE_TYPE_CHALLENGE;
  12887. + *(c++) = chlen;
  12888. + memcpy(c, challenge, chlen);
  12889. +
  12890. + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
  12891. +
  12892. + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
  12893. +
  12894. + softmac_mgmt_xmit(skb, ieee);
  12895. +
  12896. + if(!timer_pending(&ieee->associate_timer)){
  12897. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  12898. + add_timer(&ieee->associate_timer);
  12899. + }
  12900. + dev_kfree_skb_any(skb);//edit by thomas
  12901. + }
  12902. + kfree(challenge);
  12903. +}
  12904. +
  12905. +#ifdef _RTL8187_EXT_PATCH_
  12906. +
  12907. +// based on ieee80211_assoc_resp
  12908. +struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
  12909. +{
  12910. + struct sk_buff *skb;
  12911. + u8* tag;
  12912. +
  12913. + struct ieee80211_crypt_data* crypt;
  12914. + struct ieee80211_assoc_response_frame *assoc;
  12915. + short encrypt;
  12916. +
  12917. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  12918. + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
  12919. +
  12920. + if(ieee->iw_mode == ieee->iw_ext_mode)
  12921. + skb = dev_alloc_skb(len+256); // stanley
  12922. + else
  12923. + skb = dev_alloc_skb(len);
  12924. +
  12925. + if (!skb)
  12926. + return NULL;
  12927. +
  12928. + assoc = (struct ieee80211_assoc_response_frame *)
  12929. + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
  12930. +
  12931. + assoc->header.frame_ctl = cpu_to_le16(pkt_type);
  12932. +
  12933. + memcpy(assoc->header.addr1, dest,ETH_ALEN);
  12934. + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  12935. + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  12936. + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
  12937. + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
  12938. +
  12939. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
  12940. + ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
  12941. +
  12942. + if(ieee->short_slot)
  12943. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  12944. +
  12945. + if (ieee->host_encrypt)
  12946. +#ifdef _RTL8187_EXT_PATCH_
  12947. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  12948. +#else
  12949. + crypt = ieee->crypt[ieee->tx_keyidx];
  12950. +#endif
  12951. +
  12952. + else crypt = NULL;
  12953. +
  12954. + encrypt = ( crypt && crypt->ops);
  12955. +
  12956. + if (encrypt)
  12957. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  12958. +
  12959. + assoc->status = 0;
  12960. + assoc->aid = cpu_to_le16(ieee->assoc_id);
  12961. + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
  12962. + else ieee->assoc_id++;
  12963. +
  12964. + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
  12965. + assoc->info_element.len = 0;
  12966. +
  12967. + tag = (u8*) skb_put(skb, rate_len);
  12968. +
  12969. + ieee80211_MFIE_Brate(ieee, &tag);
  12970. + ieee80211_MFIE_Grate(ieee, &tag);
  12971. +
  12972. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
  12973. + ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
  12974. +
  12975. + return skb;
  12976. +}
  12977. +
  12978. +// based on ieee80211_resp_to_assoc_rq
  12979. +void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
  12980. +{
  12981. + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
  12982. +
  12983. + if (buf)
  12984. + softmac_mgmt_xmit(buf, ieee);
  12985. +}
  12986. +
  12987. +// based on ieee80211_associate_step2
  12988. +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
  12989. +{
  12990. +
  12991. + struct sk_buff* skb;
  12992. +
  12993. + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
  12994. +
  12995. + ieee->softmac_stats.tx_ass_rq++;
  12996. + skb=ieee80211_association_req(pstat, ieee);
  12997. + if (skb)
  12998. + softmac_mgmt_xmit(skb, ieee);
  12999. +}
  13000. +
  13001. +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
  13002. +{
  13003. + // do nothing
  13004. + // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
  13005. + return;
  13006. +}
  13007. +#endif // _RTL8187_EXT_PATCH_
  13008. +
  13009. +void ieee80211_associate_step2(struct ieee80211_device *ieee)
  13010. +{
  13011. + struct sk_buff* skb;
  13012. + struct ieee80211_network *beacon = &ieee->current_network;
  13013. +
  13014. +// del_timer_sync(&ieee->associate_timer);
  13015. +
  13016. + IEEE80211_DEBUG_MGMT("Sending association request\n");
  13017. +
  13018. + ieee->softmac_stats.tx_ass_rq++;
  13019. + skb=ieee80211_association_req(beacon, ieee);
  13020. + if (!skb)
  13021. + ieee80211_associate_abort(ieee);
  13022. + else{
  13023. + softmac_mgmt_xmit(skb, ieee);
  13024. + if(!timer_pending(&ieee->associate_timer)){
  13025. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  13026. + add_timer(&ieee->associate_timer);
  13027. + }
  13028. + dev_kfree_skb_any(skb);//edit by thomas
  13029. + }
  13030. +}
  13031. +
  13032. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  13033. +void ieee80211_associate_complete_wq(struct work_struct *work)
  13034. +{
  13035. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
  13036. +#else
  13037. +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
  13038. +{
  13039. +#endif
  13040. + printk(KERN_INFO "Associated successfully\n");
  13041. + if(ieee80211_is_54g(ieee->current_network) &&
  13042. + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  13043. +
  13044. + ieee->rate = 540;
  13045. + printk(KERN_INFO"Using G rates\n");
  13046. + }else{
  13047. + ieee->rate = 110;
  13048. + printk(KERN_INFO"Using B rates\n");
  13049. + }
  13050. +
  13051. +//by lizhaoming for LED LINK
  13052. +#ifdef LED_SHIN
  13053. + {
  13054. + struct net_device *dev = ieee->dev;
  13055. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  13056. + }
  13057. +#endif
  13058. +
  13059. + ieee->link_change(ieee->dev);
  13060. + notify_wx_assoc_event(ieee);
  13061. + if (ieee->data_hard_resume)
  13062. + ieee->data_hard_resume(ieee->dev);
  13063. + netif_carrier_on(ieee->dev);
  13064. +}
  13065. +
  13066. +void ieee80211_associate_complete(struct ieee80211_device *ieee)
  13067. +{
  13068. + int i;
  13069. +// struct net_device *dev = ieee->dev;
  13070. + del_timer_sync(&ieee->associate_timer);
  13071. +
  13072. + for(i = 0; i < 6; i++) {
  13073. +// ieee->seq_ctrl[i] = 0;
  13074. + }
  13075. + ieee->state = IEEE80211_LINKED;
  13076. + IEEE80211_DEBUG_MGMT("Successfully associated\n");
  13077. +
  13078. + //by lizhaoming for LED LINK
  13079. + //ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  13080. +
  13081. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13082. + queue_work(ieee->wq, &ieee->associate_complete_wq);
  13083. +#else
  13084. + schedule_task(&ieee->associate_complete_wq);
  13085. +#endif
  13086. +}
  13087. +
  13088. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  13089. +void ieee80211_associate_procedure_wq(struct work_struct *work)
  13090. +{
  13091. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
  13092. +#else
  13093. +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
  13094. +{
  13095. +#endif
  13096. + ieee->sync_scan_hurryup = 1;
  13097. + down(&ieee->wx_sem);
  13098. +
  13099. + if (ieee->data_hard_stop)
  13100. + ieee->data_hard_stop(ieee->dev);
  13101. +
  13102. + ieee80211_stop_scan(ieee);
  13103. + //printk("=======>%s set chan:%d\n", __func__, ieee->current_network.channel);
  13104. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  13105. +
  13106. + ieee->associate_seq = 1;
  13107. + ieee80211_associate_step1(ieee);
  13108. +
  13109. + up(&ieee->wx_sem);
  13110. +}
  13111. +#ifdef _RTL8187_EXT_PATCH_
  13112. +// based on ieee80211_associate_procedure_wq
  13113. +
  13114. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13115. +void ieee80211_ext_stop_scan_wq(struct work_struct *work)
  13116. +{
  13117. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
  13118. +#else
  13119. +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
  13120. +{
  13121. +#endif
  13122. +/*
  13123. + if (ieee->scanning == 0)
  13124. + {
  13125. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
  13126. + && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
  13127. + return;
  13128. + }
  13129. +*/
  13130. + ieee->sync_scan_hurryup = 1;
  13131. +
  13132. + down(&ieee->wx_sem);
  13133. +
  13134. + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
  13135. + if (ieee->data_hard_stop)
  13136. + ieee->data_hard_stop(ieee->dev);
  13137. +
  13138. + ieee80211_stop_scan(ieee);
  13139. +
  13140. + // set channel
  13141. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
  13142. + {
  13143. + int ch = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
  13144. + ieee->current_network.channel = ch;
  13145. + ieee->set_chan(ieee->dev, ch);
  13146. + }
  13147. + else
  13148. + {
  13149. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  13150. + }
  13151. + //
  13152. + up(&ieee->wx_sem);
  13153. +}
  13154. +
  13155. +
  13156. +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
  13157. +{
  13158. + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13159. + queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
  13160. + #else
  13161. + schedule_task(&ieee->ext_send_beacon_wq);
  13162. + #endif
  13163. +
  13164. +}
  13165. +
  13166. +#endif // _RTL8187_EXT_PATCH_
  13167. +
  13168. +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
  13169. +{
  13170. + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
  13171. + int tmp_ssid_len = 0;
  13172. +
  13173. + short apset,ssidset,ssidbroad,apmatch,ssidmatch;
  13174. +// printk("===============>%s()\n",__FUNCTION__);
  13175. + /* we are interested in new new only if we are not associated
  13176. + * and we are not associating / authenticating
  13177. + */
  13178. + if (ieee->state != IEEE80211_NOLINK)
  13179. + return;
  13180. +
  13181. + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
  13182. + return;
  13183. +
  13184. + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
  13185. + return;
  13186. +
  13187. +
  13188. + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
  13189. + /* if the user specified the AP MAC, we need also the essid
  13190. + * This could be obtained by beacons or, if the network does not
  13191. + * broadcast it, it can be put manually.
  13192. + */
  13193. + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
  13194. + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
  13195. + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
  13196. + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
  13197. + if(ieee->current_network.ssid_len != net->ssid_len)
  13198. + ssidmatch = 0;
  13199. + else
  13200. + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
  13201. +
  13202. +
  13203. +
  13204. + if ( /* if the user set the AP check if match.
  13205. + * if the network does not broadcast essid we check the user supplyed ANY essid
  13206. + * if the network does broadcast and the user does not set essid it is OK
  13207. + * if the network does broadcast and the user did set essid chech if essid match
  13208. + */
  13209. + ( apset && apmatch &&
  13210. + //((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
  13211. + ((ssidset && ssidbroad && ssidmatch) || (!ssidbroad && ssidset)) ) ||
  13212. + /* if the ap is not set, check that the user set the bssid
  13213. + * and the network does bradcast and that those two bssid matches
  13214. + */
  13215. + (!apset && ssidset && ssidbroad && ssidmatch)
  13216. + ){
  13217. + /* if the essid is hidden replace it with the
  13218. + * essid provided by the user.
  13219. + */
  13220. + if (!ssidbroad){
  13221. + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
  13222. + tmp_ssid_len = ieee->current_network.ssid_len;
  13223. + }
  13224. + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
  13225. +
  13226. + if (!ssidbroad){
  13227. + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
  13228. + ieee->current_network.ssid_len = tmp_ssid_len;
  13229. + }
  13230. + printk(KERN_INFO"Linking with %s, channel:%d\n",ieee->current_network.ssid, ieee->current_network.channel);
  13231. +
  13232. +#ifdef CONFIG_IPS
  13233. + ieee->ieee80211_ips_leave(ieee->dev);
  13234. +#endif
  13235. +
  13236. + if (ieee->iw_mode == IW_MODE_INFRA){
  13237. + ieee->state = IEEE80211_ASSOCIATING;
  13238. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13239. + queue_work(ieee->wq, &ieee->associate_procedure_wq);
  13240. +#else
  13241. + schedule_task(&ieee->associate_procedure_wq);
  13242. +#endif
  13243. + }else{
  13244. + ieee->state = IEEE80211_LINKED;
  13245. + if(ieee80211_is_54g(ieee->current_network) &&
  13246. + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  13247. + ieee->rate = 540;
  13248. + printk(KERN_INFO"Using G rates\n");
  13249. + }else{
  13250. + ieee->rate = 110;
  13251. + printk(KERN_INFO"Using B rates\n");
  13252. + }
  13253. + }
  13254. +
  13255. + }
  13256. + }
  13257. +
  13258. +}
  13259. +
  13260. +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
  13261. +{
  13262. + unsigned long flags;
  13263. + struct ieee80211_network *target;
  13264. +
  13265. + spin_lock_irqsave(&ieee->lock, flags);
  13266. +#if 0
  13267. + list_for_each_entry(target, &ieee->network_list, list) {
  13268. + printk(KERN_INFO"check network list SSID: %s, channel: %d\n",target->ssid,target->channel);
  13269. + }
  13270. +#endif
  13271. + list_for_each_entry(target, &ieee->network_list, list) {
  13272. +
  13273. + /* if the state become different that NOLINK means
  13274. + * we had found what we are searching for
  13275. + */
  13276. +
  13277. + if (ieee->state != IEEE80211_NOLINK)
  13278. + break;
  13279. +
  13280. + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
  13281. + ieee80211_softmac_new_net(ieee, target);
  13282. + }
  13283. +
  13284. + spin_unlock_irqrestore(&ieee->lock, flags);
  13285. +
  13286. + //printk("<=====%s\n", __func__);
  13287. +}
  13288. +
  13289. +
  13290. +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
  13291. +{
  13292. + struct ieee80211_authentication *a;
  13293. + u8 *t;
  13294. + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
  13295. + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
  13296. + return 0xcafe;
  13297. + }
  13298. + *challenge = NULL;
  13299. + a = (struct ieee80211_authentication*) skb->data;
  13300. + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
  13301. + t = skb->data + sizeof(struct ieee80211_authentication);
  13302. +
  13303. + if(*(t++) == MFIE_TYPE_CHALLENGE){
  13304. + *chlen = *(t++);
  13305. + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
  13306. + memcpy(*challenge, t, *chlen);
  13307. + }
  13308. + }
  13309. +
  13310. + return cpu_to_le16(a->status);
  13311. +
  13312. +}
  13313. +
  13314. +
  13315. +int auth_rq_parse(struct sk_buff *skb,u8* dest)
  13316. +{
  13317. + struct ieee80211_authentication *a;
  13318. +
  13319. + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
  13320. + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
  13321. + return -1;
  13322. + }
  13323. + a = (struct ieee80211_authentication*) skb->data;
  13324. +
  13325. + memcpy(dest,a->header.addr2, ETH_ALEN);
  13326. +
  13327. + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
  13328. + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
  13329. +
  13330. + return WLAN_STATUS_SUCCESS;
  13331. +}
  13332. +
  13333. +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
  13334. +{
  13335. + u8 *tag;
  13336. + u8 *skbend;
  13337. + u8 *ssid=NULL;
  13338. + u8 ssidlen = 0;
  13339. +
  13340. + struct ieee80211_hdr_3addr *header =
  13341. + (struct ieee80211_hdr_3addr *) skb->data;
  13342. +
  13343. + if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
  13344. + return -1; /* corrupted */
  13345. +
  13346. + memcpy(src,header->addr2, ETH_ALEN);
  13347. +
  13348. + skbend = (u8*)skb->data + skb->len;
  13349. +
  13350. + tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
  13351. +
  13352. + while (tag+1 < skbend){
  13353. + if (*tag == 0){
  13354. + ssid = tag+2;
  13355. + ssidlen = *(tag+1);
  13356. + break;
  13357. + }
  13358. + tag++; /* point to the len field */
  13359. + tag = tag + *(tag); /* point to the last data byte of the tag */
  13360. + tag++; /* point to the next tag */
  13361. + }
  13362. +
  13363. + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
  13364. + if (ssidlen == 0) return 1;
  13365. +
  13366. + if (!ssid) return 1; /* ssid not found in tagged param */
  13367. + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
  13368. +
  13369. +}
  13370. +
  13371. +int assoc_rq_parse(struct sk_buff *skb,u8* dest)
  13372. +{
  13373. + struct ieee80211_assoc_request_frame *a;
  13374. +
  13375. + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
  13376. + sizeof(struct ieee80211_info_element))) {
  13377. +
  13378. + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
  13379. + return -1;
  13380. + }
  13381. +
  13382. + a = (struct ieee80211_assoc_request_frame*) skb->data;
  13383. +
  13384. + memcpy(dest,a->header.addr2,ETH_ALEN);
  13385. +
  13386. + return 0;
  13387. +}
  13388. +
  13389. +static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
  13390. +{
  13391. + struct ieee80211_assoc_response_frame *a;
  13392. + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
  13393. + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
  13394. + return 0xcafe;
  13395. + }
  13396. +
  13397. + a = (struct ieee80211_assoc_response_frame*) skb->data;
  13398. + *aid = le16_to_cpu(a->aid) & 0x3fff;
  13399. + return le16_to_cpu(a->status);
  13400. +}
  13401. +
  13402. +static inline void
  13403. +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  13404. +{
  13405. + u8 dest[ETH_ALEN];
  13406. +
  13407. + //IEEE80211DMESG("Rx probe");
  13408. + ieee->softmac_stats.rx_probe_rq++;
  13409. + //DMESG("Dest is "MACSTR, MAC2STR(dest));
  13410. + if (probe_rq_parse(ieee, skb, dest)){
  13411. + //IEEE80211DMESG("Was for me!");
  13412. + ieee->softmac_stats.tx_probe_rs++;
  13413. + ieee80211_resp_to_probe(ieee, dest);
  13414. + }
  13415. +}
  13416. +
  13417. +//static inline void
  13418. +inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  13419. +{
  13420. + u8 dest[ETH_ALEN];
  13421. + int status;
  13422. + //IEEE80211DMESG("Rx probe");
  13423. + ieee->softmac_stats.rx_auth_rq++;
  13424. +
  13425. + if ((status = auth_rq_parse(skb, dest))!= -1){
  13426. + ieee80211_resp_to_auth(ieee, status, dest);
  13427. + }
  13428. + //DMESG("Dest is "MACSTR, MAC2STR(dest));
  13429. +
  13430. +}
  13431. +
  13432. +//static inline void
  13433. +inline void
  13434. +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  13435. +{
  13436. +
  13437. + u8 dest[ETH_ALEN];
  13438. + //unsigned long flags;
  13439. +
  13440. + ieee->softmac_stats.rx_ass_rq++;
  13441. + if (assoc_rq_parse(skb,dest) != -1){
  13442. + ieee80211_resp_to_assoc_rq(ieee, dest);
  13443. + }
  13444. +
  13445. + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
  13446. + //FIXME
  13447. + #if 0
  13448. + spin_lock_irqsave(&ieee->lock,flags);
  13449. + add_associate(ieee,dest);
  13450. + spin_unlock_irqrestore(&ieee->lock,flags);
  13451. + #endif
  13452. +}
  13453. +
  13454. +
  13455. +
  13456. +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
  13457. +{
  13458. +
  13459. + struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
  13460. +
  13461. + printk(KERN_ALERT "ieee80211_sta_ps_send_null_frame \n");
  13462. + if (buf)
  13463. + softmac_ps_mgmt_xmit(buf, ieee);
  13464. +
  13465. +}
  13466. +
  13467. +
  13468. +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
  13469. +{
  13470. + int timeout = ieee->ps_timeout;
  13471. + u8 dtim;
  13472. + /*if(ieee->ps == IEEE80211_PS_DISABLED ||
  13473. + ieee->iw_mode != IW_MODE_INFRA ||
  13474. + ieee->state != IEEE80211_LINKED)
  13475. +
  13476. + return 0;
  13477. + */
  13478. + dtim = ieee->current_network.dtim_data;
  13479. + //printk("DTIM\n");
  13480. + if(!(dtim & IEEE80211_DTIM_VALID))
  13481. + return 0;
  13482. + //printk("VALID\n");
  13483. + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
  13484. +
  13485. + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
  13486. + return 2;
  13487. +
  13488. + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
  13489. + return 0;
  13490. +
  13491. + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
  13492. + return 0;
  13493. +
  13494. + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
  13495. + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
  13496. + return 0;
  13497. +
  13498. + if(time_l){
  13499. + *time_l = ieee->current_network.last_dtim_sta_time[0]
  13500. + + (ieee->current_network.beacon_interval
  13501. + * ieee->current_network.dtim_period) * 1000;
  13502. + }
  13503. +
  13504. + if(time_h){
  13505. + *time_h = ieee->current_network.last_dtim_sta_time[1];
  13506. + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
  13507. + *time_h += 1;
  13508. + }
  13509. +
  13510. + return 1;
  13511. +
  13512. +
  13513. +}
  13514. +
  13515. +inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
  13516. +{
  13517. +
  13518. + u32 th,tl;
  13519. + short sleep;
  13520. +
  13521. + unsigned long flags,flags2;
  13522. +
  13523. + spin_lock_irqsave(&ieee->lock, flags);
  13524. +
  13525. + if((ieee->ps == IEEE80211_PS_DISABLED ||
  13526. + ieee->iw_mode != IW_MODE_INFRA ||
  13527. + ieee->state != IEEE80211_LINKED)){
  13528. +
  13529. + // #warning CHECK_LOCK_HERE
  13530. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  13531. +
  13532. + ieee80211_sta_wakeup(ieee, 1);
  13533. +
  13534. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  13535. + }
  13536. +
  13537. + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
  13538. + /* 2 wake, 1 sleep, 0 do nothing */
  13539. + if(sleep == 0)
  13540. + goto out;
  13541. +
  13542. + if(sleep == 1){
  13543. +
  13544. + if(ieee->sta_sleep == 1)
  13545. + ieee->enter_sleep_state(ieee->dev,th,tl);
  13546. +
  13547. + else if(ieee->sta_sleep == 0){
  13548. + // printk("send null 1\n");
  13549. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  13550. +
  13551. + if(ieee->ps_is_queue_empty(ieee->dev)){
  13552. +
  13553. +
  13554. + ieee->sta_sleep = 2;
  13555. +
  13556. + ieee->ps_request_tx_ack(ieee->dev);
  13557. +
  13558. + ieee80211_sta_ps_send_null_frame(ieee,1);
  13559. +
  13560. + ieee->ps_th = th;
  13561. + ieee->ps_tl = tl;
  13562. + }
  13563. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  13564. +
  13565. + }
  13566. +
  13567. +
  13568. + }else if(sleep == 2){
  13569. +//#warning CHECK_LOCK_HERE
  13570. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  13571. +
  13572. + ieee80211_sta_wakeup(ieee,1);
  13573. +
  13574. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  13575. + }
  13576. +
  13577. +out:
  13578. + spin_unlock_irqrestore(&ieee->lock, flags);
  13579. +
  13580. +}
  13581. +
  13582. +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
  13583. +{
  13584. + if(ieee->sta_sleep == 0){
  13585. + if(nl){
  13586. + printk("Warning: driver is probably failing to report TX ps error\n");
  13587. + ieee->ps_request_tx_ack(ieee->dev);
  13588. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  13589. + }
  13590. + return;
  13591. +
  13592. + }
  13593. +
  13594. + if(ieee->sta_sleep == 1)
  13595. + ieee->sta_wake_up(ieee->dev);
  13596. +
  13597. + ieee->sta_sleep = 0;
  13598. +
  13599. + if(nl){
  13600. + ieee->ps_request_tx_ack(ieee->dev);
  13601. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  13602. + }
  13603. +}
  13604. +
  13605. +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
  13606. +{
  13607. + unsigned long flags,flags2;
  13608. +
  13609. + spin_lock_irqsave(&ieee->lock, flags);
  13610. +
  13611. + if(ieee->sta_sleep == 2){
  13612. + /* Null frame with PS bit set */
  13613. + if(success){
  13614. + ieee->sta_sleep = 1;
  13615. + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
  13616. + }
  13617. + /* if the card report not success we can't be sure the AP
  13618. + * has not RXed so we can't assume the AP believe us awake
  13619. + */
  13620. + }
  13621. + /* 21112005 - tx again null without PS bit if lost */
  13622. + else {
  13623. +
  13624. + if((ieee->sta_sleep == 0) && !success){
  13625. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  13626. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  13627. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  13628. + }
  13629. + }
  13630. + spin_unlock_irqrestore(&ieee->lock, flags);
  13631. +}
  13632. +
  13633. +inline int
  13634. +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
  13635. + struct ieee80211_rx_stats *rx_stats, u16 type,
  13636. + u16 stype)
  13637. +{
  13638. + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
  13639. + u16 errcode;
  13640. + u8* challenge=NULL;
  13641. + int chlen=0;
  13642. + int aid=0;
  13643. + struct ieee80211_assoc_response_frame *assoc_resp;
  13644. + struct ieee80211_info_element *info_element;
  13645. +
  13646. + if(!ieee->proto_started)
  13647. + return 0;
  13648. +
  13649. + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
  13650. + ieee->iw_mode == IW_MODE_INFRA &&
  13651. + ieee->state == IEEE80211_LINKED))
  13652. +
  13653. + tasklet_schedule(&ieee->ps_task);
  13654. +
  13655. + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
  13656. + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
  13657. + ieee->last_rx_ps_time = jiffies;
  13658. +
  13659. + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  13660. + case IEEE80211_STYPE_ASSOC_RESP:
  13661. + case IEEE80211_STYPE_REASSOC_RESP:
  13662. +
  13663. + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
  13664. + WLAN_FC_GET_STYPE(header->frame_ctl));
  13665. + //printk(KERN_WARNING "Received association response\n");
  13666. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  13667. + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
  13668. + ieee->iw_mode == IW_MODE_INFRA){
  13669. + if (0 == (errcode=assoc_parse(skb, &aid))){
  13670. + u16 left;
  13671. +
  13672. + ieee->state=IEEE80211_LINKED;
  13673. + ieee->assoc_id = aid;
  13674. + ieee->softmac_stats.rx_ass_ok++;
  13675. +
  13676. + //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
  13677. + if(1 == rx_stats->nic_type) //card type is 8187
  13678. + {
  13679. + goto associate_complete;
  13680. + }
  13681. + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
  13682. + info_element = &assoc_resp->info_element;
  13683. + left = skb->len - ((void*)info_element - (void*)assoc_resp);
  13684. +
  13685. + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
  13686. + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
  13687. + printk(KERN_WARNING "[re]associate reeponse error!");
  13688. + return 1;
  13689. + }
  13690. + switch (info_element->id) {
  13691. + case MFIE_TYPE_GENERIC:
  13692. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
  13693. + if (info_element->len >= 8 &&
  13694. + info_element->data[0] == 0x00 &&
  13695. + info_element->data[1] == 0x50 &&
  13696. + info_element->data[2] == 0xf2 &&
  13697. + info_element->data[3] == 0x02 &&
  13698. + info_element->data[4] == 0x01) {
  13699. + // Not care about version at present.
  13700. + //WMM Parameter Element
  13701. + memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
  13702. + + 8),(info_element->len - 8));
  13703. +
  13704. + if (((ieee->current_network.wmm_info^info_element->data[6])& \
  13705. + 0x0f)||(!ieee->init_wmmparam_flag)) {
  13706. + //refresh paramete element for current network
  13707. + // update the register parameter for hardware
  13708. + ieee->init_wmmparam_flag = 1;
  13709. + //ieee->wmm_param_update(ieee);
  13710. + //schedule_work(&ieee->wmm_param_update_wq);
  13711. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13712. + queue_work(ieee->wq, &ieee->wmm_param_update_wq);
  13713. +#else
  13714. + schedule_task(&ieee->wmm_param_update_wq);
  13715. +#endif
  13716. +
  13717. + }
  13718. + //update info_element for current network
  13719. + ieee->current_network.wmm_info = info_element->data[6];
  13720. + }
  13721. + break;
  13722. + default:
  13723. + //nothing to do at present!!!
  13724. + break;
  13725. + }
  13726. +
  13727. + left -= sizeof(struct ieee80211_info_element_hdr) +
  13728. + info_element->len;
  13729. + info_element = (struct ieee80211_info_element *)
  13730. + &info_element->data[info_element->len];
  13731. + }
  13732. + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
  13733. + {
  13734. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13735. + queue_work(ieee->wq,&ieee->wmm_param_update_wq);
  13736. +#else
  13737. + schedule_task(&ieee->wmm_param_update_wq);
  13738. +#endif
  13739. + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
  13740. + }
  13741. +associate_complete:
  13742. + ieee80211_associate_complete(ieee);
  13743. + }else{
  13744. + ieee->softmac_stats.rx_ass_err++;
  13745. + IEEE80211_DEBUG_MGMT(
  13746. + "Association response status code 0x%x\n",
  13747. + errcode);
  13748. + printk(KERN_WARNING "Association response status code 0x%x\n",
  13749. + errcode);
  13750. + ieee80211_associate_abort(ieee);
  13751. + }
  13752. + }
  13753. +#ifdef _RTL8187_EXT_PATCH_
  13754. + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
  13755. + {
  13756. + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
  13757. + }
  13758. +#endif
  13759. + break;
  13760. +
  13761. + case IEEE80211_STYPE_ASSOC_REQ:
  13762. + case IEEE80211_STYPE_REASSOC_REQ:
  13763. + //printk("Received IEEE80211_STYPE_ASSOC_REQ\n");
  13764. +
  13765. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  13766. + ieee->iw_mode == IW_MODE_MASTER)
  13767. +
  13768. + ieee80211_rx_assoc_rq(ieee, skb);
  13769. +#ifdef _RTL8187_EXT_PATCH_
  13770. + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
  13771. + {
  13772. + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
  13773. + }
  13774. +#endif
  13775. + break;
  13776. +
  13777. + case IEEE80211_STYPE_AUTH:
  13778. + //printk("Received authentication response\n");
  13779. +
  13780. +#ifdef _RTL8187_EXT_PATCH_
  13781. +//printk("IEEE80211_STYPE_AUTH\n");
  13782. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
  13783. + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
  13784. +#endif
  13785. + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
  13786. + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
  13787. + ieee->iw_mode == IW_MODE_INFRA){
  13788. +
  13789. + IEEE80211_DEBUG_MGMT("Received authentication response");
  13790. +
  13791. + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
  13792. + if(ieee->open_wep || !challenge){
  13793. + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
  13794. + ieee->softmac_stats.rx_auth_rs_ok++;
  13795. +
  13796. + ieee80211_associate_step2(ieee);
  13797. + }else{
  13798. + ieee80211_auth_challenge(ieee, challenge, chlen);
  13799. + }
  13800. + }else{
  13801. + ieee->softmac_stats.rx_auth_rs_err++;
  13802. + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
  13803. + ieee80211_associate_abort(ieee);
  13804. + }
  13805. +
  13806. + }else if (ieee->iw_mode == IW_MODE_MASTER){
  13807. + ieee80211_rx_auth_rq(ieee, skb);
  13808. + }
  13809. + }
  13810. + break;
  13811. +
  13812. + case IEEE80211_STYPE_PROBE_REQ:
  13813. + //printk("Received IEEE80211_STYPE_PROBE_REQ\n");
  13814. +
  13815. + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
  13816. + ((ieee->iw_mode == IW_MODE_ADHOC ||
  13817. + ieee->iw_mode == IW_MODE_MASTER) &&
  13818. + ieee->state == IEEE80211_LINKED))
  13819. +
  13820. + ieee80211_rx_probe_rq(ieee, skb);
  13821. + break;
  13822. +
  13823. + case IEEE80211_STYPE_DISASSOC:
  13824. + case IEEE80211_STYPE_DEAUTH:
  13825. + //printk("Received IEEE80211_STYPE_DISASSOC\n");
  13826. +#ifdef _RTL8187_EXT_PATCH_
  13827. +//printk("IEEE80211_STYPE_DEAUTH\n");
  13828. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
  13829. + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
  13830. +#endif
  13831. + /* FIXME for now repeat all the association procedure
  13832. + * both for disassociation and deauthentication
  13833. + */
  13834. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  13835. + ieee->state == IEEE80211_LINKED &&
  13836. + ieee->iw_mode == IW_MODE_INFRA){
  13837. +
  13838. + ieee->state = IEEE80211_ASSOCIATING;
  13839. + ieee->softmac_stats.reassoc++;
  13840. +
  13841. + notify_wx_assoc_event(ieee);
  13842. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  13843. + queue_work(ieee->wq, &ieee->associate_procedure_wq);
  13844. +#else
  13845. + schedule_task(&ieee->associate_procedure_wq);
  13846. +#endif
  13847. + }
  13848. +
  13849. + break;
  13850. +
  13851. + default:
  13852. + return -1;
  13853. + break;
  13854. + }
  13855. +
  13856. + //dev_kfree_skb_any(skb);
  13857. + return 0;
  13858. +}
  13859. +
  13860. +
  13861. +
  13862. +/* following are for a simplier TX queue management.
  13863. + * Instead of using netif_[stop/wake]_queue the driver
  13864. + * will uses these two function (plus a reset one), that
  13865. + * will internally uses the kernel netif_* and takes
  13866. + * care of the ieee802.11 fragmentation.
  13867. + * So the driver receives a fragment per time and might
  13868. + * call the stop function when it want without take care
  13869. + * to have enought room to TX an entire packet.
  13870. + * This might be useful if each fragment need it's own
  13871. + * descriptor, thus just keep a total free memory > than
  13872. + * the max fragmentation treshold is not enought.. If the
  13873. + * ieee802.11 stack passed a TXB struct then you needed
  13874. + * to keep N free descriptors where
  13875. + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
  13876. + * In this way you need just one and the 802.11 stack
  13877. + * will take care of buffering fragments and pass them to
  13878. + * to the driver later, when it wakes the queue.
  13879. + */
  13880. +
  13881. +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
  13882. +{
  13883. +
  13884. +
  13885. + unsigned long flags;
  13886. + int i;
  13887. +#ifdef _RTL8187_EXT_PATCH_
  13888. + int rate = ieee->rate;
  13889. +#endif
  13890. +
  13891. + spin_lock_irqsave(&ieee->lock,flags);
  13892. + #if 0
  13893. + if(ieee->queue_stop){
  13894. + IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
  13895. + netif_stop_queue(ieee->dev);
  13896. + ieee->ieee_stats.swtxstop++;
  13897. + //dev_kfree_skb_any(skb);
  13898. + err = 1;
  13899. + goto exit;
  13900. + }
  13901. +
  13902. + ieee->stats.tx_bytes+=skb->len;
  13903. +
  13904. +
  13905. + txb=ieee80211_skb_to_txb(ieee,skb);
  13906. +
  13907. +
  13908. + if(txb==NULL){
  13909. + IEEE80211DMESG("WW: IEEE stack failed to provide txb");
  13910. + //dev_kfree_skb_any(skb);
  13911. + err = 1;
  13912. + goto exit;
  13913. + }
  13914. + #endif
  13915. +
  13916. +#ifdef _RTL8187_EXT_PATCH_
  13917. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
  13918. + {
  13919. + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
  13920. + }
  13921. +#endif
  13922. + /* called with 2nd parm 0, no tx mgmt lock required */
  13923. + ieee80211_sta_wakeup(ieee,0);
  13924. +
  13925. + for(i = 0; i < txb->nr_frags; i++) {
  13926. +
  13927. + if (ieee->queue_stop){
  13928. + ieee->tx_pending.txb = txb;
  13929. + ieee->tx_pending.frag = i;
  13930. + goto exit;
  13931. + }else{
  13932. + ieee->softmac_data_hard_start_xmit(
  13933. + txb->fragments[i],
  13934. +#ifdef _RTL8187_EXT_PATCH_
  13935. + ieee->dev, rate);
  13936. +#else
  13937. + ieee->dev,ieee->rate);
  13938. +#endif
  13939. + //(i+1)<txb->nr_frags);
  13940. + ieee->stats.tx_packets++;
  13941. + ieee->stats.tx_bytes += txb->fragments[i]->len;
  13942. + ieee->dev->trans_start = jiffies;
  13943. + }
  13944. + }
  13945. +
  13946. + ieee80211_txb_free(txb);
  13947. +
  13948. + exit:
  13949. + spin_unlock_irqrestore(&ieee->lock,flags);
  13950. +
  13951. +}
  13952. +
  13953. +/* called with ieee->lock acquired */
  13954. +void ieee80211_resume_tx(struct ieee80211_device *ieee)
  13955. +{
  13956. + int i;
  13957. + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
  13958. +
  13959. + if (ieee->queue_stop){
  13960. + ieee->tx_pending.frag = i;
  13961. + return;
  13962. + }else{
  13963. +
  13964. + ieee->softmac_data_hard_start_xmit(
  13965. + ieee->tx_pending.txb->fragments[i],
  13966. + ieee->dev,ieee->rate);
  13967. + //(i+1)<ieee->tx_pending.txb->nr_frags);
  13968. + ieee->stats.tx_packets++;
  13969. + ieee->dev->trans_start = jiffies;
  13970. + }
  13971. + }
  13972. +
  13973. +
  13974. + ieee80211_txb_free(ieee->tx_pending.txb);
  13975. + ieee->tx_pending.txb = NULL;
  13976. +}
  13977. +
  13978. +
  13979. +void ieee80211_reset_queue(struct ieee80211_device *ieee)
  13980. +{
  13981. + unsigned long flags;
  13982. +
  13983. + spin_lock_irqsave(&ieee->lock,flags);
  13984. + init_mgmt_queue(ieee);
  13985. + if (ieee->tx_pending.txb){
  13986. + ieee80211_txb_free(ieee->tx_pending.txb);
  13987. + ieee->tx_pending.txb = NULL;
  13988. + }
  13989. + ieee->queue_stop = 0;
  13990. + spin_unlock_irqrestore(&ieee->lock,flags);
  13991. +
  13992. +}
  13993. +
  13994. +void ieee80211_wake_queue(struct ieee80211_device *ieee)
  13995. +{
  13996. +
  13997. + unsigned long flags;
  13998. + struct sk_buff *skb;
  13999. + struct ieee80211_hdr_3addr *header;
  14000. +
  14001. + spin_lock_irqsave(&ieee->lock,flags);
  14002. + if (! ieee->queue_stop) goto exit;
  14003. +
  14004. + ieee->queue_stop = 0;
  14005. +
  14006. + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
  14007. + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
  14008. +
  14009. + header = (struct ieee80211_hdr_3addr *) skb->data;
  14010. +
  14011. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  14012. +
  14013. + if (ieee->seq_ctrl[0] == 0xFFF)
  14014. + ieee->seq_ctrl[0] = 0;
  14015. + else
  14016. + ieee->seq_ctrl[0]++;
  14017. +
  14018. + printk(KERN_ALERT "ieee80211_wake_queue \n");
  14019. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  14020. + dev_kfree_skb_any(skb);//edit by thomas
  14021. + }
  14022. + }
  14023. + if (!ieee->queue_stop && ieee->tx_pending.txb)
  14024. + ieee80211_resume_tx(ieee);
  14025. +
  14026. + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
  14027. + ieee->softmac_stats.swtxawake++;
  14028. + netif_wake_queue(ieee->dev);
  14029. + }
  14030. +
  14031. +exit :
  14032. + spin_unlock_irqrestore(&ieee->lock,flags);
  14033. +}
  14034. +
  14035. +
  14036. +void ieee80211_stop_queue(struct ieee80211_device *ieee)
  14037. +{
  14038. + //unsigned long flags;
  14039. + //spin_lock_irqsave(&ieee->lock,flags);
  14040. +
  14041. + if (! netif_queue_stopped(ieee->dev)){
  14042. + netif_stop_queue(ieee->dev);
  14043. + ieee->softmac_stats.swtxstop++;
  14044. + }
  14045. + ieee->queue_stop = 1;
  14046. + //spin_unlock_irqrestore(&ieee->lock,flags);
  14047. +
  14048. +}
  14049. +
  14050. +
  14051. +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
  14052. +{
  14053. +
  14054. + get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
  14055. +
  14056. + /* an IBSS cell address must have the two less significant
  14057. + * bits of the first byte = 2
  14058. + */
  14059. + ieee->current_network.bssid[0] &= ~0x01;
  14060. + ieee->current_network.bssid[0] |= 0x02;
  14061. +}
  14062. +
  14063. +/* called in user context only */
  14064. +void ieee80211_start_master_bss(struct ieee80211_device *ieee)
  14065. +{
  14066. + ieee->assoc_id = 1;
  14067. +
  14068. + if (ieee->current_network.ssid_len == 0){
  14069. + strncpy(ieee->current_network.ssid,
  14070. + IEEE80211_DEFAULT_TX_ESSID,
  14071. + IW_ESSID_MAX_SIZE);
  14072. +
  14073. + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  14074. + ieee->ssid_set = 1;
  14075. + }
  14076. +
  14077. + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
  14078. +
  14079. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  14080. + ieee->state = IEEE80211_LINKED;
  14081. +
  14082. +//by lizhaoming for LED LINK
  14083. +#ifdef LED_SHIN
  14084. + {
  14085. + struct net_device *dev = ieee->dev;
  14086. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  14087. + }
  14088. +#endif
  14089. + ieee->link_change(ieee->dev);
  14090. + notify_wx_assoc_event(ieee);
  14091. +
  14092. + if (ieee->data_hard_resume)
  14093. + ieee->data_hard_resume(ieee->dev);
  14094. +
  14095. + netif_carrier_on(ieee->dev);
  14096. +}
  14097. +
  14098. +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
  14099. +{
  14100. + if(ieee->raw_tx){
  14101. +
  14102. + if (ieee->data_hard_resume)
  14103. + ieee->data_hard_resume(ieee->dev);
  14104. +
  14105. + netif_carrier_on(ieee->dev);
  14106. + }
  14107. +}
  14108. +
  14109. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  14110. +void ieee80211_start_ibss_wq(struct work_struct *work)
  14111. +{
  14112. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  14113. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
  14114. +#else
  14115. +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
  14116. +{
  14117. +#endif
  14118. +
  14119. + /* iwconfig mode ad-hoc will schedule this and return
  14120. + * on the other hand this will block further iwconfig SET
  14121. + * operations because of the wx_sem hold.
  14122. + * Anyway some most set operations set a flag to speed-up
  14123. + * (abort) this wq (when syncro scanning) before sleeping
  14124. + * on the semaphore
  14125. + */
  14126. +
  14127. + down(&ieee->wx_sem);
  14128. +
  14129. + if (ieee->current_network.ssid_len == 0){
  14130. + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
  14131. + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  14132. + ieee->ssid_set = 1;
  14133. + }
  14134. +
  14135. +//by lizhaoming for LED BLINK 2008.6.23
  14136. +#ifdef LED_SHIN
  14137. + {
  14138. + struct net_device *dev = ieee->dev;
  14139. + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
  14140. + }
  14141. +#endif
  14142. +
  14143. + /* check if we have this cell in our network list */
  14144. + ieee80211_softmac_check_all_nets(ieee);
  14145. +
  14146. +#ifdef ENABLE_DOT11D
  14147. + //[World wide 13]:
  14148. + // Adhoc:
  14149. + // (1) active scan from ch1~11 and passive scan from ch12~13
  14150. + // (2) IBSS can join ch1~13 adhoc, but only start at ch10.
  14151. + if(ieee->state == IEEE80211_NOLINK)
  14152. + if(ieee->IbssStartChnl != 0)
  14153. + ieee->current_network.channel = ieee->IbssStartChnl;//chan 10
  14154. +#endif
  14155. +
  14156. + /* if not then the state is not linked. Maybe the user swithced to
  14157. + * ad-hoc mode just after being in monitor mode, or just after
  14158. + * being very few time in managed mode (so the card have had no
  14159. + * time to scan all the chans..) or we have just run up the iface
  14160. + * after setting ad-hoc mode. So we have to give another try..
  14161. + * Here, in ibss mode, should be safe to do this without extra care
  14162. + * (in bss mode we had to make sure no-one tryed to associate when
  14163. + * we had just checked the ieee->state and we was going to start the
  14164. + * scan) beacause in ibss mode the ieee80211_new_net function, when
  14165. + * finds a good net, just set the ieee->state to IEEE80211_LINKED,
  14166. + * so, at worst, we waste a bit of time to initiate an unneeded syncro
  14167. + * scan, that will stop at the first round because it sees the state
  14168. + * associated.
  14169. + */
  14170. + if (ieee->state == IEEE80211_NOLINK){
  14171. + ieee80211_start_scan_syncro(ieee);
  14172. + }
  14173. +
  14174. + /* the network definitively is not here.. create a new cell */
  14175. + if (ieee->state == IEEE80211_NOLINK){
  14176. + printk("creating new IBSS cell\n");
  14177. + ieee->state = IEEE80211_LINKED;
  14178. + if(!ieee->wap_set)
  14179. + ieee80211_randomize_cell(ieee);
  14180. +
  14181. + if(ieee->modulation & IEEE80211_CCK_MODULATION){
  14182. +
  14183. + ieee->current_network.rates_len = 4;
  14184. +
  14185. + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  14186. + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  14187. + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  14188. + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  14189. +
  14190. + }else
  14191. + ieee->current_network.rates_len = 0;
  14192. +
  14193. + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
  14194. + ieee->current_network.rates_ex_len = 8;
  14195. +
  14196. + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  14197. + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
  14198. + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  14199. + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
  14200. + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  14201. + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
  14202. + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
  14203. + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
  14204. +
  14205. + ieee->rate = 540;
  14206. + }else{
  14207. + ieee->current_network.rates_ex_len = 0;
  14208. + ieee->rate = 110;
  14209. + }
  14210. +
  14211. + // By default, WMM function will be disabled in IBSS mode
  14212. + ieee->current_network.QoS_Enable = 0;
  14213. +
  14214. + ieee->current_network.atim_window = 0;
  14215. + ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
  14216. + if(ieee->short_slot)
  14217. + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
  14218. +
  14219. + }
  14220. +
  14221. + ieee->state = IEEE80211_LINKED;
  14222. +
  14223. +//by lizhaoming for LED LINK
  14224. +#ifdef LED_SHIN
  14225. + {
  14226. + struct net_device *dev = ieee->dev;
  14227. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  14228. + }
  14229. +#endif
  14230. +
  14231. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  14232. + ieee->link_change(ieee->dev);
  14233. +
  14234. + notify_wx_assoc_event(ieee);
  14235. +
  14236. + ieee80211_start_send_beacons(ieee);
  14237. + printk(KERN_WARNING "after sending beacon packet!\n");
  14238. +
  14239. + if (ieee->data_hard_resume)
  14240. + ieee->data_hard_resume(ieee->dev);
  14241. +
  14242. + netif_carrier_on(ieee->dev);
  14243. +
  14244. + up(&ieee->wx_sem);
  14245. +}
  14246. +
  14247. +inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
  14248. +{
  14249. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14250. + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); //change to delayed work, delayed time is need to check
  14251. +#else
  14252. + schedule_task(&ieee->start_ibss_wq);
  14253. +#endif
  14254. +}
  14255. +
  14256. +/* this is called only in user context, with wx_sem held */
  14257. +void ieee80211_start_bss(struct ieee80211_device *ieee)
  14258. +{
  14259. + unsigned long flags;
  14260. + /* check if we have already found the net we
  14261. + * are interested in (if any).
  14262. + * if not (we are disassociated and we are not
  14263. + * in associating / authenticating phase) start the background scanning.
  14264. + */
  14265. +
  14266. +//by lizhaoming for LED BLINK 2008.6.23
  14267. +#ifdef LED_SHIN
  14268. + {
  14269. + struct net_device *dev = ieee->dev;
  14270. + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
  14271. + }
  14272. +#endif
  14273. +
  14274. +#ifdef ENABLE_DOT11D
  14275. + //
  14276. + // Ref: 802.11d 11.1.3.3
  14277. + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
  14278. + //
  14279. + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
  14280. + {
  14281. + if(! ieee->bGlobalDomain)
  14282. + {
  14283. + return;
  14284. + }
  14285. + }
  14286. +#endif
  14287. + //printk("======>%s()\n",__FUNCTION__);
  14288. + ieee80211_softmac_check_all_nets(ieee);
  14289. +
  14290. + /* ensure no-one start an associating process (thus setting
  14291. + * the ieee->state to ieee80211_ASSOCIATING) while we
  14292. + * have just cheked it and we are going to enable scan.
  14293. + * The ieee80211_new_net function is always called with
  14294. + * lock held (from both ieee80211_softmac_check_all_nets and
  14295. + * the rx path), so we cannot be in the middle of such function
  14296. + */
  14297. +
  14298. + spin_lock_irqsave(&ieee->lock, flags);
  14299. + if (ieee->state == IEEE80211_NOLINK){
  14300. + //printk("Not find SSID in network list scan now\n");
  14301. + ieee80211_start_scan(ieee);
  14302. + }
  14303. + spin_unlock_irqrestore(&ieee->lock, flags);
  14304. +
  14305. +}
  14306. +
  14307. +/* called only in userspace context */
  14308. +void ieee80211_disassociate(struct ieee80211_device *ieee)
  14309. +{
  14310. + netif_carrier_off(ieee->dev);
  14311. +
  14312. + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
  14313. + ieee80211_reset_queue(ieee);
  14314. +
  14315. + if (ieee->data_hard_stop)
  14316. + ieee->data_hard_stop(ieee->dev);
  14317. +
  14318. +#ifdef ENABLE_DOT11D
  14319. + if(IS_DOT11D_ENABLE(ieee))
  14320. + Dot11d_Reset(ieee);
  14321. +#endif
  14322. +
  14323. + ieee->state = IEEE80211_NOLINK;
  14324. + ieee->link_change(ieee->dev);
  14325. + notify_wx_assoc_event(ieee);
  14326. +
  14327. +}
  14328. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  14329. +void ieee80211_associate_retry_wq(struct work_struct *work)
  14330. +{
  14331. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  14332. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
  14333. +#else
  14334. +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
  14335. +{
  14336. +#endif
  14337. + unsigned long flags;
  14338. +
  14339. + down(&ieee->wx_sem);
  14340. + if(!ieee->proto_started)
  14341. + goto exit;
  14342. +
  14343. + if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
  14344. + goto exit;
  14345. +
  14346. + /* until we do not set the state to IEEE80211_NOLINK
  14347. + * there are no possibility to have someone else trying
  14348. + * to start an association procdure (we get here with
  14349. + * ieee->state = IEEE80211_ASSOCIATING).
  14350. + * When we set the state to IEEE80211_NOLINK it is possible
  14351. + * that the RX path run an attempt to associate, but
  14352. + * both ieee80211_softmac_check_all_nets and the
  14353. + * RX path works with ieee->lock held so there are no
  14354. + * problems. If we are still disassociated then start a scan.
  14355. + * the lock here is necessary to ensure no one try to start
  14356. + * an association procedure when we have just checked the
  14357. + * state and we are going to start the scan.
  14358. + */
  14359. + ieee->state = IEEE80211_NOLINK;
  14360. +
  14361. + ieee80211_softmac_check_all_nets(ieee);
  14362. +
  14363. + spin_lock_irqsave(&ieee->lock, flags);
  14364. + if(ieee->state == IEEE80211_NOLINK)
  14365. + {
  14366. + printk("%s():Not find SSID:%s[ch=%d, mode=%s] in network list scan now\n", __FUNCTION__,
  14367. + ieee->current_network.ssid,ieee->current_network.channel,
  14368. + (ieee->iw_mode == IW_MODE_INFRA) ? "BSS" : "IBSS");
  14369. +
  14370. + ieee80211_start_scan(ieee);
  14371. + }
  14372. +
  14373. + spin_unlock_irqrestore(&ieee->lock, flags);
  14374. +
  14375. +exit:
  14376. + up(&ieee->wx_sem);
  14377. +}
  14378. +
  14379. +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
  14380. +{
  14381. + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
  14382. +
  14383. + struct sk_buff *skb = NULL;
  14384. + struct ieee80211_probe_response *b;
  14385. +
  14386. +//rz
  14387. +#ifdef _RTL8187_EXT_PATCH_
  14388. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
  14389. + skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
  14390. + else
  14391. + skb = ieee80211_probe_resp(ieee, broadcast_addr);
  14392. +#else
  14393. + skb = ieee80211_probe_resp(ieee, broadcast_addr);
  14394. +#endif
  14395. +//
  14396. + if (!skb)
  14397. + return NULL;
  14398. +
  14399. + b = (struct ieee80211_probe_response *) skb->data;
  14400. + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
  14401. +
  14402. + return skb;
  14403. +
  14404. +}
  14405. +
  14406. +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
  14407. +{
  14408. + struct sk_buff *skb;
  14409. + struct ieee80211_probe_response *b;
  14410. +// printk("=========>%s()\n", __FUNCTION__);
  14411. + skb = ieee80211_get_beacon_(ieee);
  14412. + if(!skb)
  14413. + return NULL;
  14414. +
  14415. + b = (struct ieee80211_probe_response *) skb->data;
  14416. + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  14417. +
  14418. + if (ieee->seq_ctrl[0] == 0xFFF)
  14419. + ieee->seq_ctrl[0] = 0;
  14420. + else
  14421. + ieee->seq_ctrl[0]++;
  14422. +
  14423. + return skb;
  14424. +}
  14425. +
  14426. +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
  14427. +{
  14428. + ieee->sync_scan_hurryup = 1;
  14429. + down(&ieee->wx_sem);
  14430. + ieee80211_stop_protocol(ieee);
  14431. + up(&ieee->wx_sem);
  14432. +}
  14433. +
  14434. +
  14435. +void ieee80211_stop_protocol(struct ieee80211_device *ieee)
  14436. +{
  14437. + if (!ieee->proto_started)
  14438. + return;
  14439. +
  14440. + ieee->proto_started = 0;
  14441. + //printk("=====>%s\n", __func__);
  14442. +
  14443. +#ifdef _RTL8187_EXT_PATCH_
  14444. + if(ieee->ext_patch_ieee80211_stop_protocol)
  14445. + ieee->ext_patch_ieee80211_stop_protocol(ieee);
  14446. +//if call queue_delayed_work,can call this,or do nothing..
  14447. +//edit by lawrence,20071118
  14448. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14449. +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
  14450. +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
  14451. +#endif
  14452. +#endif // _RTL8187_EXT_PATCH_
  14453. +
  14454. + ieee80211_stop_send_beacons(ieee);
  14455. +
  14456. + del_timer_sync(&ieee->associate_timer);
  14457. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14458. + cancel_delayed_work(&ieee->associate_retry_wq);
  14459. + cancel_delayed_work(&ieee->start_ibss_wq); //cancel ibss start workqueue when stop protocol
  14460. +#endif
  14461. + ieee80211_stop_scan(ieee);
  14462. +
  14463. + ieee80211_disassociate(ieee);
  14464. + //printk("<=====%s\n", __func__);
  14465. +
  14466. +}
  14467. +
  14468. +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
  14469. +{
  14470. + ieee->sync_scan_hurryup = 0;
  14471. + down(&ieee->wx_sem);
  14472. + ieee80211_start_protocol(ieee);
  14473. + up(&ieee->wx_sem);
  14474. +}
  14475. +
  14476. +void ieee80211_start_protocol(struct ieee80211_device *ieee)
  14477. +{
  14478. + short ch = 0;
  14479. + int i = 0;
  14480. +
  14481. + if (ieee->proto_started)
  14482. + return;
  14483. +
  14484. + //printk("=====>%s\n", __func__);
  14485. +
  14486. + ieee->proto_started = 1;
  14487. +
  14488. + if (ieee->current_network.channel == 0){
  14489. + do{
  14490. + ch++;
  14491. + if (ch > MAX_CHANNEL_NUMBER)
  14492. + return; /* no channel found */
  14493. +#ifdef ENABLE_DOT11D
  14494. + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
  14495. +#else
  14496. + }while(!ieee->channel_map[ch]);
  14497. +#endif
  14498. + ieee->current_network.channel = ch;
  14499. + }
  14500. +
  14501. + if (ieee->current_network.beacon_interval == 0)
  14502. + ieee->current_network.beacon_interval = 100;
  14503. +
  14504. + ieee->set_chan(ieee->dev,ieee->current_network.channel);
  14505. + mdelay(10);//must or link change will fail lzm
  14506. +
  14507. + for(i = 0; i < 17; i++) {
  14508. + ieee->last_rxseq_num[i] = -1;
  14509. + ieee->last_rxfrag_num[i] = -1;
  14510. + ieee->last_packet_time[i] = 0;
  14511. + }
  14512. +
  14513. + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
  14514. +
  14515. +
  14516. + /* if the user set the MAC of the ad-hoc cell and then
  14517. + * switch to managed mode, shall we make sure that association
  14518. + * attempts does not fail just because the user provide the essid
  14519. + * and the nic is still checking for the AP MAC ??
  14520. + */
  14521. +
  14522. + if (ieee->iw_mode == IW_MODE_INFRA){
  14523. + ieee80211_start_bss(ieee);
  14524. + // printk("==========> IW_MODE_INFRA\n");
  14525. + }
  14526. + else if (ieee->iw_mode == IW_MODE_ADHOC){
  14527. + // printk("==========> IW_MODE_ADHOC\n");
  14528. + ieee80211_start_ibss(ieee);
  14529. + }
  14530. + else if (ieee->iw_mode == IW_MODE_MASTER){
  14531. + ieee80211_start_master_bss(ieee);
  14532. +// printk("==========> IW_MODE_MASTER\n");
  14533. + }
  14534. + else if(ieee->iw_mode == IW_MODE_MONITOR){
  14535. + ieee80211_start_monitor_mode(ieee);
  14536. +// printk("==========> IW_MODE_MONITOR\n");
  14537. + }
  14538. +
  14539. +#ifdef _RTL8187_EXT_PATCH_
  14540. +// else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol && ieee->ext_patch_ieee80211_start_protocol(ieee))
  14541. + else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol)
  14542. + {
  14543. + ieee->ext_patch_ieee80211_start_mesh(ieee);
  14544. + }
  14545. +#endif
  14546. +}
  14547. +
  14548. +
  14549. +#define DRV_NAME "Ieee80211"
  14550. +void ieee80211_softmac_init(struct ieee80211_device *ieee)
  14551. +{
  14552. + int i;
  14553. + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
  14554. +
  14555. + ieee->state = IEEE80211_NOLINK;
  14556. + ieee->sync_scan_hurryup = 0;
  14557. + for(i = 0; i < 5; i++) {
  14558. + ieee->seq_ctrl[i] = 0;
  14559. + }
  14560. +
  14561. + ieee->assoc_id = 0;
  14562. + ieee->queue_stop = 0;
  14563. + ieee->scanning = 0;
  14564. + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
  14565. + ieee->softmac_features = 0; //so IEEE2100-like driver are happy
  14566. + ieee->wap_set = 0;
  14567. + ieee->ssid_set = 0;
  14568. + ieee->proto_started = 0;
  14569. + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
  14570. + ieee->rate = 3;
  14571. + ieee->ps = IEEE80211_PS_DISABLED;
  14572. + ieee->sta_sleep = 0;
  14573. +//by amy
  14574. + ieee->bInactivePs = false;
  14575. + ieee->actscanning = false;
  14576. + ieee->ListenInterval = 2;
  14577. + ieee->NumRxData = 0;
  14578. + ieee->NumRxDataInPeriod = 0; //YJ,add,080828
  14579. + ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
  14580. + ieee->bHwRadioOff = false;//by lizhaoming
  14581. +//by amy
  14582. +#ifdef _RTL8187_EXT_PATCH_
  14583. + ieee->iw_ext_mode = 999;
  14584. +#endif
  14585. +
  14586. + init_mgmt_queue(ieee);
  14587. +
  14588. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  14589. + init_timer(&ieee->scan_timer);
  14590. + ieee->scan_timer.data = (unsigned long)ieee;
  14591. + ieee->scan_timer.function = ieee80211_softmac_scan_cb;
  14592. +#endif
  14593. + ieee->tx_pending.txb = NULL;
  14594. +
  14595. + init_timer(&ieee->associate_timer);
  14596. + ieee->associate_timer.data = (unsigned long)ieee;
  14597. + ieee->associate_timer.function = ieee80211_associate_abort_cb;
  14598. +
  14599. + init_timer(&ieee->beacon_timer);
  14600. + ieee->beacon_timer.data = (unsigned long) ieee;
  14601. + ieee->beacon_timer.function = ieee80211_send_beacon_cb;
  14602. +
  14603. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14604. +#ifdef PF_SYNCTHREAD
  14605. + ieee->wq = create_workqueue(DRV_NAME,0);
  14606. +#else
  14607. + ieee->wq = create_workqueue(DRV_NAME);
  14608. +#endif
  14609. +#endif
  14610. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14611. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
  14612. + INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
  14613. + INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
  14614. + INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
  14615. + INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
  14616. + INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
  14617. + INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
  14618. +//added by lawrence,20071118
  14619. +#ifdef _RTL8187_EXT_PATCH_
  14620. + INIT_WORK(&ieee->ext_stop_scan_wq, ieee80211_ext_stop_scan_wq);
  14621. + //INIT_WORK(&ieee->ext_send_beacon_wq, ieee80211_beacons_start,ieee);
  14622. + INIT_WORK(&ieee->ext_send_beacon_wq, ext_ieee80211_send_beacon_wq);
  14623. +#endif //_RTL8187_EXT_PATCH_
  14624. +#else
  14625. + INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
  14626. + INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
  14627. + INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
  14628. + INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
  14629. + INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
  14630. + INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
  14631. +#ifdef _RTL8187_EXT_PATCH_
  14632. + INIT_WORK(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
  14633. + //INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
  14634. + INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
  14635. +#endif
  14636. +#endif
  14637. +#else
  14638. + tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
  14639. + tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
  14640. + tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
  14641. + tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
  14642. + tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
  14643. + tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
  14644. +#ifdef _RTL8187_EXT_PATCH_
  14645. + tq_init(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
  14646. + //tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
  14647. + tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
  14648. +#endif
  14649. +#endif
  14650. + sema_init(&ieee->wx_sem, 1);
  14651. + sema_init(&ieee->scan_sem, 1);
  14652. + sema_init(&ieee->ips_sem,1);
  14653. + spin_lock_init(&ieee->mgmt_tx_lock);
  14654. + spin_lock_init(&ieee->beacon_lock);
  14655. + spin_lock_init(&ieee->beaconflag_lock);
  14656. + tasklet_init(&ieee->ps_task,
  14657. + (void(*)(unsigned long)) ieee80211_sta_ps,
  14658. + (unsigned long)ieee);
  14659. +#ifdef ENABLE_DOT11D
  14660. + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
  14661. +#endif
  14662. +
  14663. +}
  14664. +
  14665. +void ieee80211_softmac_free(struct ieee80211_device *ieee)
  14666. +{
  14667. + down(&ieee->wx_sem);
  14668. +
  14669. + del_timer_sync(&ieee->associate_timer);
  14670. +
  14671. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  14672. + cancel_delayed_work(&ieee->associate_retry_wq);
  14673. +
  14674. +
  14675. +
  14676. +#ifdef _RTL8187_EXT_PATCH_
  14677. + //When kernel>2.6.20,crash....
  14678. +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
  14679. +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
  14680. +#endif
  14681. + destroy_workqueue(ieee->wq);
  14682. +#endif
  14683. +
  14684. +#ifdef ENABLE_DOT11D
  14685. + if(NULL != ieee->pDot11dInfo)
  14686. + kfree(ieee->pDot11dInfo);
  14687. +#endif
  14688. +
  14689. + up(&ieee->wx_sem);
  14690. +}
  14691. +
  14692. +/********************************************************
  14693. + * Start of WPA code. *
  14694. + * this is stolen from the ipw2200 driver *
  14695. + ********************************************************/
  14696. +
  14697. +
  14698. +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
  14699. +{
  14700. + /* This is called when wpa_supplicant loads and closes the driver
  14701. + * interface. */
  14702. + printk("%s WPA\n",value ? "enabling" : "disabling");
  14703. + ieee->wpa_enabled = value;
  14704. + return 0;
  14705. +}
  14706. +
  14707. +
  14708. +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
  14709. +{
  14710. + /* make sure WPA is enabled */
  14711. + ieee80211_wpa_enable(ieee, 1);
  14712. +
  14713. + ieee80211_disassociate(ieee);
  14714. +}
  14715. +
  14716. +
  14717. +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
  14718. +{
  14719. +
  14720. + int ret = 0;
  14721. +
  14722. + switch (command) {
  14723. + case IEEE_MLME_STA_DEAUTH:
  14724. + // silently ignore
  14725. + break;
  14726. +
  14727. + case IEEE_MLME_STA_DISASSOC:
  14728. + ieee80211_disassociate(ieee);
  14729. + break;
  14730. +
  14731. + default:
  14732. + printk("Unknown MLME request: %d\n", command);
  14733. + ret = -EOPNOTSUPP;
  14734. + }
  14735. +
  14736. + return ret;
  14737. +}
  14738. +
  14739. +
  14740. +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
  14741. + struct ieee_param *param, int plen)
  14742. +{
  14743. + u8 *buf;
  14744. +
  14745. + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
  14746. + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
  14747. + return -EINVAL;
  14748. +
  14749. + if (param->u.wpa_ie.len) {
  14750. + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
  14751. + if (buf == NULL)
  14752. + return -ENOMEM;
  14753. +
  14754. + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
  14755. + kfree(ieee->wpa_ie);
  14756. + ieee->wpa_ie = buf;
  14757. + ieee->wpa_ie_len = param->u.wpa_ie.len;
  14758. + } else {
  14759. + kfree(ieee->wpa_ie);
  14760. + ieee->wpa_ie = NULL;
  14761. + ieee->wpa_ie_len = 0;
  14762. + }
  14763. +
  14764. + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
  14765. + return 0;
  14766. +}
  14767. +
  14768. +#define AUTH_ALG_OPEN_SYSTEM 0x1
  14769. +#define AUTH_ALG_SHARED_KEY 0x2
  14770. +
  14771. +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
  14772. +{
  14773. +
  14774. + struct ieee80211_security sec = {
  14775. + .flags = SEC_AUTH_MODE,
  14776. + };
  14777. + int ret = 0;
  14778. +
  14779. + if (value & AUTH_ALG_SHARED_KEY) {
  14780. + sec.auth_mode = WLAN_AUTH_SHARED_KEY;
  14781. + ieee->open_wep = 0;
  14782. + } else {
  14783. + sec.auth_mode = WLAN_AUTH_OPEN;
  14784. + ieee->open_wep = 1;
  14785. + }
  14786. +
  14787. + if (ieee->set_security)
  14788. + ieee->set_security(ieee->dev, &sec);
  14789. + else
  14790. + ret = -EOPNOTSUPP;
  14791. +
  14792. + return ret;
  14793. +}
  14794. +
  14795. +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
  14796. +{
  14797. + int ret=0;
  14798. + unsigned long flags;
  14799. +
  14800. + switch (name) {
  14801. + case IEEE_PARAM_WPA_ENABLED:
  14802. + ret = ieee80211_wpa_enable(ieee, value);
  14803. + break;
  14804. +
  14805. + case IEEE_PARAM_TKIP_COUNTERMEASURES:
  14806. + ieee->tkip_countermeasures=value;
  14807. + break;
  14808. +
  14809. + case IEEE_PARAM_DROP_UNENCRYPTED: {
  14810. + /* HACK:
  14811. + *
  14812. + * wpa_supplicant calls set_wpa_enabled when the driver
  14813. + * is loaded and unloaded, regardless of if WPA is being
  14814. + * used. No other calls are made which can be used to
  14815. + * determine if encryption will be used or not prior to
  14816. + * association being expected. If encryption is not being
  14817. + * used, drop_unencrypted is set to false, else true -- we
  14818. + * can use this to determine if the CAP_PRIVACY_ON bit should
  14819. + * be set.
  14820. + */
  14821. + struct ieee80211_security sec = {
  14822. + .flags = SEC_ENABLED,
  14823. + .enabled = value,
  14824. + };
  14825. + ieee->drop_unencrypted = value;
  14826. + /* We only change SEC_LEVEL for open mode. Others
  14827. + * are set by ipw_wpa_set_encryption.
  14828. + */
  14829. + if (!value) {
  14830. + sec.flags |= SEC_LEVEL;
  14831. + sec.level = SEC_LEVEL_0;
  14832. + }
  14833. + else {
  14834. + sec.flags |= SEC_LEVEL;
  14835. + sec.level = SEC_LEVEL_1;
  14836. + }
  14837. + if (ieee->set_security)
  14838. + ieee->set_security(ieee->dev, &sec);
  14839. + break;
  14840. + }
  14841. +
  14842. + case IEEE_PARAM_PRIVACY_INVOKED:
  14843. + ieee->privacy_invoked=value;
  14844. + break;
  14845. +
  14846. + case IEEE_PARAM_AUTH_ALGS:
  14847. + ret = ieee80211_wpa_set_auth_algs(ieee, value);
  14848. + break;
  14849. +
  14850. + case IEEE_PARAM_IEEE_802_1X:
  14851. + ieee->ieee802_1x=value;
  14852. + break;
  14853. + case IEEE_PARAM_WPAX_SELECT:
  14854. + // added for WPA2 mixed mode
  14855. + //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
  14856. + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
  14857. + ieee->wpax_type_set = 1;
  14858. + ieee->wpax_type_notify = value;
  14859. + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
  14860. + break;
  14861. +
  14862. + default:
  14863. + printk("Unknown WPA param: %d\n",name);
  14864. + ret = -EOPNOTSUPP;
  14865. + }
  14866. +
  14867. + return ret;
  14868. +}
  14869. +
  14870. +/* implementation borrowed from hostap driver */
  14871. +
  14872. +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
  14873. + struct ieee_param *param, int param_len)
  14874. +{
  14875. + int ret = 0;
  14876. +
  14877. + struct ieee80211_crypto_ops *ops;
  14878. + struct ieee80211_crypt_data **crypt;
  14879. +
  14880. + struct ieee80211_security sec = {
  14881. + .flags = 0,
  14882. + };
  14883. +
  14884. + param->u.crypt.err = 0;
  14885. + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
  14886. +
  14887. + if (param_len !=
  14888. + (int) ((char *) param->u.crypt.key - (char *) param) +
  14889. + param->u.crypt.key_len) {
  14890. + printk("Len mismatch %d, %d\n", param_len,
  14891. + param->u.crypt.key_len);
  14892. + return -EINVAL;
  14893. + }
  14894. + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
  14895. + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
  14896. + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
  14897. + if (param->u.crypt.idx >= WEP_KEYS)
  14898. + return -EINVAL;
  14899. +#ifdef _RTL8187_EXT_PATCH_
  14900. + crypt = &ieee->cryptlist[0]->crypt[param->u.crypt.idx];
  14901. +#else
  14902. + crypt = &ieee->crypt[param->u.crypt.idx];
  14903. +#endif
  14904. +
  14905. + } else {
  14906. + return -EINVAL;
  14907. + }
  14908. +
  14909. + if (strcmp(param->u.crypt.alg, "none") == 0) {
  14910. + if (crypt) {
  14911. + sec.enabled = 0;
  14912. + // FIXME FIXME
  14913. + //sec.encrypt = 0;
  14914. + sec.level = SEC_LEVEL_0;
  14915. + sec.flags |= SEC_ENABLED | SEC_LEVEL;
  14916. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  14917. + }
  14918. + goto done;
  14919. + }
  14920. + sec.enabled = 1;
  14921. +// FIXME FIXME
  14922. +// sec.encrypt = 1;
  14923. + sec.flags |= SEC_ENABLED;
  14924. +
  14925. + /* IPW HW cannot build TKIP MIC, host decryption still needed. */
  14926. + if (!(ieee->host_encrypt || ieee->host_decrypt) &&
  14927. + strcmp(param->u.crypt.alg, "TKIP"))
  14928. + goto skip_host_crypt;
  14929. +
  14930. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  14931. + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
  14932. + request_module("ieee80211_crypt_wep");
  14933. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  14934. + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
  14935. + request_module("ieee80211_crypt_tkip");
  14936. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  14937. + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
  14938. + request_module("ieee80211_crypt_ccmp");
  14939. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  14940. + }
  14941. + if (ops == NULL) {
  14942. + printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
  14943. + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
  14944. + ret = -EINVAL;
  14945. + goto done;
  14946. + }
  14947. +
  14948. +#ifdef _RTL8187_EXT_PATCH_
  14949. + u8 i;
  14950. + for (i=0; i<MAX_MP; i++){
  14951. + crypt = &ieee->cryptlist[i]->crypt[param->u.crypt.idx];
  14952. +// if (crypt != NULL) printk("crypt not null\n", crypt);
  14953. +
  14954. + *crypt = ieee->cryptlist[i]->crypt[param->u.crypt.idx];
  14955. +#endif
  14956. + if (*crypt == NULL || (*crypt)->ops != ops) {
  14957. + struct ieee80211_crypt_data *new_crypt;
  14958. +
  14959. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  14960. +
  14961. + new_crypt = (struct ieee80211_crypt_data *)
  14962. + kmalloc(sizeof(*new_crypt), GFP_KERNEL);
  14963. + if (new_crypt == NULL) {
  14964. + ret = -ENOMEM;
  14965. + goto done;
  14966. + }
  14967. + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
  14968. + new_crypt->ops = ops;
  14969. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  14970. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  14971. +#else
  14972. + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
  14973. +#endif
  14974. + new_crypt->priv =
  14975. + new_crypt->ops->init(param->u.crypt.idx);
  14976. +
  14977. + if (new_crypt->priv == NULL) {
  14978. + kfree(new_crypt);
  14979. + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
  14980. + ret = -EINVAL;
  14981. + goto done;
  14982. + }
  14983. +
  14984. + *crypt = new_crypt;
  14985. + }
  14986. +
  14987. + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
  14988. + (*crypt)->ops->set_key(param->u.crypt.key,
  14989. + param->u.crypt.key_len, param->u.crypt.seq,
  14990. + (*crypt)->priv) < 0) {
  14991. + printk("key setting failed\n");
  14992. + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
  14993. + ret = -EINVAL;
  14994. + goto done;
  14995. + }
  14996. +#ifdef _RTL8187_EXT_PATCH_
  14997. + }
  14998. +#endif
  14999. + skip_host_crypt:
  15000. + if (param->u.crypt.set_tx) {
  15001. + ieee->tx_keyidx = param->u.crypt.idx;
  15002. + sec.active_key = param->u.crypt.idx;
  15003. + sec.flags |= SEC_ACTIVE_KEY;
  15004. + } else
  15005. + sec.flags &= ~SEC_ACTIVE_KEY;
  15006. +
  15007. + if (param->u.crypt.alg != NULL) {
  15008. + memcpy(sec.keys[param->u.crypt.idx],
  15009. + param->u.crypt.key,
  15010. + param->u.crypt.key_len);
  15011. + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
  15012. + sec.flags |= (1 << param->u.crypt.idx);
  15013. +
  15014. + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
  15015. + sec.flags |= SEC_LEVEL;
  15016. + sec.level = SEC_LEVEL_1;
  15017. + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
  15018. + sec.flags |= SEC_LEVEL;
  15019. + sec.level = SEC_LEVEL_2;
  15020. + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
  15021. + sec.flags |= SEC_LEVEL;
  15022. + sec.level = SEC_LEVEL_3;
  15023. + }
  15024. + }
  15025. + done:
  15026. + if (ieee->set_security)
  15027. + ieee->set_security(ieee->dev, &sec);
  15028. +#if 1
  15029. +#ifdef _RTL8187_EXT_PATCH_
  15030. + if (ret != 0)//error out
  15031. + {
  15032. + for (i=0; i<MAX_MP; i++)
  15033. + {
  15034. + if (ieee->cryptlist[i]->crypt[param->u.crypt.idx]==NULL){
  15035. + break;
  15036. + }
  15037. + else{
  15038. + //if (ieee->cryptlist[i]->crypt[param->u.crypt.idx] != NULL)
  15039. + // {
  15040. + kfree(ieee->cryptlist[i]->crypt[param->u.crypt.idx]);
  15041. + ieee->cryptlist[i]->crypt[param->u.crypt.idx] = NULL;
  15042. + // }
  15043. + // kfree(ieee->cryptlist[i]);
  15044. + // ieee->cryptlist[i] = NULL;
  15045. + }
  15046. + }
  15047. + }
  15048. +#endif
  15049. +#endif
  15050. + /* Do not reset port if card is in Managed mode since resetting will
  15051. + * generate new IEEE 802.11 authentication which may end up in looping
  15052. + * with IEEE 802.1X. If your hardware requires a reset after WEP
  15053. + * configuration (for example... Prism2), implement the reset_port in
  15054. + * the callbacks structures used to initialize the 802.11 stack. */
  15055. + if (ieee->reset_on_keychange &&
  15056. + ieee->iw_mode != IW_MODE_INFRA &&
  15057. + ieee->reset_port &&
  15058. + ieee->reset_port(ieee->dev)) {
  15059. + printk("reset_port failed\n");
  15060. + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
  15061. + return -EINVAL;
  15062. + }
  15063. +
  15064. + return ret;
  15065. +}
  15066. +
  15067. +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
  15068. +{
  15069. + struct ieee_param *param;
  15070. + int ret=0;
  15071. +
  15072. + down(&ieee->wx_sem);
  15073. + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
  15074. +
  15075. + if (p->length < sizeof(struct ieee_param) || !p->pointer){
  15076. + ret = -EINVAL;
  15077. + goto out;
  15078. + }
  15079. +
  15080. + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
  15081. + if (param == NULL){
  15082. + ret = -ENOMEM;
  15083. + goto out;
  15084. + }
  15085. + if (copy_from_user(param, p->pointer, p->length)) {
  15086. + kfree(param);
  15087. + ret = -EFAULT;
  15088. + goto out;
  15089. + }
  15090. +
  15091. + switch (param->cmd) {
  15092. +
  15093. + case IEEE_CMD_SET_WPA_PARAM:
  15094. + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
  15095. + param->u.wpa_param.value);
  15096. + break;
  15097. +
  15098. + case IEEE_CMD_SET_WPA_IE:
  15099. + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
  15100. + break;
  15101. +
  15102. + case IEEE_CMD_SET_ENCRYPTION:
  15103. + ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
  15104. + break;
  15105. +
  15106. + case IEEE_CMD_MLME:
  15107. + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
  15108. + param->u.mlme.reason_code);
  15109. + break;
  15110. +
  15111. + default:
  15112. + printk("Unknown WPA supplicant request: %d\n",param->cmd);
  15113. + ret = -EOPNOTSUPP;
  15114. + break;
  15115. + }
  15116. +
  15117. + if (ret == 0 && copy_to_user(p->pointer, param, p->length))
  15118. + ret = -EFAULT;
  15119. +
  15120. + kfree(param);
  15121. +out:
  15122. + up(&ieee->wx_sem);
  15123. +
  15124. + return ret;
  15125. +}
  15126. +
  15127. +void notify_wx_assoc_event(struct ieee80211_device *ieee)
  15128. +{
  15129. + union iwreq_data wrqu;
  15130. + wrqu.ap_addr.sa_family = ARPHRD_ETHER;
  15131. + if (ieee->state == IEEE80211_LINKED)
  15132. + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
  15133. + else
  15134. + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
  15135. + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
  15136. +}
  15137. +
  15138. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  15139. +EXPORT_SYMBOL(ieee80211_get_beacon);
  15140. +EXPORT_SYMBOL(ieee80211_wake_queue);
  15141. +EXPORT_SYMBOL(ieee80211_stop_queue);
  15142. +EXPORT_SYMBOL(ieee80211_reset_queue);
  15143. +EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
  15144. +EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
  15145. +EXPORT_SYMBOL(ieee80211_is_shortslot);
  15146. +EXPORT_SYMBOL(ieee80211_is_54g);
  15147. +EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
  15148. +EXPORT_SYMBOL(ieee80211_ps_tx_ack);
  15149. +EXPORT_SYMBOL(notify_wx_assoc_event);
  15150. +EXPORT_SYMBOL(ieee80211_stop_send_beacons);
  15151. +EXPORT_SYMBOL(ieee80211_start_send_beacons);
  15152. +EXPORT_SYMBOL(ieee80211_start_scan_syncro);
  15153. +EXPORT_SYMBOL(ieee80211_start_protocol);
  15154. +EXPORT_SYMBOL(ieee80211_stop_protocol);
  15155. +EXPORT_SYMBOL(ieee80211_start_scan);
  15156. +EXPORT_SYMBOL(ieee80211_stop_scan);
  15157. +#ifdef _RTL8187_EXT_PATCH_
  15158. +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
  15159. +EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
  15160. +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
  15161. +EXPORT_SYMBOL(softmac_mgmt_xmit);
  15162. +EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
  15163. +EXPORT_SYMBOL(ieee80211_stop_scan);
  15164. +EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
  15165. +EXPORT_SYMBOL(ieee80211_rx_auth_rq);
  15166. +EXPORT_SYMBOL(ieee80211_associate_step1);
  15167. +#endif // _RTL8187_EXT_PATCH_
  15168. +#else
  15169. +EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
  15170. +EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
  15171. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
  15172. +EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
  15173. +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
  15174. +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
  15175. +EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
  15176. +EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
  15177. +EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
  15178. +EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
  15179. +EXPORT_SYMBOL_NOVERS(ieee80211_start_scan);
  15180. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
  15181. +#ifdef _RTL8187_EXT_PATCH_
  15182. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_req);
  15183. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_disassoc);
  15184. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_rsp);
  15185. +EXPORT_SYMBOL_NOVERS(softmac_mgmt_xmit);
  15186. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_probe_resp_by_net);
  15187. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
  15188. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_send_11s_beacon);
  15189. +EXPORT_SYMBOL_NOVERS(ieee80211_rx_auth_rq);
  15190. +EXPORT_SYMBOL(ieee80211_associate_step1);
  15191. +#endif // _RTL8187_EXT_PATCH_
  15192. +
  15193. +#endif
  15194. +//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
  15195. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c
  15196. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 1970-01-01 01:00:00.000000000 +0100
  15197. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 2010-03-06 16:43:22.000000000 +0100
  15198. @@ -0,0 +1,629 @@
  15199. +/* IEEE 802.11 SoftMAC layer
  15200. + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  15201. + *
  15202. + * Mostly extracted from the rtl8180-sa2400 driver for the
  15203. + * in-kernel generic ieee802.11 stack.
  15204. + *
  15205. + * Some pieces of code might be stolen from ipw2100 driver
  15206. + * copyright of who own it's copyright ;-)
  15207. + *
  15208. + * PS wx handler mostly stolen from hostap, copyright who
  15209. + * own it's copyright ;-)
  15210. + *
  15211. + * released under the GPL
  15212. + */
  15213. +
  15214. +
  15215. +#include "ieee80211.h"
  15216. +#ifdef ENABLE_DOT11D
  15217. +#include "dot11d.h"
  15218. +#endif
  15219. +
  15220. +/* FIXME: add A freqs */
  15221. +
  15222. +const long ieee80211_wlan_frequencies[] = {
  15223. + 2412, 2417, 2422, 2427,
  15224. + 2432, 2437, 2442, 2447,
  15225. + 2452, 2457, 2462, 2467,
  15226. + 2472, 2484
  15227. +};
  15228. +
  15229. +
  15230. +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  15231. + union iwreq_data *wrqu, char *b)
  15232. +{
  15233. + int ret;
  15234. + struct iw_freq *fwrq = & wrqu->freq;
  15235. +
  15236. + down(&ieee->wx_sem);
  15237. +
  15238. + if(ieee->iw_mode == IW_MODE_INFRA){
  15239. + ret = -EOPNOTSUPP;
  15240. + goto out;
  15241. + }
  15242. +
  15243. + /* if setting by freq convert to channel */
  15244. + if (fwrq->e == 1) {
  15245. + if ((fwrq->m >= (int) 2.412e8 &&
  15246. + fwrq->m <= (int) 2.487e8)) {
  15247. + int f = fwrq->m / 100000;
  15248. + int c = 0;
  15249. +
  15250. + while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
  15251. + c++;
  15252. +
  15253. + /* hack to fall through */
  15254. + fwrq->e = 0;
  15255. + fwrq->m = c + 1;
  15256. + }
  15257. + }
  15258. +
  15259. + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
  15260. + ret = -EOPNOTSUPP;
  15261. + goto out;
  15262. +
  15263. + }else { /* Set the channel */
  15264. +
  15265. +#ifdef ENABLE_DOT11D
  15266. + if(!IsLegalChannel(ieee, fwrq->m) )
  15267. + {
  15268. + printk("channel(%d). is invalide\n", fwrq->m);
  15269. + ret = -EOPNOTSUPP;
  15270. + goto out;
  15271. + }
  15272. + else
  15273. + {
  15274. + if(ieee->iw_mode == IW_MODE_ADHOC)
  15275. + {
  15276. + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
  15277. + {
  15278. + if(fwrq->m >= ieee->MinPassiveChnlNum)
  15279. + {
  15280. + ret = -EOPNOTSUPP;
  15281. + goto out;
  15282. + }
  15283. + }
  15284. + }
  15285. + }
  15286. +#endif
  15287. + ieee->current_network.channel = fwrq->m;
  15288. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  15289. +
  15290. + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
  15291. + if(ieee->state == IEEE80211_LINKED){
  15292. +
  15293. + ieee80211_stop_send_beacons(ieee);
  15294. + ieee80211_start_send_beacons(ieee);
  15295. + }
  15296. + }
  15297. +
  15298. + ret = 0;
  15299. +out:
  15300. + up(&ieee->wx_sem);
  15301. + return ret;
  15302. +}
  15303. +
  15304. +
  15305. +int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
  15306. + struct iw_request_info *a,
  15307. + union iwreq_data *wrqu, char *b)
  15308. +{
  15309. + struct iw_freq *fwrq = & wrqu->freq;
  15310. +
  15311. + if (ieee->current_network.channel == 0)
  15312. + return -1;
  15313. +
  15314. + fwrq->m = ieee->current_network.channel;
  15315. + fwrq->e = 0;
  15316. +
  15317. + return 0;
  15318. +}
  15319. +
  15320. +int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
  15321. + struct iw_request_info *info,
  15322. + union iwreq_data *wrqu, char *extra)
  15323. +{
  15324. + unsigned long flags;
  15325. +
  15326. + wrqu->ap_addr.sa_family = ARPHRD_ETHER;
  15327. +
  15328. + if (ieee->iw_mode == IW_MODE_MONITOR)
  15329. + return -1;
  15330. +
  15331. + /* We want avoid to give to the user inconsistent infos*/
  15332. + spin_lock_irqsave(&ieee->lock, flags);
  15333. +
  15334. + if (ieee->state != IEEE80211_LINKED &&
  15335. + ieee->state != IEEE80211_LINKED_SCANNING &&
  15336. + ieee->wap_set == 0)
  15337. +
  15338. + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
  15339. + else
  15340. + memcpy(wrqu->ap_addr.sa_data,
  15341. + ieee->current_network.bssid, ETH_ALEN);
  15342. +
  15343. + spin_unlock_irqrestore(&ieee->lock, flags);
  15344. +
  15345. + return 0;
  15346. +}
  15347. +
  15348. +
  15349. +int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
  15350. + struct iw_request_info *info,
  15351. + union iwreq_data *awrq,
  15352. + char *extra)
  15353. +{
  15354. +
  15355. + int ret = 0;
  15356. + u8 zero[] = {0,0,0,0,0,0};
  15357. + unsigned long flags;
  15358. +
  15359. + short ifup = ieee->proto_started;//dev->flags & IFF_UP;
  15360. + struct sockaddr *temp = (struct sockaddr *)awrq;
  15361. +
  15362. + ieee->sync_scan_hurryup = 1;
  15363. +
  15364. + down(&ieee->wx_sem);
  15365. + /* use ifconfig hw ether */
  15366. + if (ieee->iw_mode == IW_MODE_MASTER){
  15367. + ret = -1;
  15368. + goto out;
  15369. + }
  15370. +
  15371. + if (temp->sa_family != ARPHRD_ETHER){
  15372. + ret = -EINVAL;
  15373. + goto out;
  15374. + }
  15375. +
  15376. + if (ifup)
  15377. + ieee80211_stop_protocol(ieee);
  15378. +
  15379. + /* just to avoid to give inconsistent infos in the
  15380. + * get wx method. not really needed otherwise
  15381. + */
  15382. + spin_lock_irqsave(&ieee->lock, flags);
  15383. +
  15384. + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
  15385. + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
  15386. +
  15387. + spin_unlock_irqrestore(&ieee->lock, flags);
  15388. +
  15389. + if (ifup)
  15390. + ieee80211_start_protocol(ieee);
  15391. +
  15392. +out:
  15393. + up(&ieee->wx_sem);
  15394. + return ret;
  15395. +}
  15396. +
  15397. + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
  15398. +{
  15399. + int len,ret = 0;
  15400. + unsigned long flags;
  15401. +
  15402. + if (ieee->iw_mode == IW_MODE_MONITOR)
  15403. + return -1;
  15404. +
  15405. + /* We want avoid to give to the user inconsistent infos*/
  15406. + spin_lock_irqsave(&ieee->lock, flags);
  15407. +
  15408. + if (ieee->current_network.ssid[0] == '\0' ||
  15409. + ieee->current_network.ssid_len == 0){
  15410. + ret = -1;
  15411. + goto out;
  15412. + }
  15413. +
  15414. + if (ieee->state != IEEE80211_LINKED &&
  15415. + ieee->state != IEEE80211_LINKED_SCANNING &&
  15416. + ieee->ssid_set == 0){
  15417. + ret = -1;
  15418. + goto out;
  15419. + }
  15420. + len = ieee->current_network.ssid_len;
  15421. + wrqu->essid.length = len;
  15422. + strncpy(b,ieee->current_network.ssid,len);
  15423. + wrqu->essid.flags = 1;
  15424. +
  15425. +out:
  15426. + spin_unlock_irqrestore(&ieee->lock, flags);
  15427. +
  15428. + return ret;
  15429. +
  15430. +}
  15431. +
  15432. +int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
  15433. + struct iw_request_info *info,
  15434. + union iwreq_data *wrqu, char *extra)
  15435. +{
  15436. +
  15437. + u32 target_rate = wrqu->bitrate.value;
  15438. +
  15439. + ieee->rate = target_rate/100000;
  15440. + //FIXME: we might want to limit rate also in management protocols.
  15441. + return 0;
  15442. +}
  15443. +
  15444. +
  15445. +
  15446. +int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
  15447. + struct iw_request_info *info,
  15448. + union iwreq_data *wrqu, char *extra)
  15449. +{
  15450. +
  15451. + wrqu->bitrate.value = ieee->rate * 100000;
  15452. +
  15453. + return 0;
  15454. +}
  15455. +
  15456. +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  15457. + union iwreq_data *wrqu, char *b)
  15458. +{
  15459. +
  15460. + ieee->sync_scan_hurryup = 1;
  15461. +
  15462. + down(&ieee->wx_sem);
  15463. + //printk("=======>%s\n", __func__);
  15464. +
  15465. + if (wrqu->mode == ieee->iw_mode)
  15466. + goto out;
  15467. +
  15468. + if (wrqu->mode == IW_MODE_MONITOR){
  15469. +
  15470. + ieee->dev->type = ARPHRD_IEEE80211;
  15471. + }else{
  15472. + ieee->dev->type = ARPHRD_ETHER;
  15473. + }
  15474. +
  15475. + if (!ieee->proto_started){
  15476. + ieee->iw_mode = wrqu->mode;
  15477. + }else{
  15478. + ieee80211_stop_protocol(ieee);
  15479. + ieee->iw_mode = wrqu->mode;
  15480. + ieee80211_start_protocol(ieee);
  15481. + }
  15482. +
  15483. +out:
  15484. + up(&ieee->wx_sem);
  15485. + return 0;
  15486. +}
  15487. +
  15488. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15489. +void ieee80211_wx_sync_scan_wq(struct work_struct *work)
  15490. +{
  15491. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
  15492. +#else
  15493. +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
  15494. +{
  15495. +#endif
  15496. + short chan;
  15497. +
  15498. + chan = ieee->current_network.channel;
  15499. +
  15500. + netif_carrier_off(ieee->dev);
  15501. +
  15502. + if (ieee->data_hard_stop)
  15503. + ieee->data_hard_stop(ieee->dev);
  15504. +
  15505. + ieee80211_stop_send_beacons(ieee);
  15506. +
  15507. + ieee->state = IEEE80211_LINKED_SCANNING;
  15508. + ieee->link_change(ieee->dev);
  15509. +
  15510. + ieee80211_start_scan_syncro(ieee);
  15511. +
  15512. + ieee->set_chan(ieee->dev, chan);
  15513. +
  15514. + ieee->state = IEEE80211_LINKED;
  15515. + ieee->link_change(ieee->dev);
  15516. +
  15517. + if (ieee->data_hard_resume)
  15518. + ieee->data_hard_resume(ieee->dev);
  15519. +
  15520. + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
  15521. + ieee80211_start_send_beacons(ieee);
  15522. +
  15523. + netif_carrier_on(ieee->dev);
  15524. +
  15525. + up(&ieee->wx_sem);
  15526. +
  15527. +}
  15528. +
  15529. +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
  15530. + union iwreq_data *wrqu, char *b)
  15531. +{
  15532. + int ret = 0;
  15533. +
  15534. + down(&ieee->wx_sem);
  15535. +
  15536. + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
  15537. + ret = -1;
  15538. + goto out;
  15539. + }
  15540. +
  15541. + if ( ieee->state == IEEE80211_LINKED){
  15542. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  15543. + queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
  15544. +#else
  15545. + schedule_task(&ieee->wx_sync_scan_wq);
  15546. +#endif
  15547. + /* intentionally forget to up sem */
  15548. + return 0;
  15549. + }
  15550. +
  15551. +out:
  15552. + up(&ieee->wx_sem);
  15553. + return ret;
  15554. +}
  15555. +
  15556. +int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
  15557. + struct iw_request_info *a,
  15558. + union iwreq_data *wrqu, char *extra)
  15559. +{
  15560. +
  15561. + int ret=0,len;
  15562. + short proto_started;
  15563. + unsigned long flags;
  15564. +
  15565. + ieee->sync_scan_hurryup = 1;
  15566. +
  15567. + down(&ieee->wx_sem);
  15568. +
  15569. + //printk("=======>%s\n", __func__);
  15570. + proto_started = ieee->proto_started;
  15571. +
  15572. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  15573. + ret= -E2BIG;
  15574. + goto out;
  15575. + }
  15576. +
  15577. + if (ieee->iw_mode == IW_MODE_MONITOR){
  15578. + ret= -1;
  15579. + goto out;
  15580. + }
  15581. +
  15582. + if(proto_started){
  15583. + ieee80211_stop_protocol(ieee);
  15584. + }
  15585. +
  15586. + /* this is just to be sure that the GET wx callback
  15587. + * has consisten infos. not needed otherwise
  15588. + */
  15589. + spin_lock_irqsave(&ieee->lock, flags);
  15590. +
  15591. + if (wrqu->essid.flags && wrqu->essid.length) {
  15592. + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
  15593. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  15594. + strncpy(ieee->current_network.ssid, extra, len);
  15595. + ieee->current_network.ssid_len = len;
  15596. +#else
  15597. + strncpy(ieee->current_network.ssid, extra, len+1);
  15598. + ieee->current_network.ssid_len = len+1;
  15599. +#endif
  15600. + ieee->ssid_set = 1;
  15601. + //YJ,add,080819,for hidden ap
  15602. + if(len == 0){
  15603. + memset(ieee->current_network.bssid, 0, ETH_ALEN);
  15604. + ieee->current_network.capability = 0;
  15605. + }
  15606. + //YJ,add,080819,for hidden ap,end
  15607. + }
  15608. + else{
  15609. + ieee->ssid_set = 0;
  15610. + ieee->current_network.ssid[0] = '\0';
  15611. + ieee->current_network.ssid_len = 0;
  15612. + }
  15613. +
  15614. + spin_unlock_irqrestore(&ieee->lock, flags);
  15615. +
  15616. + if (proto_started){
  15617. + ieee80211_start_protocol(ieee);
  15618. + }
  15619. +out:
  15620. + up(&ieee->wx_sem);
  15621. + return ret;
  15622. +}
  15623. +
  15624. + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  15625. + union iwreq_data *wrqu, char *b)
  15626. +{
  15627. +
  15628. + wrqu->mode = ieee->iw_mode;
  15629. + return 0;
  15630. +}
  15631. +
  15632. + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
  15633. + struct iw_request_info *info,
  15634. + union iwreq_data *wrqu, char *extra)
  15635. +{
  15636. +
  15637. + int *parms = (int *)extra;
  15638. + int enable = (parms[0] > 0);
  15639. + short prev = ieee->raw_tx;
  15640. +
  15641. + down(&ieee->wx_sem);
  15642. +
  15643. + if(enable)
  15644. + ieee->raw_tx = 1;
  15645. + else
  15646. + ieee->raw_tx = 0;
  15647. +
  15648. + printk(KERN_INFO"raw TX is %s\n",
  15649. + ieee->raw_tx ? "enabled" : "disabled");
  15650. +
  15651. + if(ieee->iw_mode == IW_MODE_MONITOR)
  15652. + {
  15653. + if(prev == 0 && ieee->raw_tx){
  15654. + if (ieee->data_hard_resume)
  15655. + ieee->data_hard_resume(ieee->dev);
  15656. +
  15657. + netif_carrier_on(ieee->dev);
  15658. + }
  15659. +
  15660. + if(prev && ieee->raw_tx == 1)
  15661. + netif_carrier_off(ieee->dev);
  15662. + }
  15663. +
  15664. + up(&ieee->wx_sem);
  15665. +
  15666. + return 0;
  15667. +}
  15668. +
  15669. +int ieee80211_wx_get_name(struct ieee80211_device *ieee,
  15670. + struct iw_request_info *info,
  15671. + union iwreq_data *wrqu, char *extra)
  15672. +{
  15673. + strcpy(wrqu->name, "802.11");
  15674. + if(ieee->modulation & IEEE80211_CCK_MODULATION){
  15675. + strcat(wrqu->name, "b");
  15676. + if(ieee->modulation & IEEE80211_OFDM_MODULATION)
  15677. + strcat(wrqu->name, "/g");
  15678. + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
  15679. + strcat(wrqu->name, "g");
  15680. +
  15681. + if((ieee->state == IEEE80211_LINKED) ||
  15682. + (ieee->state == IEEE80211_LINKED_SCANNING))
  15683. + strcat(wrqu->name," linked");
  15684. + else if(ieee->state != IEEE80211_NOLINK)
  15685. + strcat(wrqu->name," link..");
  15686. +
  15687. +
  15688. + return 0;
  15689. +}
  15690. +
  15691. +
  15692. +/* this is mostly stolen from hostap */
  15693. +int ieee80211_wx_set_power(struct ieee80211_device *ieee,
  15694. + struct iw_request_info *info,
  15695. + union iwreq_data *wrqu, char *extra)
  15696. +{
  15697. + int ret = 0;
  15698. +
  15699. + if(
  15700. + (!ieee->sta_wake_up) ||
  15701. + (!ieee->ps_request_tx_ack) ||
  15702. + (!ieee->enter_sleep_state) ||
  15703. + (!ieee->ps_is_queue_empty)){
  15704. +
  15705. + printk("ERROR. PS mode is tryied to be use but\
  15706. +driver missed a callback\n\n");
  15707. +
  15708. + return -1;
  15709. + }
  15710. +
  15711. + down(&ieee->wx_sem);
  15712. +
  15713. + if (wrqu->power.disabled){
  15714. + ieee->ps = IEEE80211_PS_DISABLED;
  15715. +
  15716. + goto exit;
  15717. + }
  15718. + switch (wrqu->power.flags & IW_POWER_MODE) {
  15719. + case IW_POWER_UNICAST_R:
  15720. + ieee->ps = IEEE80211_PS_UNICAST;
  15721. +
  15722. + break;
  15723. + case IW_POWER_ALL_R:
  15724. + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
  15725. + break;
  15726. +
  15727. + case IW_POWER_ON:
  15728. + ieee->ps = IEEE80211_PS_DISABLED;
  15729. + break;
  15730. +
  15731. + default:
  15732. + ret = -EINVAL;
  15733. + goto exit;
  15734. + }
  15735. +
  15736. + if (wrqu->power.flags & IW_POWER_TIMEOUT) {
  15737. +
  15738. + ieee->ps_timeout = wrqu->power.value / 1000;
  15739. + printk("Timeout %d\n",ieee->ps_timeout);
  15740. + }
  15741. +
  15742. + if (wrqu->power.flags & IW_POWER_PERIOD) {
  15743. +
  15744. + ret = -EOPNOTSUPP;
  15745. + goto exit;
  15746. + //wrq->value / 1024;
  15747. +
  15748. + }
  15749. +exit:
  15750. + up(&ieee->wx_sem);
  15751. + return ret;
  15752. +
  15753. +}
  15754. +
  15755. +/* this is stolen from hostap */
  15756. +int ieee80211_wx_get_power(struct ieee80211_device *ieee,
  15757. + struct iw_request_info *info,
  15758. + union iwreq_data *wrqu, char *extra)
  15759. +{
  15760. + int ret =0;
  15761. +
  15762. + down(&ieee->wx_sem);
  15763. +
  15764. + if(ieee->ps == IEEE80211_PS_DISABLED){
  15765. + wrqu->power.disabled = 1;
  15766. + goto exit;
  15767. + }
  15768. +
  15769. + wrqu->power.disabled = 0;
  15770. +
  15771. +// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
  15772. + wrqu->power.flags = IW_POWER_TIMEOUT;
  15773. + wrqu->power.value = ieee->ps_timeout * 1000;
  15774. +// } else {
  15775. +// ret = -EOPNOTSUPP;
  15776. +// goto exit;
  15777. + //wrqu->power.flags = IW_POWER_PERIOD;
  15778. + //wrqu->power.value = ieee->current_network.dtim_period *
  15779. + // ieee->current_network.beacon_interval * 1024;
  15780. +// }
  15781. +
  15782. +
  15783. + if (ieee->ps & IEEE80211_PS_MBCAST)
  15784. + wrqu->power.flags |= IW_POWER_ALL_R;
  15785. + else
  15786. + wrqu->power.flags |= IW_POWER_UNICAST_R;
  15787. +
  15788. +exit:
  15789. + up(&ieee->wx_sem);
  15790. + return ret;
  15791. +
  15792. +}
  15793. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  15794. +EXPORT_SYMBOL(ieee80211_wx_get_essid);
  15795. +EXPORT_SYMBOL(ieee80211_wx_set_essid);
  15796. +EXPORT_SYMBOL(ieee80211_wx_set_rate);
  15797. +EXPORT_SYMBOL(ieee80211_wx_get_rate);
  15798. +EXPORT_SYMBOL(ieee80211_wx_set_wap);
  15799. +EXPORT_SYMBOL(ieee80211_wx_get_wap);
  15800. +EXPORT_SYMBOL(ieee80211_wx_set_mode);
  15801. +EXPORT_SYMBOL(ieee80211_wx_get_mode);
  15802. +EXPORT_SYMBOL(ieee80211_wx_set_scan);
  15803. +EXPORT_SYMBOL(ieee80211_wx_get_freq);
  15804. +EXPORT_SYMBOL(ieee80211_wx_set_freq);
  15805. +EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
  15806. +EXPORT_SYMBOL(ieee80211_wx_get_name);
  15807. +EXPORT_SYMBOL(ieee80211_wx_set_power);
  15808. +EXPORT_SYMBOL(ieee80211_wx_get_power);
  15809. +EXPORT_SYMBOL(ieee80211_wlan_frequencies);
  15810. +#else
  15811. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
  15812. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
  15813. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
  15814. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
  15815. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
  15816. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
  15817. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
  15818. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
  15819. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
  15820. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
  15821. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
  15822. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
  15823. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
  15824. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
  15825. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
  15826. +EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
  15827. +#endif
  15828. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c
  15829. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 1970-01-01 01:00:00.000000000 +0100
  15830. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 2010-03-06 16:43:22.000000000 +0100
  15831. @@ -0,0 +1,876 @@
  15832. +/******************************************************************************
  15833. +
  15834. + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
  15835. +
  15836. + This program is free software; you can redistribute it and/or modify it
  15837. + under the terms of version 2 of the GNU General Public License as
  15838. + published by the Free Software Foundation.
  15839. +
  15840. + This program is distributed in the hope that it will be useful, but WITHOUT
  15841. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15842. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  15843. + more details.
  15844. +
  15845. + You should have received a copy of the GNU General Public License along with
  15846. + this program; if not, write to the Free Software Foundation, Inc., 59
  15847. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15848. +
  15849. + The full GNU General Public License is included in this distribution in the
  15850. + file called LICENSE.
  15851. +
  15852. + Contact Information:
  15853. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  15854. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  15855. +
  15856. +******************************************************************************
  15857. +
  15858. + Few modifications for Realtek's Wi-Fi drivers by
  15859. + Andrea Merello <andreamrl@tiscali.it>
  15860. +
  15861. + A special thanks goes to Realtek for their support !
  15862. +
  15863. +******************************************************************************/
  15864. +
  15865. +#include <linux/compiler.h>
  15866. +//#include <linux/config.h>
  15867. +#include <linux/errno.h>
  15868. +#include <linux/if_arp.h>
  15869. +#include <linux/in6.h>
  15870. +#include <linux/in.h>
  15871. +#include <linux/ip.h>
  15872. +#include <linux/kernel.h>
  15873. +#include <linux/module.h>
  15874. +#include <linux/netdevice.h>
  15875. +#include <linux/pci.h>
  15876. +#include <linux/proc_fs.h>
  15877. +#include <linux/skbuff.h>
  15878. +#include <linux/slab.h>
  15879. +#include <linux/tcp.h>
  15880. +#include <linux/types.h>
  15881. +#include <linux/version.h>
  15882. +#include <linux/wireless.h>
  15883. +#include <linux/etherdevice.h>
  15884. +#include <asm/uaccess.h>
  15885. +#include <linux/if_vlan.h>
  15886. +
  15887. +#include "ieee80211.h"
  15888. +
  15889. +
  15890. +/*
  15891. +
  15892. +
  15893. +802.11 Data Frame
  15894. +
  15895. +
  15896. +802.11 frame_contorl for data frames - 2 bytes
  15897. + ,-----------------------------------------------------------------------------------------.
  15898. +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
  15899. + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  15900. +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
  15901. + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  15902. +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
  15903. + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
  15904. + '-----------------------------------------------------------------------------------------'
  15905. + /\
  15906. + |
  15907. +802.11 Data Frame |
  15908. + ,--------- 'ctrl' expands to >-----------'
  15909. + |
  15910. + ,--'---,-------------------------------------------------------------.
  15911. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
  15912. + |------|------|---------|---------|---------|------|---------|------|
  15913. +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
  15914. + | | tion | (BSSID) | | | ence | data | |
  15915. + `--------------------------------------------------| |------'
  15916. +Total: 28 non-data bytes `----.----'
  15917. + |
  15918. + .- 'Frame data' expands to <---------------------------'
  15919. + |
  15920. + V
  15921. + ,---------------------------------------------------.
  15922. +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
  15923. + |------|------|---------|----------|------|---------|
  15924. +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
  15925. + | DSAP | SSAP | | | | Packet |
  15926. + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
  15927. + `-----------------------------------------| |
  15928. +Total: 8 non-data bytes `----.----'
  15929. + |
  15930. + .- 'IP Packet' expands, if WEP enabled, to <--'
  15931. + |
  15932. + V
  15933. + ,-----------------------.
  15934. +Bytes | 4 | 0-2296 | 4 |
  15935. + |-----|-----------|-----|
  15936. +Desc. | IV | Encrypted | ICV |
  15937. + | | IP Packet | |
  15938. + `-----------------------'
  15939. +Total: 8 non-data bytes
  15940. +
  15941. +
  15942. +802.3 Ethernet Data Frame
  15943. +
  15944. + ,-----------------------------------------.
  15945. +Bytes | 6 | 6 | 2 | Variable | 4 |
  15946. + |-------|-------|------|-----------|------|
  15947. +Desc. | Dest. | Source| Type | IP Packet | fcs |
  15948. + | MAC | MAC | | | |
  15949. + `-----------------------------------------'
  15950. +Total: 18 non-data bytes
  15951. +
  15952. +In the event that fragmentation is required, the incoming payload is split into
  15953. +N parts of size ieee->fts. The first fragment contains the SNAP header and the
  15954. +remaining packets are just data.
  15955. +
  15956. +If encryption is enabled, each fragment payload size is reduced by enough space
  15957. +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
  15958. +So if you have 1500 bytes of payload with ieee->fts set to 500 without
  15959. +encryption it will take 3 frames. With WEP it will take 4 frames as the
  15960. +payload of each frame is reduced to 492 bytes.
  15961. +
  15962. +* SKB visualization
  15963. +*
  15964. +* ,- skb->data
  15965. +* |
  15966. +* | ETHERNET HEADER ,-<-- PAYLOAD
  15967. +* | | 14 bytes from skb->data
  15968. +* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
  15969. +* | | | |
  15970. +* |,-Dest.--. ,--Src.---. | | |
  15971. +* | 6 bytes| | 6 bytes | | | |
  15972. +* v | | | | | |
  15973. +* 0 | v 1 | v | v 2
  15974. +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  15975. +* ^ | ^ | ^ |
  15976. +* | | | | | |
  15977. +* | | | | `T' <---- 2 bytes for Type
  15978. +* | | | |
  15979. +* | | '---SNAP--' <-------- 6 bytes for SNAP
  15980. +* | |
  15981. +* `-IV--' <-------------------- 4 bytes for IV (WEP)
  15982. +*
  15983. +* SNAP HEADER
  15984. +*
  15985. +*/
  15986. +
  15987. +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
  15988. +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
  15989. +
  15990. +static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
  15991. +{
  15992. + struct ieee80211_snap_hdr *snap;
  15993. + u8 *oui;
  15994. +
  15995. + snap = (struct ieee80211_snap_hdr *)data;
  15996. + snap->dsap = 0xaa;
  15997. + snap->ssap = 0xaa;
  15998. + snap->ctrl = 0x03;
  15999. +
  16000. + if (h_proto == 0x8137 || h_proto == 0x80f3)
  16001. + oui = P802_1H_OUI;
  16002. + else
  16003. + oui = RFC1042_OUI;
  16004. + snap->oui[0] = oui[0];
  16005. + snap->oui[1] = oui[1];
  16006. + snap->oui[2] = oui[2];
  16007. +
  16008. + *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
  16009. +
  16010. + return SNAP_SIZE + sizeof(u16);
  16011. +}
  16012. +
  16013. +int ieee80211_encrypt_fragment(
  16014. + struct ieee80211_device *ieee,
  16015. + struct sk_buff *frag,
  16016. + int hdr_len)
  16017. +{
  16018. + struct ieee80211_crypt_data* crypt = NULL;//ieee->crypt[ieee->tx_keyidx];
  16019. + int res;//, i;
  16020. +// printk("====>wwwwww%s():ieee:%x, hdr_len:%d\n", __FUNCTION__, ieee, hdr_len);
  16021. +/* printk("\n%s(), hdr_len:%d\n", __FUNCTION__, hdr_len);
  16022. + for (i = 0; i < 48; i++) {
  16023. + if (i % 16 == 0) printk("\n\t");
  16024. + printk("%2x ", *(frag->data+i));
  16025. + }
  16026. +*/
  16027. +
  16028. +#ifdef _RTL8187_EXT_PATCH_
  16029. +#if 0
  16030. + i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*) frag->data)->addr1);
  16031. + if (i== -1){
  16032. + printk("error find MP entry in %s()\n", __FUNCTION__);
  16033. + return i;
  16034. + }
  16035. + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)frag->data)->addr1), i);
  16036. +#endif
  16037. +// crypt = ieee->cryptlist[MAX_MP-1]->crypt[ieee->tx_keyidx];
  16038. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16039. +#else
  16040. + crypt = ieee->crypt[ieee->tx_keyidx];
  16041. +#endif
  16042. + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
  16043. + if (!crypt || !crypt->ops)
  16044. + return -1;
  16045. +
  16046. +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
  16047. + struct ieee80211_hdr *header;
  16048. +
  16049. + if (ieee->tkip_countermeasures &&
  16050. + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
  16051. + header = (struct ieee80211_hdr *) frag->data;
  16052. + if (net_ratelimit()) {
  16053. + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
  16054. + "TX packet to " MAC_FMT "\n",
  16055. + ieee->dev->name, MAC_ARG(header->addr1));
  16056. + }
  16057. + return -1;
  16058. + }
  16059. +#endif
  16060. + /* To encrypt, frame format is:
  16061. + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
  16062. +
  16063. + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
  16064. + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
  16065. + * call both MSDU and MPDU encryption functions from here. */
  16066. + atomic_inc(&crypt->refcnt);
  16067. + res = 0;
  16068. + if (crypt->ops->encrypt_msdu)
  16069. + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
  16070. + if (res == 0 && crypt->ops->encrypt_mpdu)
  16071. + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
  16072. + atomic_dec(&crypt->refcnt);
  16073. + if (res < 0) {
  16074. + printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
  16075. + ieee->dev->name, frag->len);
  16076. + ieee->ieee_stats.tx_discards++;
  16077. + return -1;
  16078. + }
  16079. +
  16080. + return 0;
  16081. +}
  16082. +
  16083. +
  16084. +void ieee80211_txb_free(struct ieee80211_txb *txb) {
  16085. + int i;
  16086. + if (unlikely(!txb))
  16087. + return;
  16088. + for (i = 0; i < txb->nr_frags; i++)
  16089. + if (txb->fragments[i])
  16090. + dev_kfree_skb_any(txb->fragments[i]);
  16091. + kfree(txb);
  16092. +}
  16093. +
  16094. +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
  16095. + int gfp_mask)
  16096. +{
  16097. + struct ieee80211_txb *txb;
  16098. + int i;
  16099. + txb = kmalloc(
  16100. + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
  16101. + gfp_mask);
  16102. + if (!txb)
  16103. + return NULL;
  16104. +
  16105. + memset(txb, 0, sizeof(struct ieee80211_txb));
  16106. + txb->nr_frags = nr_frags;
  16107. + txb->frag_size = txb_size;
  16108. +
  16109. + for (i = 0; i < nr_frags; i++) {
  16110. + txb->fragments[i] = dev_alloc_skb(txb_size);
  16111. + if (unlikely(!txb->fragments[i])) {
  16112. + i--;
  16113. + break;
  16114. + }
  16115. + }
  16116. + if (unlikely(i != nr_frags)) {
  16117. + while (i >= 0)
  16118. + dev_kfree_skb_any(txb->fragments[i--]);
  16119. + kfree(txb);
  16120. + return NULL;
  16121. + }
  16122. + return txb;
  16123. +}
  16124. +
  16125. +// Classify the to-be send data packet
  16126. +// Need to acquire the sent queue index.
  16127. +static int
  16128. +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
  16129. +{
  16130. + struct ether_header *eh = (struct ether_header*)skb->data;
  16131. + unsigned int wme_UP = 0;
  16132. +
  16133. + if(!network->QoS_Enable) {
  16134. + skb->priority = 0;
  16135. + return(wme_UP);
  16136. + }
  16137. +
  16138. + if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
  16139. + const struct iphdr *ih = (struct iphdr*)(skb->data + \
  16140. + sizeof(struct ether_header));
  16141. + wme_UP = (ih->tos >> 5)&0x07;
  16142. + } else if (vlan_tx_tag_present(skb)) {//vtag packet
  16143. +#ifndef VLAN_PRI_SHIFT
  16144. +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
  16145. +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
  16146. +#endif
  16147. + u32 tag = vlan_tx_tag_get(skb);
  16148. + wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
  16149. + } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
  16150. + //printk(KERN_WARNING "type = normal packet\n");
  16151. + wme_UP = 7;
  16152. + }
  16153. + skb->priority = wme_UP;
  16154. +/*
  16155. + if (network->QoS_Enable) {
  16156. + skb->priority = wme_UP;
  16157. + }else {
  16158. + skb->priority = 0;
  16159. + }
  16160. +*/
  16161. + return(wme_UP);
  16162. +}
  16163. +
  16164. +#ifdef _RTL8187_EXT_PATCH_
  16165. +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
  16166. +struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
  16167. +{
  16168. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  16169. + struct ieee80211_device *ieee = netdev_priv(dev);
  16170. +#else
  16171. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  16172. +#endif
  16173. + struct ieee80211_txb *txb = NULL;
  16174. + struct ieee80211_hdr_3addr *frag_hdr;
  16175. + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
  16176. + int ether_type;
  16177. + int bytes, QOS_ctl;
  16178. + struct sk_buff *skb_frag;
  16179. +
  16180. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  16181. +
  16182. + /* Advance the SKB to the start of the payload */
  16183. + skb_pull(skb, sizeof(struct ethhdr));
  16184. +
  16185. + /* Determine total amount of storage required for TXB packets */
  16186. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  16187. +
  16188. + /* Determine fragmentation size based on destination (multicast
  16189. + * and broadcast are not fragmented) */
  16190. + // if (is_multicast_ether_addr(dest) ||
  16191. + // is_broadcast_ether_addr(dest)) {
  16192. + if (is_multicast_ether_addr(header->addr1) ||
  16193. + is_broadcast_ether_addr(header->addr1)) {
  16194. + frag_size = MAX_FRAG_THRESHOLD;
  16195. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  16196. + }
  16197. + else {
  16198. + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
  16199. + frag_size = ieee->fts;//default:392
  16200. + QOS_ctl = 0;
  16201. + }
  16202. +
  16203. + if(isQoS) {
  16204. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  16205. + *pQOS_ctl = cpu_to_le16(QOS_ctl);
  16206. + }
  16207. + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
  16208. + /* Determine amount of payload per fragment. Regardless of if
  16209. + * this stack is providing the full 802.11 header, one will
  16210. + * eventually be affixed to this fragment -- so we must account for
  16211. + * it when determining the amount of payload space. */
  16212. + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
  16213. + bytes_per_frag = frag_size - hdr_len;
  16214. + if (ieee->config &
  16215. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  16216. + bytes_per_frag -= IEEE80211_FCS_LEN;
  16217. +
  16218. + /* Each fragment may need to have room for encryptiong pre/postfix */
  16219. + if (isEncrypt)
  16220. + bytes_per_frag -= crypt->ops->extra_prefix_len +
  16221. + crypt->ops->extra_postfix_len;
  16222. +
  16223. + /* Number of fragments is the total bytes_per_frag /
  16224. + * payload_per_fragment */
  16225. + nr_frags = bytes / bytes_per_frag;
  16226. + bytes_last_frag = bytes % bytes_per_frag;
  16227. + if (bytes_last_frag)
  16228. + nr_frags++;
  16229. + else
  16230. + bytes_last_frag = bytes_per_frag;
  16231. +
  16232. + /* When we allocate the TXB we allocate enough space for the reserve
  16233. + * and full fragment bytes (bytes_per_frag doesn't include prefix,
  16234. + * postfix, header, FCS, etc.) */
  16235. + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
  16236. + if (unlikely(!txb)) {
  16237. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  16238. + ieee->dev->name);
  16239. + return NULL;
  16240. + }
  16241. + txb->encrypted = isEncrypt;
  16242. + txb->payload_size = bytes;
  16243. +
  16244. + for (i = 0; i < nr_frags; i++) {
  16245. + skb_frag = txb->fragments[i];
  16246. + skb_frag->priority = UP2AC(skb->priority);
  16247. + if (isEncrypt)
  16248. + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
  16249. +
  16250. + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
  16251. + memcpy(frag_hdr, (void *)header, hdr_len);
  16252. +
  16253. + /* If this is not the last fragment, then add the MOREFRAGS
  16254. + * bit to the frame control */
  16255. + if (i != nr_frags - 1) {
  16256. + frag_hdr->frame_ctl = cpu_to_le16(
  16257. + header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
  16258. + bytes = bytes_per_frag;
  16259. +
  16260. + } else {
  16261. + /* The last fragment takes the remaining length */
  16262. + bytes = bytes_last_frag;
  16263. + }
  16264. +
  16265. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
  16266. + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
  16267. + //
  16268. +
  16269. + /* Put a SNAP header on the first fragment */
  16270. + if (i == 0) {
  16271. + ieee80211_put_snap(
  16272. + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
  16273. + bytes -= SNAP_SIZE + sizeof(u16);
  16274. + }
  16275. +
  16276. + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
  16277. +
  16278. + /* Advance the SKB... */
  16279. + skb_pull(skb, bytes);
  16280. +
  16281. + /* Encryption routine will move the header forward in order
  16282. + * to insert the IV between the header and the payload */
  16283. + if (isEncrypt)
  16284. + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
  16285. + if (ieee->config &
  16286. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  16287. + skb_put(skb_frag, 4);
  16288. + }
  16289. + // Advance sequence number in data frame.
  16290. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  16291. + if (ieee->seq_ctrl[0] == 0xFFF)
  16292. + ieee->seq_ctrl[0] = 0;
  16293. + else
  16294. + ieee->seq_ctrl[0]++;
  16295. + // stanley, just for debug
  16296. +/*
  16297. +{
  16298. + int j=0;
  16299. + for(j=0;j<nr_frags;j++)
  16300. + {
  16301. + int i;
  16302. + struct sk_buff *skb = txb->fragments[j];
  16303. + printk("send(%d): ", j);
  16304. + for (i=0;i<skb->len;i++)
  16305. + printk("%02X ", skb->data[i]&0xff);
  16306. + printk("\n");
  16307. + }
  16308. +}
  16309. +*/
  16310. +
  16311. + return txb;
  16312. +}
  16313. +
  16314. +
  16315. +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
  16316. +// Assume no encryption, no FCS computing
  16317. +struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
  16318. +{
  16319. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  16320. + struct ieee80211_device *ieee = netdev_priv(dev);
  16321. +#else
  16322. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  16323. +#endif
  16324. + struct ieee80211_txb *txb = NULL;
  16325. + struct ieee80211_hdr_3addr *frag_hdr;
  16326. + int ether_type;
  16327. + int bytes, QOS_ctl;
  16328. +
  16329. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  16330. +
  16331. + /* Advance the SKB to the start of the payload */
  16332. + skb_pull(skb, sizeof(struct ethhdr));
  16333. +
  16334. + /* Determine total amount of storage required for TXB packets */
  16335. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  16336. +
  16337. + if (is_multicast_ether_addr(header->addr1) ||
  16338. + is_broadcast_ether_addr(header->addr1)) {
  16339. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  16340. + }
  16341. + else {
  16342. + QOS_ctl = 0;
  16343. + }
  16344. +
  16345. + if(isQoS) {
  16346. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  16347. + *pQOS_ctl = cpu_to_le16(QOS_ctl);
  16348. + }
  16349. +
  16350. + txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
  16351. + if (unlikely(!txb)) {
  16352. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  16353. + ieee->dev->name);
  16354. + return NULL;
  16355. + }
  16356. +
  16357. + txb->nr_frags = 1;
  16358. + txb->frag_size = bytes;
  16359. + txb->encrypted = isEncrypt;
  16360. + txb->payload_size = bytes;
  16361. +
  16362. + txb->fragments[0] = skb;
  16363. + ieee80211_put_snap(
  16364. + skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
  16365. + frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
  16366. + memcpy(frag_hdr, (void *)header, hdr_len);
  16367. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
  16368. + skb->priority = UP2AC(skb->priority);
  16369. + if(isEncrypt)
  16370. + ieee80211_encrypt_fragment(ieee,skb,hdr_len);
  16371. +
  16372. + // Advance sequence number in data frame.
  16373. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  16374. + if (ieee->seq_ctrl[0] == 0xFFF)
  16375. + ieee->seq_ctrl[0] = 0;
  16376. + else
  16377. + ieee->seq_ctrl[0]++;
  16378. +
  16379. + return txb;
  16380. +}
  16381. +
  16382. +#endif // _RTL8187_EXT_PATCH_
  16383. +
  16384. +/* SKBs are added to the ieee->tx_queue. */
  16385. +int ieee80211_xmit(struct sk_buff *skb,
  16386. + struct net_device *dev)
  16387. +{
  16388. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  16389. + struct ieee80211_device *ieee = netdev_priv(dev);
  16390. +#else
  16391. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  16392. +#endif
  16393. + struct ieee80211_txb *txb = NULL;
  16394. + struct ieee80211_hdr_3addr_QOS *frag_hdr;
  16395. + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
  16396. + unsigned long flags;
  16397. + struct net_device_stats *stats = &ieee->stats;
  16398. + int ether_type, encrypt;
  16399. + int bytes, fc, QOS_ctl, hdr_len;
  16400. + struct sk_buff *skb_frag;
  16401. + //struct ieee80211_hdr header = { /* Ensure zero initialized */
  16402. + // .duration_id = 0,
  16403. + // .seq_ctl = 0
  16404. + //};
  16405. + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
  16406. + .duration_id = 0,
  16407. + .seq_ctl = 0,
  16408. + .QOS_ctl = 0
  16409. + };
  16410. + u8 dest[ETH_ALEN], src[ETH_ALEN];
  16411. +
  16412. + struct ieee80211_crypt_data* crypt;
  16413. +
  16414. + //printk(KERN_WARNING "upper layer packet!\n");
  16415. + spin_lock_irqsave(&ieee->lock, flags);
  16416. +
  16417. + /* If there is no driver handler to take the TXB, dont' bother
  16418. + * creating it... */
  16419. + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
  16420. + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
  16421. + printk(KERN_WARNING "%s: No xmit handler.\n",
  16422. + ieee->dev->name);
  16423. + goto success;
  16424. + }
  16425. +
  16426. + ieee80211_classify(skb,&ieee->current_network);
  16427. + if(likely(ieee->raw_tx == 0)){
  16428. +
  16429. + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
  16430. + printk(KERN_WARNING "%s: skb too small (%d).\n",
  16431. + ieee->dev->name, skb->len);
  16432. + goto success;
  16433. + }
  16434. +
  16435. +
  16436. +#ifdef _RTL8187_EXT_PATCH_
  16437. + // note, skb->priority which was set by ieee80211_classify, and used by physical tx
  16438. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
  16439. + {
  16440. + txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
  16441. + goto success;
  16442. + }
  16443. +#endif
  16444. +
  16445. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  16446. +#ifdef _RTL8187_EXT_PATCH_
  16447. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16448. +#else
  16449. + crypt = ieee->crypt[ieee->tx_keyidx];
  16450. +#endif
  16451. + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
  16452. + ieee->host_encrypt && crypt && crypt->ops;
  16453. +
  16454. + if (!encrypt && ieee->ieee802_1x &&
  16455. + ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
  16456. + stats->tx_dropped++;
  16457. + goto success;
  16458. + }
  16459. +
  16460. + #ifdef CONFIG_IEEE80211_DEBUG
  16461. + if (crypt && !encrypt && ether_type == ETH_P_PAE) {
  16462. + struct eapol *eap = (struct eapol *)(skb->data +
  16463. + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
  16464. + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
  16465. + eap_get_type(eap->type));
  16466. + }
  16467. + #endif
  16468. +
  16469. + /* Save source and destination addresses */
  16470. + memcpy(&dest, skb->data, ETH_ALEN);
  16471. + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
  16472. +
  16473. + /* Advance the SKB to the start of the payload */
  16474. + skb_pull(skb, sizeof(struct ethhdr));
  16475. +
  16476. + /* Determine total amount of storage required for TXB packets */
  16477. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  16478. +
  16479. + if(ieee->current_network.QoS_Enable) {
  16480. + if (encrypt)
  16481. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
  16482. + IEEE80211_FCTL_WEP;
  16483. + else
  16484. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
  16485. +
  16486. + } else {
  16487. + if (encrypt)
  16488. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
  16489. + IEEE80211_FCTL_WEP;
  16490. + else
  16491. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
  16492. + }
  16493. +
  16494. + if (ieee->iw_mode == IW_MODE_INFRA) {
  16495. + fc |= IEEE80211_FCTL_TODS;
  16496. + /* To DS: Addr1 = BSSID, Addr2 = SA,
  16497. + Addr3 = DA */
  16498. + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
  16499. + memcpy(&header.addr2, &src, ETH_ALEN);
  16500. + memcpy(&header.addr3, &dest, ETH_ALEN);
  16501. + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
  16502. + /* not From/To DS: Addr1 = DA, Addr2 = SA,
  16503. + Addr3 = BSSID */
  16504. + memcpy(&header.addr1, dest, ETH_ALEN);
  16505. + memcpy(&header.addr2, src, ETH_ALEN);
  16506. + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
  16507. + }
  16508. + // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
  16509. + header.frame_ctl = cpu_to_le16(fc);
  16510. + //hdr_len = IEEE80211_3ADDR_LEN;
  16511. +
  16512. + /* Determine fragmentation size based on destination (multicast
  16513. + * and broadcast are not fragmented) */
  16514. +// if (is_multicast_ether_addr(dest) ||
  16515. +// is_broadcast_ether_addr(dest)) {
  16516. + if (is_multicast_ether_addr(header.addr1) ||
  16517. + is_broadcast_ether_addr(header.addr1)) {
  16518. + frag_size = MAX_FRAG_THRESHOLD;
  16519. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  16520. + }
  16521. + else {
  16522. + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
  16523. + frag_size = ieee->fts;//default:392
  16524. + QOS_ctl = 0;
  16525. + }
  16526. +
  16527. + if (ieee->current_network.QoS_Enable) {
  16528. + hdr_len = IEEE80211_3ADDR_LEN + 2;
  16529. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  16530. + header.QOS_ctl = cpu_to_le16(QOS_ctl);
  16531. + } else {
  16532. + hdr_len = IEEE80211_3ADDR_LEN;
  16533. + }
  16534. + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
  16535. + /* Determine amount of payload per fragment. Regardless of if
  16536. + * this stack is providing the full 802.11 header, one will
  16537. + * eventually be affixed to this fragment -- so we must account for
  16538. + * it when determining the amount of payload space. */
  16539. + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
  16540. + bytes_per_frag = frag_size - hdr_len;
  16541. + if (ieee->config &
  16542. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  16543. + bytes_per_frag -= IEEE80211_FCS_LEN;
  16544. +
  16545. + /* Each fragment may need to have room for encryptiong pre/postfix */
  16546. + if (encrypt)
  16547. + bytes_per_frag -= crypt->ops->extra_prefix_len +
  16548. + crypt->ops->extra_postfix_len;
  16549. +
  16550. + /* Number of fragments is the total bytes_per_frag /
  16551. + * payload_per_fragment */
  16552. + nr_frags = bytes / bytes_per_frag;
  16553. + bytes_last_frag = bytes % bytes_per_frag;
  16554. + if (bytes_last_frag)
  16555. + nr_frags++;
  16556. + else
  16557. + bytes_last_frag = bytes_per_frag;
  16558. +
  16559. + /* When we allocate the TXB we allocate enough space for the reserve
  16560. + * and full fragment bytes (bytes_per_frag doesn't include prefix,
  16561. + * postfix, header, FCS, etc.) */
  16562. + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
  16563. + if (unlikely(!txb)) {
  16564. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  16565. + ieee->dev->name);
  16566. + goto failed;
  16567. + }
  16568. + txb->encrypted = encrypt;
  16569. + txb->payload_size = bytes;
  16570. +
  16571. + for (i = 0; i < nr_frags; i++) {
  16572. + skb_frag = txb->fragments[i];
  16573. + skb_frag->priority = UP2AC(skb->priority);
  16574. + if (encrypt)
  16575. + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
  16576. +
  16577. + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
  16578. + memcpy(frag_hdr, &header, hdr_len);
  16579. +
  16580. + /* If this is not the last fragment, then add the MOREFRAGS
  16581. + * bit to the frame control */
  16582. + if (i != nr_frags - 1) {
  16583. + frag_hdr->frame_ctl = cpu_to_le16(
  16584. + fc | IEEE80211_FCTL_MOREFRAGS);
  16585. + bytes = bytes_per_frag;
  16586. +
  16587. + } else {
  16588. + /* The last fragment takes the remaining length */
  16589. + bytes = bytes_last_frag;
  16590. + }
  16591. + if(ieee->current_network.QoS_Enable) {
  16592. + // add 1 only indicate to corresponding seq number control 2006/7/12
  16593. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
  16594. + //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
  16595. + //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
  16596. + } else {
  16597. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
  16598. + }
  16599. + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
  16600. + //
  16601. +
  16602. + /* Put a SNAP header on the first fragment */
  16603. + if (i == 0) {
  16604. + ieee80211_put_snap(
  16605. + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
  16606. + ether_type);
  16607. + bytes -= SNAP_SIZE + sizeof(u16);
  16608. + }
  16609. +
  16610. + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
  16611. +
  16612. + /* Advance the SKB... */
  16613. + skb_pull(skb, bytes);
  16614. +
  16615. + /* Encryption routine will move the header forward in order
  16616. + * to insert the IV between the header and the payload */
  16617. + if (encrypt)
  16618. + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
  16619. + if (ieee->config &
  16620. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  16621. + skb_put(skb_frag, 4);
  16622. + }
  16623. + // Advance sequence number in data frame.
  16624. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  16625. + if (ieee->current_network.QoS_Enable) {
  16626. + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
  16627. + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
  16628. + else
  16629. + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
  16630. + } else {
  16631. + if (ieee->seq_ctrl[0] == 0xFFF)
  16632. + ieee->seq_ctrl[0] = 0;
  16633. + else
  16634. + ieee->seq_ctrl[0]++;
  16635. + }
  16636. + //---
  16637. + }else{
  16638. + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
  16639. + printk(KERN_WARNING "%s: skb too small (%d).\n",
  16640. + ieee->dev->name, skb->len);
  16641. + goto success;
  16642. + }
  16643. +
  16644. + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
  16645. + if(!txb){
  16646. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  16647. + ieee->dev->name);
  16648. + goto failed;
  16649. + }
  16650. +
  16651. + txb->encrypted = 0;
  16652. + txb->payload_size = skb->len;
  16653. + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
  16654. + }
  16655. +
  16656. + success:
  16657. + spin_unlock_irqrestore(&ieee->lock, flags);
  16658. +#ifdef _RTL8187_EXT_PATCH_
  16659. + // Sometimes, extension mode can reuse skb (by txb->fragments[0])
  16660. + if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
  16661. +#endif
  16662. + dev_kfree_skb_any(skb);
  16663. + if (txb) {
  16664. + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
  16665. + ieee80211_softmac_xmit(txb, ieee);
  16666. + }else{
  16667. + if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
  16668. + stats->tx_packets++;
  16669. + stats->tx_bytes += txb->payload_size;
  16670. + return 0;
  16671. + }
  16672. + ieee80211_txb_free(txb);
  16673. + }
  16674. + }
  16675. +
  16676. + return 0;
  16677. +
  16678. + failed:
  16679. + spin_unlock_irqrestore(&ieee->lock, flags);
  16680. + netif_stop_queue(dev);
  16681. + printk("netif_stop_queue in ieee80211_xmit \n");
  16682. + stats->tx_errors++;
  16683. + return 1;
  16684. +
  16685. +}
  16686. +
  16687. +
  16688. +
  16689. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  16690. +EXPORT_SYMBOL(ieee80211_txb_free);
  16691. +#ifdef _RTL8187_EXT_PATCH_
  16692. +EXPORT_SYMBOL(ieee80211_alloc_txb);
  16693. +EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
  16694. +EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
  16695. +
  16696. +EXPORT_SYMBOL(ieee80211_encrypt_fragment);
  16697. +#endif // _RTL8187_EXT_PATCH_
  16698. +#else
  16699. +EXPORT_SYMBOL_NOVERS(ieee80211_txb_free);
  16700. +#ifdef _RTL8187_EXT_PATCH_
  16701. +EXPORT_SYMBOL_NOVERS(ieee80211_alloc_txb);
  16702. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_reuse_txb);
  16703. +
  16704. +EXPORT_SYMBOL_NOVERS(ieee80211_encrypt_fragment);
  16705. +#endif // _RTL8187_EXT_PATCH_
  16706. +#endif
  16707. +
  16708. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c
  16709. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 1970-01-01 01:00:00.000000000 +0100
  16710. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 2010-03-06 16:43:22.000000000 +0100
  16711. @@ -0,0 +1,926 @@
  16712. +/******************************************************************************
  16713. +
  16714. + Copyright(c) 2004 Intel Corporation. All rights reserved.
  16715. +
  16716. + Portions of this file are based on the WEP enablement code provided by the
  16717. + Host AP project hostap-drivers v0.1.3
  16718. + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  16719. + <jkmaline@cc.hut.fi>
  16720. + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  16721. +
  16722. + This program is free software; you can redistribute it and/or modify it
  16723. + under the terms of version 2 of the GNU General Public License as
  16724. + published by the Free Software Foundation.
  16725. +
  16726. + This program is distributed in the hope that it will be useful, but WITHOUT
  16727. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16728. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  16729. + more details.
  16730. +
  16731. + You should have received a copy of the GNU General Public License along with
  16732. + this program; if not, write to the Free Software Foundation, Inc., 59
  16733. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16734. +
  16735. + The full GNU General Public License is included in this distribution in the
  16736. + file called LICENSE.
  16737. +
  16738. + Contact Information:
  16739. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  16740. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  16741. +
  16742. +******************************************************************************/
  16743. +#include <linux/wireless.h>
  16744. +#include <linux/version.h>
  16745. +#include <linux/kmod.h>
  16746. +#include <linux/module.h>
  16747. +
  16748. +#include "ieee80211.h"
  16749. +static const char *ieee80211_modes[] = {
  16750. + "?", "a", "b", "ab", "g", "ag", "bg", "abg"
  16751. +};
  16752. +
  16753. +#define MAX_CUSTOM_LEN 64
  16754. +static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
  16755. + char *start, char *stop,
  16756. + struct ieee80211_network *network,
  16757. + struct iw_request_info *info)
  16758. +{
  16759. + char custom[MAX_CUSTOM_LEN];
  16760. + char *p;
  16761. + struct iw_event iwe;
  16762. + int i, j;
  16763. + u8 max_rate, rate;
  16764. +
  16765. + /* First entry *MUST* be the AP MAC address */
  16766. + iwe.cmd = SIOCGIWAP;
  16767. + iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
  16768. + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
  16769. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16770. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
  16771. +#else
  16772. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
  16773. +#endif
  16774. + /* Remaining entries will be displayed in the order we provide them */
  16775. +
  16776. + /* Add the ESSID */
  16777. + iwe.cmd = SIOCGIWESSID;
  16778. + iwe.u.data.flags = 1;
  16779. + //YJ,modified,080903,for hidden ap
  16780. + //if (network->flags & NETWORK_EMPTY_ESSID) {
  16781. + if (network->ssid_len == 0) {
  16782. + iwe.u.data.length = sizeof("<hidden>");
  16783. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16784. + start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
  16785. +#else
  16786. + start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
  16787. +#endif
  16788. + } else {
  16789. + iwe.u.data.length = min(network->ssid_len, (u8)32);
  16790. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16791. + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
  16792. +#else
  16793. + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
  16794. +#endif
  16795. + }
  16796. +
  16797. + /* Add the protocol name */
  16798. + iwe.cmd = SIOCGIWNAME;
  16799. + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
  16800. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16801. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
  16802. +#else
  16803. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
  16804. +#endif
  16805. + /* Add mode */
  16806. + iwe.cmd = SIOCGIWMODE;
  16807. + if (network->capability &
  16808. + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
  16809. + if (network->capability & WLAN_CAPABILITY_BSS)
  16810. + iwe.u.mode = IW_MODE_MASTER;
  16811. + else
  16812. + iwe.u.mode = IW_MODE_ADHOC;
  16813. +
  16814. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16815. + start = iwe_stream_add_event(info, start, stop, &iwe,
  16816. + IW_EV_UINT_LEN);
  16817. +#else
  16818. + start = iwe_stream_add_event(start, stop, &iwe,
  16819. + IW_EV_UINT_LEN);
  16820. +#endif
  16821. + }
  16822. +
  16823. + /* Add frequency/channel */
  16824. + iwe.cmd = SIOCGIWFREQ;
  16825. +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
  16826. + iwe.u.freq.e = 3; */
  16827. + iwe.u.freq.m = network->channel;
  16828. + iwe.u.freq.e = 0;
  16829. + iwe.u.freq.i = 0;
  16830. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16831. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
  16832. +#else
  16833. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
  16834. +#endif
  16835. + /* Add encryption capability */
  16836. + iwe.cmd = SIOCGIWENCODE;
  16837. + if (network->capability & WLAN_CAPABILITY_PRIVACY)
  16838. + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
  16839. + else
  16840. + iwe.u.data.flags = IW_ENCODE_DISABLED;
  16841. + iwe.u.data.length = 0;
  16842. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16843. + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
  16844. +#else
  16845. + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
  16846. +#endif
  16847. + /* Add basic and extended rates */
  16848. + max_rate = 0;
  16849. + p = custom;
  16850. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
  16851. + for (i = 0, j = 0; i < network->rates_len; ) {
  16852. + if (j < network->rates_ex_len &&
  16853. + ((network->rates_ex[j] & 0x7F) <
  16854. + (network->rates[i] & 0x7F)))
  16855. + rate = network->rates_ex[j++] & 0x7F;
  16856. + else
  16857. + rate = network->rates[i++] & 0x7F;
  16858. + if (rate > max_rate)
  16859. + max_rate = rate;
  16860. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  16861. + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
  16862. + }
  16863. + for (; j < network->rates_ex_len; j++) {
  16864. + rate = network->rates_ex[j] & 0x7F;
  16865. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  16866. + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
  16867. + if (rate > max_rate)
  16868. + max_rate = rate;
  16869. + }
  16870. +
  16871. + iwe.cmd = SIOCGIWRATE;
  16872. + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
  16873. + iwe.u.bitrate.value = max_rate * 500000;
  16874. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16875. + start = iwe_stream_add_event(info, start, stop, &iwe,IW_EV_PARAM_LEN);
  16876. +#else
  16877. + start = iwe_stream_add_event(start, stop, &iwe,IW_EV_PARAM_LEN);
  16878. +#endif
  16879. + iwe.cmd = IWEVCUSTOM;
  16880. + iwe.u.data.length = p - custom;
  16881. + if (iwe.u.data.length)
  16882. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16883. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  16884. +#else
  16885. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  16886. +#endif
  16887. + /* Add quality statistics */
  16888. + /* TODO: Fix these values... */
  16889. + iwe.cmd = IWEVQUAL;
  16890. + iwe.u.qual.qual = network->stats.signalstrength;//network->stats.signal;
  16891. + iwe.u.qual.level = network->stats.signal;//network->stats.rssi;
  16892. + iwe.u.qual.noise = network->stats.noise;
  16893. +#if 0
  16894. + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
  16895. + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
  16896. + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
  16897. + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
  16898. + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
  16899. + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
  16900. + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
  16901. +#endif
  16902. +
  16903. + iwe.u.qual.updated = 0x7;//network->stats.mask & IEEE80211_STATMASK_WEMASK;
  16904. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16905. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
  16906. +#else
  16907. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
  16908. +#endif
  16909. + iwe.cmd = IWEVCUSTOM;
  16910. + p = custom;
  16911. +
  16912. + iwe.u.data.length = p - custom;
  16913. + if (iwe.u.data.length)
  16914. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16915. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  16916. +#else
  16917. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  16918. +#endif
  16919. +#if 0
  16920. + if (ieee->wpa_enabled && network->wpa_ie_len){
  16921. + char buf[MAX_WPA_IE_LEN * 2 + 30];
  16922. + // printk("WPA IE\n");
  16923. + u8 *p = buf;
  16924. + p += sprintf(p, "wpa_ie=");
  16925. + for (i = 0; i < network->wpa_ie_len; i++) {
  16926. + p += sprintf(p, "%02x", network->wpa_ie[i]);
  16927. + }
  16928. +
  16929. + memset(&iwe, 0, sizeof(iwe));
  16930. + iwe.cmd = IWEVCUSTOM;
  16931. + iwe.u.data.length = strlen(buf);
  16932. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  16933. + }
  16934. +
  16935. + if (ieee->wpa_enabled && network->rsn_ie_len){
  16936. + char buf[MAX_WPA_IE_LEN * 2 + 30];
  16937. +
  16938. + u8 *p = buf;
  16939. + p += sprintf(p, "rsn_ie=");
  16940. + for (i = 0; i < network->rsn_ie_len; i++) {
  16941. + p += sprintf(p, "%02x", network->rsn_ie[i]);
  16942. + }
  16943. +
  16944. +
  16945. +#else
  16946. + memset(&iwe, 0, sizeof(iwe));
  16947. + if (network->wpa_ie_len) {
  16948. + //printk("wpa_ie_len:%d\n", network->wpa_ie_len);
  16949. + char buf[MAX_WPA_IE_LEN];
  16950. + memcpy(buf, network->wpa_ie, network->wpa_ie_len);
  16951. + iwe.cmd = IWEVGENIE;
  16952. + iwe.u.data.length = network->wpa_ie_len;
  16953. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16954. + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
  16955. +#else
  16956. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  16957. +#endif
  16958. + }
  16959. +
  16960. + memset(&iwe, 0, sizeof(iwe));
  16961. + if (network->rsn_ie_len) {
  16962. + //printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
  16963. + #if 0
  16964. + {
  16965. + int i;
  16966. + for (i=0; i<network->rsn_ie_len; i++);
  16967. + printk("%2x ", network->rsn_ie[i]);
  16968. + printk("\n");
  16969. + }
  16970. + #endif
  16971. + char buf[MAX_WPA_IE_LEN];
  16972. + memcpy(buf, network->rsn_ie, network->rsn_ie_len);
  16973. + iwe.cmd = IWEVGENIE;
  16974. + iwe.u.data.length = network->rsn_ie_len;
  16975. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16976. + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
  16977. +#else
  16978. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  16979. +#endif
  16980. + }
  16981. +
  16982. +#endif
  16983. +
  16984. + /* Add EXTRA: Age to display seconds since last beacon/probe response
  16985. + * for given network. */
  16986. + iwe.cmd = IWEVCUSTOM;
  16987. + p = custom;
  16988. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  16989. + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
  16990. + iwe.u.data.length = p - custom;
  16991. + if (iwe.u.data.length)
  16992. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  16993. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  16994. +#else
  16995. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  16996. +#endif
  16997. +
  16998. + return start;
  16999. +}
  17000. +
  17001. +int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
  17002. + struct iw_request_info *info,
  17003. + union iwreq_data *wrqu, char *extra)
  17004. +{
  17005. + struct ieee80211_network *network;
  17006. + unsigned long flags;
  17007. + int err = 0;
  17008. + char *ev = extra;
  17009. + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
  17010. + //char *stop = ev + IW_SCAN_MAX_DATA;
  17011. + int i = 0;
  17012. +
  17013. + IEEE80211_DEBUG_WX("Getting scan\n");
  17014. + down(&ieee->wx_sem);
  17015. + spin_lock_irqsave(&ieee->lock, flags);
  17016. +
  17017. + if(!ieee->bHwRadioOff)
  17018. + {
  17019. + list_for_each_entry(network, &ieee->network_list, list) {
  17020. + i++;
  17021. +
  17022. + if((stop-ev)<200)
  17023. + {
  17024. + err = -E2BIG;
  17025. + break;
  17026. + }
  17027. +
  17028. + if (ieee->scan_age == 0 ||
  17029. + time_after(network->last_scanned + ieee->scan_age, jiffies))
  17030. + {
  17031. + ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
  17032. + }
  17033. + else
  17034. + IEEE80211_DEBUG_SCAN(
  17035. + "Not showing network '%s ("
  17036. + MAC_FMT ")' due to age (%lums).\n",
  17037. + escape_essid(network->ssid,
  17038. + network->ssid_len),
  17039. + MAC_ARG(network->bssid),
  17040. + (jiffies - network->last_scanned) / (HZ / 100));
  17041. + }
  17042. + }
  17043. + spin_unlock_irqrestore(&ieee->lock, flags);
  17044. + up(&ieee->wx_sem);
  17045. + wrqu->data.length = ev - extra;
  17046. + wrqu->data.flags = 0;
  17047. +
  17048. + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
  17049. +
  17050. + return err;
  17051. +}
  17052. +
  17053. +int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
  17054. + struct iw_request_info *info,
  17055. + union iwreq_data *wrqu, char *keybuf)
  17056. +{
  17057. + struct iw_point *erq = &(wrqu->encoding);
  17058. + struct net_device *dev = ieee->dev;
  17059. + struct ieee80211_security sec = {
  17060. + .flags = 0
  17061. + };
  17062. + int i, key, key_provided, len;
  17063. + struct ieee80211_crypt_data **crypt;
  17064. +
  17065. + IEEE80211_DEBUG_WX("SET_ENCODE\n");
  17066. +
  17067. + key = erq->flags & IW_ENCODE_INDEX;
  17068. + if (key) {
  17069. + if (key > WEP_KEYS)
  17070. + return -EINVAL;
  17071. + key--;
  17072. + key_provided = 1;
  17073. + } else {
  17074. + key_provided = 0;
  17075. + key = ieee->tx_keyidx;
  17076. + }
  17077. +
  17078. + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
  17079. + "provided" : "default");
  17080. +#ifdef _RTL8187_EXT_PATCH_
  17081. +#if 0
  17082. +{
  17083. + int j;
  17084. + for(j=0; j<MAX_MP; j++){
  17085. + crypt = &ieee->cryptlist[j]->crypt[key];
  17086. +#else
  17087. + crypt = &ieee->cryptlist[0]->crypt[key];
  17088. +#endif
  17089. +#else
  17090. + crypt = &ieee->crypt[key];
  17091. +#endif
  17092. + if (erq->flags & IW_ENCODE_DISABLED) {
  17093. + if (key_provided && *crypt) {
  17094. + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
  17095. + key);
  17096. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  17097. + } else
  17098. + IEEE80211_DEBUG_WX("Disabling encryption.\n");
  17099. +
  17100. + /* Check all the keys to see if any are still configured,
  17101. + * and if no key index was provided, de-init them all */
  17102. + for (i = 0; i < WEP_KEYS; i++) {
  17103. +#ifdef _RTL8187_EXT_PATCH_
  17104. +
  17105. + if (ieee->cryptlist[0]->crypt[i] != NULL){
  17106. +#else
  17107. +
  17108. + if (ieee->crypt[i] != NULL) {
  17109. +#endif
  17110. + if (key_provided)
  17111. + break;
  17112. + ieee80211_crypt_delayed_deinit(
  17113. +#ifdef _RTL8187_EXT_PATCH_
  17114. + ieee, &ieee->cryptlist[0]->crypt[i]);
  17115. +#else
  17116. + ieee, &ieee->crypt[i]);
  17117. +#endif
  17118. + }
  17119. + }
  17120. +
  17121. + if (i == WEP_KEYS) {
  17122. + sec.enabled = 0;
  17123. + sec.level = SEC_LEVEL_0;
  17124. + sec.flags |= SEC_ENABLED | SEC_LEVEL;
  17125. + }
  17126. +
  17127. + goto done;
  17128. + }
  17129. +
  17130. +
  17131. +
  17132. + sec.enabled = 1;
  17133. + sec.flags |= SEC_ENABLED;
  17134. +
  17135. + if (*crypt != NULL && (*crypt)->ops != NULL &&
  17136. + strcmp((*crypt)->ops->name, "WEP") != 0) {
  17137. + /* changing to use WEP; deinit previously used algorithm
  17138. + * on this key */
  17139. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  17140. + }
  17141. +
  17142. + if (*crypt == NULL) {
  17143. + struct ieee80211_crypt_data *new_crypt;
  17144. +
  17145. + /* take WEP into use */
  17146. + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
  17147. + GFP_KERNEL);
  17148. + if (new_crypt == NULL)
  17149. + return -ENOMEM;
  17150. + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
  17151. + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
  17152. + if (!new_crypt->ops) {
  17153. + request_module("ieee80211_crypt_wep");
  17154. + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
  17155. + }
  17156. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  17157. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  17158. +#else
  17159. + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
  17160. +#endif
  17161. + new_crypt->priv = new_crypt->ops->init(key);
  17162. +
  17163. + if (!new_crypt->ops || !new_crypt->priv) {
  17164. + kfree(new_crypt);
  17165. + new_crypt = NULL;
  17166. +
  17167. + printk(KERN_WARNING "%s: could not initialize WEP: "
  17168. + "load module ieee80211_crypt_wep\n",
  17169. + dev->name);
  17170. + return -EOPNOTSUPP;
  17171. + }
  17172. + *crypt = new_crypt;
  17173. + }
  17174. +
  17175. + /* If a new key was provided, set it up */
  17176. + if (erq->length > 0) {
  17177. + len = erq->length <= 5 ? 5 : 13;
  17178. + memcpy(sec.keys[key], keybuf, erq->length);
  17179. + if (len > erq->length)
  17180. + memset(sec.keys[key] + erq->length, 0,
  17181. + len - erq->length);
  17182. + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
  17183. + key, escape_essid(sec.keys[key], len),
  17184. + erq->length, len);
  17185. + sec.key_sizes[key] = len;
  17186. + (*crypt)->ops->set_key(sec.keys[key], len, NULL,
  17187. + (*crypt)->priv);
  17188. + sec.flags |= (1 << key);
  17189. + /* This ensures a key will be activated if no key is
  17190. + * explicitely set */
  17191. + if (key == sec.active_key)
  17192. + sec.flags |= SEC_ACTIVE_KEY;
  17193. +
  17194. + ieee->tx_keyidx = key; //we need it to support multi_key setting. added by wb 2008_2_22
  17195. + } else {
  17196. + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
  17197. + NULL, (*crypt)->priv);
  17198. + if (len == 0) {
  17199. + /* Set a default key of all 0 */
  17200. + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
  17201. + key);
  17202. + memset(sec.keys[key], 0, 13);
  17203. + (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
  17204. + (*crypt)->priv);
  17205. + sec.key_sizes[key] = 13;
  17206. + sec.flags |= (1 << key);
  17207. + }
  17208. +
  17209. + /* No key data - just set the default TX key index */
  17210. + if (key_provided) {
  17211. + IEEE80211_DEBUG_WX(
  17212. + "Setting key %d to default Tx key.\n", key);
  17213. + ieee->tx_keyidx = key;
  17214. + sec.active_key = key;
  17215. + sec.flags |= SEC_ACTIVE_KEY;
  17216. + }
  17217. + }
  17218. +#ifdef _RTL8187_EXT_PATCH_
  17219. +#if 0
  17220. +}
  17221. +}
  17222. +#endif
  17223. +#endif
  17224. + done:
  17225. + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
  17226. + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
  17227. + sec.flags |= SEC_AUTH_MODE;
  17228. + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
  17229. + "OPEN" : "SHARED KEY");
  17230. +
  17231. + /* For now we just support WEP, so only set that security level...
  17232. + * TODO: When WPA is added this is one place that needs to change */
  17233. + sec.flags |= SEC_LEVEL;
  17234. + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
  17235. +
  17236. + if (ieee->set_security)
  17237. + ieee->set_security(dev, &sec);
  17238. +
  17239. + /* Do not reset port if card is in Managed mode since resetting will
  17240. + * generate new IEEE 802.11 authentication which may end up in looping
  17241. + * with IEEE 802.1X. If your hardware requires a reset after WEP
  17242. + * configuration (for example... Prism2), implement the reset_port in
  17243. + * the callbacks structures used to initialize the 802.11 stack. */
  17244. + if (ieee->reset_on_keychange &&
  17245. + ieee->iw_mode != IW_MODE_INFRA &&
  17246. + ieee->reset_port && ieee->reset_port(dev)) {
  17247. + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
  17248. + return -EINVAL;
  17249. + }
  17250. + return 0;
  17251. +}
  17252. +
  17253. +int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
  17254. + struct iw_request_info *info,
  17255. + union iwreq_data *wrqu, char *keybuf)
  17256. +{
  17257. + struct iw_point *erq = &(wrqu->encoding);
  17258. + int len, key;
  17259. + struct ieee80211_crypt_data *crypt;
  17260. +
  17261. + IEEE80211_DEBUG_WX("GET_ENCODE\n");
  17262. +
  17263. + if(ieee->iw_mode == IW_MODE_MONITOR)
  17264. + return -1;
  17265. +
  17266. + key = erq->flags & IW_ENCODE_INDEX;
  17267. + if (key) {
  17268. + if (key > WEP_KEYS)
  17269. + return -EINVAL;
  17270. + key--;
  17271. + } else
  17272. + key = ieee->tx_keyidx;
  17273. +#ifdef _RTL8187_EXT_PATCH_
  17274. + crypt = ieee->cryptlist[0]->crypt[key];
  17275. +#else
  17276. + crypt = ieee->crypt[key];
  17277. +#endif
  17278. + erq->flags = key + 1;
  17279. +
  17280. + if (crypt == NULL || crypt->ops == NULL) {
  17281. + erq->length = 0;
  17282. + erq->flags |= IW_ENCODE_DISABLED;
  17283. + return 0;
  17284. + }
  17285. +
  17286. + if (strcmp(crypt->ops->name, "WEP") != 0) {
  17287. + /* only WEP is supported with wireless extensions, so just
  17288. + * report that encryption is used */
  17289. + erq->length = 0;
  17290. + erq->flags |= IW_ENCODE_ENABLED;
  17291. + return 0;
  17292. + }
  17293. +
  17294. + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
  17295. + erq->length = (len >= 0 ? len : 0);
  17296. +
  17297. + erq->flags |= IW_ENCODE_ENABLED;
  17298. +
  17299. + if (ieee->open_wep)
  17300. + erq->flags |= IW_ENCODE_OPEN;
  17301. + else
  17302. + erq->flags |= IW_ENCODE_RESTRICTED;
  17303. +
  17304. + return 0;
  17305. +}
  17306. +
  17307. +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
  17308. + struct iw_request_info *info,
  17309. + union iwreq_data *wrqu, char *extra)
  17310. +{
  17311. + struct net_device *dev = ieee->dev;
  17312. + struct iw_point *encoding = &wrqu->encoding;
  17313. + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
  17314. + int i, idx, ret = 0;
  17315. + int group_key = 0;
  17316. + const char *alg, *module;
  17317. + struct ieee80211_crypto_ops *ops;
  17318. + struct ieee80211_crypt_data **crypt;
  17319. +
  17320. + struct ieee80211_security sec = {
  17321. + .flags = 0,
  17322. + };
  17323. + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
  17324. + idx = encoding->flags & IW_ENCODE_INDEX;
  17325. + if (idx) {
  17326. + if (idx < 1 || idx > WEP_KEYS)
  17327. + return -EINVAL;
  17328. + idx--;
  17329. + } else
  17330. + idx = ieee->tx_keyidx;
  17331. +
  17332. + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
  17333. +#ifdef _RTL8187_EXT_PATCH_
  17334. + crypt = &ieee->cryptlist[0]->crypt[idx];
  17335. +#else
  17336. + crypt = &ieee->crypt[idx];
  17337. +#endif
  17338. + group_key = 1;
  17339. + } else {
  17340. + /* some Cisco APs use idx>0 for unicast in dynamic WEP */
  17341. + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
  17342. + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
  17343. + return -EINVAL;
  17344. + if (ieee->iw_mode == IW_MODE_INFRA)
  17345. +#ifdef _RTL8187_EXT_PATCH_
  17346. + crypt = &ieee->cryptlist[0]->crypt[idx];
  17347. +#else
  17348. + crypt = &ieee->crypt[idx];
  17349. +#endif
  17350. + else
  17351. + return -EINVAL;
  17352. + }
  17353. +
  17354. + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
  17355. + if ((encoding->flags & IW_ENCODE_DISABLED) ||
  17356. + ext->alg == IW_ENCODE_ALG_NONE) {
  17357. + if (*crypt)
  17358. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  17359. +
  17360. + for (i = 0; i < WEP_KEYS; i++)
  17361. +#ifdef _RTL8187_EXT_PATCH_
  17362. + if (ieee->cryptlist[0]->crypt[i] != NULL)
  17363. +#else
  17364. + if (ieee->crypt[i] != NULL)
  17365. +#endif
  17366. + break;
  17367. +
  17368. + if (i == WEP_KEYS) {
  17369. + sec.enabled = 0;
  17370. + // sec.encrypt = 0;
  17371. + sec.level = SEC_LEVEL_0;
  17372. + sec.flags |= SEC_LEVEL;
  17373. + }
  17374. + //printk("disabled: flag:%x\n", encoding->flags);
  17375. + goto done;
  17376. + }
  17377. +
  17378. + sec.enabled = 1;
  17379. + // sec.encrypt = 1;
  17380. +#if 0
  17381. + if (group_key ? !ieee->host_mc_decrypt :
  17382. + !(ieee->host_encrypt || ieee->host_decrypt ||
  17383. + ieee->host_encrypt_msdu))
  17384. + goto skip_host_crypt;
  17385. +#endif
  17386. + switch (ext->alg) {
  17387. + case IW_ENCODE_ALG_WEP:
  17388. + alg = "WEP";
  17389. + module = "ieee80211_crypt_wep";
  17390. + break;
  17391. + case IW_ENCODE_ALG_TKIP:
  17392. + alg = "TKIP";
  17393. + module = "ieee80211_crypt_tkip";
  17394. + break;
  17395. + case IW_ENCODE_ALG_CCMP:
  17396. + alg = "CCMP";
  17397. + module = "ieee80211_crypt_ccmp";
  17398. + break;
  17399. + default:
  17400. + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
  17401. + dev->name, ext->alg);
  17402. + ret = -EINVAL;
  17403. + goto done;
  17404. + }
  17405. + printk("alg name:%s\n",alg);
  17406. +
  17407. + ops = ieee80211_get_crypto_ops(alg);
  17408. + if (ops == NULL) {
  17409. + request_module(module);
  17410. + ops = ieee80211_get_crypto_ops(alg);
  17411. + }
  17412. + if (ops == NULL) {
  17413. + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
  17414. + dev->name, ext->alg);
  17415. + printk("========>unknown crypto alg %d\n", ext->alg);
  17416. + ret = -EINVAL;
  17417. + goto done;
  17418. + }
  17419. +
  17420. + if (*crypt == NULL || (*crypt)->ops != ops) {
  17421. + struct ieee80211_crypt_data *new_crypt;
  17422. +
  17423. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  17424. +
  17425. + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
  17426. + if (new_crypt == NULL) {
  17427. + ret = -ENOMEM;
  17428. + goto done;
  17429. + }
  17430. + new_crypt->ops = ops;
  17431. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  17432. + new_crypt->priv = new_crypt->ops->init(idx);
  17433. + if (new_crypt->priv == NULL) {
  17434. + kfree(new_crypt);
  17435. + ret = -EINVAL;
  17436. + goto done;
  17437. + }
  17438. + *crypt = new_crypt;
  17439. +
  17440. + }
  17441. + //I need to deinit other crypt here in mesh mode instead deinit them while use them to tx&rx.
  17442. +#ifdef _RTL8187_EXT_PATCH_
  17443. + if (ieee->iw_mode == ieee->iw_ext_mode)
  17444. + {
  17445. + int j;
  17446. + for (j=1; j<MAX_MP; j++)
  17447. + {
  17448. + struct ieee80211_crypt_data ** crypttmp = &ieee->cryptlist[j]->crypt[idx];
  17449. + if (*crypttmp == NULL)
  17450. + break;
  17451. + if (*crypttmp && (*crypttmp)->ops != ops)
  17452. + ieee80211_crypt_delayed_deinit(ieee, crypttmp);
  17453. + }
  17454. + }
  17455. +#endif
  17456. + if (ext->key_len > 0 && (*crypt)->ops->set_key &&
  17457. + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
  17458. + (*crypt)->priv) < 0) {
  17459. + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
  17460. + printk("key setting failed\n");
  17461. + ret = -EINVAL;
  17462. + goto done;
  17463. + }
  17464. +#if 1
  17465. +// skip_host_crypt:
  17466. + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
  17467. + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
  17468. + ieee->tx_keyidx = idx;
  17469. + sec.active_key = idx;
  17470. + sec.flags |= SEC_ACTIVE_KEY;
  17471. + }
  17472. +
  17473. + if (ext->alg != IW_ENCODE_ALG_NONE) {
  17474. + memcpy(sec.keys[idx], ext->key, ext->key_len);
  17475. + sec.key_sizes[idx] = ext->key_len;
  17476. + sec.flags |= (1 << idx);
  17477. + if (ext->alg == IW_ENCODE_ALG_WEP) {
  17478. + // sec.encode_alg[idx] = SEC_ALG_WEP;
  17479. + sec.flags |= SEC_LEVEL;
  17480. + sec.level = SEC_LEVEL_1;
  17481. + } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
  17482. + // sec.encode_alg[idx] = SEC_ALG_TKIP;
  17483. + sec.flags |= SEC_LEVEL;
  17484. + sec.level = SEC_LEVEL_2;
  17485. + } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
  17486. + // sec.encode_alg[idx] = SEC_ALG_CCMP;
  17487. + sec.flags |= SEC_LEVEL;
  17488. + sec.level = SEC_LEVEL_3;
  17489. + }
  17490. + /* Don't set sec level for group keys. */
  17491. + if (group_key)
  17492. + sec.flags &= ~SEC_LEVEL;
  17493. + }
  17494. +#endif
  17495. +done:
  17496. + if (ieee->set_security)
  17497. + ieee->set_security(ieee->dev, &sec);
  17498. +
  17499. + if (ieee->reset_on_keychange &&
  17500. + ieee->iw_mode != IW_MODE_INFRA &&
  17501. + ieee->reset_port && ieee->reset_port(dev)) {
  17502. + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
  17503. + return -EINVAL;
  17504. + }
  17505. +
  17506. + return ret;
  17507. +}
  17508. +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
  17509. + struct iw_request_info *info,
  17510. + union iwreq_data *wrqu, char *extra)
  17511. +{
  17512. + struct iw_mlme *mlme = (struct iw_mlme *) extra;
  17513. +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
  17514. +#if 1
  17515. + switch (mlme->cmd) {
  17516. + case IW_MLME_DEAUTH:
  17517. + case IW_MLME_DISASSOC:
  17518. + // printk("disassoc now\n");
  17519. + ieee80211_disassociate(ieee);
  17520. + break;
  17521. + default:
  17522. + return -EOPNOTSUPP;
  17523. + }
  17524. +#endif
  17525. + return 0;
  17526. +}
  17527. +
  17528. +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
  17529. + struct iw_request_info *info,
  17530. + struct iw_param *data, char *extra)
  17531. +{
  17532. +/*
  17533. + struct ieee80211_security sec = {
  17534. + .flags = SEC_AUTH_MODE,
  17535. + }
  17536. +*/
  17537. + //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
  17538. + switch (data->flags & IW_AUTH_INDEX) {
  17539. + case IW_AUTH_WPA_VERSION:
  17540. + /*need to support wpa2 here*/
  17541. + //printk("wpa version:%x\n", data->value);
  17542. + break;
  17543. + case IW_AUTH_CIPHER_PAIRWISE:
  17544. + case IW_AUTH_CIPHER_GROUP:
  17545. + case IW_AUTH_KEY_MGMT:
  17546. + /*
  17547. + * * Host AP driver does not use these parameters and allows
  17548. + * * wpa_supplicant to control them internally.
  17549. + * */
  17550. + break;
  17551. + case IW_AUTH_TKIP_COUNTERMEASURES:
  17552. + ieee->tkip_countermeasures = data->value;
  17553. + break;
  17554. + case IW_AUTH_DROP_UNENCRYPTED:
  17555. + ieee->drop_unencrypted = data->value;
  17556. + break;
  17557. +
  17558. + case IW_AUTH_80211_AUTH_ALG:
  17559. + ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
  17560. + //printk("open_wep:%d\n", ieee->open_wep);
  17561. + break;
  17562. +
  17563. +#if 1
  17564. + case IW_AUTH_WPA_ENABLED:
  17565. + ieee->wpa_enabled = (data->value)?1:0;
  17566. + //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
  17567. + break;
  17568. +
  17569. +#endif
  17570. + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
  17571. + ieee->ieee802_1x = data->value;
  17572. + break;
  17573. + case IW_AUTH_PRIVACY_INVOKED:
  17574. + ieee->privacy_invoked = data->value;
  17575. + break;
  17576. + default:
  17577. + return -EOPNOTSUPP;
  17578. + }
  17579. + return 0;
  17580. +}
  17581. +
  17582. +#if 1
  17583. +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
  17584. +{
  17585. +#if 0
  17586. + printk("====>%s()\n", __FUNCTION__);
  17587. + {
  17588. + int i;
  17589. + for (i=0; i<len; i++)
  17590. + printk("%2x ", ie[i]&0xff);
  17591. + printk("\n");
  17592. + }
  17593. +#endif
  17594. + u8 *buf = NULL;
  17595. +
  17596. + if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
  17597. + {
  17598. + // printk("return error out, len:%d\n", len);
  17599. + return -EINVAL;
  17600. + }
  17601. + if (len)
  17602. + {
  17603. +
  17604. + if (len != ie[1]+2) printk("len:%d, ie:%d\n", (int)len, ie[1]);
  17605. + buf = kmalloc(len, GFP_KERNEL);
  17606. + if (buf == NULL)
  17607. + return -ENOMEM;
  17608. + memcpy(buf, ie, len);
  17609. + kfree(ieee->wpa_ie);
  17610. + ieee->wpa_ie = buf;
  17611. + ieee->wpa_ie_len = len;
  17612. + }
  17613. + else{
  17614. + if (ieee->wpa_ie)
  17615. + kfree(ieee->wpa_ie);
  17616. + ieee->wpa_ie = NULL;
  17617. + ieee->wpa_ie_len = 0;
  17618. + }
  17619. +// printk("<=====out %s()\n", __FUNCTION__);
  17620. +
  17621. + return 0;
  17622. +
  17623. +}
  17624. +#endif
  17625. +
  17626. +EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
  17627. +EXPORT_SYMBOL(ieee80211_wx_set_mlme);
  17628. +EXPORT_SYMBOL(ieee80211_wx_set_auth);
  17629. +EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
  17630. +EXPORT_SYMBOL(ieee80211_wx_get_scan);
  17631. +EXPORT_SYMBOL(ieee80211_wx_set_encode);
  17632. +EXPORT_SYMBOL(ieee80211_wx_get_encode);
  17633. +#if 0
  17634. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
  17635. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
  17636. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
  17637. +#endif
  17638. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/internal.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/internal.h
  17639. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/internal.h 1970-01-01 01:00:00.000000000 +0100
  17640. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/internal.h 2010-03-06 16:43:22.000000000 +0100
  17641. @@ -0,0 +1,115 @@
  17642. +/*
  17643. + * Cryptographic API.
  17644. + *
  17645. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  17646. + *
  17647. + * This program is free software; you can redistribute it and/or modify it
  17648. + * under the terms of the GNU General Public License as published by the Free
  17649. + * Software Foundation; either version 2 of the License, or (at your option)
  17650. + * any later version.
  17651. + *
  17652. + */
  17653. +#ifndef _CRYPTO_INTERNAL_H
  17654. +#define _CRYPTO_INTERNAL_H
  17655. +
  17656. +
  17657. +//#include <linux/crypto.h>
  17658. +#include "rtl_crypto.h"
  17659. +#include <linux/mm.h>
  17660. +#include <linux/highmem.h>
  17661. +#include <linux/init.h>
  17662. +#include <asm/hardirq.h>
  17663. +#include <asm/softirq.h>
  17664. +#include <asm/kmap_types.h>
  17665. +
  17666. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
  17667. +#define list_for_each_entry(pos, head, member) \
  17668. + for (pos = list_entry((head)->next, typeof(*pos), member), \
  17669. + prefetch(pos->member.next); \
  17670. + &pos->member != (head); \
  17671. + pos = list_entry(pos->member.next, typeof(*pos), member), \
  17672. + prefetch(pos->member.next))
  17673. +
  17674. +static inline void cond_resched(void)
  17675. +{
  17676. + if (need_resched()) {
  17677. + set_current_state(TASK_RUNNING);
  17678. + schedule();
  17679. + }
  17680. +}
  17681. +#endif
  17682. +
  17683. +extern enum km_type crypto_km_types[];
  17684. +
  17685. +static inline enum km_type crypto_kmap_type(int out)
  17686. +{
  17687. + return crypto_km_types[(in_softirq() ? 2 : 0) + out];
  17688. +}
  17689. +
  17690. +static inline void *crypto_kmap(struct page *page, int out)
  17691. +{
  17692. + return kmap_atomic(page, crypto_kmap_type(out));
  17693. +}
  17694. +
  17695. +static inline void crypto_kunmap(void *vaddr, int out)
  17696. +{
  17697. + kunmap_atomic(vaddr, crypto_kmap_type(out));
  17698. +}
  17699. +
  17700. +static inline void crypto_yield(struct crypto_tfm *tfm)
  17701. +{
  17702. + if (!in_softirq())
  17703. + cond_resched();
  17704. +}
  17705. +
  17706. +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
  17707. +{
  17708. + return (void *)&tfm[1];
  17709. +}
  17710. +
  17711. +struct crypto_alg *crypto_alg_lookup(const char *name);
  17712. +
  17713. +#ifdef CONFIG_KMOD
  17714. +void crypto_alg_autoload(const char *name);
  17715. +struct crypto_alg *crypto_alg_mod_lookup(const char *name);
  17716. +#else
  17717. +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
  17718. +{
  17719. + return crypto_alg_lookup(name);
  17720. +}
  17721. +#endif
  17722. +
  17723. +#ifdef CONFIG_CRYPTO_HMAC
  17724. +int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
  17725. +void crypto_free_hmac_block(struct crypto_tfm *tfm);
  17726. +#else
  17727. +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
  17728. +{
  17729. + return 0;
  17730. +}
  17731. +
  17732. +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
  17733. +{ }
  17734. +#endif
  17735. +
  17736. +#ifdef CONFIG_PROC_FS
  17737. +void __init crypto_init_proc(void);
  17738. +#else
  17739. +static inline void crypto_init_proc(void)
  17740. +{ }
  17741. +#endif
  17742. +
  17743. +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
  17744. +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
  17745. +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
  17746. +
  17747. +int crypto_init_digest_ops(struct crypto_tfm *tfm);
  17748. +int crypto_init_cipher_ops(struct crypto_tfm *tfm);
  17749. +int crypto_init_compress_ops(struct crypto_tfm *tfm);
  17750. +
  17751. +void crypto_exit_digest_ops(struct crypto_tfm *tfm);
  17752. +void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
  17753. +void crypto_exit_compress_ops(struct crypto_tfm *tfm);
  17754. +
  17755. +#endif /* _CRYPTO_INTERNAL_H */
  17756. +
  17757. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h
  17758. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 1970-01-01 01:00:00.000000000 +0100
  17759. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 2010-03-06 16:43:22.000000000 +0100
  17760. @@ -0,0 +1,20 @@
  17761. +#ifndef __KMAP_TYPES_H
  17762. +
  17763. +#define __KMAP_TYPES_H
  17764. +
  17765. +
  17766. +enum km_type {
  17767. + KM_BOUNCE_READ,
  17768. + KM_SKB_SUNRPC_DATA,
  17769. + KM_SKB_DATA_SOFTIRQ,
  17770. + KM_USER0,
  17771. + KM_USER1,
  17772. + KM_BH_IRQ,
  17773. + KM_SOFTIRQ0,
  17774. + KM_SOFTIRQ1,
  17775. + KM_TYPE_NR
  17776. +};
  17777. +
  17778. +#define _ASM_KMAP_TYPES_H
  17779. +
  17780. +#endif
  17781. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/readme linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/readme
  17782. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/readme 1970-01-01 01:00:00.000000000 +0100
  17783. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/readme 2010-03-06 16:43:22.000000000 +0100
  17784. @@ -0,0 +1,162 @@
  17785. +What this layer should do
  17786. +
  17787. +- It mantain the old mechanism as alternative, so the
  17788. + ipw2100 driver works with really few changes.
  17789. +- Encapsulate / Decapsulate ieee80211 packet
  17790. +- Handle fragmentation
  17791. +- Optionally provide an alterantive mechanism for netif queue stop/wake,
  17792. + so that the ieee80211 layer will pass one fragment per time instead of
  17793. + one txb struct per time. so the driver can stop the queue in the middle
  17794. + of a packet.
  17795. +- Provide two different TX interfaces for cards that can handle management
  17796. + frames on one HW queue, and data on another, and for cards that have only
  17797. + one HW queue (the latter untested and very, very rough).
  17798. +- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
  17799. + and for the channel, essid and wap get/set wireless extension requests.
  17800. + so that the driver has only to change channel when the ieee stack tell it.
  17801. +- Optionally provide a scanning mechanism so that the driver has not to
  17802. + worry about this, just implement the set channel calback and pass
  17803. + frames to the upper layer
  17804. +- Optionally provide the bss client protocol handshaking (just with open
  17805. + authentication)
  17806. +- Optionally provide the probe request send mechanism
  17807. +- Optionally provide the bss master mode logic to handle association
  17808. + protocol (only open authentication) and probe responses.
  17809. +- SW wep encryption (with open authentication)
  17810. +- It collects some stats
  17811. +- It provides beacons to the card when it ask for them
  17812. +
  17813. +What this layer doesn't do (yet)
  17814. +- Perform shared authentication
  17815. +- Have full support for master mode (the AP should loop back in the air
  17816. + frames from an associated client to another. This could be done easily
  17817. + with few lines of code, and it is done in my previous version of the
  17818. + stach, but a table of association must be keept and a disassociation
  17819. + policy must be decided and implemented.
  17820. +- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
  17821. + disassociate clients, and it is really prone to always allow access.
  17822. + In bss client mode it is a bit rough with AP deauth and disassoc requests.
  17823. +- It has not any entry point to view the collected stats.
  17824. +- Altought it takes care of the card supported rates in the management frame
  17825. + it sends, support for rate changing on TXed packet is not complete.
  17826. +- Give up once associated in bss client mode (it never detect a
  17827. + signal loss condition to disassociate and restart scanning)
  17828. +- Provide a mechanism for enabling the TX in monitor mode, so
  17829. + userspace programs can TX raw packets.
  17830. +- Provide a mechanism for cards that need that the SW take care of beacon
  17831. + TX completely, in sense that the SW has to enqueue by itself beacons
  17832. + to the card so it TX them (if any...)
  17833. +APIs
  17834. +
  17835. +Callback functions in the original stack has been mantained.
  17836. +following has been added (from ieee80211.h)
  17837. +
  17838. + /* Softmac-generated frames (mamagement) are TXed via this
  17839. + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
  17840. + * not set. As some cards may have different HW queues that
  17841. + * one might want to use for data and management frames
  17842. + * the option to have two callbacks might be useful.
  17843. + * This fucntion can't sleep.
  17844. + */
  17845. + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
  17846. + struct net_device *dev);
  17847. +
  17848. + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
  17849. + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
  17850. + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
  17851. + * then also management frames are sent via this callback.
  17852. + * This function can't sleep.
  17853. + */
  17854. + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
  17855. + struct net_device *dev);
  17856. +
  17857. + /* stops the HW queue for DATA frames. Useful to avoid
  17858. + * waste time to TX data frame when we are reassociating
  17859. + * This function can sleep.
  17860. + */
  17861. + void (*data_hard_stop)(struct net_device *dev);
  17862. +
  17863. + /* OK this is complementar to data_poll_hard_stop */
  17864. + void (*data_hard_resume)(struct net_device *dev);
  17865. +
  17866. + /* ask to the driver to retune the radio .
  17867. + * This function can sleep. the driver should ensure
  17868. + * the radio has been swithced before return.
  17869. + */
  17870. + void (*set_chan)(struct net_device *dev,short ch);
  17871. +
  17872. + /* These are not used if the ieee stack takes care of
  17873. + * scanning (IEEE_SOFTMAC_SCAN feature set).
  17874. + * In this case only the set_chan is used.
  17875. + *
  17876. + * The syncro version is similar to the start_scan but
  17877. + * does not return until all channels has been scanned.
  17878. + * this is called in user context and should sleep,
  17879. + * it is called in a work_queue when swithcing to ad-hoc mode
  17880. + * or in behalf of iwlist scan when the card is associated
  17881. + * and root user ask for a scan.
  17882. + * the fucntion stop_scan should stop both the syncro and
  17883. + * background scanning and can sleep.
  17884. + * The fucntion start_scan should initiate the background
  17885. + * scanning and can't sleep.
  17886. + */
  17887. + void (*scan_syncro)(struct net_device *dev);
  17888. + void (*start_scan)(struct net_device *dev);
  17889. + void (*stop_scan)(struct net_device *dev);
  17890. +
  17891. + /* indicate the driver that the link state is changed
  17892. + * for example it may indicate the card is associated now.
  17893. + * Driver might be interested in this to apply RX filter
  17894. + * rules or simply light the LINK led
  17895. + */
  17896. + void (*link_change)(struct net_device *dev);
  17897. +
  17898. +Functions hard_data_[resume/stop] are optional and should not be used
  17899. +if the driver decides to uses data+management frames enqueue in a
  17900. +single HQ queue (thus using just the softmac_hard_data_start_xmit
  17901. +callback).
  17902. +
  17903. +Function that the driver can use are:
  17904. +
  17905. +ieee80211_get_beacon - this is called by the driver when
  17906. + the HW needs a beacon.
  17907. +ieee80211_softmac_start_protocol - this should normally be called in the
  17908. + driver open function
  17909. +ieee80211_softmac_stop_protocol - the opposite of the above
  17910. +ieee80211_wake_queue - this is similar to netif_wake_queue
  17911. +ieee80211_reset_queue - this throw away fragments pending(if any)
  17912. +ieee80211_stop_queue - this is similar to netif_stop_queue
  17913. +
  17914. +
  17915. +known BUGS:
  17916. +- When performing syncro scan (possiblily when swithcing to ad-hoc mode
  17917. + and when running iwlist scan when associated) there is still an odd
  17918. + behaviour.. I have not looked in this more accurately (yet).
  17919. +
  17920. +locking:
  17921. +locking is done by means of three structures.
  17922. +1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
  17923. +2- ieee->wx_sem
  17924. +3- ieee->scan_sem
  17925. +
  17926. +the lock 1 is what protect most of the critical sections in the ieee stack.
  17927. +the lock 2 is used to avoid that more than one of the SET wireless extension
  17928. +handlers (as well as start/stop protocol function) are running at the same time.
  17929. +the lock 1 is used when we need to modify or read the shared data in the wx handlers.
  17930. +In other words the lock 2 will prevent one SET action will run across another SET
  17931. +action (by make sleep the 2nd one) but allow GET actions, while the lock 1
  17932. +make atomic those little shared data access in both GET and SET operation.
  17933. +So get operation will be never be delayed really: they will never sleep..
  17934. +Furthermore in the top of some SET operations a flag is set before acquiring
  17935. +the lock. This is an help to make the previous running SET operation to
  17936. +finish faster if needed (just in case the second one will totally undo the
  17937. +first, so there is not need to complete the 1st really.. ).
  17938. +The background scanning mechaninsm is protected by the lock 1 except for the
  17939. +workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
  17940. +might be appreciated by USB network card driver developer). In this case the lock 3
  17941. +take its turn.
  17942. +Thus the stop function needs both the locks.
  17943. +Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
  17944. +function and the stop scan function are called with this semaphore held).
  17945. +
  17946. +
  17947. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h
  17948. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 1970-01-01 01:00:00.000000000 +0100
  17949. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 2010-03-06 16:43:22.000000000 +0100
  17950. @@ -0,0 +1,282 @@
  17951. +#ifndef _RTL8187_MESH_H_
  17952. +#define _RTL8187_MESH_H_
  17953. +
  17954. +#include "msh_class.h" // struct mshclass
  17955. +#include "mesh.h" // struct MESH-Neighbor-Entry
  17956. +#include "ieee80211.h" // struct ieee80211-network
  17957. +#include "mesh_8185_util.h" // DOT11-QUEUE
  17958. +#include "hash_table.h" // hash-table
  17959. +#include "8185s_pathsel.h"
  17960. +#include <linux/list.h>
  17961. +
  17962. +#define GET_MESH_PRIV(x) ((struct mshclass_priv *)(x->priv))
  17963. +
  17964. +struct ieee80211_hdr_mesh {
  17965. + u16 frame_ctl;
  17966. + u16 duration_id;
  17967. + u8 addr1[ETH_ALEN];
  17968. + u8 addr2[ETH_ALEN];
  17969. + u8 addr3[ETH_ALEN];
  17970. + u16 seq_ctl;
  17971. + u8 addr4[ETH_ALEN];
  17972. + unsigned char mesh_flag;
  17973. + INT8 TTL;
  17974. + UINT16 segNum;
  17975. + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
  17976. + unsigned char SrcMACAddr[ETH_ALEN];
  17977. +} __attribute__ ((packed));
  17978. +
  17979. +struct myMeshIDNode {
  17980. + struct list_head list;
  17981. + char id[MESH_ID_LEN+1];
  17982. + short popEN;
  17983. + char tried;
  17984. + unsigned long expire;
  17985. + struct ieee80211_network mesh_network;
  17986. +};
  17987. +
  17988. +struct ieee80211_hdr_mesh_QOS {
  17989. + u16 frame_ctl;
  17990. + u16 duration_id;
  17991. + u8 addr1[ETH_ALEN];
  17992. + u8 addr2[ETH_ALEN];
  17993. + u8 addr3[ETH_ALEN];
  17994. + u16 seq_ctl;
  17995. + u8 addr4[ETH_ALEN];
  17996. + u16 QOS_ctl;
  17997. + unsigned char mesh_flag;
  17998. + INT8 TTL;
  17999. + UINT16 segNum;
  18000. + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
  18001. + unsigned char SrcMACAddr[ETH_ALEN];
  18002. +} __attribute__ ((packed));
  18003. +
  18004. +
  18005. +struct mesh_PeerEntry {
  18006. + // based on 8185ag.h
  18007. + struct list_head hash_list;
  18008. + unsigned int used; ///< used == TRUE => has been allocated, \n used == FALSE => can be allocated
  18009. + unsigned char hwaddr[MACADDRLEN]; ///< hardware address
  18010. +
  18011. + // struct list_head mesh_unEstablish_ptr; // 尚未(或從已連線 -> 未連線) 之 MP list
  18012. + struct list_head mesh_mp_ptr; // MP list
  18013. +
  18014. + /*mesh_neighbor:
  18015. + * Inited by "Neighbor Discovering"
  18016. + * cleaned by "Disassociation" or "Expired"
  18017. + */
  18018. + struct MESH_Neighbor_Entry mesh_neighbor_TBL;
  18019. +
  18020. + struct ieee80211_network * pstat; // a backward pointer
  18021. +
  18022. + // 802.11 seq checking
  18023. + u16 last_rxseq; /* rx seq previous per-tid */
  18024. + u16 last_rxfrag;/* tx frag previous per-tid */
  18025. + unsigned long last_time;
  18026. + //
  18027. +};
  18028. +
  18029. +
  18030. +struct mshclass_priv {
  18031. +
  18032. + struct mesh_PeerEntry *meshEntries; // 1-to-1 for priv->ieee80211->networks
  18033. +
  18034. + spinlock_t lock_stainfo; // lock for accessing the data structure of stat info
  18035. + spinlock_t lock_queue; // lock for DOT11_EnQueue2/DOT11_DeQueue2/enque/dequeue
  18036. + spinlock_t lock_Rreq; // lock for rreq_retry. Some function like aodv_expire/tx use lock_queue simultaneously
  18037. +// spinlock_t lock_meshlist;
  18038. +
  18039. + // struct _DOT11_QUEUE *pevent_queue; ///< 802.11 QUEUE結構
  18040. + // struct hash_table *pathsel_table; // GANTOE
  18041. + //tsananiu
  18042. + struct _DOT11_QUEUE *pathsel_queue; ///< 802.11 QUEUE結構
  18043. +
  18044. + //tsananiu end
  18045. +
  18046. + //add by shlu 20070518
  18047. + unsigned char RreqMAC[AODV_RREQ_TABLE_SIZE][6];
  18048. + unsigned int RreqBegin;
  18049. + unsigned int RreqEnd;
  18050. +
  18051. +#if defined(MESH_ROLE_ROOT) || defined(MESH_ROLE_PORTAL)
  18052. +#define MAX_SZ_BAD_MAC 3
  18053. + unsigned char BadMac[MAX_SZ_BAD_MAC][MACADDRLEN];
  18054. + int idx_BadMac;
  18055. +#endif // MESH_ROLE_ROOT || MESH_ROLE_PORTAL
  18056. +
  18057. + //-------------
  18058. + unsigned char root_mac[MACADDRLEN];
  18059. + struct mesh_info dot11MeshInfo; // extrated from wifi_mib (ieee802_mib.h)
  18060. + struct hash_table *proxy_table, *mesh_rreq_retry_queue; //GANTOE //GANTOE
  18061. + struct hash_table *pathsel_table; // add by chuangch 2007.09.13
  18062. + // add by Jason
  18063. + struct mpp_tb *pann_mpp_tb;
  18064. +
  18065. + struct timer_list expire_timer; // 1sec timer
  18066. +
  18067. + struct timer_list beacon_timer; // 1sec timer
  18068. + struct list_head stat_hash[MAX_NETWORK_COUNT]; // sta_info hash table (aid_obj)
  18069. +
  18070. + struct list_head meshList[MAX_CHANNEL_NUMBER];
  18071. + int scanMode;
  18072. +
  18073. + struct {
  18074. + struct ieee80211_network *pstat;
  18075. + unsigned char hwaddr[MACADDRLEN];
  18076. + } stainfo_cache;
  18077. +
  18078. + // The following elements are used by 802.11s.
  18079. + // For copyright-pretection, we use an independent (binary) module.
  18080. + // Note that it can also be put either under r8180_priv or ieee80211_device. The adv of put under
  18081. + // r8180_priv is to get "higher encapsulation". On the other hand, r8180_priv was originally designed
  18082. + // for "hardward specific."
  18083. + char mesh_mac_filter_allow[8][13];
  18084. + char mesh_mac_filter_deny[8][13];
  18085. +
  18086. + struct MESH_Share meshare; // mesh share data
  18087. +
  18088. + struct {
  18089. +
  18090. + int prev_iw_mode; // Save this->iw_mode for r8180_wx->r8180_wx_enable_mesh. No init requirement
  18091. +
  18092. + struct MESH_Profile mesh_profile; // contains MESHID
  18093. +
  18094. + struct mesh_info dot11MeshInfo; // contains meshMaxAssocNum
  18095. +
  18096. + struct net_device_stats mesh_stats;
  18097. +
  18098. + UINT8 mesh_Version; // 使用的版本
  18099. + // WLAN Mesh Capability
  18100. + INT16 mesh_PeerCAP_cap; // peer capability-Cap number (有號數)
  18101. + UINT8 mesh_PeerCAP_flags; // peer capability-flags
  18102. + UINT8 mesh_PowerSaveCAP; // Power Save capability
  18103. + UINT8 mesh_SyncCAP; // Synchronization capability
  18104. + UINT8 mesh_MDA_CAP; // MDA capability
  18105. + UINT32 mesh_ChannelPrecedence; // Channel Precedence
  18106. +
  18107. + // neighbor -> candidate neighbor, if mesh_available_peerlink > 0, page 56, D0.02
  18108. + UINT8 mesh_AvailablePeerLink; // 此是否有需要?(因它等同於 mesh_PeerCAP)=>暫 時保 留
  18109. +
  18110. + UINT8 mesh_HeaderFlags; // mesh header 內的 mesh flags field
  18111. +
  18112. + // MKD domain element [MKDDIE]
  18113. + UINT8 mesh_MKD_DomainID[6];
  18114. + UINT8 mesh_MKDDIE_SecurityConfiguration;
  18115. +
  18116. + // EMSA Handshake element [EMSAIE]
  18117. + UINT8 mesh_EMSAIE_ANonce[32];
  18118. + UINT8 mesh_EMSAIE_SNonce[32];
  18119. + UINT8 mesh_EMSAIE_MA_ID[6];
  18120. + UINT16 mesh_EMSAIE_MIC_Control;
  18121. + UINT8 mesh_EMSAIE_MIC[16];
  18122. +
  18123. + struct timer_list mesh_peer_link_timer; ///< 對尚未連 線(與連線退至未連線) MP mesh_unEstablish_hdr 作 peer link time out
  18124. +
  18125. +// struct timer_list mesh_beacon_timer;
  18126. + // mesh_unEstablish_hdr:
  18127. + // It is a list structure, only stores unEstablish (or Establish -> unEstablish [MP_HOLDING])MP entry
  18128. + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
  18129. + // and removed by successful "Peer link setup" or "Expired"
  18130. + struct list_head mesh_unEstablish_hdr;
  18131. +
  18132. + // mesh_mp_hdr:
  18133. + // It is a list of MP/MAP/MPP who has already passed "Peer link setup"
  18134. + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
  18135. + // Every entry is inserted by "successful peer link setup"
  18136. + // and removed by "Expired"
  18137. + struct list_head mesh_mp_hdr;
  18138. +
  18139. + } mesh;
  18140. +
  18141. + int iCurChannel; // remember the working channel
  18142. +};
  18143. +
  18144. +// Stanley, 04/23/07
  18145. +// The following mode is used by ieee80211_device->iw_mode
  18146. +// Although it is better to put the definition under linux/wireless.h (or wireless_copy.h), it is a system file
  18147. +// that we shouldn't modify directly.
  18148. +#define IW_MODE_MESH 11 /* 802.11s mesh mode */
  18149. +
  18150. +// Default MESHID
  18151. +#define IEEE80211S_DEFAULT_MESHID "802.11s"
  18152. +
  18153. +// callback for 802.11s
  18154. +extern short rtl8187_patch_ieee80211_probe_req_1 (struct ieee80211_device *ieee);
  18155. +extern u8* rtl8187_patch_ieee80211_probe_req_2 (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag);
  18156. +
  18157. +// wx
  18158. +extern int rtl8187_patch_r8180_wx_get_meshinfo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18159. +extern int rtl8187_patch_r8180_wx_enable_mesh(struct net_device *dev);
  18160. +extern int rtl8187_patch_r8180_wx_disable_mesh(struct net_device *dev);
  18161. +extern int rtl8187_patch_r8180_wx_wx_set_meshID(struct net_device *dev, char *ext,unsigned char channel);
  18162. +extern void rtl8187_patch_r8180_wx_set_channel (struct ieee80211_device *ieee, int ch);
  18163. +extern int rtl8187_patch_r8180_wx_set_add_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18164. +extern int rtl8187_patch_r8180_wx_set_del_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18165. +extern int rtl8187_patch_r8180_wx_set_add_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18166. +extern int rtl8187_patch_r8180_wx_set_del_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18167. +extern int rtl8187_patch_r8180_wx_get_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18168. +extern int rtl8187_patch_r8180_wx_get_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18169. +
  18170. +extern int rtl8187_patch_r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18171. +extern int rtl8187_patch_r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18172. +extern int rtl8187_patch_r8180_wx_get_selected_mesh(struct net_device *dev, int en, char *cho, char* id);
  18173. +//by amy for networkmanager UI
  18174. +extern int rtl8187_patch_r8180_wx_get_selected_mesh_channel(struct net_device *dev, char *extmeshid, char *cho);
  18175. +//by amy for networkmanager UI
  18176. +// osdep
  18177. +extern int rtl8187_patch_ieee80211_start_protocol (struct ieee80211_device *ieee);
  18178. +extern u8 rtl8187_patch_rtl8180_up(struct mshclass *priv);
  18179. +extern void rtl8187_patch_ieee80211_stop_protocol(struct ieee80211_device *ieee);
  18180. +
  18181. +// issue_assocreq_MP
  18182. +extern void rtl8187_patch_ieee80211_association_req_1 (struct ieee80211_assoc_request_frame *hdr);
  18183. +extern u8* rtl8187_patch_ieee80211_association_req_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  18184. +
  18185. +// OnAssocReq_MP
  18186. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_req (struct ieee80211_device *ieee, struct sk_buff *skb);
  18187. +
  18188. +// issue_assocrsp_MP
  18189. +extern void rtl8187_patch_ieee80211_assoc_resp_by_net_1 (struct ieee80211_assoc_response_frame *assoc);
  18190. +u8* rtl8187_patch_ieee80211_assoc_resp_by_net_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  18191. +
  18192. +// OnAssocRsp_MP
  18193. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_rsp (struct ieee80211_device *ieee, struct sk_buff *skb);
  18194. +
  18195. +
  18196. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_auth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18197. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_deauth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18198. +extern unsigned int rtl8187_patch_ieee80211_process_probe_response_1( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  18199. +extern void rtl8187_patch_ieee80211_rx_mgt_on_probe_req( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  18200. +extern void rtl8187_patch_ieee80211_rx_mgt_update_expire ( struct ieee80211_device *ieee, struct sk_buff *skb);
  18201. +
  18202. +// set channel
  18203. +extern int rtl8187_patch_ieee80211_ext_stop_scan_wq_set_channel (struct ieee80211_device *ieee);
  18204. +
  18205. +// on rx (rx isr)
  18206. +extern int rtl8187_patch_ieee80211_rx_on_rx (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
  18207. +
  18208. +// r8187_core
  18209. +// handle ioctl
  18210. +extern int rtl8187_patch_rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
  18211. +// create proc
  18212. +extern void rtl8187_patch_create_proc(struct r8180_priv *priv);
  18213. +extern void rtl8187_patch_remove_proc(struct r8180_priv *priv);
  18214. +
  18215. +// tx, xmit
  18216. +// locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  18217. +extern struct ieee80211_txb* rtl8187_patch_ieee80211_xmit (struct sk_buff *skb, struct net_device *dev);
  18218. +
  18219. +// given a skb, output header's length
  18220. +extern int rtl8187_patch_ieee80211_rx_frame_get_hdrlen (struct ieee80211_device *ieee, struct sk_buff *skb);
  18221. +
  18222. +// check the frame control field, return 0: not accept, 1: accept
  18223. +extern int rtl8187_patch_ieee80211_rx_is_valid_framectl (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  18224. +
  18225. +// process_dataframe
  18226. +extern int rtl8187_patch_ieee80211_rx_process_dataframe (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18227. +
  18228. +extern int rtl8187_patch_is_duplicate_packet (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  18229. +
  18230. +extern int rtl8187_patch_ieee80211_softmac_xmit_get_rate (struct ieee80211_device *ieee, struct sk_buff *skb);
  18231. +extern void ieee80211_start_mesh(struct ieee80211_device *ieee);
  18232. +#endif // _RTL8187_MESH_H_
  18233. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h
  18234. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 1970-01-01 01:00:00.000000000 +0100
  18235. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 2010-03-06 16:43:22.000000000 +0100
  18236. @@ -0,0 +1,399 @@
  18237. +/*
  18238. + * Scatterlist Cryptographic API.
  18239. + *
  18240. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  18241. + * Copyright (c) 2002 David S. Miller (davem@redhat.com)
  18242. + *
  18243. + * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
  18244. + * and Nettle, by Niels M敿ēer.
  18245. + *
  18246. + * This program is free software; you can redistribute it and/or modify it
  18247. + * under the terms of the GNU General Public License as published by the Free
  18248. + * Software Foundation; either version 2 of the License, or (at your option)
  18249. + * any later version.
  18250. + *
  18251. + */
  18252. +#ifndef _LINUX_CRYPTO_H
  18253. +#define _LINUX_CRYPTO_H
  18254. +
  18255. +#include <linux/module.h>
  18256. +#include <linux/kernel.h>
  18257. +#include <linux/types.h>
  18258. +#include <linux/list.h>
  18259. +#include <linux/string.h>
  18260. +#include <asm/page.h>
  18261. +#include <asm/errno.h>
  18262. +
  18263. +#define crypto_register_alg crypto_register_alg_rtl
  18264. +#define crypto_unregister_alg crypto_unregister_alg_rtl
  18265. +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
  18266. +#define crypto_free_tfm crypto_free_tfm_rtl
  18267. +#define crypto_alg_available crypto_alg_available_rtl
  18268. +
  18269. +/*
  18270. + * Algorithm masks and types.
  18271. + */
  18272. +#define CRYPTO_ALG_TYPE_MASK 0x000000ff
  18273. +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
  18274. +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
  18275. +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
  18276. +
  18277. +/*
  18278. + * Transform masks and values (for crt_flags).
  18279. + */
  18280. +#define CRYPTO_TFM_MODE_MASK 0x000000ff
  18281. +#define CRYPTO_TFM_REQ_MASK 0x000fff00
  18282. +#define CRYPTO_TFM_RES_MASK 0xfff00000
  18283. +
  18284. +#define CRYPTO_TFM_MODE_ECB 0x00000001
  18285. +#define CRYPTO_TFM_MODE_CBC 0x00000002
  18286. +#define CRYPTO_TFM_MODE_CFB 0x00000004
  18287. +#define CRYPTO_TFM_MODE_CTR 0x00000008
  18288. +
  18289. +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
  18290. +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
  18291. +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
  18292. +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
  18293. +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
  18294. +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
  18295. +
  18296. +/*
  18297. + * Miscellaneous stuff.
  18298. + */
  18299. +#define CRYPTO_UNSPEC 0
  18300. +#define CRYPTO_MAX_ALG_NAME 64
  18301. +
  18302. +struct scatterlist;
  18303. +
  18304. +/*
  18305. + * Algorithms: modular crypto algorithm implementations, managed
  18306. + * via crypto_register_alg() and crypto_unregister_alg().
  18307. + */
  18308. +struct cipher_alg {
  18309. + unsigned int cia_min_keysize;
  18310. + unsigned int cia_max_keysize;
  18311. + int (*cia_setkey)(void *ctx, const u8 *key,
  18312. + unsigned int keylen, u32 *flags);
  18313. + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
  18314. + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
  18315. +};
  18316. +
  18317. +struct digest_alg {
  18318. + unsigned int dia_digestsize;
  18319. + void (*dia_init)(void *ctx);
  18320. + void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
  18321. + void (*dia_final)(void *ctx, u8 *out);
  18322. + int (*dia_setkey)(void *ctx, const u8 *key,
  18323. + unsigned int keylen, u32 *flags);
  18324. +};
  18325. +
  18326. +struct compress_alg {
  18327. + int (*coa_init)(void *ctx);
  18328. + void (*coa_exit)(void *ctx);
  18329. + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
  18330. + u8 *dst, unsigned int *dlen);
  18331. + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
  18332. + u8 *dst, unsigned int *dlen);
  18333. +};
  18334. +
  18335. +#define cra_cipher cra_u.cipher
  18336. +#define cra_digest cra_u.digest
  18337. +#define cra_compress cra_u.compress
  18338. +
  18339. +struct crypto_alg {
  18340. + struct list_head cra_list;
  18341. + u32 cra_flags;
  18342. + unsigned int cra_blocksize;
  18343. + unsigned int cra_ctxsize;
  18344. + const char cra_name[CRYPTO_MAX_ALG_NAME];
  18345. +
  18346. + union {
  18347. + struct cipher_alg cipher;
  18348. + struct digest_alg digest;
  18349. + struct compress_alg compress;
  18350. + } cra_u;
  18351. +
  18352. + struct module *cra_module;
  18353. +};
  18354. +
  18355. +/*
  18356. + * Algorithm registration interface.
  18357. + */
  18358. +int crypto_register_alg(struct crypto_alg *alg);
  18359. +int crypto_unregister_alg(struct crypto_alg *alg);
  18360. +
  18361. +/*
  18362. + * Algorithm query interface.
  18363. + */
  18364. +int crypto_alg_available(const char *name, u32 flags);
  18365. +
  18366. +/*
  18367. + * Transforms: user-instantiated objects which encapsulate algorithms
  18368. + * and core processing logic. Managed via crypto_alloc_tfm() and
  18369. + * crypto_free_tfm(), as well as the various helpers below.
  18370. + */
  18371. +struct crypto_tfm;
  18372. +
  18373. +struct cipher_tfm {
  18374. + void *cit_iv;
  18375. + unsigned int cit_ivsize;
  18376. + u32 cit_mode;
  18377. + int (*cit_setkey)(struct crypto_tfm *tfm,
  18378. + const u8 *key, unsigned int keylen);
  18379. + int (*cit_encrypt)(struct crypto_tfm *tfm,
  18380. + struct scatterlist *dst,
  18381. + struct scatterlist *src,
  18382. + unsigned int nbytes);
  18383. + int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
  18384. + struct scatterlist *dst,
  18385. + struct scatterlist *src,
  18386. + unsigned int nbytes, u8 *iv);
  18387. + int (*cit_decrypt)(struct crypto_tfm *tfm,
  18388. + struct scatterlist *dst,
  18389. + struct scatterlist *src,
  18390. + unsigned int nbytes);
  18391. + int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
  18392. + struct scatterlist *dst,
  18393. + struct scatterlist *src,
  18394. + unsigned int nbytes, u8 *iv);
  18395. + void (*cit_xor_block)(u8 *dst, const u8 *src);
  18396. +};
  18397. +
  18398. +struct digest_tfm {
  18399. + void (*dit_init)(struct crypto_tfm *tfm);
  18400. + void (*dit_update)(struct crypto_tfm *tfm,
  18401. + struct scatterlist *sg, unsigned int nsg);
  18402. + void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
  18403. + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
  18404. + unsigned int nsg, u8 *out);
  18405. + int (*dit_setkey)(struct crypto_tfm *tfm,
  18406. + const u8 *key, unsigned int keylen);
  18407. +#ifdef CONFIG_CRYPTO_HMAC
  18408. + void *dit_hmac_block;
  18409. +#endif
  18410. +};
  18411. +
  18412. +struct compress_tfm {
  18413. + int (*cot_compress)(struct crypto_tfm *tfm,
  18414. + const u8 *src, unsigned int slen,
  18415. + u8 *dst, unsigned int *dlen);
  18416. + int (*cot_decompress)(struct crypto_tfm *tfm,
  18417. + const u8 *src, unsigned int slen,
  18418. + u8 *dst, unsigned int *dlen);
  18419. +};
  18420. +
  18421. +#define crt_cipher crt_u.cipher
  18422. +#define crt_digest crt_u.digest
  18423. +#define crt_compress crt_u.compress
  18424. +
  18425. +struct crypto_tfm {
  18426. +
  18427. + u32 crt_flags;
  18428. +
  18429. + union {
  18430. + struct cipher_tfm cipher;
  18431. + struct digest_tfm digest;
  18432. + struct compress_tfm compress;
  18433. + } crt_u;
  18434. +
  18435. + struct crypto_alg *__crt_alg;
  18436. +};
  18437. +
  18438. +/*
  18439. + * Transform user interface.
  18440. + */
  18441. +
  18442. +/*
  18443. + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
  18444. + * If that fails and the kernel supports dynamically loadable modules, it
  18445. + * will then attempt to load a module of the same name or alias. A refcount
  18446. + * is grabbed on the algorithm which is then associated with the new transform.
  18447. + *
  18448. + * crypto_free_tfm() frees up the transform and any associated resources,
  18449. + * then drops the refcount on the associated algorithm.
  18450. + */
  18451. +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
  18452. +void crypto_free_tfm(struct crypto_tfm *tfm);
  18453. +
  18454. +/*
  18455. + * Transform helpers which query the underlying algorithm.
  18456. + */
  18457. +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
  18458. +{
  18459. + return tfm->__crt_alg->cra_name;
  18460. +}
  18461. +
  18462. +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
  18463. +{
  18464. + struct crypto_alg *alg = tfm->__crt_alg;
  18465. +
  18466. + if (alg->cra_module)
  18467. + return alg->cra_module->name;
  18468. + else
  18469. + return NULL;
  18470. +}
  18471. +
  18472. +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
  18473. +{
  18474. + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
  18475. +}
  18476. +
  18477. +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
  18478. +{
  18479. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18480. + return tfm->__crt_alg->cra_cipher.cia_min_keysize;
  18481. +}
  18482. +
  18483. +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
  18484. +{
  18485. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18486. + return tfm->__crt_alg->cra_cipher.cia_max_keysize;
  18487. +}
  18488. +
  18489. +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
  18490. +{
  18491. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18492. + return tfm->crt_cipher.cit_ivsize;
  18493. +}
  18494. +
  18495. +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
  18496. +{
  18497. + return tfm->__crt_alg->cra_blocksize;
  18498. +}
  18499. +
  18500. +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
  18501. +{
  18502. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18503. + return tfm->__crt_alg->cra_digest.dia_digestsize;
  18504. +}
  18505. +
  18506. +/*
  18507. + * API wrappers.
  18508. + */
  18509. +static inline void crypto_digest_init(struct crypto_tfm *tfm)
  18510. +{
  18511. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18512. + tfm->crt_digest.dit_init(tfm);
  18513. +}
  18514. +
  18515. +static inline void crypto_digest_update(struct crypto_tfm *tfm,
  18516. + struct scatterlist *sg,
  18517. + unsigned int nsg)
  18518. +{
  18519. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18520. + tfm->crt_digest.dit_update(tfm, sg, nsg);
  18521. +}
  18522. +
  18523. +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
  18524. +{
  18525. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18526. + tfm->crt_digest.dit_final(tfm, out);
  18527. +}
  18528. +
  18529. +static inline void crypto_digest_digest(struct crypto_tfm *tfm,
  18530. + struct scatterlist *sg,
  18531. + unsigned int nsg, u8 *out)
  18532. +{
  18533. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18534. + tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
  18535. +}
  18536. +
  18537. +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
  18538. + const u8 *key, unsigned int keylen)
  18539. +{
  18540. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  18541. + if (tfm->crt_digest.dit_setkey == NULL)
  18542. + return -ENOSYS;
  18543. + return tfm->crt_digest.dit_setkey(tfm, key, keylen);
  18544. +}
  18545. +
  18546. +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
  18547. + const u8 *key, unsigned int keylen)
  18548. +{
  18549. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18550. + return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
  18551. +}
  18552. +
  18553. +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
  18554. + struct scatterlist *dst,
  18555. + struct scatterlist *src,
  18556. + unsigned int nbytes)
  18557. +{
  18558. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18559. + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
  18560. +}
  18561. +
  18562. +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
  18563. + struct scatterlist *dst,
  18564. + struct scatterlist *src,
  18565. + unsigned int nbytes, u8 *iv)
  18566. +{
  18567. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18568. + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
  18569. + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
  18570. +}
  18571. +
  18572. +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
  18573. + struct scatterlist *dst,
  18574. + struct scatterlist *src,
  18575. + unsigned int nbytes)
  18576. +{
  18577. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18578. + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
  18579. +}
  18580. +
  18581. +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
  18582. + struct scatterlist *dst,
  18583. + struct scatterlist *src,
  18584. + unsigned int nbytes, u8 *iv)
  18585. +{
  18586. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18587. + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
  18588. + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
  18589. +}
  18590. +
  18591. +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
  18592. + const u8 *src, unsigned int len)
  18593. +{
  18594. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18595. + memcpy(tfm->crt_cipher.cit_iv, src, len);
  18596. +}
  18597. +
  18598. +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
  18599. + u8 *dst, unsigned int len)
  18600. +{
  18601. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  18602. + memcpy(dst, tfm->crt_cipher.cit_iv, len);
  18603. +}
  18604. +
  18605. +static inline int crypto_comp_compress(struct crypto_tfm *tfm,
  18606. + const u8 *src, unsigned int slen,
  18607. + u8 *dst, unsigned int *dlen)
  18608. +{
  18609. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
  18610. + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
  18611. +}
  18612. +
  18613. +static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
  18614. + const u8 *src, unsigned int slen,
  18615. + u8 *dst, unsigned int *dlen)
  18616. +{
  18617. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
  18618. + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
  18619. +}
  18620. +
  18621. +/*
  18622. + * HMAC support.
  18623. + */
  18624. +#ifdef CONFIG_CRYPTO_HMAC
  18625. +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
  18626. +void crypto_hmac_update(struct crypto_tfm *tfm,
  18627. + struct scatterlist *sg, unsigned int nsg);
  18628. +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
  18629. + unsigned int *keylen, u8 *out);
  18630. +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
  18631. + struct scatterlist *sg, unsigned int nsg, u8 *out);
  18632. +#endif /* CONFIG_CRYPTO_HMAC */
  18633. +
  18634. +#endif /* _LINUX_CRYPTO_H */
  18635. +
  18636. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
  18637. --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 1970-01-01 01:00:00.000000000 +0100
  18638. +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 2010-03-06 16:43:22.000000000 +0100
  18639. @@ -0,0 +1,51 @@
  18640. +/*
  18641. + * Cryptographic API.
  18642. + *
  18643. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  18644. + * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
  18645. + * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
  18646. + *
  18647. + * This program is free software; you can redistribute it and/or modify it
  18648. + * under the terms of the GNU General Public License as published by the Free
  18649. + * Software Foundation; either version 2 of the License, or (at your option)
  18650. + * any later version.
  18651. + *
  18652. + */
  18653. +
  18654. +#ifndef _CRYPTO_SCATTERWALK_H
  18655. +#define _CRYPTO_SCATTERWALK_H
  18656. +#include <linux/mm.h>
  18657. +#include <asm/scatterlist.h>
  18658. +
  18659. +struct scatter_walk {
  18660. + struct scatterlist *sg;
  18661. + struct page *page;
  18662. + void *data;
  18663. + unsigned int len_this_page;
  18664. + unsigned int len_this_segment;
  18665. + unsigned int offset;
  18666. +};
  18667. +
  18668. +/* Define sg_next is an inline routine now in case we want to change
  18669. + scatterlist to a linked list later. */
  18670. +static inline struct scatterlist *sg_next(struct scatterlist *sg)
  18671. +{
  18672. + return sg + 1;
  18673. +}
  18674. +
  18675. +static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
  18676. + struct scatter_walk *walk_out,
  18677. + void *src_p, void *dst_p)
  18678. +{
  18679. + return walk_in->page == walk_out->page &&
  18680. + walk_in->offset == walk_out->offset &&
  18681. + walk_in->data == src_p && walk_out->data == dst_p;
  18682. +}
  18683. +
  18684. +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
  18685. +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
  18686. +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
  18687. +void scatterwalk_map(struct scatter_walk *walk, int out);
  18688. +void scatterwalk_done(struct scatter_walk *walk, int out, int more);
  18689. +
  18690. +#endif /* _CRYPTO_SCATTERWALK_H */
  18691. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/Makefile linux-lemote/drivers/net/wireless/rtl8187b/Makefile
  18692. --- linux-2.6.33/drivers/net/wireless/rtl8187b/Makefile 1970-01-01 01:00:00.000000000 +0100
  18693. +++ linux-lemote/drivers/net/wireless/rtl8187b/Makefile 2010-03-06 16:43:22.000000000 +0100
  18694. @@ -0,0 +1,41 @@
  18695. +obj-$(CONFIG_RTL8187B) += rtl8187b.o
  18696. +
  18697. +rtl8187b-objs := r8187_core.o \
  18698. + r8180_93cx6.o \
  18699. + r8180_wx.o \
  18700. + r8180_rtl8225.o \
  18701. + r8180_rtl8225z2.o \
  18702. + r8180_pm.o \
  18703. + r8180_dm.o \
  18704. + r8187_led.o \
  18705. + r8187_rfkill.o \
  18706. + ieee80211/dot11d.o \
  18707. + ieee80211/ieee80211_softmac.o \
  18708. + ieee80211/ieee80211_rx.o \
  18709. + ieee80211/ieee80211_tx.o \
  18710. + ieee80211/ieee80211_wx.o \
  18711. + ieee80211/ieee80211_module.o \
  18712. + ieee80211/ieee80211_softmac_wx.o \
  18713. + ieee80211/ieee80211_crypt.o \
  18714. + ieee80211/ieee80211_crypt_tkip.o \
  18715. + ieee80211/ieee80211_crypt_ccmp.o \
  18716. + ieee80211/ieee80211_crypt_wep.o
  18717. +
  18718. +EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
  18719. +EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
  18720. +EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
  18721. +EXTRA_CFLAGS += -DJOHN_IOCTL
  18722. +EXTRA_CFLAGS += -DLED
  18723. +#EXTRA_CFLAGS += -DLED_SHIN
  18724. +#EXTRA_CFLAGS += -DSW_ANTE_DIVERSITY
  18725. +EXTRA_CFLAGS += -DCPU_64BIT
  18726. +EXTRA_CFLAGS += -DCONFIG_IPS
  18727. +#CFLAGS += -DJOHN_HWSEC -DJOHN_TKIP
  18728. +#CFLAGS += -DJOHN_DUMP_TX
  18729. +#EXTRA_CFLAGS += -DJOHN_DUMP_TXPKT
  18730. +
  18731. +#Radio On/Off debug
  18732. +#EXTRA_CFLAGS += -DCONFIG_RADIO_DEBUG
  18733. +
  18734. +#for dot11d
  18735. +EXTRA_CFLAGS += -DENABLE_DOT11D
  18736. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/msh_class.h linux-lemote/drivers/net/wireless/rtl8187b/msh_class.h
  18737. --- linux-2.6.33/drivers/net/wireless/rtl8187b/msh_class.h 1970-01-01 01:00:00.000000000 +0100
  18738. +++ linux-lemote/drivers/net/wireless/rtl8187b/msh_class.h 2010-03-06 16:43:22.000000000 +0100
  18739. @@ -0,0 +1,117 @@
  18740. +/*! \file msh_class.h
  18741. + \brief msh CLASS extension
  18742. +
  18743. + \date 2007/5/2
  18744. + \author Stanley Chang <chagnsl@cs.nctu.edu.tw>
  18745. +*/
  18746. +
  18747. +#ifndef _MESH_CLASS_HDR_H_
  18748. +#define _MESH_CLASS_HDR_H_
  18749. +
  18750. +#include <linux/if_ether.h> /* ETH_ALEN */
  18751. +#include <linux/kernel.h> /* ARRAY_SIZE */
  18752. +#include <linux/version.h>
  18753. +#include <linux/jiffies.h>
  18754. +#include <linux/timer.h>
  18755. +#include <linux/sched.h>
  18756. +
  18757. +#include "ieee80211/ieee80211.h" // for struct ieee80211-xxxx
  18758. +#include "r8187.h" // for struct r8180-priv
  18759. +
  18760. +#define MAC_TABLE_SIZE 8
  18761. +
  18762. +struct mshclass {
  18763. + struct r8180_priv * p8187;
  18764. +
  18765. + // callback functions
  18766. + // ieee80211_softmac.c
  18767. + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
  18768. +
  18769. + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
  18770. + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
  18771. +
  18772. + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
  18773. + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  18774. +
  18775. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
  18776. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
  18777. +
  18778. + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
  18779. +
  18780. + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
  18781. + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  18782. +
  18783. + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
  18784. +
  18785. + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  18786. +
  18787. + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
  18788. + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18789. + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18790. +//by amy for mesh
  18791. + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
  18792. +//by amy for mesh
  18793. + /// r8180_wx.c
  18794. + int (*ext_patch_r8180_wx_get_meshinfo) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18795. + int (*ext_patch_r8180_wx_enable_mesh) (struct net_device *dev);
  18796. + int (*ext_patch_r8180_wx_disable_mesh) (struct net_device *dev);
  18797. + int (*ext_patch_r8180_wx_set_meshID) ( struct net_device *dev, char *ext);
  18798. +//by amy for mesh
  18799. + int (*ext_patch_r8180_wx_set_mesh_chan)(struct net_device *dev, unsigned char channel);
  18800. +//by amy for mesh
  18801. + void (*ext_patch_r8180_wx_set_channel) (struct ieee80211_device *ieee, int ch);
  18802. +
  18803. + int (*ext_patch_r8180_wx_set_add_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18804. + int (*ext_patch_r8180_wx_set_del_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18805. + int (*ext_patch_r8180_wx_set_add_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18806. + int (*ext_patch_r8180_wx_set_del_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18807. + int (*ext_patch_r8180_wx_get_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18808. + int (*ext_patch_r8180_wx_get_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18809. +
  18810. + int (*ext_patch_r8180_wx_get_mesh_list) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18811. + int (*ext_patch_r8180_wx_mesh_scan) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  18812. + int (*ext_patch_r8180_wx_get_selected_mesh)(struct net_device *dev, int en, char *cho, char* id);
  18813. +//by amy for networkmanager UI
  18814. + int (*ext_patch_r8180_wx_get_selected_mesh_channel)(struct net_device *dev, char* extmeshid, char *cho);
  18815. +//by amy for networkmanager UI
  18816. + /// r8187_core.c
  18817. + u8 (*ext_patch_rtl8180_up) (struct mshclass *priv);
  18818. +
  18819. + // ieee80211_rx.c
  18820. + unsigned int (*ext_patch_ieee80211_process_probe_response_1) ( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  18821. + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  18822. +
  18823. + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
  18824. +
  18825. + int (*ext_patch_ieee80211_rx_on_rx) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype);
  18826. +
  18827. + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
  18828. +
  18829. + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  18830. +
  18831. + // return > 0 is success. 0 when failed
  18832. + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  18833. +
  18834. + int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  18835. + /* added by david for setting acl dynamically */
  18836. + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
  18837. +
  18838. + // r8187_core.c
  18839. + int (*ext_patch_rtl8180_ioctl) (struct net_device *dev, struct ifreq *rq, int cmd);
  18840. + void (*ext_patch_create_proc) (struct r8180_priv *priv);
  18841. + void (*ext_patch_remove_proc) (struct r8180_priv *priv);
  18842. +
  18843. + // ieee80211_tx.c
  18844. +
  18845. + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  18846. + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
  18847. +
  18848. + // DO NOT MODIFY ANY STRUCTURE BELOW THIS LINE
  18849. + u8 priv[0]; // mshclass_priv;
  18850. +};
  18851. +
  18852. +extern void free_mshobj(struct mshclass **pObj);
  18853. +extern struct mshclass *alloc_mshobj(struct r8180_priv *caller_priv);
  18854. +
  18855. +
  18856. +#endif // _MESH_CLASS_HDR_H_
  18857. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.c
  18858. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.c 1970-01-01 01:00:00.000000000 +0100
  18859. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.c 2010-03-06 16:43:22.000000000 +0100
  18860. @@ -0,0 +1,146 @@
  18861. +/*
  18862. + This files contains card eeprom (93c46 or 93c56) programming routines,
  18863. + memory is addressed by 16 bits words.
  18864. +
  18865. + This is part of rtl8180 OpenSource driver.
  18866. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  18867. + Released under the terms of GPL (General Public Licence)
  18868. +
  18869. + Parts of this driver are based on the GPL part of the
  18870. + official realtek driver.
  18871. +
  18872. + Parts of this driver are based on the rtl8180 driver skeleton
  18873. + from Patric Schenke & Andres Salomon.
  18874. +
  18875. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  18876. +
  18877. + We want to tanks the Authors of those projects and the Ndiswrapper
  18878. + project Authors.
  18879. +*/
  18880. +
  18881. +#include "r8180_93cx6.h"
  18882. +
  18883. +void eprom_cs(struct net_device *dev, short bit)
  18884. +{
  18885. + if(bit)
  18886. + write_nic_byte(dev, EPROM_CMD,
  18887. + (1<<EPROM_CS_SHIFT) | \
  18888. + read_nic_byte(dev, EPROM_CMD)); //enable EPROM
  18889. + else
  18890. + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
  18891. + &~(1<<EPROM_CS_SHIFT)); //disable EPROM
  18892. +
  18893. + force_pci_posting(dev);
  18894. + udelay(EPROM_DELAY);
  18895. +}
  18896. +
  18897. +
  18898. +void eprom_ck_cycle(struct net_device *dev)
  18899. +{
  18900. + write_nic_byte(dev, EPROM_CMD,
  18901. + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
  18902. + force_pci_posting(dev);
  18903. + udelay(EPROM_DELAY);
  18904. + write_nic_byte(dev, EPROM_CMD,
  18905. + read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
  18906. + force_pci_posting(dev);
  18907. + udelay(EPROM_DELAY);
  18908. +}
  18909. +
  18910. +
  18911. +void eprom_w(struct net_device *dev,short bit)
  18912. +{
  18913. + if(bit)
  18914. + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
  18915. + read_nic_byte(dev,EPROM_CMD));
  18916. + else
  18917. + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
  18918. + &~(1<<EPROM_W_SHIFT));
  18919. +
  18920. + force_pci_posting(dev);
  18921. + udelay(EPROM_DELAY);
  18922. +}
  18923. +
  18924. +
  18925. +short eprom_r(struct net_device *dev)
  18926. +{
  18927. + short bit;
  18928. +
  18929. + bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
  18930. + udelay(EPROM_DELAY);
  18931. +
  18932. + if(bit) return 1;
  18933. + return 0;
  18934. +}
  18935. +
  18936. +
  18937. +void eprom_send_bits_string(struct net_device *dev, short b[], int len)
  18938. +{
  18939. + int i;
  18940. +
  18941. + for(i=0; i<len; i++){
  18942. + eprom_w(dev, b[i]);
  18943. + eprom_ck_cycle(dev);
  18944. + }
  18945. +}
  18946. +
  18947. +
  18948. +u32 eprom_read(struct net_device *dev, u32 addr)
  18949. +{
  18950. + struct r8180_priv *priv = ieee80211_priv(dev);
  18951. + short read_cmd[]={1,1,0};
  18952. + short addr_str[8];
  18953. + int i;
  18954. + int addr_len;
  18955. + u32 ret;
  18956. +
  18957. + ret=0;
  18958. + //enable EPROM programming
  18959. + write_nic_byte(dev, EPROM_CMD,
  18960. + (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
  18961. + force_pci_posting(dev);
  18962. + udelay(EPROM_DELAY);
  18963. +
  18964. + if (priv->epromtype==EPROM_93c56){
  18965. + addr_str[7]=addr & 1;
  18966. + addr_str[6]=addr & (1<<1);
  18967. + addr_str[5]=addr & (1<<2);
  18968. + addr_str[4]=addr & (1<<3);
  18969. + addr_str[3]=addr & (1<<4);
  18970. + addr_str[2]=addr & (1<<5);
  18971. + addr_str[1]=addr & (1<<6);
  18972. + addr_str[0]=addr & (1<<7);
  18973. + addr_len=8;
  18974. + }else{
  18975. + addr_str[5]=addr & 1;
  18976. + addr_str[4]=addr & (1<<1);
  18977. + addr_str[3]=addr & (1<<2);
  18978. + addr_str[2]=addr & (1<<3);
  18979. + addr_str[1]=addr & (1<<4);
  18980. + addr_str[0]=addr & (1<<5);
  18981. + addr_len=6;
  18982. + }
  18983. + eprom_cs(dev, 1);
  18984. + eprom_ck_cycle(dev);
  18985. + eprom_send_bits_string(dev, read_cmd, 3);
  18986. + eprom_send_bits_string(dev, addr_str, addr_len);
  18987. +
  18988. + //keep chip pin D to low state while reading.
  18989. + //I'm unsure if it is necessary, but anyway shouldn't hurt
  18990. + eprom_w(dev, 0);
  18991. +
  18992. + for(i=0;i<16;i++){
  18993. + //eeprom needs a clk cycle between writing opcode&adr
  18994. + //and reading data. (eeprom outs a dummy 0)
  18995. + eprom_ck_cycle(dev);
  18996. + ret |= (eprom_r(dev)<<(15-i));
  18997. + }
  18998. +
  18999. + eprom_cs(dev, 0);
  19000. + eprom_ck_cycle(dev);
  19001. +
  19002. + //disable EPROM programming
  19003. + write_nic_byte(dev, EPROM_CMD,
  19004. + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
  19005. + return ret;
  19006. +}
  19007. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.h
  19008. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.h 1970-01-01 01:00:00.000000000 +0100
  19009. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.h 2010-03-06 16:43:22.000000000 +0100
  19010. @@ -0,0 +1,46 @@
  19011. +/*
  19012. + This is part of rtl8187 OpenSource driver
  19013. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  19014. + Released under the terms of GPL (General Public Licence)
  19015. +
  19016. + Parts of this driver are based on the GPL part of the official realtek driver
  19017. + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
  19018. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  19019. +
  19020. + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
  19021. +*/
  19022. +
  19023. +/*This files contains card eeprom (93c46 or 93c56) programming routines*/
  19024. +/*memory is addressed by WORDS*/
  19025. +
  19026. +#include "r8187.h"
  19027. +#include "r8180_hw.h"
  19028. +
  19029. +#define EPROM_DELAY 10
  19030. +
  19031. +#define EPROM_ANAPARAM_ADDRLWORD 0xd
  19032. +#define EPROM_ANAPARAM_ADDRHWORD 0xe
  19033. +
  19034. +#define EPROM_CHANNEL_PLAN 0x3 //0x6>>1
  19035. +//0x77 BIT[0]0:use gpio 1 bit 1, 1:use gpio 1 bit 2.
  19036. +#define EPROM_SELECT_GPIO (0x77 >> 1)
  19037. +//#define EEPROM_COUNTRY_CODE 0x2E//87se channel plan is here
  19038. +
  19039. +#define EPROM_RFCHIPID 0x6
  19040. +#define EPROM_TXPW_BASE 0x05
  19041. +#define EPROM_RFCHIPID_RTL8225U 5
  19042. +#define EPROM_RFCHIPID_RTL8225U_VF 6
  19043. +#define EPROM_RF_PARAM 0x4
  19044. +#define EPROM_CONFIG2 0xc
  19045. +
  19046. +#define EPROM_VERSION 0x1E
  19047. +#define MAC_ADR 0x7
  19048. +
  19049. +#define CIS 0x18
  19050. +
  19051. +#define EPROM_TXPW0 0x16
  19052. +#define EPROM_TXPW2 0x1b
  19053. +#define EPROM_TXPW1 0x3d
  19054. +
  19055. +
  19056. +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
  19057. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.c
  19058. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.c 1970-01-01 01:00:00.000000000 +0100
  19059. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.c 2010-03-06 16:43:22.000000000 +0100
  19060. @@ -0,0 +1,882 @@
  19061. +/*++
  19062. +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
  19063. +
  19064. +Module Name:
  19065. + r8180_dig.c
  19066. +
  19067. +Abstract:
  19068. + Hardware dynamic mechanism for RTL8187B
  19069. +
  19070. +Major Change History:
  19071. + When Who What
  19072. + ---------- --------------- -------------------------------
  19073. + 2006-11-15 david Created
  19074. +
  19075. +Notes:
  19076. + This file is ported from RTL8187B Windows driver.
  19077. +
  19078. +
  19079. +--*/
  19080. +#include "r8180_dm.h"
  19081. +#include "r8180_hw.h"
  19082. +#include "r8180_rtl8225.h"
  19083. +
  19084. +//================================================================================
  19085. +// Local Constant.
  19086. +//================================================================================
  19087. +#define Z1_HIPWR_UPPER_TH 99
  19088. +#define Z1_HIPWR_LOWER_TH 70
  19089. +#define Z2_HIPWR_UPPER_TH 99
  19090. +#define Z2_HIPWR_LOWER_TH 90
  19091. +
  19092. +bool CheckDig(struct net_device *dev)
  19093. +{
  19094. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19095. + struct ieee80211_device *ieee = priv->ieee80211;
  19096. +
  19097. + if(ieee->state != IEEE80211_LINKED)
  19098. + return false;
  19099. +
  19100. + if(priv->card_8187 == NIC_8187B) {
  19101. + //
  19102. + // We need to schedule dig workitem on either of the below mechanisms.
  19103. + // By Bruce, 2007-06-01.
  19104. + //
  19105. + if(!priv->bDigMechanism && !priv->bCCKThMechanism)
  19106. + return false;
  19107. +
  19108. + if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
  19109. + return false;
  19110. + } else {
  19111. + if(!priv->bDigMechanism)
  19112. + return false;
  19113. +
  19114. + if(priv->CurrentOperaRate < 48)
  19115. + return false;
  19116. + }
  19117. + return true;
  19118. +}
  19119. +
  19120. +
  19121. +//
  19122. +// Description:
  19123. +// Implementation of DIG for Zebra and Zebra2.
  19124. +//
  19125. +void DIG_Zebra(struct net_device *dev)
  19126. +{
  19127. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19128. + //PHAL_DATA_8187 pHalData = GetHalData8187(Adapter);
  19129. + u16 CCKFalseAlarm, OFDMFalseAlarm;
  19130. + u16 OfdmFA1, OfdmFA2;
  19131. + int InitialGainStep = 7; // The number of initial gain stages.
  19132. + int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
  19133. +
  19134. +// printk("---------> DIG_Zebra()\n");
  19135. +
  19136. + //Read only 1 byte because of HW bug. This is a temporal modification. Joseph
  19137. + // Modify by Isaiah 2006-06-27
  19138. + if(priv->card_8187_Bversion == VERSION_8187B_B)
  19139. + {
  19140. + CCKFalseAlarm = 0;
  19141. + OFDMFalseAlarm = (u16)(priv->FalseAlarmRegValue);
  19142. + OfdmFA1 = 0x01;
  19143. + OfdmFA2 = priv->RegDigOfdmFaUpTh;
  19144. + }
  19145. + else
  19146. + {
  19147. + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
  19148. + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
  19149. + OfdmFA1 = 0x15;
  19150. + //OfdmFA2 = 0xC00;
  19151. + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
  19152. + }
  19153. +
  19154. +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
  19155. +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
  19156. +
  19157. +
  19158. +
  19159. + // The number of initial gain steps is different, by Bruce, 2007-04-13.
  19160. + if(priv->card_8187 == NIC_8187) {
  19161. + if (priv->InitialGain == 0 ) //autoDIG
  19162. + {
  19163. + switch( priv->rf_chip)
  19164. + {
  19165. + case RF_ZEBRA:
  19166. + priv->InitialGain = 5; // m74dBm;
  19167. + break;
  19168. + case RF_ZEBRA2:
  19169. + priv->InitialGain = 4; // m78dBm;
  19170. + break;
  19171. + default:
  19172. + priv->InitialGain = 5; // m74dBm;
  19173. + break;
  19174. + }
  19175. + }
  19176. + InitialGainStep = 7;
  19177. + if(priv->InitialGain > 7)
  19178. + priv->InitialGain = 5;
  19179. + LowestGainStage = 4;
  19180. + } else {
  19181. + if (priv->InitialGain == 0 ) //autoDIG
  19182. + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
  19183. + priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
  19184. + }
  19185. + if(priv->card_8187_Bversion != VERSION_8187B_B)
  19186. + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
  19187. + OfdmFA1 = 0x20;
  19188. + }
  19189. + InitialGainStep = 8;
  19190. + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
  19191. + }
  19192. +
  19193. + if (OFDMFalseAlarm > OfdmFA1)
  19194. + {
  19195. + if (OFDMFalseAlarm > OfdmFA2)
  19196. + {
  19197. + priv->DIG_NumberFallbackVote++;
  19198. + if (priv->DIG_NumberFallbackVote >1)
  19199. + {
  19200. + //serious OFDM False Alarm, need fallback
  19201. + // By Bruce, 2007-03-29.
  19202. + // if (pHalData->InitialGain < 7) // In 87B, m66dBm means State 7 (m74dBm)
  19203. + if (priv->InitialGain < InitialGainStep)
  19204. + {
  19205. + priv->InitialGain = (priv->InitialGain + 1);
  19206. + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
  19207. + //printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
  19208. + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
  19209. + }
  19210. + priv->DIG_NumberFallbackVote = 0;
  19211. + priv->DIG_NumberUpgradeVote=0;
  19212. + }
  19213. + }
  19214. + else
  19215. + {
  19216. + if (priv->DIG_NumberFallbackVote)
  19217. + priv->DIG_NumberFallbackVote--;
  19218. + }
  19219. + priv->DIG_NumberUpgradeVote=0;
  19220. + }
  19221. + else //OFDM False Alarm < 0x15
  19222. + {
  19223. + if (priv->DIG_NumberFallbackVote)
  19224. + priv->DIG_NumberFallbackVote--;
  19225. + priv->DIG_NumberUpgradeVote++;
  19226. +
  19227. + if (priv->DIG_NumberUpgradeVote>9)
  19228. + {
  19229. + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
  19230. + {
  19231. + priv->InitialGain = (priv->InitialGain - 1);
  19232. + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
  19233. + //printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
  19234. + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
  19235. + }
  19236. + priv->DIG_NumberFallbackVote = 0;
  19237. + priv->DIG_NumberUpgradeVote=0;
  19238. + }
  19239. + }
  19240. +
  19241. +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
  19242. +// printk("<--------- DIG_Zebra()\n");
  19243. +}
  19244. +
  19245. +//
  19246. +// Description:
  19247. +// Dispatch DIG implementation according to RF.
  19248. +//
  19249. +void DynamicInitGain(struct net_device *dev)
  19250. +{
  19251. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19252. +
  19253. + switch(priv->rf_chip)
  19254. + {
  19255. + case RF_ZEBRA:
  19256. + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
  19257. + //case RF_ZEBRA4:
  19258. + DIG_Zebra(dev);
  19259. + break;
  19260. +
  19261. + default:
  19262. + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
  19263. + break;
  19264. + }
  19265. +}
  19266. +
  19267. +// By Bruce, 2007-03-29.
  19268. +//
  19269. +// Description:
  19270. +// Dispatch CCK Power Detection implementation according to RF.
  19271. +//
  19272. +void DynamicCCKThreshold(struct net_device *dev)
  19273. +{
  19274. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19275. + u16 CCK_Up_Th;
  19276. + u16 CCK_Lw_Th;
  19277. + u16 CCKFalseAlarm;
  19278. +
  19279. + printk("=====>DynamicCCKThreshold()\n");
  19280. +
  19281. + CCK_Up_Th = priv->CCKUpperTh;
  19282. + CCK_Lw_Th = priv->CCKLowerTh;
  19283. + CCKFalseAlarm = (u16)((priv->FalseAlarmRegValue & 0x0000ffff) >> 8); // We only care about the higher byte.
  19284. + printk("DynamicCCKThreshold(): CCK Upper Threshold: 0x%02X, Lower Threshold: 0x%02X, CCKFalseAlarmHighByte: 0x%02X\n", CCK_Up_Th, CCK_Lw_Th, CCKFalseAlarm);
  19285. +
  19286. + if(priv->StageCCKTh < 3 && CCKFalseAlarm >= CCK_Up_Th)
  19287. + {
  19288. + priv->StageCCKTh ++;
  19289. + UpdateCCKThreshold(dev);
  19290. + }
  19291. + else if(priv->StageCCKTh > 0 && CCKFalseAlarm <= CCK_Lw_Th)
  19292. + {
  19293. + priv->StageCCKTh --;
  19294. + UpdateCCKThreshold(dev);
  19295. + }
  19296. +
  19297. + printk("<=====DynamicCCKThreshold()\n");
  19298. +}
  19299. +
  19300. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19301. +void rtl8180_hw_dig_wq (struct work_struct *work)
  19302. +{
  19303. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  19304. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
  19305. + struct net_device *dev = ieee->dev;
  19306. +#else
  19307. +void rtl8180_hw_dig_wq(struct net_device *dev)
  19308. +{
  19309. + // struct r8180_priv *priv = ieee80211_priv(dev);
  19310. +#endif
  19311. + struct r8180_priv *priv = ieee80211_priv(dev);
  19312. +
  19313. + // Read CCK and OFDM False Alarm.
  19314. + if(priv->card_8187_Bversion == VERSION_8187B_B) {
  19315. + // Read only 1 byte because of HW bug. This is a temporal modification. Joseph
  19316. + // Modify by Isaiah 2006-06-27
  19317. + priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1));
  19318. + } else {
  19319. + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
  19320. + }
  19321. +
  19322. + // Adjust Initial Gain dynamically.
  19323. + if(priv->bDigMechanism) {
  19324. + DynamicInitGain(dev);
  19325. + }
  19326. +
  19327. + //
  19328. + // Move from DynamicInitGain to be independent of the OFDM DIG mechanism, by Bruce, 2007-06-01.
  19329. + //
  19330. + if(priv->card_8187 == NIC_8187B) {
  19331. + // By Bruce, 2007-03-29.
  19332. + // Dynamically update CCK Power Detection Threshold.
  19333. + if(priv->bCCKThMechanism)
  19334. + {
  19335. + DynamicCCKThreshold(dev);
  19336. + }
  19337. + }
  19338. +}
  19339. +
  19340. +void SetTxPowerLevel8187(struct net_device *dev, short chan)
  19341. +{
  19342. + struct r8180_priv *priv = ieee80211_priv(dev);
  19343. +
  19344. + switch(priv->rf_chip)
  19345. + {
  19346. + case RF_ZEBRA:
  19347. + rtl8225_SetTXPowerLevel(dev,chan);
  19348. + break;
  19349. +
  19350. + case RF_ZEBRA2:
  19351. + //case RF_ZEBRA4:
  19352. + rtl8225z2_SetTXPowerLevel(dev,chan);
  19353. + break;
  19354. + }
  19355. +}
  19356. +
  19357. +//
  19358. +// Description:
  19359. +// Check if input power signal strength exceeds maximum input power threshold
  19360. +// of current HW.
  19361. +// If yes, we set our HW to high input power state:
  19362. +// RX: always force TR switch to SW Tx mode to reduce input power.
  19363. +// TX: turn off smaller Tx output power (see RtUsbCheckForHang).
  19364. +//
  19365. +// If no, we restore our HW to normal input power state:
  19366. +/// RX: restore TR switch to HW controled mode.
  19367. +// TX: restore TX output power (see RtUsbCheckForHang).
  19368. +//
  19369. +// TODO:
  19370. +// 1. Tx power control shall not be done in Platform-dependent timer (e.g. RtUsbCheckForHang).
  19371. +// 2. Allow these threshold adjustable by RF SD.
  19372. +//
  19373. +void DoRxHighPower(struct net_device *dev)
  19374. +{
  19375. + struct r8180_priv *priv = ieee80211_priv(dev);
  19376. + TR_SWITCH_STATE TrSwState;
  19377. + u16 HiPwrUpperTh = 0;
  19378. + u16 HiPwrLowerTh = 0;
  19379. + u16 RSSIHiPwrUpperTh = 0;
  19380. + u16 RSSIHiPwrLowerTh = 0;
  19381. +
  19382. + //87S remove TrSwitch mechanism
  19383. + if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) {
  19384. +
  19385. + //printk("----> DoRxHighPower()\n");
  19386. +
  19387. + //
  19388. + // Get current TR switch setting.
  19389. + //
  19390. + //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_TR_SWITCH, (pu1Byte)(&TrSwState));
  19391. + TrSwState = priv->TrSwitchState;
  19392. +
  19393. + //
  19394. + // Determine threshold according to RF type.
  19395. + //
  19396. + switch(priv->rf_chip)
  19397. + {
  19398. + case RF_ZEBRA:
  19399. + HiPwrUpperTh = Z1_HIPWR_UPPER_TH;
  19400. + HiPwrLowerTh = Z1_HIPWR_LOWER_TH;
  19401. + printk("DoRxHighPower(): RF_ZEBRA, Upper Threshold: %d LOWER Threshold: %d\n",
  19402. + HiPwrUpperTh, HiPwrLowerTh);
  19403. + break;
  19404. +
  19405. + case RF_ZEBRA2:
  19406. + if((priv->card_8187 == NIC_8187)) {
  19407. + HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
  19408. + HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
  19409. + } else {
  19410. + // By Bruce, 2007-04-11.
  19411. + // HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
  19412. + // HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
  19413. +
  19414. + HiPwrUpperTh = priv->Z2HiPwrUpperTh;
  19415. + HiPwrLowerTh = priv->Z2HiPwrLowerTh;
  19416. + HiPwrUpperTh = HiPwrUpperTh * 10;
  19417. + HiPwrLowerTh = HiPwrLowerTh * 10;
  19418. +
  19419. + RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh;
  19420. + RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh;
  19421. + //printk("DoRxHighPower(): RF_ZEBRA2, Upper Threshold: %d LOWER Threshold: %d, RSSI Upper Th: %d, RSSI Lower Th: %d\n",HiPwrUpperTh, HiPwrLowerTh, RSSIHiPwrUpperTh, RSSIHiPwrLowerTh);
  19422. + }
  19423. + break;
  19424. +
  19425. + default:
  19426. + printk("DoRxHighPower(): Unknown RFChipID(%d), UndecoratedSmoothedSS(%d), TrSwState(%d)!!!\n",
  19427. + priv->rf_chip, priv->UndecoratedSmoothedSS, TrSwState);
  19428. + return;
  19429. + break;
  19430. + }
  19431. +
  19432. + /*printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",\
  19433. + priv->UndecoratedSmoothedSS, priv->CurCCKRSSI);
  19434. + */
  19435. + if((priv->card_8187 == NIC_8187)) {
  19436. + //
  19437. + // Perform Rx part High Power Mechanism by UndecoratedSmoothedSS.
  19438. + //
  19439. + if (priv->UndecoratedSmoothedSS > HiPwrUpperTh)
  19440. + { // High input power state.
  19441. + if( priv->TrSwitchState == TR_HW_CONTROLLED )
  19442. + {
  19443. + /* printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d \n", \
  19444. + priv->UndecoratedSmoothedSS);
  19445. + // printk(">>>>>>>>>> TR_SW_TX\n");
  19446. + */
  19447. + write_nic_byte(dev, RFPinsSelect,
  19448. + (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 ));
  19449. + write_nic_byte(dev, RFPinsOutput,
  19450. + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
  19451. + priv->TrSwitchState = TR_SW_TX;
  19452. + priv->bToUpdateTxPwr = true;
  19453. + }
  19454. + }
  19455. + else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh)
  19456. + { // Normal input power state.
  19457. + if( priv->TrSwitchState == TR_SW_TX)
  19458. + {
  19459. + /* printk("<<<<<<<<<<<Set TR switch to hardware control UndecoratedSmoothedSS:%d \n", \
  19460. + priv->UndecoratedSmoothedSS);
  19461. + // printk("<<<<<<<<<< TR_HW_CONTROLLED\n");
  19462. + */
  19463. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  19464. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  19465. + priv->TrSwitchState = TR_HW_CONTROLLED;
  19466. + priv->bToUpdateTxPwr = true;
  19467. + }
  19468. + }
  19469. + }else {
  19470. + /*printk("=====>TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
  19471. + //printk("UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); */
  19472. + // Asked by SD3 DZ, by Bruce, 2007-04-12.
  19473. + if(TrSwState == TR_HW_CONTROLLED)
  19474. + {
  19475. + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
  19476. + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
  19477. + {
  19478. + //printk("===============================> high power!\n");
  19479. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 ));
  19480. + write_nic_byte(dev, RFPinsOutput,
  19481. + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
  19482. + priv->TrSwitchState = TR_SW_TX;
  19483. + priv->bToUpdateTxPwr = true;
  19484. + }
  19485. + }
  19486. + else
  19487. + {
  19488. + if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
  19489. + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
  19490. + {
  19491. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  19492. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  19493. + priv->TrSwitchState = TR_HW_CONTROLLED;
  19494. + priv->bToUpdateTxPwr = true;
  19495. + }
  19496. + }
  19497. + //printk("<=======TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
  19498. + }
  19499. + //printk("<---- DoRxHighPower()\n");
  19500. + }
  19501. +}
  19502. +
  19503. +
  19504. +//
  19505. +// Description:
  19506. +// Callback function of UpdateTxPowerWorkItem.
  19507. +// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
  19508. +// We update Tx power of current channel again.
  19509. +//
  19510. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19511. +void rtl8180_tx_pw_wq (struct work_struct *work)
  19512. +{
  19513. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  19514. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
  19515. + struct net_device *dev = ieee->dev;
  19516. +#else
  19517. +void rtl8180_tx_pw_wq(struct net_device *dev)
  19518. +{
  19519. + // struct r8180_priv *priv = ieee80211_priv(dev);
  19520. +#endif
  19521. +
  19522. + struct r8180_priv *priv = ieee80211_priv(dev);
  19523. +
  19524. + //printk("----> UpdateTxPowerWorkItemCallback()\n");
  19525. +
  19526. + if(priv->bToUpdateTxPwr)
  19527. + {
  19528. + //printk("DoTxHighPower(): schedule UpdateTxPowerWorkItem......\n");
  19529. + priv->bToUpdateTxPwr = false;
  19530. + SetTxPowerLevel8187(dev, priv->chan);
  19531. + }
  19532. +
  19533. + DoRxHighPower(dev);
  19534. + //printk("<---- UpdateTxPowerWorkItemCallback()\n");
  19535. +}
  19536. +
  19537. +//
  19538. +// Description:
  19539. +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
  19540. +//
  19541. +bool CheckHighPower(struct net_device *dev)
  19542. +{
  19543. + struct r8180_priv *priv = ieee80211_priv(dev);
  19544. + struct ieee80211_device *ieee = priv->ieee80211;
  19545. +
  19546. + if(!priv->bRegHighPowerMechanism)
  19547. + {
  19548. + return false;
  19549. + }
  19550. +
  19551. + if((ieee->state == IEEE80211_LINKED_SCANNING)||(ieee->state == IEEE80211_MESH_SCANNING))
  19552. + {
  19553. + return false;
  19554. + }
  19555. +
  19556. + return true;
  19557. +}
  19558. +
  19559. +#ifdef SW_ANTE_DIVERSITY
  19560. +
  19561. +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
  19562. +
  19563. +void
  19564. +SwAntennaDiversityRxOk8185(
  19565. + struct net_device *dev,
  19566. + u8 SignalStrength
  19567. + )
  19568. +{
  19569. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19570. +
  19571. + //printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
  19572. +
  19573. + priv->AdRxOkCnt++;
  19574. +
  19575. + if( priv->AdRxSignalStrength != -1)
  19576. + {
  19577. + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
  19578. + }
  19579. + else
  19580. + { // Initialization case.
  19581. + priv->AdRxSignalStrength = SignalStrength;
  19582. + }
  19583. +
  19584. + //printk("====>pkt rcvd by %d\n", priv->LastRxPktAntenna);
  19585. + if( priv->LastRxPktAntenna ) //Main antenna.
  19586. + priv->AdMainAntennaRxOkCnt++;
  19587. + else // Aux antenna.
  19588. + priv->AdAuxAntennaRxOkCnt++;
  19589. + //printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
  19590. +}
  19591. +
  19592. +//
  19593. +// Description: Change Antenna Switch.
  19594. +//
  19595. +bool
  19596. +SetAntenna8185(
  19597. + struct net_device *dev,
  19598. + u8 u1bAntennaIndex
  19599. + )
  19600. +{
  19601. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19602. + bool bAntennaSwitched = false;
  19603. +
  19604. +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
  19605. +
  19606. + switch(u1bAntennaIndex)
  19607. + {
  19608. + case 0://main antenna
  19609. + switch(priv->rf_chip)
  19610. + {
  19611. + case RF_ZEBRA:
  19612. + case RF_ZEBRA2:
  19613. + //case RF_ZEBRA4:
  19614. + // Tx Antenna.
  19615. + write_nic_byte(dev, ANTSEL, 0x03); // Config TX antenna.
  19616. +
  19617. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x01009b90); // Config CCK RX antenna.
  19618. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x5c8D); // Config OFDM RX antenna.
  19619. +
  19620. + // Rx CCK .
  19621. + write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24));
  19622. + write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16));
  19623. + write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8));
  19624. + write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0));
  19625. +
  19626. + // Rx OFDM.
  19627. + write_nic_byte(dev, 0x7f, ((0x00005c8D & 0xff000000) >> 24));
  19628. + write_nic_byte(dev, 0x7e, ((0x00005c8D & 0x00ff0000) >> 16));
  19629. + write_nic_byte(dev, 0x7d, ((0x00005c8D & 0x0000ff00) >> 8));
  19630. + write_nic_byte(dev, 0x7c, ((0x00005c8D & 0x000000ff) >> 0));
  19631. +
  19632. + bAntennaSwitched = true;
  19633. + break;
  19634. +
  19635. + default:
  19636. + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
  19637. + break;
  19638. + }
  19639. + break;
  19640. +
  19641. + case 1:
  19642. + switch(priv->rf_chip)
  19643. + {
  19644. + case RF_ZEBRA:
  19645. + case RF_ZEBRA2:
  19646. + //case RF_ZEBRA4:
  19647. + // Tx Antenna.
  19648. + write_nic_byte(dev, ANTSEL, 0x00); // Config TX antenna.
  19649. +
  19650. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x0100bb90); // Config CCK RX antenna.
  19651. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x548D); // Config OFDM RX antenna.
  19652. +
  19653. + // Rx CCK.
  19654. + write_nic_byte(dev, 0x7f, ((0x0100bb90 & 0xff000000) >> 24));
  19655. + write_nic_byte(dev, 0x7e, ((0x0100bb90 & 0x00ff0000) >> 16));
  19656. + write_nic_byte(dev, 0x7d, ((0x0100bb90 & 0x0000ff00) >> 8));
  19657. + write_nic_byte(dev, 0x7c, ((0x0100bb90 & 0x000000ff) >> 0));
  19658. +
  19659. + // Rx OFDM.
  19660. + write_nic_byte(dev, 0x7f, ((0x0000548D & 0xff000000) >> 24));
  19661. + write_nic_byte(dev, 0x7e, ((0x0000548D & 0x00ff0000) >> 16));
  19662. + write_nic_byte(dev, 0x7d, ((0x0000548D & 0x0000ff00) >> 8));
  19663. + write_nic_byte(dev, 0x7c, ((0x0000548D & 0x000000ff) >> 0));
  19664. +
  19665. + bAntennaSwitched = true;
  19666. + break;
  19667. +
  19668. + default:
  19669. + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
  19670. + break;
  19671. + }
  19672. + break;
  19673. +
  19674. + default:
  19675. + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
  19676. + break;
  19677. + }
  19678. +
  19679. + if(bAntennaSwitched)
  19680. + {
  19681. + priv->CurrAntennaIndex = u1bAntennaIndex;
  19682. + }
  19683. +
  19684. +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
  19685. +
  19686. + return bAntennaSwitched;
  19687. +}
  19688. +
  19689. +//
  19690. +// Description: Toggle Antenna switch.
  19691. +//
  19692. +bool SwitchAntenna(struct net_device *dev)
  19693. +{
  19694. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19695. +
  19696. + bool bResult = false;
  19697. +
  19698. + if(priv->CurrAntennaIndex == 0)
  19699. + {
  19700. + bResult = SetAntenna8185(dev, 1);
  19701. + if(priv->ieee80211->state == IEEE80211_LINKED)
  19702. + printk("Switching to Aux antenna 1 \n");
  19703. + }
  19704. + else
  19705. + {
  19706. + bResult = SetAntenna8185(dev, 0);
  19707. + if(priv->ieee80211->state == IEEE80211_LINKED)
  19708. + printk("Switching to Main antenna 0 \n");
  19709. + }
  19710. +
  19711. + return bResult;
  19712. +}
  19713. +
  19714. +//
  19715. +// Description:
  19716. +// Engine of SW Antenna Diversity mechanism.
  19717. +// Since 8187 has no Tx part information,
  19718. +// this implementation is only dependend on Rx part information.
  19719. +//
  19720. +// 2006.04.17, by rcnjko.
  19721. +//
  19722. +void SwAntennaDiversity(struct net_device *dev)
  19723. +{
  19724. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19725. + //bool bSwCheckSS=false;
  19726. + bool bSwCheckSS=true;//open the SignalStrength check if not switched by rx ok pkt.
  19727. +
  19728. +// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
  19729. +
  19730. +//by amy 080312
  19731. + if(bSwCheckSS){
  19732. + priv->AdTickCount++;
  19733. +
  19734. + //printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod);
  19735. + //printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  19736. + }
  19737. +// priv->AdTickCount++;//-by amy 080312
  19738. +
  19739. + // Case 1. No Link.
  19740. + if(priv->ieee80211->state != IEEE80211_LINKED){
  19741. + //printk("SwAntennaDiversity(): Case 1. No Link.\n");
  19742. +
  19743. + priv->bAdSwitchedChecking = false;
  19744. + // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
  19745. + SwitchAntenna(dev);
  19746. + }
  19747. + // Case 2. Linked but no packet received.
  19748. + else if(priv->AdRxOkCnt == 0){
  19749. + printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
  19750. +
  19751. + priv->bAdSwitchedChecking = false;
  19752. + SwitchAntenna(dev);
  19753. + }
  19754. + // Case 3. Evaluate last antenna switch action in case4. and undo it if necessary.
  19755. + else if(priv->bAdSwitchedChecking == true){
  19756. + //printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
  19757. +
  19758. + priv->bAdSwitchedChecking = false;
  19759. +
  19760. + // Adjust Rx signal strength threashold.
  19761. + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
  19762. +
  19763. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
  19764. + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
  19765. + if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched){
  19766. + // Rx signal strength is not improved after we swtiched antenna. => Swich back.
  19767. + printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
  19768. +
  19769. + //by amy 080312
  19770. + // Increase Antenna Diversity checking period due to bad decision.
  19771. + priv->AdCheckPeriod *= 2;
  19772. + //by amy 080312
  19773. + //
  19774. + // Increase Antenna Diversity checking period.
  19775. + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
  19776. + priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
  19777. +
  19778. + // Wrong deceision => switch back.
  19779. + SwitchAntenna(dev);
  19780. + }else{ // Rx Signal Strength is improved.
  19781. + printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
  19782. +
  19783. + // Reset Antenna Diversity checking period to its min value.
  19784. + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
  19785. + }
  19786. +
  19787. + //printk("SwAntennaDiversity(): AdRxSsThreshold: %ld, AdCheckPeriod: %d\n",
  19788. + // priv->AdRxSsThreshold, priv->AdCheckPeriod);
  19789. + }
  19790. + // Case 4. Evaluate if we shall switch antenna now.
  19791. + // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
  19792. + else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
  19793. + {
  19794. + //printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
  19795. +
  19796. + priv->AdTickCount = 0;
  19797. +
  19798. + //
  19799. + // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
  19800. + // evaluate signal strength.
  19801. + // The following operation can overcome the disability of CCA on both two antennas
  19802. + // When signal strength was extremely low or high.
  19803. + // 2008.01.30.
  19804. + //
  19805. +
  19806. + //
  19807. + // Evaluate RxOk count from each antenna if we shall switch default antenna now.
  19808. + // Added by Roger, 2008.02.21.
  19809. +
  19810. + //{by amy 080312
  19811. + if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)){
  19812. + // We set Main antenna as default but RxOk count was less than Aux ones.
  19813. +
  19814. + printk("SwAntennaDiversity(): Main antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  19815. +
  19816. + // Switch to Aux antenna.
  19817. + SwitchAntenna(dev);
  19818. + priv->bHWAdSwitched = true;
  19819. + }else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)){
  19820. + // We set Aux antenna as default but RxOk count was less than Main ones.
  19821. +
  19822. + printk("SwAntennaDiversity(): Aux antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  19823. +
  19824. + // Switch to Main antenna.
  19825. + SwitchAntenna(dev);
  19826. + priv->bHWAdSwitched = true;
  19827. + }else{// Default antenna is better.
  19828. +
  19829. + printk("SwAntennaDiversity(): Current Antenna %d is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  19830. +
  19831. + // Still need to check current signal strength.
  19832. + priv->bHWAdSwitched = false;
  19833. + }
  19834. + //
  19835. + // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
  19836. + // didn't changed by HW evaluation.
  19837. + // 2008.02.27.
  19838. + //
  19839. + // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
  19840. + // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
  19841. + // but AdRxSignalStrength is less than main.
  19842. + // Our guess is that main antenna have lower throughput and get many change
  19843. + // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
  19844. + //
  19845. + if( (!priv->bHWAdSwitched) && (bSwCheckSS)){
  19846. + //by amy 080312}
  19847. +
  19848. + // Evaluate Rx signal strength if we shall switch antenna now.
  19849. + if(priv->AdRxSignalStrength < priv->AdRxSsThreshold){
  19850. + // Rx signal strength is weak => Switch Antenna.
  19851. + printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  19852. +
  19853. + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
  19854. + priv->bAdSwitchedChecking = true;
  19855. +
  19856. + SwitchAntenna(dev);
  19857. + }else{ // Rx signal strength is OK.
  19858. + printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  19859. +
  19860. + priv->bAdSwitchedChecking = false;
  19861. + // Increase Rx signal strength threashold if necessary.
  19862. + if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
  19863. + priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
  19864. + {
  19865. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
  19866. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
  19867. + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
  19868. + }
  19869. +
  19870. + // Reduce Antenna Diversity checking period if possible.
  19871. + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
  19872. + {
  19873. + priv->AdCheckPeriod /= 2;
  19874. + }
  19875. + }
  19876. + }
  19877. + }
  19878. +//by amy 080312
  19879. + // Reset antenna diversity Rx related statistics.
  19880. + priv->AdRxOkCnt = 0;
  19881. + priv->AdMainAntennaRxOkCnt = 0;
  19882. + priv->AdAuxAntennaRxOkCnt = 0;
  19883. +//by amy 080312
  19884. +
  19885. +// priv->AdRxOkCnt = 0;//-by amy 080312
  19886. +
  19887. + //printk("-SwAntennaDiversity()\n");
  19888. +}
  19889. +
  19890. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19891. +void SwAntennaWorkItemCallback(struct work_struct *work)
  19892. +{
  19893. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, SwAntennaWorkItem.work);
  19894. + struct net_device *dev = ieee->dev;
  19895. +#else
  19896. +void SwAntennaWorkItemCallback(struct net_device *dev)
  19897. +{
  19898. +#endif
  19899. + //printk("==>%s \n", __func__);
  19900. + SwAntennaDiversity(dev);
  19901. +}
  19902. +
  19903. +//
  19904. +// Description: Timer callback function of SW Antenna Diversity.
  19905. +//
  19906. +void SwAntennaDiversityTimerCallback(struct net_device *dev)
  19907. +{
  19908. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  19909. + RT_RF_POWER_STATE rtState;
  19910. +
  19911. + //printk("+SwAntennaDiversityTimerCallback()\n");
  19912. +
  19913. + //
  19914. + // We do NOT need to switch antenna while RF is off.
  19915. + // 2007.05.09, added by Roger.
  19916. + //
  19917. + rtState = priv->eRFPowerState;
  19918. + do{
  19919. + if (rtState == eRfOff){
  19920. +// printk("SwAntennaDiversityTimer - RF is OFF.\n");
  19921. + break;
  19922. + }else if (rtState == eRfSleep){
  19923. + // Don't access BB/RF under Disable PLL situation.
  19924. + //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
  19925. + break;
  19926. + }
  19927. +
  19928. + queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem);
  19929. +
  19930. + }while(false);
  19931. +
  19932. + if(priv->up){
  19933. + //priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
  19934. + //add_timer(&priv->SwAntennaDiversityTimer);
  19935. + mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD));
  19936. + }
  19937. +
  19938. +}
  19939. +#endif
  19940. +
  19941. +
  19942. +
  19943. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.h
  19944. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.h 1970-01-01 01:00:00.000000000 +0100
  19945. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.h 2010-03-06 16:43:22.000000000 +0100
  19946. @@ -0,0 +1,38 @@
  19947. +/*
  19948. + Hardware dynamic mechanism for RTL8187B.
  19949. +Notes:
  19950. + This file is ported from RTL8187B Windows driver
  19951. +*/
  19952. +
  19953. +#ifndef R8180_DM_H
  19954. +#define R8180_DM_H
  19955. +
  19956. +#include "r8187.h"
  19957. +
  19958. +bool CheckDig(struct net_device *dev);
  19959. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19960. +void rtl8180_hw_dig_wq (struct work_struct *work);
  19961. +#else
  19962. +void rtl8180_hw_dig_wq(struct net_device *dev);
  19963. +#endif
  19964. +
  19965. +bool CheckHighPower(struct net_device *dev);
  19966. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19967. +void rtl8180_tx_pw_wq (struct work_struct *work);
  19968. +#else
  19969. +void rtl8180_tx_pw_wq(struct net_device *dev);
  19970. +#endif
  19971. +
  19972. +//by lzm for antenna
  19973. +#ifdef SW_ANTE_DIVERSITY
  19974. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  19975. +void SwAntennaWorkItemCallback(struct work_struct *work);
  19976. +#else
  19977. +void SwAntennaWorkItemCallback(struct net_device *dev);
  19978. +#endif
  19979. +void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
  19980. +void SwAntennaDiversityTimerCallback(struct net_device *dev);
  19981. +#endif
  19982. +//by lzm for antenna
  19983. +
  19984. +#endif //R8180_PM_H
  19985. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_hw.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_hw.h
  19986. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_hw.h 1970-01-01 01:00:00.000000000 +0100
  19987. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_hw.h 2010-03-06 16:43:22.000000000 +0100
  19988. @@ -0,0 +1,788 @@
  19989. +/*
  19990. + This is part of rtl8187 OpenSource driver.
  19991. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  19992. + Released under the terms of GPL (General Public Licence)
  19993. +
  19994. + Parts of this driver are based on the GPL part of the
  19995. + official Realtek driver.
  19996. + Parts of this driver are based on the rtl8180 driver skeleton
  19997. + from Patric Schenke & Andres Salomon.
  19998. + Parts of this driver are based on the Intel Pro Wireless
  19999. + 2100 GPL driver.
  20000. +
  20001. + We want to tanks the Authors of those projects
  20002. + and the Ndiswrapper project Authors.
  20003. +*/
  20004. +
  20005. +/* Mariusz Matuszek added full registers definition with Realtek's name */
  20006. +
  20007. +/* this file contains register definitions for the rtl8187 MAC controller */
  20008. +#ifndef R8180_HW
  20009. +#define R8180_HW
  20010. +
  20011. +typedef enum _RF_TYPE_8187{
  20012. + RF_TYPE_MIN,
  20013. + RF_ZEBRA = 5,
  20014. + RF_ZEBRA2, // added by Annie, 2005-08-01.
  20015. + RF_TYPE_MAX,
  20016. +}RF_TYPE_8187,*PRF_TYPE_8187;
  20017. +
  20018. +typedef enum _VERSION_8187{
  20019. + // RTL8187
  20020. + VERSION_8187_B, // B-cut
  20021. + VERSION_8187_D, // D-cut
  20022. + // RTL8187B
  20023. + VERSION_8187B_B, // B-cut
  20024. + VERSION_8187B_D, //D-cut //added 2007-9-14
  20025. + VERSION_8187B_E, //E-cut //added 2007-9-14
  20026. +}VERSION_8187,*PVERSION_8187;
  20027. +
  20028. +//by lzm for antenna
  20029. +#ifdef SW_ANTE_DIVERSITY
  20030. +#define RF_PARAM 0x19
  20031. +#define RF_PARAM_DIGPHY_SHIFT 0
  20032. +#define RF_PARAM_ANTBDEFAULT_SHIFT 1
  20033. +#define EEPROM_VERSION 0x3c
  20034. +#define EEPROM_CONFIG2 0x18
  20035. +#define EEPROM_CS_THRESHOLD 0x2F
  20036. +#define EEPROM_RF_PARAM 0x08
  20037. +//// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
  20038. +#define EEPROM_SW_AD_MASK 0x0300
  20039. +#define EEPROM_SW_AD_ENABLE 0x0100
  20040. +//// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
  20041. +#define EEPROM_DEF_ANT_MASK 0x0C00
  20042. +#define EEPROM_DEF_ANT_1 0x0400
  20043. +
  20044. +#define RCR_EnCS1 BIT29 // enable carrier sense method 1
  20045. +#define RCR_EnCS2 BIT30 // enable carrier sense method 2
  20046. +#endif
  20047. +//by lzm for antenna
  20048. +
  20049. +#define RTL8187_RF_INDEX 0x8225
  20050. +#define RTL8187_REQT_READ 0xc0
  20051. +#define RTL8187_REQT_WRITE 0x40
  20052. +#define RTL8187_REQ_GET_REGS 0x05
  20053. +#define RTL8187_REQ_SET_REGS 0x05
  20054. +
  20055. +
  20056. +
  20057. +#define MAX_TX_URB 5
  20058. +#define MAX_RX_URB 16
  20059. +#define RX_URB_SIZE 0x9C4
  20060. +
  20061. +
  20062. +
  20063. +
  20064. +
  20065. +#define BB_ANTATTEN_CHAN14 0x0c
  20066. +#define BB_ANTENNA_B 0x40
  20067. +
  20068. +#define BB_HOST_BANG (1<<30)
  20069. +#define BB_HOST_BANG_EN (1<<2)
  20070. +#define BB_HOST_BANG_CLK (1<<1)
  20071. +#define BB_HOST_BANG_RW (1<<3)
  20072. +#define BB_HOST_BANG_DATA 1
  20073. +
  20074. +#define ANAPARAM_TXDACOFF_SHIFT 27
  20075. +#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
  20076. +#define ANAPARAM_PWR0_SHIFT 28
  20077. +#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
  20078. +#define ANAPARAM_PWR1_SHIFT 20
  20079. +
  20080. +#define MAC0 0
  20081. +#define MAC1 1
  20082. +#define MAC2 2
  20083. +#define MAC3 3
  20084. +#define MAC4 4
  20085. +#define MAC5 5
  20086. +
  20087. +#define RXFIFOCOUNT 0x10
  20088. +#define TXFIFOCOUNT 0x12
  20089. +#define BcnIntTime 0x74
  20090. +#define TALLY_SEL 0xfc
  20091. +#define BQREQ 0x13
  20092. +
  20093. +#define CMD 0x37
  20094. +#define CMD_RST_SHIFT 4
  20095. +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
  20096. +#define CMD_RX_ENABLE_SHIFT 3
  20097. +#define CMD_TX_ENABLE_SHIFT 2
  20098. +
  20099. +#define EPROM_CMD 0x50
  20100. +#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
  20101. +#define EPROM_CMD_OPERATING_MODE_SHIFT 6
  20102. +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
  20103. +#define EPROM_CMD_CONFIG 0x3
  20104. +#define EPROM_CMD_NORMAL 0
  20105. +#define EPROM_CMD_LOAD 1
  20106. +#define EPROM_CMD_PROGRAM 2
  20107. +#define EPROM_CS_SHIFT 3
  20108. +#define EPROM_CK_SHIFT 2
  20109. +#define EPROM_W_SHIFT 1
  20110. +#define EPROM_R_SHIFT 0
  20111. +#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
  20112. +#define INTA 0x3e
  20113. +#define INTA_TXOVERFLOW (1<<15)
  20114. +#define INTA_TIMEOUT (1<<14)
  20115. +#define INTA_BEACONTIMEOUT (1<<13)
  20116. +#define INTA_ATIM (1<<12)
  20117. +#define INTA_BEACONDESCERR (1<<11)
  20118. +#define INTA_BEACONDESCOK (1<<10)
  20119. +#define INTA_HIPRIORITYDESCERR (1<<9)
  20120. +#define INTA_HIPRIORITYDESCOK (1<<8)
  20121. +#define INTA_NORMPRIORITYDESCERR (1<<7)
  20122. +#define INTA_NORMPRIORITYDESCOK (1<<6)
  20123. +#define INTA_RXOVERFLOW (1<<5)
  20124. +#define INTA_RXDESCERR (1<<4)
  20125. +#define INTA_LOWPRIORITYDESCERR (1<<3)
  20126. +#define INTA_LOWPRIORITYDESCOK (1<<2)
  20127. +#define INTA_RXCRCERR (1<<1)
  20128. +#define INTA_RXOK (1)
  20129. +#define INTA_MASK 0x3c
  20130. +#define RXRING_ADDR 0xe4 // page 0
  20131. +#define PGSELECT 0x5e
  20132. +#define PGSELECT_PG_SHIFT 0
  20133. +#define RX_CONF 0x44
  20134. +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
  20135. +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
  20136. +#define RX_CHECK_BSSID_SHIFT 23
  20137. +#define ACCEPT_PWR_FRAME_SHIFT 22
  20138. +#define ACCEPT_MNG_FRAME_SHIFT 20
  20139. +#define ACCEPT_CTL_FRAME_SHIFT 19
  20140. +#define ACCEPT_DATA_FRAME_SHIFT 18
  20141. +#define ACCEPT_ICVERR_FRAME_SHIFT 12
  20142. +#define ACCEPT_CRCERR_FRAME_SHIFT 5
  20143. +#define ACCEPT_BCAST_FRAME_SHIFT 3
  20144. +#define ACCEPT_MCAST_FRAME_SHIFT 2
  20145. +#define ACCEPT_ALLMAC_FRAME_SHIFT 0
  20146. +#define ACCEPT_NICMAC_FRAME_SHIFT 1
  20147. +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
  20148. +#define RX_FIFO_THRESHOLD_SHIFT 13
  20149. +#define RX_FIFO_THRESHOLD_128 3
  20150. +#define RX_FIFO_THRESHOLD_256 4
  20151. +#define RX_FIFO_THRESHOLD_512 5
  20152. +#define RX_FIFO_THRESHOLD_1024 6
  20153. +#define RX_FIFO_THRESHOLD_NONE 7
  20154. +#define RX_AUTORESETPHY_SHIFT 28
  20155. +#define EPROM_TYPE_SHIFT 6
  20156. +#define TX_CONF 0x40
  20157. +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
  20158. +#define TX_LOOPBACK_SHIFT 17
  20159. +#define TX_LOOPBACK_MAC 1
  20160. +#define TX_LOOPBACK_BASEBAND 2
  20161. +#define TX_LOOPBACK_NONE 0
  20162. +#define TX_LOOPBACK_CONTINUE 3
  20163. +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
  20164. +#define TX_LRLRETRY_SHIFT 0
  20165. +#define R8180_MAX_RETRY 255
  20166. +#define TX_SRLRETRY_SHIFT 8
  20167. +#define TX_NOICV_SHIFT 19
  20168. +#define TX_NOCRC_SHIFT 16
  20169. +#define TX_DMA_POLLING 0xd9
  20170. +#define TX_DMA_POLLING_BEACON_SHIFT 7
  20171. +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
  20172. +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
  20173. +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
  20174. +#define TX_DMA_STOP_BEACON_SHIFT 3
  20175. +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
  20176. +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
  20177. +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
  20178. +#define TX_NORMPRIORITY_RING_ADDR 0x24
  20179. +#define TX_HIGHPRIORITY_RING_ADDR 0x28
  20180. +#define TX_LOWPRIORITY_RING_ADDR 0x20
  20181. +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
  20182. +#define MAX_RX_DMA_2048 7
  20183. +#define MAX_RX_DMA_1024 6
  20184. +#define MAX_RX_DMA_SHIFT 10
  20185. +#define INT_TIMEOUT 0x48
  20186. +#define CONFIG3_CLKRUN_SHIFT 2
  20187. +#define CONFIG3_ANAPARAM_W_SHIFT 6
  20188. +#define ANAPARAM 0x54
  20189. +#define BEACON_INTERVAL 0x70
  20190. +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
  20191. +(1<<6)|(1<<7)|(1<<8)|(1<<9))
  20192. +#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
  20193. +(1<<8)|(1<<9))
  20194. +#define ATIM 0x72
  20195. +#define EPROM_CS_SHIFT 3
  20196. +#define EPROM_CK_SHIFT 2
  20197. +#define PHY_DELAY 0x78
  20198. +#define PHY_CONFIG 0x80
  20199. +#define PHY_ADR 0x7c
  20200. +#define PHY_READ 0x7e
  20201. +#define CARRIER_SENSE_COUNTER 0x79 //byte
  20202. +#define SECURITY 0x5f
  20203. +#define SECURITY_WEP_TX_ENABLE_SHIFT 1
  20204. +#define SECURITY_WEP_RX_ENABLE_SHIFT 0
  20205. +#define SECURITY_ENCRYP_104 1
  20206. +#define SECURITY_ENCRYP_SHIFT 4
  20207. +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
  20208. +#define KEY0 0x90
  20209. +#define CONFIG2_ANTENNA_SHIFT 6
  20210. +#define TX_BEACON_RING_ADDR 0x4c
  20211. +#define CONFIG0_WEP40_SHIFT 7
  20212. +#define CONFIG0_WEP104_SHIFT 6
  20213. +#define AGCRESET_SHIFT 5
  20214. +
  20215. +
  20216. +
  20217. +/*
  20218. + * Operational registers offsets in PCI (I/O) space.
  20219. + * RealTek names are used.
  20220. + */
  20221. +
  20222. +#define IDR0 0x0000
  20223. +#define IDR1 0x0001
  20224. +#define IDR2 0x0002
  20225. +#define IDR3 0x0003
  20226. +#define IDR4 0x0004
  20227. +#define IDR5 0x0005
  20228. +
  20229. +/* 0x0006 - 0x0007 - reserved */
  20230. +
  20231. +#define MAR0 0x0008
  20232. +#define MAR1 0x0009
  20233. +#define MAR2 0x000A
  20234. +#define MAR3 0x000B
  20235. +#define MAR4 0x000C
  20236. +#define MAR5 0x000D
  20237. +#define MAR6 0x000E
  20238. +#define MAR7 0x000F
  20239. +
  20240. +/* 0x0010 - 0x0017 - reserved */
  20241. +
  20242. +#define TSFTR 0x0018
  20243. +#define TSFTR_END 0x001F
  20244. +
  20245. +#define TLPDA 0x0020
  20246. +#define TLPDA_END 0x0023
  20247. +#define TNPDA 0x0024
  20248. +#define TNPDA_END 0x0027
  20249. +#define THPDA 0x0028
  20250. +#define THPDA_END 0x002B
  20251. +
  20252. +#define BRSR_8187 0x002C
  20253. +#define BRSR_8187_END 0x002D
  20254. +#define BRSR_8187B 0x0034
  20255. +#define BRSR_8187B_END 0x0035
  20256. +
  20257. +#define BSSID 0x002E
  20258. +#define BSSID_END 0x0033
  20259. +
  20260. +/* 0x0034 - 0x0034 - reserved */
  20261. +
  20262. +/* 0x0038 - 0x003B - reserved */
  20263. +
  20264. +#define IMR 0x003C
  20265. +#define IMR_END 0x003D
  20266. +
  20267. +#define ISR 0x003E
  20268. +#define ISR_END 0x003F
  20269. +
  20270. +#define TCR 0x0040
  20271. +#define TCR_END 0x0043
  20272. +
  20273. +#define RCR 0x0044
  20274. +#define RCR_END 0x0047
  20275. +
  20276. +#define TimerInt 0x0048
  20277. +#define TimerInt_END 0x004B
  20278. +
  20279. +#define TBDA 0x004C
  20280. +#define TBDA_END 0x004F
  20281. +
  20282. +#define CR9346 0x0050
  20283. +
  20284. +#define CONFIG0 0x0051
  20285. +#define CONFIG1 0x0052
  20286. +#define CONFIG2 0x0053
  20287. +
  20288. +#define ANA_PARAM 0x0054
  20289. +#define ANA_PARAM_END 0x0x0057
  20290. +
  20291. +#define MSR 0x0058
  20292. +
  20293. +#define CONFIG3 0x0059
  20294. +#define CONFIG4 0x005A
  20295. +
  20296. +#define TESTR 0x005B
  20297. +
  20298. +/* 0x005C - 0x005D - reserved */
  20299. +#define TFPC_AC 0x005C
  20300. +#define PSR 0x005E
  20301. +
  20302. +#define SCR 0x005F
  20303. +
  20304. +/* 0x0060 - 0x006F - reserved */
  20305. +#define ANA_PARAM2 0x0060
  20306. +#define ANA_PARAM2_END 0x0063
  20307. +
  20308. +#define BcnIntv 0x0070
  20309. +#define BcnItv_END 0x0071
  20310. +
  20311. +#define AtimWnd 0x0072
  20312. +#define AtimWnd_END 0x0073
  20313. +
  20314. +#define BintrItv 0x0074
  20315. +#define BintrItv_END 0x0075
  20316. +
  20317. +#define AtimtrItv 0x0076
  20318. +#define AtimtrItv_END 0x0077
  20319. +
  20320. +#define PhyDelay 0x0078
  20321. +
  20322. +//#define CRCount 0x0079
  20323. +
  20324. +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
  20325. +/* 0x007A - 0x007B - reserved */
  20326. +#define BBAddr 0x007C
  20327. +
  20328. +
  20329. +#define PhyAddr 0x007C
  20330. +#define PhyDataW 0x007D
  20331. +#define PhyDataR 0x007E
  20332. +#define RF_Ready 0x007F
  20333. +
  20334. +#define PhyCFG 0x0080
  20335. +#define PhyCFG_END 0x0083
  20336. +
  20337. +/* following are for rtl8185 */
  20338. +#define RFPinsOutput 0x80
  20339. +#define RFPinsEnable 0x82
  20340. +#define RF_TIMING 0x8c
  20341. +#define RFPinsSelect 0x84
  20342. +#define ANAPARAM2 0x60
  20343. +#define RF_PARA 0x88
  20344. +#define RFPinsInput 0x86
  20345. +#define GP_ENABLE 0x90
  20346. +#define GPIO 0x91
  20347. +#define HSSI_PARA 0x94 // HSS Parameter
  20348. +#define SW_CONTROL_GPIO 0x400
  20349. +#define CCK_TXAGC 0x9d
  20350. +#define OFDM_TXAGC 0x9e
  20351. +#define ANTSEL 0x9f
  20352. +#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
  20353. +#define WPA_CONFIG 0xb0
  20354. +#define TX_AGC_CTL 0x9c
  20355. +#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01
  20356. +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
  20357. +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
  20358. +#define TX_AGC_CTL_FEEDBACK_ANT 2
  20359. +#define RESP_RATE 0x34
  20360. +#define SIFS 0xb4
  20361. +#define DIFS 0xb5
  20362. +#define EIFS_8187 0x35
  20363. +#define EIFS_8187B 0x2D
  20364. +#define SLOT 0xb6
  20365. +#define CW_VAL 0xbd
  20366. +#define CW_CONF 0xbc
  20367. +#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
  20368. +#define CW_CONF_PERPACKET_CW 0x01
  20369. +#define CW_CONF_PERPACKET_RETRY_SHIFT 1
  20370. +#define CW_CONF_PERPACKET_CW_SHIFT 0
  20371. +#define MAX_RESP_RATE_SHIFT 4
  20372. +#define MIN_RESP_RATE_SHIFT 0
  20373. +#define RATE_FALLBACK 0xbe
  20374. +#define RATE_FALLBACK_CTL_ENABLE 0x80
  20375. +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
  20376. +
  20377. +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
  20378. +#define RMS 0x1EC // Rx Max Pacetk Size (0x1ec[0:12])
  20379. +
  20380. +/*
  20381. + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
  20382. + * is set to 1
  20383. + */
  20384. +
  20385. +#define Wakeup0 0x0084
  20386. +#define Wakeup0_END 0x008B
  20387. +
  20388. +#define Wakeup1 0x008C
  20389. +#define Wakeup1_END 0x0093
  20390. +
  20391. +#define Wakeup2LD 0x0094
  20392. +#define Wakeup2LD_END 0x009B
  20393. +#define Wakeup2HD 0x009C
  20394. +#define Wakeup2HD_END 0x00A3
  20395. +
  20396. +#define Wakeup3LD 0x00A4
  20397. +#define Wakeup3LD_END 0x00AB
  20398. +#define Wakeup3HD 0x00AC
  20399. +#define Wakeup3HD_END 0x00B3
  20400. +
  20401. +#define Wakeup4LD 0x00B4
  20402. +#define Wakeup4LD_END 0x00BB
  20403. +#define Wakeup4HD 0x00BC
  20404. +#define Wakeup4HD_END 0x00C3
  20405. +
  20406. +#define CRC0 0x00C4
  20407. +#define CRC0_END 0x00C5
  20408. +#define CRC1 0x00C6
  20409. +#define CRC1_END 0x00C7
  20410. +#define CRC2 0x00C8
  20411. +#define CRC2_END 0x00C9
  20412. +#define CRC3 0x00CA
  20413. +#define CRC3_END 0x00CB
  20414. +#define CRC4 0x00CC
  20415. +#define CRC4_END 0x00CD
  20416. +
  20417. +/* 0x00CE - 0x00D3 - reserved */
  20418. +
  20419. +
  20420. +
  20421. +/*
  20422. + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
  20423. + * is set to 0
  20424. + */
  20425. +
  20426. +/* 0x0084 - 0x008F - reserved */
  20427. +
  20428. +#define DK0 0x0090
  20429. +#define DK0_END 0x009F
  20430. +#define DK1 0x00A0
  20431. +#define DK1_END 0x00AF
  20432. +#define DK2 0x00B0
  20433. +#define DK2_END 0x00BF
  20434. +#define DK3 0x00C0
  20435. +#define DK3_END 0x00CF
  20436. +
  20437. +#define GPO 0x90
  20438. +#define GPE 0x91
  20439. +#define GPI 0x92
  20440. +
  20441. +#define RFTiming 0x008C
  20442. +#define ACM_CONTROL 0x00BF // ACM Control Registe
  20443. +#define INT_MIG 0x00E2 // Interrupt Migration (0xE2 ~ 0xE3)
  20444. +#define TID_AC_MAP 0x00E8 // TID to AC Mapping Register
  20445. +
  20446. +#define AC_VO_PARAM 0x00F0 // AC_VO Parameters Record
  20447. +#define AC_VI_PARAM 0x00F4 // AC_VI Parameters Record
  20448. +#define AC_BE_PARAM 0x00F8 // AC_BE Parameters Record
  20449. +#define AC_BK_PARAM 0x00FC // AC_BK Parameters Record
  20450. +
  20451. +/* 0x00D0 - 0x00D3 - reserved */
  20452. +#define CCK_FALSE_ALARM 0x00D0
  20453. +#define OFDM_FALSE_ALARM 0x00D2
  20454. +
  20455. +
  20456. +/* 0x00D4 - 0x00D7 - reserved */
  20457. +
  20458. +#define CONFIG5 0x00D8
  20459. +
  20460. +#define TPPoll 0x00D9
  20461. +
  20462. +/* 0x00DA - 0x00DB - reserved */
  20463. +
  20464. +#define CWR 0x00DC
  20465. +#define CWR_END 0x00DD
  20466. +
  20467. +#define RetryCTR 0x00DE
  20468. +
  20469. +/* 0x00DF - 0x00E3 - reserved */
  20470. +
  20471. +#define RDSAR 0x00E4
  20472. +#define RDSAR_END 0x00E7
  20473. +
  20474. +/* 0x00E8 - 0x00EF - reserved */
  20475. +#define ANA_PARAM3 0x00EE
  20476. +
  20477. +#define FER 0x00F0
  20478. +#define FER_END 0x00F3
  20479. +
  20480. +#define FEMR 0x1D4 // Function Event Mask register (0xf4 ~ 0xf7)
  20481. +//#define FEMR 0x00F4
  20482. +#define FEMR_END 0x00F7
  20483. +
  20484. +#define FPSR 0x00F8
  20485. +#define FPSR_END 0x00FB
  20486. +
  20487. +#define FFER 0x00FC
  20488. +#define FFER_END 0x00FF
  20489. +
  20490. +/*
  20491. + * 0x0000 - 0x00ff is selected to page 0 when PSEn bit (bit0, PSR)
  20492. + * is set to 2
  20493. + */
  20494. +#define RFSW_CTRL 0x272 // 0x272-0x273.
  20495. +
  20496. +
  20497. +
  20498. +//----------------------------------------------------------------------------
  20499. +// 8187B AC_XX_PARAM bits
  20500. +//----------------------------------------------------------------------------
  20501. +#define AC_PARAM_TXOP_LIMIT_OFFSET 16
  20502. +#define AC_PARAM_ECW_MAX_OFFSET 12
  20503. +#define AC_PARAM_ECW_MIN_OFFSET 8
  20504. +#define AC_PARAM_AIFS_OFFSET 0
  20505. +
  20506. +//----------------------------------------------------------------------------
  20507. +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
  20508. +//----------------------------------------------------------------------------
  20509. +#define VOQ_ACM_EN (0x01 << 7) //BIT7
  20510. +#define VIQ_ACM_EN (0x01 << 6) //BIT6
  20511. +#define BEQ_ACM_EN (0x01 << 5) //BIT5
  20512. +#define ACM_HW_EN (0x01 << 4) //BIT4
  20513. +#define TXOPSEL (0x01 << 3) //BIT3
  20514. +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
  20515. +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
  20516. +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
  20517. +
  20518. +//----------------------------------------------------------------------------
  20519. +// 8187B RF pins related setting (offset 0xFF80-0xFF87,)
  20520. +//----------------------------------------------------------------------------
  20521. +#define TR_SW_MASK_TX_8187 BIT5
  20522. +#define TR_SW_MASK_RX_8187 BIT6
  20523. +#define TR_SW_MASK_8187 (TR_SW_MASK_TX_8187 | TR_SW_MASK_RX_8187)
  20524. +
  20525. +/*
  20526. + * Bitmasks for specific register functions.
  20527. + * Names are derived from the register name and function name.
  20528. + *
  20529. + * <REGISTER>_<FUNCTION>[<bit>]
  20530. + *
  20531. + * this leads to some awkward names...
  20532. + */
  20533. +
  20534. +#define BRSR_BPLCP ((1<< 8))
  20535. +#define BRSR_MBR ((1<< 1)|(1<< 0))
  20536. +#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0))
  20537. +#define BRSR_MBR0 ((1<< 0))
  20538. +#define BRSR_MBR1 ((1<< 1))
  20539. +
  20540. +#define CR_RST ((1<< 4))
  20541. +#define CR_RE ((1<< 3))
  20542. +#define CR_TE ((1<< 2))
  20543. +#define CR_MulRW ((1<< 0))
  20544. +
  20545. +#define IMR_TXFOVW ((1<<15))
  20546. +#define IMR_TimeOut ((1<<14))
  20547. +#define IMR_BcnInt ((1<<13))
  20548. +#define IMR_ATIMInt ((1<<12))
  20549. +#define IMR_TBDER ((1<<11))
  20550. +#define IMR_TBDOK ((1<<10))
  20551. +#define IMR_THPDER ((1<< 9))
  20552. +#define IMR_THPDOK ((1<< 8))
  20553. +#define IMR_TNPDER ((1<< 7))
  20554. +#define IMR_TNPDOK ((1<< 6))
  20555. +#define IMR_RXFOVW ((1<< 5))
  20556. +#define IMR_RDU ((1<< 4))
  20557. +#define IMR_TLPDER ((1<< 3))
  20558. +#define IMR_TLPDOK ((1<< 2))
  20559. +#define IMR_RER ((1<< 1))
  20560. +#define IMR_ROK ((1<< 0))
  20561. +
  20562. +#define ISR_TXFOVW ((1<<15))
  20563. +#define ISR_TimeOut ((1<<14))
  20564. +#define ISR_BcnInt ((1<<13))
  20565. +#define ISR_ATIMInt ((1<<12))
  20566. +#define ISR_TBDER ((1<<11))
  20567. +#define ISR_TBDOK ((1<<10))
  20568. +#define ISR_THPDER ((1<< 9))
  20569. +#define ISR_THPDOK ((1<< 8))
  20570. +#define ISR_TNPDER ((1<< 7))
  20571. +#define ISR_TNPDOK ((1<< 6))
  20572. +#define ISR_RXFOVW ((1<< 5))
  20573. +#define ISR_RDU ((1<< 4))
  20574. +#define ISR_TLPDER ((1<< 3))
  20575. +#define ISR_TLPDOK ((1<< 2))
  20576. +#define ISR_RER ((1<< 1))
  20577. +#define ISR_ROK ((1<< 0))
  20578. +
  20579. +#define HW_VERID_R8180_F 3
  20580. +#define HW_VERID_R8180_ABCD 2
  20581. +#define HW_VERID_R8185_ABC 4
  20582. +#define HW_VERID_R8185_D 5
  20583. +
  20584. +#define TCR_DurProcMode ((1<<30))
  20585. +#define TCR_DISReqQsize ((1<<28))
  20586. +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
  20587. +#define TCR_HWVERID_SHIFT 25
  20588. +#define TCR_SWPLCPLEN ((1<<24))
  20589. +#define TCR_PLCP_LEN TCR_SAT // rtl8180
  20590. +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
  20591. +#define TCR_MXDMA_1024 6
  20592. +#define TCR_MXDMA_2048 7
  20593. +#define TCR_MXDMA_SHIFT 21
  20594. +#define TCR_DISCW ((1<<20))
  20595. +#define TCR_ICV ((1<<19))
  20596. +#define TCR_LBK ((1<<18)|(1<<17))
  20597. +#define TCR_LBK1 ((1<<18))
  20598. +#define TCR_LBK0 ((1<<17))
  20599. +#define TCR_CRC ((1<<16))
  20600. +#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
  20601. +#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
  20602. +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
  20603. +
  20604. +#define RCR_ONLYERLPKT ((1<<31))
  20605. +#define RCR_CS_SHIFT 29
  20606. +#define RCR_CS_MASK ((1<<30) | (1<<29))
  20607. +#define RCR_ENMARP ((1<<28))
  20608. +#define RCR_CBSSID ((1<<23))
  20609. +#define RCR_APWRMGT ((1<<22))
  20610. +#define RCR_ADD3 ((1<<21))
  20611. +#define RCR_AMF ((1<<20))
  20612. +#define RCR_ACF ((1<<19))
  20613. +#define RCR_ADF ((1<<18))
  20614. +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
  20615. +#define RCR_RXFTH2 ((1<<15))
  20616. +#define RCR_RXFTH1 ((1<<14))
  20617. +#define RCR_RXFTH0 ((1<<13))
  20618. +#define RCR_AICV ((1<<12))
  20619. +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
  20620. +#define RCR_MXDMA2 ((1<<10))
  20621. +#define RCR_MXDMA1 ((1<< 9))
  20622. +#define RCR_MXDMA0 ((1<< 8))
  20623. +#define RCR_9356SEL ((1<< 6))
  20624. +#define RCR_ACRC32 ((1<< 5))
  20625. +#define RCR_AB ((1<< 3))
  20626. +#define RCR_AM ((1<< 2))
  20627. +#define RCR_APM ((1<< 1))
  20628. +#define RCR_AAP ((1<< 0))
  20629. +
  20630. +#define CR9346_EEM ((1<<7)|(1<<6))
  20631. +#define CR9346_EEM1 ((1<<7))
  20632. +#define CR9346_EEM0 ((1<<6))
  20633. +#define CR9346_EECS ((1<<3))
  20634. +#define CR9346_EESK ((1<<2))
  20635. +#define CR9346_EED1 ((1<<1))
  20636. +#define CR9346_EED0 ((1<<0))
  20637. +
  20638. +#define CONFIG0_WEP104 ((1<<6))
  20639. +#define CONFIG0_LEDGPO_En ((1<<4))
  20640. +#define CONFIG0_Aux_Status ((1<<3))
  20641. +#define CONFIG0_GL ((1<<1)|(1<<0))
  20642. +#define CONFIG0_GL1 ((1<<1))
  20643. +#define CONFIG0_GL0 ((1<<0))
  20644. +
  20645. +#define CONFIG1_LEDS ((1<<7)|(1<<6))
  20646. +#define CONFIG1_LEDS1 ((1<<7))
  20647. +#define CONFIG1_LEDS0 ((1<<6))
  20648. +#define CONFIG1_LWACT ((1<<4))
  20649. +#define CONFIG1_MEMMAP ((1<<3))
  20650. +#define CONFIG1_IOMAP ((1<<2))
  20651. +#define CONFIG1_VPD ((1<<1))
  20652. +#define CONFIG1_PMEn ((1<<0))
  20653. +
  20654. +#define CONFIG2_LCK ((1<<7))
  20655. +#define CONFIG2_ANT ((1<<6))
  20656. +#define CONFIG2_DPS ((1<<3))
  20657. +#define CONFIG2_PAPE_sign ((1<<2))
  20658. +#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
  20659. +#define CONFIG2_PAPE_time1 ((1<<1))
  20660. +#define CONFIG2_PAPE_time0 ((1<<0))
  20661. +
  20662. +#define CONFIG3_GNTSel ((1<<7))
  20663. +#define CONFIG3_PARM_En ((1<<6))
  20664. +#define CONFIG3_Magic ((1<<5))
  20665. +#define CONFIG3_CardB_En ((1<<3))
  20666. +#define CONFIG3_CLKRUN_En ((1<<2))
  20667. +#define CONFIG3_FuncRegEn ((1<<1))
  20668. +#define CONFIG3_FBtbEn ((1<<0))
  20669. +
  20670. +#define CONFIG4_VCOPDN ((1<<7))
  20671. +#define CONFIG4_PWROFF ((1<<6))
  20672. +#define CONFIG4_PWRMGT ((1<<5))
  20673. +#define CONFIG4_LWPME ((1<<4))
  20674. +#define CONFIG4_LWPTN ((1<<2))
  20675. +#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
  20676. +#define CONFIG4_RFTYPE1 ((1<<1))
  20677. +#define CONFIG4_RFTYPE0 ((1<<0))
  20678. +
  20679. +#define CONFIG5_TX_FIFO_OK ((1<<7))
  20680. +#define CONFIG5_RX_FIFO_OK ((1<<6))
  20681. +#define CONFIG5_CALON ((1<<5))
  20682. +#define CONFIG5_EACPI ((1<<2))
  20683. +#define CONFIG5_LANWake ((1<<1))
  20684. +#define CONFIG5_PME_STS ((1<<0))
  20685. +
  20686. +#define MSR_LINK_MASK ((1<<2)|(1<<3))
  20687. +#define MSR_LINK_MANAGED 2
  20688. +#define MSR_LINK_NONE 0
  20689. +#define MSR_LINK_SHIFT 2
  20690. +#define MSR_LINK_ADHOC 1
  20691. +#define MSR_LINK_MASTER 3
  20692. +#define MSR_LINK_ENEDCA (1<<4)
  20693. +
  20694. +#define PSR_GPO ((1<<7))
  20695. +#define PSR_GPI ((1<<6))
  20696. +#define PSR_LEDGPO1 ((1<<5))
  20697. +#define PSR_LEDGPO0 ((1<<4))
  20698. +#define PSR_UWF ((1<<1))
  20699. +#define PSR_PSEn ((1<<0))
  20700. +
  20701. +#define SCR_KM ((1<<5)|(1<<4))
  20702. +#define SCR_KM1 ((1<<5))
  20703. +#define SCR_KM0 ((1<<4))
  20704. +#define SCR_TXSECON ((1<<1))
  20705. +#define SCR_RXSECON ((1<<0))
  20706. +
  20707. +#define BcnItv_BcnItv (0x01FF)
  20708. +
  20709. +#define AtimWnd_AtimWnd (0x01FF)
  20710. +
  20711. +#define BintrItv_BintrItv (0x01FF)
  20712. +
  20713. +#define AtimtrItv_AtimtrItv (0x01FF)
  20714. +
  20715. +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
  20716. +
  20717. +#define TPPoll_BQ ((1<<7))
  20718. +#define TPPoll_HPQ ((1<<6))
  20719. +#define TPPoll_NPQ ((1<<5))
  20720. +#define TPPoll_LPQ ((1<<4))
  20721. +#define TPPoll_SBQ ((1<<3))
  20722. +#define TPPoll_SHPQ ((1<<2))
  20723. +#define TPPoll_SNPQ ((1<<1))
  20724. +#define TPPoll_SLPQ ((1<<0))
  20725. +
  20726. +#define CWR_CW (0x01FF)
  20727. +
  20728. +#define FER_INTR ((1<<15))
  20729. +#define FER_GWAKE ((1<< 4))
  20730. +
  20731. +#define FEMR_INTR ((1<<15))
  20732. +#define FEMR_WKUP ((1<<14))
  20733. +#define FEMR_GWAKE ((1<< 4))
  20734. +
  20735. +#define FPSR_INTR ((1<<15))
  20736. +#define FPSR_GWAKE ((1<< 4))
  20737. +
  20738. +#define FFER_INTR ((1<<15))
  20739. +#define FFER_GWAKE ((1<< 4))
  20740. +
  20741. +
  20742. +//----------------------------------------------------------------------------
  20743. +// 818xB AnaParm & AnaParm2 Register
  20744. +//----------------------------------------------------------------------------
  20745. +/*
  20746. +#ifdef RTL8185B_FPGA
  20747. +#define ANAPARM_FPGA_ON 0xa0000b59
  20748. +//#define ANAPARM_FPGA_OFF
  20749. +#define ANAPARM2_FPGA_ON 0x860dec11
  20750. +//#define ANAPARM2_FPGA_OFF
  20751. +#else //ASIC
  20752. +*/
  20753. +#define ANAPARM_ASIC_ON 0x45090658
  20754. +//#define ANAPARM_ASIC_OFF
  20755. +#define ANAPARM2_ASIC_ON 0x727f3f52
  20756. +//#define ANAPARM2_ASIC_OFF
  20757. +//#endif
  20758. +//by amy for power save
  20759. +#define RF_CHANGE_BY_SW BIT31
  20760. +#define RF_CHANGE_BY_HW BIT30
  20761. +#define RF_CHANGE_BY_PS BIT29
  20762. +#define RF_CHANGE_BY_IPS BIT28
  20763. +#define ANAPARM_ASIC_ON 0x45090658
  20764. +#define ANAPARM2_ASIC_ON 0x727f3f52
  20765. +
  20766. +#define ANAPARM_ON ANAPARM_ASIC_ON
  20767. +#define ANAPARM2_ON ANAPARM2_ASIC_ON
  20768. +#define TFPC 0x5C // Tx FIFO Packet Count for BK, BE, VI, VO queues (2 bytes)
  20769. +#define Config4_PowerOff BIT6 // Turn ON/Off RF Power(RFMD)
  20770. +#define ANAPARM_OFF 0x51480658
  20771. +#define ANAPARM2_OFF 0x72003f70
  20772. +//by amy for power save
  20773. +
  20774. +#define MAX_DOZE_WAITING_TIMES_87B 500
  20775. +
  20776. +#endif
  20777. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.c
  20778. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.c 1970-01-01 01:00:00.000000000 +0100
  20779. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.c 2010-03-06 16:43:22.000000000 +0100
  20780. @@ -0,0 +1,97 @@
  20781. +/*
  20782. + Power management interface routines.
  20783. + Written by Mariusz Matuszek.
  20784. + This code is currently just a placeholder for later work and
  20785. + does not do anything useful.
  20786. +
  20787. + This is part of rtl8180 OpenSource driver.
  20788. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  20789. + Released under the terms of GPL (General Public Licence)
  20790. +*/
  20791. +
  20792. +#ifdef CONFIG_RTL8180_PM
  20793. +
  20794. +
  20795. +#include "r8180_hw.h"
  20796. +#include "r8180_pm.h"
  20797. +#include "r8187.h"
  20798. +int rtl8180_save_state (struct pci_dev *dev, u32 state)
  20799. +{
  20800. + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
  20801. + return(-EAGAIN);
  20802. +}
  20803. +
  20804. +//netif_running is set to 0 before system call rtl8180_close,
  20805. +//netif_running is set to 1 before system call rtl8180_open,
  20806. +//if open success it will not change, or it change to 0;
  20807. +int rtl8187_suspend (struct usb_interface *intf, pm_message_t state)
  20808. +{
  20809. + struct r8180_priv *priv;
  20810. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  20811. + struct net_device *dev = usb_get_intfdata(intf);
  20812. +#else
  20813. + //struct net_device *dev = (struct net_device *)ptr;
  20814. +#endif
  20815. +
  20816. + printk("====>%s \n", __func__);
  20817. + priv=ieee80211_priv(dev);
  20818. +
  20819. + if(dev) {
  20820. + /* save the old rfkill state and then power off it */
  20821. + priv->eInactivePowerState = priv->eRFPowerState;
  20822. + /* power off the wifi by default */
  20823. + r8187b_wifi_change_rfkill_state(dev, eRfOff);
  20824. +
  20825. + if (!netif_running(dev)) {
  20826. + //printk(KERN_WARNING "UI or other close dev before suspend, go out suspend function\n");
  20827. + return 0;
  20828. + }
  20829. +
  20830. + dev->netdev_ops->ndo_stop(dev);
  20831. + netif_device_detach(dev);
  20832. + }
  20833. + return 0;
  20834. +}
  20835. +
  20836. +
  20837. +int rtl8187_resume (struct usb_interface *intf)
  20838. +{
  20839. + struct r8180_priv *priv;
  20840. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  20841. + struct net_device *dev = usb_get_intfdata(intf);
  20842. +#else
  20843. + //struct net_device *dev = (struct net_device *)ptr;
  20844. +#endif
  20845. +
  20846. + printk("====>%s \n", __func__);
  20847. + priv=ieee80211_priv(dev);
  20848. +
  20849. + if(dev) {
  20850. + /* resume the old rfkill state */
  20851. + r8187b_wifi_change_rfkill_state(dev, priv->eInactivePowerState);
  20852. +
  20853. + if (!netif_running(dev)){
  20854. + //printk(KERN_WARNING "UI or other close dev before suspend, go out resume function\n");
  20855. + return 0;
  20856. + }
  20857. +
  20858. + netif_device_attach(dev);
  20859. + dev->netdev_ops->ndo_open(dev);
  20860. + }
  20861. +
  20862. + return 0;
  20863. +}
  20864. +
  20865. +
  20866. +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
  20867. +{
  20868. +
  20869. + //printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
  20870. + // state, enable);
  20871. + return 0;
  20872. + //return(-EAGAIN);
  20873. +}
  20874. +
  20875. +
  20876. +
  20877. +#endif //CONFIG_RTL8180_PM
  20878. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.h
  20879. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.h 1970-01-01 01:00:00.000000000 +0100
  20880. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.h 2010-03-06 16:43:22.000000000 +0100
  20881. @@ -0,0 +1,28 @@
  20882. +/*
  20883. + Power management interface routines.
  20884. + Written by Mariusz Matuszek.
  20885. + This code is currently just a placeholder for later work and
  20886. + does not do anything useful.
  20887. +
  20888. + This is part of rtl8180 OpenSource driver.
  20889. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  20890. + Released under the terms of GPL (General Public Licence)
  20891. +
  20892. +*/
  20893. +
  20894. +#ifdef CONFIG_RTL8180_PM
  20895. +
  20896. +#ifndef R8180_PM_H
  20897. +#define R8180_PM_H
  20898. +
  20899. +#include <linux/types.h>
  20900. +#include <linux/usb.h>
  20901. +
  20902. +int rtl8180_save_state (struct pci_dev *dev, u32 state);
  20903. +int rtl8187_suspend (struct usb_interface *intf,pm_message_t state);
  20904. +int rtl8187_resume (struct usb_interface *intf);
  20905. +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
  20906. +
  20907. +#endif //R8180_PM_H
  20908. +
  20909. +#endif // CONFIG_RTL8180_PM
  20910. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
  20911. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 1970-01-01 01:00:00.000000000 +0100
  20912. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 2010-03-06 16:43:22.000000000 +0100
  20913. @@ -0,0 +1,1007 @@
  20914. +/*
  20915. + This is part of the rtl8180-sa2400 driver
  20916. + released under the GPL (See file COPYING for details).
  20917. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  20918. +
  20919. + This files contains programming code for the rtl8225
  20920. + radio frontend.
  20921. +
  20922. + *Many* thanks to Realtek Corp. for their great support!
  20923. +
  20924. +*/
  20925. +
  20926. +
  20927. +
  20928. +#include "r8180_hw.h"
  20929. +#include "r8180_rtl8225.h"
  20930. +#ifdef ENABLE_DOT11D
  20931. +#include "dot11d.h"
  20932. +#endif
  20933. +
  20934. +#define USE_8051_3WIRE 1
  20935. +
  20936. +u8 rtl8225_threshold[]={
  20937. + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
  20938. +};
  20939. +
  20940. +u8 rtl8225_gain[]={
  20941. + 0x23,0x88,0x7c,0xa5,// -82dbm
  20942. + 0x23,0x88,0x7c,0xb5,// -82dbm
  20943. + 0x23,0x88,0x7c,0xc5,// -82dbm
  20944. + 0x33,0x80,0x79,0xc5,// -78dbm
  20945. + 0x43,0x78,0x76,0xc5,// -74dbm
  20946. + 0x53,0x60,0x73,0xc5,// -70dbm
  20947. + 0x63,0x58,0x70,0xc5,// -66dbm
  20948. +};
  20949. +
  20950. +u16 rtl8225bcd_rxgain[]={
  20951. + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
  20952. + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
  20953. + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
  20954. + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
  20955. + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
  20956. + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
  20957. + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
  20958. + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
  20959. + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
  20960. + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
  20961. + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
  20962. + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
  20963. +
  20964. +};
  20965. +
  20966. +
  20967. +
  20968. +u8 rtl8225_tx_gain_cck_ofdm[]={
  20969. + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
  20970. +};
  20971. +
  20972. +
  20973. +u8 rtl8225_tx_power_ofdm[]={
  20974. + 0x80,0x90,0xa2,0xb5,0xcb,0xe4
  20975. +};
  20976. +
  20977. +
  20978. +u8 rtl8225_tx_power_cck_ch14[]={
  20979. + 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
  20980. + 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
  20981. + 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
  20982. + 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
  20983. + 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
  20984. + 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
  20985. +};
  20986. +
  20987. +
  20988. +u8 rtl8225_tx_power_cck[]={
  20989. + 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
  20990. + 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
  20991. + 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
  20992. + 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
  20993. + 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
  20994. + 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
  20995. +};
  20996. +
  20997. +u8 rtl8225_agc[]={
  20998. + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
  20999. + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
  21000. + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
  21001. + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
  21002. + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
  21003. + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
  21004. + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  21005. + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  21006. +};
  21007. +
  21008. +u32 rtl8225_chan[] = {
  21009. + 0, //dummy channel 0
  21010. + 0x085c, //1
  21011. + 0x08dc, //2
  21012. + 0x095c, //3
  21013. + 0x09dc, //4
  21014. + 0x0a5c, //5
  21015. + 0x0adc, //6
  21016. + 0x0b5c, //7
  21017. + 0x0bdc, //8
  21018. + 0x0c5c, //9
  21019. + 0x0cdc, //10
  21020. + 0x0d5c, //11
  21021. + 0x0ddc, //12
  21022. + 0x0e5c, //13
  21023. + //0x0f5c, //14
  21024. + 0x0f72, // 14
  21025. +};
  21026. +
  21027. +void rtl8225_set_gain(struct net_device *dev, short gain)
  21028. +{
  21029. + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
  21030. + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
  21031. + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
  21032. + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
  21033. +
  21034. +}
  21035. +
  21036. +
  21037. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
  21038. +{
  21039. +//in windows the delays in this function was del from 85 to 87,
  21040. +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  21041. +
  21042. +#ifdef USE_8051_3WIRE
  21043. +
  21044. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  21045. + struct usb_device *udev = priv->udev;
  21046. + //u8 bit;
  21047. + //u16 wReg80, wReg82, wReg84;
  21048. + u16 wReg80, wReg84;
  21049. +
  21050. + wReg80 = read_nic_word(dev, RFPinsOutput);
  21051. + wReg80 &= 0xfff3;
  21052. +// wReg82 = read_nic_word(dev, RFPinsEnable);
  21053. + wReg84 = read_nic_word(dev, RFPinsSelect);
  21054. + // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
  21055. + //wReg84 &= 0xfff0;
  21056. + wReg84 &= 0xfff8; //modified by david according to windows segment code.
  21057. +
  21058. + // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko.
  21059. +// write_nic_word(dev, RFPinsEnable, (wReg82|0x0007)); // Set To Output Enable
  21060. + write_nic_word(dev, RFPinsSelect, (wReg84|0x0007)); // Set To SW Switch
  21061. +// force_pci_posting(dev);
  21062. +// udelay(10); //
  21063. +
  21064. + write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE)
  21065. +// force_pci_posting(dev);
  21066. +// udelay(2);
  21067. + //twreg.struc.enableB = 0;
  21068. + write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE)
  21069. +// force_pci_posting(dev);
  21070. +// udelay(10);
  21071. +
  21072. + usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  21073. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  21074. + adr, 0x8225, &data, 2, HZ / 2);
  21075. +
  21076. + // write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80));
  21077. +// force_pci_posting(dev);
  21078. +// udelay(10);
  21079. +
  21080. + write_nic_word(dev, 0x80, (wReg80|0x0004));
  21081. + write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch
  21082. +
  21083. + if(priv->card_type == USB)
  21084. + ;// msleep(2);
  21085. + else
  21086. + ; // rtl8185_rf_pins_enable(dev);
  21087. +
  21088. +#else
  21089. + int i;
  21090. + u16 out,select;
  21091. + u8 bit;
  21092. + u32 bangdata = (data << 4) | (adr & 0xf);
  21093. + struct r8180_priv *priv = ieee80211_priv(dev);
  21094. +
  21095. + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
  21096. +
  21097. + write_nic_word(dev,RFPinsEnable,
  21098. + (read_nic_word(dev,RFPinsEnable) | 0x7));
  21099. +
  21100. + select = read_nic_word(dev, RFPinsSelect);
  21101. +
  21102. + write_nic_word(dev, RFPinsSelect, select | 0x7 |
  21103. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  21104. +
  21105. +// force_pci_posting(dev);
  21106. +// udelay(10);
  21107. +
  21108. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
  21109. +
  21110. +// force_pci_posting(dev);
  21111. +// udelay(2);
  21112. +
  21113. + write_nic_word(dev, RFPinsOutput, out);
  21114. +
  21115. +// force_pci_posting(dev);
  21116. +// udelay(10);
  21117. +
  21118. +
  21119. + for(i=15; i>=0;i--){
  21120. +
  21121. + bit = (bangdata & (1<<i)) >> i;
  21122. +
  21123. + write_nic_word(dev, RFPinsOutput, bit | out);
  21124. +
  21125. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21126. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21127. +
  21128. + i--;
  21129. + bit = (bangdata & (1<<i)) >> i;
  21130. +
  21131. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21132. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21133. +
  21134. + write_nic_word(dev, RFPinsOutput, bit | out);
  21135. +
  21136. + }
  21137. +
  21138. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
  21139. +
  21140. +// force_pci_posting(dev);
  21141. +// udelay(10);
  21142. +
  21143. + write_nic_word(dev, RFPinsOutput, out |
  21144. + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
  21145. +
  21146. + write_nic_word(dev, RFPinsSelect, select |
  21147. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  21148. +
  21149. + if(priv->card_type == USB)
  21150. + ;// msleep(2);
  21151. + else
  21152. +// rtl8185_rf_pins_enable(dev);
  21153. +#endif
  21154. +}
  21155. +
  21156. +
  21157. +void write_rtl8225_patch(struct net_device *dev, u8 adr, u16 data)
  21158. +{
  21159. +
  21160. + int i;
  21161. + u16 out,select;
  21162. + u8 bit;
  21163. + u32 bangdata = (data << 4) | (adr & 0xf);
  21164. + struct r8180_priv *priv = ieee80211_priv(dev);
  21165. +
  21166. + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
  21167. +
  21168. + write_nic_word(dev,RFPinsEnable,
  21169. + (read_nic_word(dev,RFPinsEnable) | 0x7));
  21170. +
  21171. + select = read_nic_word(dev, RFPinsSelect);
  21172. +
  21173. + write_nic_word(dev, RFPinsSelect, select | 0x7 |
  21174. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  21175. +
  21176. + force_pci_posting(dev);
  21177. + udelay(10);
  21178. +
  21179. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
  21180. +
  21181. + force_pci_posting(dev);
  21182. + udelay(2);
  21183. +
  21184. + write_nic_word(dev, RFPinsOutput, out);
  21185. +
  21186. + force_pci_posting(dev);
  21187. + udelay(10);
  21188. +
  21189. + for(i=15; i>=0;i--){
  21190. +
  21191. + bit = (bangdata & (1<<i)) >> i;
  21192. +
  21193. + write_nic_word(dev, RFPinsOutput, bit | out);
  21194. +
  21195. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21196. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21197. +
  21198. + i--;
  21199. + bit = (bangdata & (1<<i)) >> i;
  21200. +
  21201. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21202. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  21203. +
  21204. + write_nic_word(dev, RFPinsOutput, bit | out);
  21205. +
  21206. + }
  21207. +
  21208. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
  21209. +
  21210. + force_pci_posting(dev);
  21211. + udelay(10);
  21212. +
  21213. + write_nic_word(dev, RFPinsOutput, out |
  21214. + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
  21215. +
  21216. + write_nic_word(dev, RFPinsSelect, select |
  21217. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  21218. +
  21219. + if(priv->card_type == USB)
  21220. + mdelay(2);
  21221. + else
  21222. + rtl8185_rf_pins_enable(dev);
  21223. +
  21224. +}
  21225. +
  21226. +void rtl8225_rf_close(struct net_device *dev)
  21227. +{
  21228. + write_rtl8225(dev, 0x4, 0x1f);
  21229. +
  21230. + force_pci_posting(dev);
  21231. + mdelay(1);
  21232. +
  21233. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
  21234. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
  21235. +}
  21236. +
  21237. +#ifdef ENABLE_DOT11D
  21238. +//
  21239. +// Description:
  21240. +// Map dBm into Tx power index according to
  21241. +// current HW model, for example, RF and PA, and
  21242. +// current wireless mode.
  21243. +//
  21244. +s8
  21245. +DbmToTxPwrIdx(
  21246. + struct r8180_priv *priv,
  21247. + WIRELESS_MODE WirelessMode,
  21248. + s32 PowerInDbm
  21249. + )
  21250. +{
  21251. + bool bUseDefault = true;
  21252. + s8 TxPwrIdx = 0;
  21253. +
  21254. +#ifdef CONFIG_RTL818X_S
  21255. + //
  21256. + // 071011, SD3 SY:
  21257. + // OFDM Power in dBm = Index * 0.5 + 0
  21258. + // CCK Power in dBm = Index * 0.25 + 13
  21259. + //
  21260. + if(priv->card_8185 >= VERSION_8187S_B)
  21261. + {
  21262. + s32 tmp = 0;
  21263. +
  21264. + if(WirelessMode == WIRELESS_MODE_G)
  21265. + {
  21266. + bUseDefault = false;
  21267. + tmp = (2 * PowerInDbm);
  21268. +
  21269. + if(tmp < 0)
  21270. + TxPwrIdx = 0;
  21271. + else if(tmp > 40) // 40 means 20 dBm.
  21272. + TxPwrIdx = 40;
  21273. + else
  21274. + TxPwrIdx = (s8)tmp;
  21275. + }
  21276. + else if(WirelessMode == WIRELESS_MODE_B)
  21277. + {
  21278. + bUseDefault = false;
  21279. + tmp = (4 * PowerInDbm) - 52;
  21280. +
  21281. + if(tmp < 0)
  21282. + TxPwrIdx = 0;
  21283. + else if(tmp > 28) // 28 means 20 dBm.
  21284. + TxPwrIdx = 28;
  21285. + else
  21286. + TxPwrIdx = (s8)tmp;
  21287. + }
  21288. + }
  21289. +#endif
  21290. +
  21291. + //
  21292. + // TRUE if we want to use a default implementation.
  21293. + // We shall set it to FALSE when we have exact translation formular
  21294. + // for target IC. 070622, by rcnjko.
  21295. + //
  21296. + if(bUseDefault)
  21297. + {
  21298. + if(PowerInDbm < 0)
  21299. + TxPwrIdx = 0;
  21300. + else if(PowerInDbm > 35)
  21301. + TxPwrIdx = 35;
  21302. + else
  21303. + TxPwrIdx = (u8)PowerInDbm;
  21304. + }
  21305. +
  21306. + return TxPwrIdx;
  21307. +}
  21308. +#endif
  21309. +
  21310. +
  21311. +short rtl8225_rf_set_sens(struct net_device *dev, short sens)
  21312. +{
  21313. + if (sens <0 || sens > 6) return -1;
  21314. +
  21315. + if(sens > 4)
  21316. + write_rtl8225(dev, 0x0c, 0x850);
  21317. + else
  21318. + write_rtl8225(dev, 0x0c, 0x50);
  21319. +
  21320. + sens= 6-sens;
  21321. + rtl8225_set_gain(dev, sens);
  21322. +
  21323. + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
  21324. + return 0;
  21325. +
  21326. +}
  21327. +
  21328. +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
  21329. +{
  21330. + struct r8180_priv *priv = ieee80211_priv(dev);
  21331. +
  21332. + int GainIdx;
  21333. + int GainSetting;
  21334. + int i;
  21335. + u8 power;
  21336. + u8 *cck_power_table;
  21337. + u8 max_cck_power_level;
  21338. + u8 max_ofdm_power_level;
  21339. + u8 min_ofdm_power_level;
  21340. + u8 cck_power_level = 0xff & priv->chtxpwr[ch];
  21341. + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
  21342. +
  21343. +#ifdef ENABLE_DOT11D
  21344. + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
  21345. + IS_DOT11D_STATE_DONE(priv->ieee80211) )
  21346. + {
  21347. + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
  21348. + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
  21349. + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
  21350. + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
  21351. +
  21352. + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
  21353. +
  21354. + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
  21355. + // ch, cck_power_level, ofdm_power_level);
  21356. +
  21357. + if(cck_power_level > CckMaxPwrIdx)
  21358. + cck_power_level = CckMaxPwrIdx;
  21359. + if(ofdm_power_level > OfdmMaxPwrIdx)
  21360. + ofdm_power_level = OfdmMaxPwrIdx;
  21361. + }
  21362. +
  21363. + //priv->CurrentCckTxPwrIdx = cck_power_level;
  21364. + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
  21365. +#endif
  21366. +
  21367. +
  21368. + if(priv->card_type == USB){
  21369. + max_cck_power_level = 11;
  21370. + max_ofdm_power_level = 25; // 12 -> 25
  21371. + min_ofdm_power_level = 10;
  21372. + }else{
  21373. + max_cck_power_level = 35;
  21374. + max_ofdm_power_level = 35;
  21375. + min_ofdm_power_level = 0;
  21376. + }
  21377. + if( priv->TrSwitchState == TR_SW_TX )
  21378. + {
  21379. + printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d\n", ofdm_power_level);
  21380. + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
  21381. + cck_power_level -= GetTxCckHighPowerBias(dev);
  21382. + printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
  21383. + ofdm_power_level);
  21384. + printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
  21385. + cck_power_level);
  21386. + }
  21387. +
  21388. +
  21389. +
  21390. + /* CCK power setting */
  21391. + if(cck_power_level > max_cck_power_level)
  21392. + cck_power_level = max_cck_power_level;
  21393. + GainIdx=cck_power_level % 6;
  21394. + GainSetting=cck_power_level / 6;
  21395. +
  21396. + if(ch == 14)
  21397. + cck_power_table = rtl8225_tx_power_cck_ch14;
  21398. + else
  21399. + cck_power_table = rtl8225_tx_power_cck;
  21400. +
  21401. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
  21402. + /*Ver B*/
  21403. +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
  21404. +// }else{
  21405. + /*Ver C - D */
  21406. + write_nic_byte(dev, CCK_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
  21407. +// }
  21408. +
  21409. + for(i=0;i<8;i++){
  21410. +
  21411. + power = cck_power_table[GainIdx * 8 + i];
  21412. + write_phy_cck(dev, 0x44 + i, power);
  21413. + }
  21414. +
  21415. + /* FIXME Is this delay really needeed ? */
  21416. + force_pci_posting(dev);
  21417. + mdelay(1);
  21418. +
  21419. + /* OFDM power setting */
  21420. +// Old:
  21421. +// if(ofdm_power_level > max_ofdm_power_level)
  21422. +// ofdm_power_level = 35;
  21423. +// ofdm_power_level += min_ofdm_power_level;
  21424. +// Latest:
  21425. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  21426. + ofdm_power_level = max_ofdm_power_level;
  21427. + else
  21428. + ofdm_power_level += min_ofdm_power_level;
  21429. + if(ofdm_power_level > 35)
  21430. + ofdm_power_level = 35;
  21431. +//
  21432. +
  21433. + GainIdx=ofdm_power_level % 6;
  21434. + GainSetting=ofdm_power_level / 6;
  21435. +#if 1
  21436. +// if(priv->card_type == USB){
  21437. + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
  21438. +
  21439. + write_phy_ofdm(dev,2,0x42);
  21440. + write_phy_ofdm(dev,6,0);
  21441. + write_phy_ofdm(dev,8,0);
  21442. +// }
  21443. +#endif
  21444. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
  21445. +// /*Ver B*/
  21446. +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
  21447. +// }else{
  21448. + /*Ver C - D */
  21449. + write_nic_byte(dev, OFDM_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
  21450. +// }
  21451. +
  21452. +
  21453. + power = rtl8225_tx_power_ofdm[GainIdx];
  21454. +
  21455. + write_phy_ofdm(dev, 0x5, power);
  21456. + write_phy_ofdm(dev, 0x7, power);
  21457. +
  21458. + force_pci_posting(dev);
  21459. + mdelay(1);
  21460. + //write_nic_byte(dev, TX_AGC_CONTROL,4);
  21461. +}
  21462. +
  21463. +void rtl8225_rf_set_chan(struct net_device *dev, short ch)
  21464. +{
  21465. + struct r8180_priv *priv = ieee80211_priv(dev);
  21466. + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
  21467. + ieee80211_is_54g(priv->ieee80211->current_network)) ||
  21468. + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
  21469. + int eifs_addr;
  21470. +
  21471. + if(NIC_8187 == priv->card_8187) {
  21472. + eifs_addr = EIFS_8187;
  21473. + } else {
  21474. + eifs_addr = EIFS_8187B;
  21475. + }
  21476. +
  21477. +#ifdef ENABLE_DOT11D
  21478. + if(!IsLegalChannel(priv->ieee80211, ch) )
  21479. + {
  21480. + printk("channel(%d). is invalide\n", ch);
  21481. + return;
  21482. + }
  21483. +#endif
  21484. +
  21485. + rtl8225_SetTXPowerLevel(dev, ch);
  21486. +
  21487. + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
  21488. +
  21489. + force_pci_posting(dev);
  21490. + mdelay(10);
  21491. +
  21492. + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
  21493. +
  21494. + if(gset)
  21495. + write_nic_byte(dev,DIFS,20); //DIFS: 20
  21496. + else
  21497. + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
  21498. +
  21499. + if(priv->ieee80211->state == IEEE80211_LINKED &&
  21500. + ieee80211_is_shortslot(priv->ieee80211->current_network))
  21501. + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
  21502. +
  21503. + else
  21504. + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
  21505. +
  21506. +
  21507. + if(gset){
  21508. + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
  21509. + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
  21510. + //DMESG("using G net params");
  21511. + }else{
  21512. + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
  21513. + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
  21514. + //DMESG("using B net params");
  21515. + }
  21516. +
  21517. +
  21518. +}
  21519. +
  21520. +void rtl8225_host_pci_init(struct net_device *dev)
  21521. +{
  21522. + write_nic_word(dev, RFPinsOutput, 0x480);
  21523. +
  21524. + rtl8185_rf_pins_enable(dev);
  21525. +
  21526. + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
  21527. + //write_nic_word(dev, RFPinsSelect, 0x88);
  21528. + //else
  21529. + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
  21530. +
  21531. + write_nic_byte(dev, GP_ENABLE, 0);
  21532. +
  21533. + force_pci_posting(dev);
  21534. + mdelay(200);
  21535. +
  21536. + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
  21537. +
  21538. +
  21539. +}
  21540. +
  21541. +void rtl8225_host_usb_init(struct net_device *dev)
  21542. +{
  21543. + write_nic_byte(dev,RFPinsSelect+1,0);
  21544. +
  21545. + write_nic_byte(dev,GPIO,0);
  21546. +
  21547. + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
  21548. +
  21549. + write_nic_byte(dev,RFPinsSelect+1,4);
  21550. +
  21551. + write_nic_byte(dev,GPIO,0x20);
  21552. +
  21553. + write_nic_byte(dev,GP_ENABLE,0);
  21554. +
  21555. +
  21556. + /* Config BB & RF */
  21557. + write_nic_word(dev, RFPinsOutput, 0x80);
  21558. +
  21559. + write_nic_word(dev, RFPinsSelect, 0x80);
  21560. +
  21561. + write_nic_word(dev, RFPinsEnable, 0x80);
  21562. +
  21563. +
  21564. + mdelay(100);
  21565. +
  21566. + mdelay(1000);
  21567. +
  21568. +}
  21569. +
  21570. +void rtl8225_rf_init(struct net_device *dev)
  21571. +{
  21572. + struct r8180_priv *priv = ieee80211_priv(dev);
  21573. + int i;
  21574. + short channel = 1;
  21575. + u16 brsr;
  21576. + int brsr_addr;
  21577. +
  21578. + if(NIC_8187 == priv->card_8187) {
  21579. + brsr_addr = BRSR_8187;
  21580. + } else {
  21581. + brsr_addr = BRSR_8187B;
  21582. + }
  21583. +
  21584. +
  21585. + priv->chan = channel;
  21586. +
  21587. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  21588. +
  21589. +
  21590. + if(priv->card_type == USB)
  21591. + rtl8225_host_usb_init(dev);
  21592. + else
  21593. + rtl8225_host_pci_init(dev);
  21594. +
  21595. + write_nic_dword(dev, RF_TIMING, 0x000a8008);
  21596. +
  21597. + //brsr = read_nic_word(dev, BRSR);
  21598. + brsr = read_nic_word(dev, brsr_addr);
  21599. +
  21600. + //write_nic_word(dev, BRSR, 0xffff);
  21601. + write_nic_word(dev, brsr_addr, 0xffff);
  21602. +
  21603. + write_nic_dword(dev, RF_PARA, 0x100044);
  21604. +
  21605. + #if 1 //0->1
  21606. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  21607. + write_nic_byte(dev, CONFIG3, 0x44);
  21608. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  21609. + #endif
  21610. +
  21611. + if(priv->card_type == USB){
  21612. + rtl8185_rf_pins_enable(dev);
  21613. +
  21614. + mdelay(1000);
  21615. + }
  21616. +
  21617. + write_rtl8225(dev, 0x0, 0x67); mdelay(1);
  21618. +
  21619. +
  21620. + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
  21621. +
  21622. + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
  21623. +
  21624. + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
  21625. +
  21626. + if(priv->card_type == USB)
  21627. + write_rtl8225(dev, 0x4, 0x486);
  21628. + else
  21629. + write_rtl8225(dev, 0x4, 0x8be);
  21630. +
  21631. + mdelay(1);
  21632. +
  21633. +
  21634. + /* version B & C */
  21635. +
  21636. + if(priv->card_type == USB)
  21637. + write_rtl8225(dev, 0x5, 0xbc0);
  21638. + else if(priv->card_type == MINIPCI)
  21639. + write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
  21640. + else
  21641. + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
  21642. +
  21643. + mdelay(1);
  21644. +// }
  21645. +
  21646. + write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
  21647. +
  21648. + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
  21649. +
  21650. + write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
  21651. +
  21652. + write_rtl8225(dev, 0x9, 0x334); mdelay(1);
  21653. +
  21654. + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
  21655. +
  21656. + write_rtl8225(dev, 0xb, 0x391); mdelay(1);
  21657. +
  21658. + write_rtl8225(dev, 0xc, 0x50); mdelay(1);
  21659. +
  21660. +
  21661. + write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
  21662. +
  21663. + write_rtl8225(dev, 0xe, 0x29); mdelay(1);
  21664. +
  21665. + write_rtl8225(dev, 0xf, 0x914);
  21666. +
  21667. + if(priv->card_type == USB){
  21668. + //force_pci_posting(dev);
  21669. + mdelay(100);
  21670. + }
  21671. +
  21672. + write_rtl8225(dev, 0x2, 0xc4d);
  21673. +
  21674. + if(priv->card_type == USB){
  21675. + // force_pci_posting(dev);
  21676. + mdelay(200);
  21677. +
  21678. + write_rtl8225(dev, 0x2, 0x44d);
  21679. +
  21680. + // force_pci_posting(dev);
  21681. + mdelay(100);
  21682. +
  21683. + }//End of if(priv->card_type == USB)
  21684. + /* FIXME!! rtl8187 we have to check if calibrarion
  21685. + * is successful and eventually cal. again (repeat
  21686. + * the two write on reg 2)
  21687. + */
  21688. + force_pci_posting(dev);
  21689. +
  21690. + mdelay(100); //200 for 8187
  21691. +
  21692. + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
  21693. +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  21694. +
  21695. + write_rtl8225(dev, 0x0, 0x127);
  21696. +
  21697. + for(i=0;i<95;i++){
  21698. + write_rtl8225(dev, 0x1, (u8)(i+1));
  21699. +
  21700. + /* version B & C & D*/
  21701. +
  21702. + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
  21703. + }
  21704. +
  21705. + write_rtl8225(dev, 0x0, 0x27);
  21706. +
  21707. +
  21708. +// //if(priv->card_type != USB){
  21709. +// write_rtl8225(dev, 0x2, 0x44d);
  21710. +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  21711. +// write_rtl8225(dev, 0x2, 0x47d);
  21712. +//
  21713. +// force_pci_posting(dev);
  21714. +// mdelay(100);
  21715. +//
  21716. +// write_rtl8225(dev, 0x2, 0x44d);
  21717. +// //}
  21718. +
  21719. + write_rtl8225(dev, 0x0, 0x22f);
  21720. +
  21721. + if(priv->card_type != USB)
  21722. + rtl8185_rf_pins_enable(dev);
  21723. +
  21724. + for(i=0;i<128;i++){
  21725. + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
  21726. +
  21727. + mdelay(1);
  21728. + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
  21729. +
  21730. + mdelay(1);
  21731. + }
  21732. +
  21733. + force_pci_posting(dev);
  21734. + mdelay(1);
  21735. +
  21736. + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
  21737. + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
  21738. + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
  21739. + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
  21740. + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
  21741. + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
  21742. + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
  21743. + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
  21744. + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
  21745. + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
  21746. +
  21747. + /* ver C & D */
  21748. + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
  21749. +
  21750. + //write_phy_ofdm(dev, 0x18, 0xef);
  21751. + // }
  21752. + //}
  21753. + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
  21754. +
  21755. + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
  21756. +
  21757. +
  21758. + //if(priv->card_type != USB)
  21759. + //write_phy_ofdm(dev, 0xd, 0x33); // <>
  21760. +
  21761. + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
  21762. +
  21763. + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
  21764. +/*ver D & 8187*/
  21765. +// }
  21766. +
  21767. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  21768. +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
  21769. +// else
  21770. + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
  21771. +/*ver C & D & 8187*/
  21772. +
  21773. + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
  21774. +/*agc resp time 700*/
  21775. +
  21776. +
  21777. +// if(priv->card_8185 == 2){
  21778. + /* Ver D & 8187*/
  21779. + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
  21780. +
  21781. + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
  21782. +
  21783. + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
  21784. + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
  21785. + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
  21786. + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
  21787. +
  21788. +// if (priv->card_type == USB)
  21789. +// write_phy_ofdm(dev, 0x18, 0xef);
  21790. +
  21791. + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
  21792. +
  21793. +
  21794. + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
  21795. + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
  21796. +
  21797. +// if (priv->card_type != USB){
  21798. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  21799. +// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
  21800. +// else
  21801. + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
  21802. + /* Ver C & D */ //FIXME:MAYBE not needed
  21803. +// }
  21804. +
  21805. + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
  21806. +
  21807. + /*ver D & 8187*/
  21808. + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
  21809. +
  21810. + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
  21811. +
  21812. +// }
  21813. +
  21814. + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
  21815. +
  21816. + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
  21817. +
  21818. + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
  21819. +
  21820. +// if(priv->card_type != USB)
  21821. + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
  21822. +
  21823. + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
  21824. + write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
  21825. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
  21826. + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
  21827. +/* Ver C & D & 8187*/
  21828. +
  21829. + // <> Set init. gain to m74dBm.
  21830. +
  21831. + rtl8225_set_gain(dev,4);
  21832. + /*write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
  21833. + write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
  21834. + write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
  21835. + write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
  21836. +*/
  21837. + //if(priv->card_type == USB);
  21838. + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
  21839. +
  21840. + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
  21841. + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
  21842. + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
  21843. + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
  21844. + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
  21845. + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
  21846. + /* Ver C & D & 8187*/
  21847. +
  21848. + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
  21849. +
  21850. + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
  21851. + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
  21852. + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
  21853. + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
  21854. +
  21855. + write_phy_cck(dev, 0x19, 0x0);
  21856. + write_phy_cck(dev, 0x1a, 0xa0);
  21857. + write_phy_cck(dev, 0x1b, 0x8);
  21858. + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
  21859. +
  21860. + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
  21861. +
  21862. +
  21863. + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
  21864. + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
  21865. + write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
  21866. + write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
  21867. + write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
  21868. + write_phy_cck(dev, 0x47, 0x15); mdelay(1);
  21869. + write_phy_cck(dev, 0x48, 0x10); mdelay(1);
  21870. + write_phy_cck(dev, 0x49, 0xa); mdelay(1);
  21871. + write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
  21872. + write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
  21873. + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
  21874. +
  21875. +
  21876. + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
  21877. +
  21878. +
  21879. +
  21880. +// <>
  21881. +// // TESTR 0xb 8187
  21882. +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
  21883. +//
  21884. +// //if(priv->card_type != USB){
  21885. +// write_phy_ofdm(dev, 0x2, 0x62);
  21886. +// write_phy_ofdm(dev, 0x6, 0x0);
  21887. +// write_phy_ofdm(dev, 0x8, 0x0);
  21888. +// //}
  21889. +
  21890. + rtl8225_SetTXPowerLevel(dev, channel);
  21891. +
  21892. + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
  21893. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
  21894. +
  21895. + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
  21896. +
  21897. + /* switch to high-speed 3-wire
  21898. + * last digit. 2 for both cck and ofdm
  21899. + */
  21900. + if(priv->card_type == USB)
  21901. + write_nic_dword(dev, 0x94, 0x3dc00002);
  21902. + else{
  21903. + write_nic_dword(dev, 0x94, 0x15c00002);
  21904. + rtl8185_rf_pins_enable(dev);
  21905. + }
  21906. +
  21907. +// if(priv->card_type != USB)
  21908. +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
  21909. +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
  21910. +//
  21911. +// /* make sure is waken up! */
  21912. +// write_rtl8225(dev,0x4, 0x9ff);
  21913. +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  21914. +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  21915. +
  21916. + rtl8225_rf_set_chan(dev, priv->chan);
  21917. +
  21918. + //write_nic_word(dev,BRSR,brsr);
  21919. +
  21920. +}
  21921. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
  21922. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 1970-01-01 01:00:00.000000000 +0100
  21923. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 2010-03-06 16:43:22.000000000 +0100
  21924. @@ -0,0 +1,77 @@
  21925. +/*
  21926. + This is part of the rtl8180-sa2400 driver
  21927. + released under the GPL (See file COPYING for details).
  21928. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  21929. +
  21930. + This files contains programming code for the rtl8225
  21931. + radio frontend.
  21932. +
  21933. + *Many* thanks to Realtek Corp. for their great support!
  21934. +
  21935. +*/
  21936. +
  21937. +#ifndef RTL8225H
  21938. +#define RTL8225H
  21939. +
  21940. +#include "r8187.h"
  21941. +
  21942. +#define RTL8225_ANAPARAM_ON 0xa0000a59
  21943. +
  21944. +// FIXME: OFF ANAPARAM MIGHT BE WRONG!
  21945. +#define RTL8225_ANAPARAM_OFF 0xa00beb59
  21946. +#define RTL8225_ANAPARAM2_OFF 0x840dec11
  21947. +
  21948. +#define RTL8225_ANAPARAM2_ON 0x860c7312
  21949. +
  21950. +void rtl8225_rf_init(struct net_device *dev);
  21951. +void rtl8225z2_rf_init(struct net_device *dev);
  21952. +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
  21953. +short rtl8225_is_V_z2(struct net_device *dev);
  21954. +void rtl8225_rf_set_chan(struct net_device *dev,short ch);
  21955. +void rtl8225_rf_close(struct net_device *dev);
  21956. +short rtl8225_rf_set_sens(struct net_device *dev, short sens);
  21957. +void rtl8225_host_pci_init(struct net_device *dev);
  21958. +void rtl8225_host_usb_init(struct net_device *dev);
  21959. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  21960. +void rtl8225z2_rf_set_mode(struct net_device *dev) ;
  21961. +void rtl8185_rf_pins_enable(struct net_device *dev);
  21962. +void rtl8180_set_mode(struct net_device *dev,int mode);
  21963. +void UpdateInitialGain(struct net_device *dev);
  21964. +void UpdateCCKThreshold(struct net_device *dev);
  21965. +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch);
  21966. +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
  21967. +
  21968. +#define RTL8225_RF_MAX_SENS 6
  21969. +#define RTL8225_RF_DEF_SENS 4
  21970. +
  21971. +extern inline char GetTxOfdmHighPowerBias(struct net_device *dev)
  21972. +{
  21973. + //
  21974. + // We should always adjust our Tx Power for 8187 and 8187B.
  21975. + // It was ever recommended not to adjust Tx Power of 8187B with Atheros AP
  21976. + // for throughput by David, but now we found it is not the issue to impact
  21977. + // the Atheros's problem and also no adjustion for Tx Power will cause "low"
  21978. + // throughput. By Bruce, 2007-07-03.
  21979. + //
  21980. + return 10;
  21981. +}
  21982. +
  21983. +//
  21984. +// Description:
  21985. +// Return Tx power level to minus if we are in high power state.
  21986. +//
  21987. +// Note:
  21988. +// Adjust it according to RF if required.
  21989. +//
  21990. +extern inline char GetTxCckHighPowerBias(struct net_device *dev)
  21991. +{
  21992. + return 7;
  21993. +}
  21994. +
  21995. +
  21996. +
  21997. +extern u8 rtl8225_agc[];
  21998. +
  21999. +extern u32 rtl8225_chan[];
  22000. +
  22001. +#endif
  22002. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
  22003. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 1970-01-01 01:00:00.000000000 +0100
  22004. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 2010-03-06 16:43:22.000000000 +0100
  22005. @@ -0,0 +1,2092 @@
  22006. +/*
  22007. + This is part of the rtl8180-sa2400 driver
  22008. + released under the GPL (See file COPYING for details).
  22009. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  22010. +
  22011. + This files contains programming code for the rtl8225
  22012. + radio frontend.
  22013. +
  22014. + *Many* thanks to Realtek Corp. for their great support!
  22015. +
  22016. +*/
  22017. +
  22018. +
  22019. +
  22020. +#include "r8180_hw.h"
  22021. +#include "r8180_rtl8225.h"
  22022. +#ifdef ENABLE_DOT11D
  22023. +#include "dot11d.h"
  22024. +#endif
  22025. +
  22026. +//2005.11.16
  22027. +u8 rtl8225z2_threshold[]={
  22028. + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
  22029. +};
  22030. +
  22031. +// 0xd 0x19 0x1b 0x21
  22032. +u8 rtl8225z2_gain_bg[]={
  22033. + 0x23, 0x15, 0xa5, // -82-1dbm
  22034. + 0x23, 0x15, 0xb5, // -82-2dbm
  22035. + 0x23, 0x15, 0xc5, // -82-3dbm
  22036. + 0x33, 0x15, 0xc5, // -78dbm
  22037. + 0x43, 0x15, 0xc5, // -74dbm
  22038. + 0x53, 0x15, 0xc5, // -70dbm
  22039. + 0x63, 0x15, 0xc5, // -66dbm
  22040. +};
  22041. +
  22042. +u8 rtl8225z2_gain_a[]={
  22043. + 0x13,0x27,0x5a,//,0x37,// -82dbm
  22044. + 0x23,0x23,0x58,//,0x37,// -82dbm
  22045. + 0x33,0x1f,0x56,//,0x37,// -82dbm
  22046. + 0x43,0x1b,0x54,//,0x37,// -78dbm
  22047. + 0x53,0x17,0x51,//,0x37,// -74dbm
  22048. + 0x63,0x24,0x4f,//,0x37,// -70dbm
  22049. + 0x73,0x0f,0x4c,//,0x37,// -66dbm
  22050. +};
  22051. +static u32 MAC_REG_TABLE[][3]={
  22052. + {0xf0, 0x32, 0000}, {0xf1, 0x32, 0000}, {0xf2, 0x00, 0000}, {0xf3, 0x00, 0000},
  22053. + {0xf4, 0x32, 0000}, {0xf5, 0x43, 0000}, {0xf6, 0x00, 0000}, {0xf7, 0x00, 0000},
  22054. + {0xf8, 0x46, 0000}, {0xf9, 0xa4, 0000}, {0xfa, 0x00, 0000}, {0xfb, 0x00, 0000},
  22055. + {0xfc, 0x96, 0000}, {0xfd, 0xa4, 0000}, {0xfe, 0x00, 0000}, {0xff, 0x00, 0000},
  22056. +
  22057. + {0x58, 0x4b, 0001}, {0x59, 0x00, 0001}, {0x5a, 0x4b, 0001}, {0x5b, 0x00, 0001},
  22058. + {0x60, 0x4b, 0001}, {0x61, 0x09, 0001}, {0x62, 0x4b, 0001}, {0x63, 0x09, 0001},
  22059. + {0xce, 0x0f, 0001}, {0xcf, 0x00, 0001}, {0xe0, 0xff, 0001}, {0xe1, 0x0f, 0001},
  22060. + {0xe2, 0x00, 0001}, {0xf0, 0x4e, 0001}, {0xf1, 0x01, 0001}, {0xf2, 0x02, 0001},
  22061. + {0xf3, 0x03, 0001}, {0xf4, 0x04, 0001}, {0xf5, 0x05, 0001}, {0xf6, 0x06, 0001},
  22062. + {0xf7, 0x07, 0001}, {0xf8, 0x08, 0001},
  22063. +
  22064. + {0x4e, 0x00, 0002}, {0x0c, 0x04, 0002}, {0x21, 0x61, 0002}, {0x22, 0x68, 0002},
  22065. + {0x23, 0x6f, 0002}, {0x24, 0x76, 0002}, {0x25, 0x7d, 0002}, {0x26, 0x84, 0002},
  22066. + {0x27, 0x8d, 0002}, {0x4d, 0x08, 0002}, {0x50, 0x05, 0002}, {0x51, 0xf5, 0002},
  22067. + {0x52, 0x04, 0002}, {0x53, 0xa0, 0002}, {0x54, 0x1f, 0002}, {0x55, 0x23, 0002},
  22068. + {0x56, 0x45, 0002}, {0x57, 0x67, 0002}, {0x58, 0x08, 0002}, {0x59, 0x08, 0002},
  22069. + {0x5a, 0x08, 0002}, {0x5b, 0x08, 0002}, {0x60, 0x08, 0002}, {0x61, 0x08, 0002},
  22070. + {0x62, 0x08, 0002}, {0x63, 0x08, 0002}, {0x64, 0xcf, 0002}, {0x72, 0x56, 0002},
  22071. + {0x73, 0x9a, 0002},
  22072. +
  22073. + {0x34, 0xf0, 0000}, {0x35, 0x0f, 0000}, {0x5b, 0x40, 0000}, {0x84, 0x88, 0000},
  22074. + {0x85, 0x24, 0000}, {0x88, 0x54, 0000}, {0x8b, 0xb8, 0000}, {0x8c, 0x07, 0000},
  22075. + {0x8d, 0x00, 0000}, {0x94, 0x1b, 0000}, {0x95, 0x12, 0000}, {0x96, 0x00, 0000},
  22076. + {0x97, 0x06, 0000}, {0x9d, 0x1a, 0000}, {0x9f, 0x10, 0000}, {0xb4, 0x22, 0000},
  22077. + {0xbe, 0x80, 0000}, {0xdb, 0x00, 0000}, {0xee, 0x00, 0000}, {0x91, 0x01, 0000},
  22078. + //lzm mode 0x91 form 0x03->0x01 open GPIO BIT1,
  22079. + //because Polling methord will rurn off Radio
  22080. + //the first time when read GPI(0x92).
  22081. + //because after 0x91:bit1 form 1->0, there will
  22082. + //be time for 0x92:bit1 form 0->1
  22083. +
  22084. + {0x4c, 0x00, 0002}, {0x9f, 0x00, 0003}, {0x8c, 0x01, 0000}, {0x8d, 0x10, 0000},
  22085. + {0x8e, 0x08, 0000}, {0x8f, 0x00, 0000}
  22086. +};
  22087. +
  22088. +static u8 ZEBRA_AGC[]={
  22089. + 0,
  22090. + 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
  22091. + 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
  22092. + 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
  22093. + 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  22094. + 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
  22095. + 0x26,0x27,0x27,0x28,0x28,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,
  22096. + 0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x31,0x31,0x31,0x31,
  22097. + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
  22098. +};
  22099. +
  22100. +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
  22101. + 0,
  22102. + 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
  22103. + 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
  22104. + 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
  22105. + 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
  22106. + 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
  22107. + 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
  22108. + 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
  22109. + 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
  22110. + 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
  22111. + 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
  22112. + 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
  22113. + 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
  22114. +};
  22115. +
  22116. +// Use the new SD3 given param, by shien chang, 2006.07.14
  22117. +
  22118. +static u8 OFDM_CONFIG[]={
  22119. + // 0x00
  22120. + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
  22121. + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
  22122. +
  22123. + // 0x10
  22124. + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
  22125. + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
  22126. +
  22127. + // 0x20
  22128. + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
  22129. + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
  22130. +
  22131. + // 0x30
  22132. + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
  22133. + 0x6d, 0x3c, 0xfb, 0x07//0xc7
  22134. + };
  22135. +
  22136. +//2005.11.16,
  22137. +u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
  22138. + 0x00,0x01,0x02,0x03,0x04,0x05,
  22139. + 0x06,0x07,0x08,0x09,0x0a,0x0b,
  22140. + 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
  22141. + 0x12,0x13,0x14,0x15,0x16,0x17,
  22142. + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
  22143. + 0x1e,0x1f,0x20,0x21,0x22,0x23,
  22144. +};
  22145. +//-
  22146. +u16 rtl8225z2_rxgain[]={
  22147. + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
  22148. + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
  22149. + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
  22150. + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
  22151. + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
  22152. + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
  22153. + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
  22154. + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
  22155. + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
  22156. + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
  22157. + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
  22158. + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
  22159. +
  22160. +};
  22161. +
  22162. +
  22163. +/*
  22164. + from 0 to 0x23
  22165. +u8 rtl8225_tx_gain_cck_ofdm[]={
  22166. + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
  22167. +};
  22168. +*/
  22169. +
  22170. +//-
  22171. +u8 rtl8225z2_tx_power_ofdm[]={
  22172. + 0x42,0x00,0x40,0x00,0x40
  22173. +};
  22174. +
  22175. +
  22176. +//-
  22177. +u8 rtl8225z2_tx_power_cck_ch14[]={
  22178. + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
  22179. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  22180. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  22181. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  22182. +};
  22183. +
  22184. +
  22185. +//-
  22186. +u8 rtl8225z2_tx_power_cck[]={
  22187. + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,
  22188. + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
  22189. + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
  22190. + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
  22191. +};
  22192. +
  22193. +#ifdef ENABLE_DOT11D
  22194. +//
  22195. +// Description:
  22196. +// Map dBm into Tx power index according to
  22197. +// current HW model, for example, RF and PA, and
  22198. +// current wireless mode.
  22199. +//
  22200. +s8
  22201. +rtl8187B_DbmToTxPwrIdx(
  22202. + struct r8180_priv *priv,
  22203. + WIRELESS_MODE WirelessMode,
  22204. + s32 PowerInDbm
  22205. + )
  22206. +{
  22207. + bool bUseDefault = true;
  22208. + s8 TxPwrIdx = 0;
  22209. +
  22210. +#ifdef CONFIG_RTL818X_S
  22211. + //
  22212. + // 071011, SD3 SY:
  22213. + // OFDM Power in dBm = Index * 0.5 + 0
  22214. + // CCK Power in dBm = Index * 0.25 + 13
  22215. + //
  22216. + if(priv->card_8185 >= VERSION_8187S_B)
  22217. + {
  22218. + s32 tmp = 0;
  22219. +
  22220. + if(WirelessMode == WIRELESS_MODE_G)
  22221. + {
  22222. + bUseDefault = false;
  22223. + tmp = (2 * PowerInDbm);
  22224. +
  22225. + if(tmp < 0)
  22226. + TxPwrIdx = 0;
  22227. + else if(tmp > 40) // 40 means 20 dBm.
  22228. + TxPwrIdx = 40;
  22229. + else
  22230. + TxPwrIdx = (s8)tmp;
  22231. + }
  22232. + else if(WirelessMode == WIRELESS_MODE_B)
  22233. + {
  22234. + bUseDefault = false;
  22235. + tmp = (4 * PowerInDbm) - 52;
  22236. +
  22237. + if(tmp < 0)
  22238. + TxPwrIdx = 0;
  22239. + else if(tmp > 28) // 28 means 20 dBm.
  22240. + TxPwrIdx = 28;
  22241. + else
  22242. + TxPwrIdx = (s8)tmp;
  22243. + }
  22244. + }
  22245. +#endif
  22246. +
  22247. + //
  22248. + // TRUE if we want to use a default implementation.
  22249. + // We shall set it to FALSE when we have exact translation formular
  22250. + // for target IC. 070622, by rcnjko.
  22251. + //
  22252. + if(bUseDefault)
  22253. + {
  22254. + if(PowerInDbm < 0)
  22255. + TxPwrIdx = 0;
  22256. + else if(PowerInDbm > 35)
  22257. + TxPwrIdx = 35;
  22258. + else
  22259. + TxPwrIdx = (u8)PowerInDbm;
  22260. + }
  22261. +
  22262. + return TxPwrIdx;
  22263. +}
  22264. +#endif
  22265. +
  22266. +
  22267. +void rtl8225z2_set_gain(struct net_device *dev, short gain)
  22268. +{
  22269. + u8* rtl8225_gain;
  22270. + struct r8180_priv *priv = ieee80211_priv(dev);
  22271. +
  22272. + u8 mode = priv->ieee80211->mode;
  22273. +
  22274. + if(mode == IEEE_B || mode == IEEE_G)
  22275. + rtl8225_gain = rtl8225z2_gain_bg;
  22276. + else
  22277. + rtl8225_gain = rtl8225z2_gain_a;
  22278. +
  22279. + //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
  22280. + //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
  22281. + //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
  22282. + //2005.11.17, by ch-hsu
  22283. + write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
  22284. + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
  22285. + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
  22286. + write_phy_ofdm(dev, 0x21, 0x37);
  22287. +
  22288. +}
  22289. +
  22290. +u32 read_rtl8225(struct net_device *dev, u8 adr)
  22291. +{
  22292. + u32 data2Write = ((u32)(adr & 0x1f)) << 27;
  22293. + u32 dataRead;
  22294. + u32 mask;
  22295. + u16 oval,oval2,oval3,tmp;
  22296. +// ThreeWireReg twreg;
  22297. +// ThreeWireReg tdata;
  22298. + int i;
  22299. + short bit, rw;
  22300. +
  22301. + u8 wLength = 6;
  22302. + u8 rLength = 12;
  22303. + u8 low2high = 0;
  22304. +
  22305. + oval = read_nic_word(dev, RFPinsOutput);
  22306. + oval2 = read_nic_word(dev, RFPinsEnable);
  22307. + oval3 = read_nic_word(dev, RFPinsSelect);
  22308. + write_nic_word(dev, RFPinsEnable, (oval2|0xf));
  22309. + write_nic_word(dev, RFPinsSelect, (oval3|0xf));
  22310. +
  22311. + dataRead = 0;
  22312. +
  22313. + oval &= ~0xf;
  22314. +
  22315. + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
  22316. +
  22317. + write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
  22318. +
  22319. + rw = 0;
  22320. +
  22321. + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
  22322. + for(i = 0; i < wLength/2; i++)
  22323. + {
  22324. + bit = ((data2Write&mask) != 0) ? 1 : 0;
  22325. + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
  22326. +
  22327. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  22328. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  22329. +
  22330. + mask = (low2high) ? (mask<<1): (mask>>1);
  22331. +
  22332. + if(i == 2)
  22333. + {
  22334. + rw = BB_HOST_BANG_RW;
  22335. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  22336. + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
  22337. + break;
  22338. + }
  22339. +
  22340. + bit = ((data2Write&mask) != 0) ? 1: 0;
  22341. +
  22342. + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
  22343. + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
  22344. +
  22345. + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
  22346. +
  22347. + mask = (low2high) ? (mask<<1) : (mask>>1);
  22348. + }
  22349. +
  22350. + //twreg.struc.clk = 0;
  22351. + //twreg.struc.data = 0;
  22352. + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
  22353. + mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
  22354. +
  22355. + // We must set data pin to HW controled, otherwise RF can't driver it and
  22356. + // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
  22357. + write_nic_word(dev, RFPinsEnable,((oval2|0xe) & (~0x01)));
  22358. +
  22359. + for(i = 0; i < rLength; i++)
  22360. + {
  22361. + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
  22362. +
  22363. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  22364. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  22365. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  22366. + tmp = read_nic_word(dev, RFPinsInput);
  22367. +
  22368. + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
  22369. +
  22370. + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
  22371. +
  22372. + mask = (low2high) ? (mask<<1) : (mask>>1);
  22373. + }
  22374. +
  22375. + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
  22376. +
  22377. + write_nic_word(dev, RFPinsEnable, oval2);
  22378. + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
  22379. + write_nic_word(dev, RFPinsOutput, 0x3a0);
  22380. +
  22381. + return dataRead;
  22382. +
  22383. +}
  22384. +short rtl8225_is_V_z2(struct net_device *dev)
  22385. +{
  22386. + short vz2 = 1;
  22387. + //set VCO-PDN pin
  22388. +// printk("%s()\n", __FUNCTION__);
  22389. + write_nic_word(dev, RFPinsOutput, 0x0080);
  22390. + write_nic_word(dev, RFPinsSelect, 0x0080);
  22391. + write_nic_word(dev, RFPinsEnable, 0x0080);
  22392. +
  22393. + //lzm mod for up take too long time 20081201
  22394. + //mdelay(100);
  22395. + //mdelay(1000);
  22396. +
  22397. + /* sw to reg pg 1 */
  22398. + write_rtl8225(dev, 0, 0x1b7);
  22399. + /* reg 8 pg 1 = 23*/
  22400. + if( read_rtl8225(dev, 8) != 0x588)
  22401. + vz2 = 0;
  22402. +
  22403. + else /* reg 9 pg 1 = 24 */
  22404. + if( read_rtl8225(dev, 9) != 0x700)
  22405. + vz2 = 0;
  22406. +
  22407. + /* sw back to pg 0 */
  22408. + write_rtl8225(dev, 0, 0xb7);
  22409. +
  22410. + return vz2;
  22411. +
  22412. +}
  22413. +
  22414. +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
  22415. +{
  22416. + struct r8180_priv *priv = ieee80211_priv(dev);
  22417. +
  22418. +// int GainIdx;
  22419. +// int GainSetting;
  22420. + int i;
  22421. + u8 power;
  22422. + u8 *cck_power_table;
  22423. + u8 max_cck_power_level;
  22424. + u8 min_cck_power_level;
  22425. + u8 max_ofdm_power_level;
  22426. + u8 min_ofdm_power_level;
  22427. + s8 cck_power_level = 0xff & priv->chtxpwr[ch];
  22428. + s8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
  22429. + u8 hw_version = priv->card_8187_Bversion;
  22430. +
  22431. +#ifdef ENABLE_DOT11D
  22432. + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
  22433. + IS_DOT11D_STATE_DONE(priv->ieee80211) )
  22434. + {
  22435. + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
  22436. + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
  22437. + u8 CckMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
  22438. + u8 OfdmMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
  22439. +
  22440. + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
  22441. +
  22442. + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
  22443. + // ch, cck_power_level, ofdm_power_level);
  22444. +
  22445. + if(cck_power_level > CckMaxPwrIdx)
  22446. + cck_power_level = CckMaxPwrIdx;
  22447. + if(ofdm_power_level > OfdmMaxPwrIdx)
  22448. + ofdm_power_level = OfdmMaxPwrIdx;
  22449. + }
  22450. +
  22451. + //priv->CurrentCckTxPwrIdx = cck_power_level;
  22452. + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
  22453. +#endif
  22454. +
  22455. + if (NIC_8187B == priv->card_8187)
  22456. + {
  22457. + if (hw_version == VERSION_8187B_B)
  22458. + {
  22459. + min_cck_power_level = 0;
  22460. + max_cck_power_level = 15;
  22461. + min_ofdm_power_level = 2;
  22462. + max_ofdm_power_level = 17;
  22463. + }else
  22464. + {
  22465. + min_cck_power_level = 7;
  22466. + max_cck_power_level = 22;
  22467. + min_ofdm_power_level = 10;
  22468. + max_ofdm_power_level = 25;
  22469. + }
  22470. +
  22471. + if( priv->TrSwitchState == TR_SW_TX )
  22472. + {
  22473. + //printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d, adjust value = %d\n", ofdm_power_level,GetTxOfdmHighPowerBias(dev));
  22474. + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
  22475. + cck_power_level -= GetTxCckHighPowerBias(dev);
  22476. + //printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
  22477. + // ofdm_power_level);
  22478. + //printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
  22479. + // cck_power_level);
  22480. + }
  22481. + /* CCK power setting */
  22482. + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
  22483. + cck_power_level = max_cck_power_level;
  22484. + else
  22485. + cck_power_level += min_cck_power_level;
  22486. + cck_power_level += priv->cck_txpwr_base;
  22487. +
  22488. + if(cck_power_level > 35)
  22489. + cck_power_level = 35;
  22490. + if(cck_power_level < 0)
  22491. + cck_power_level = 0;
  22492. +
  22493. + if(ch == 14)
  22494. + cck_power_table = rtl8225z2_tx_power_cck_ch14;
  22495. + else
  22496. + cck_power_table = rtl8225z2_tx_power_cck;
  22497. + if (hw_version == VERSION_8187B_B)
  22498. + {
  22499. + if (cck_power_level <= 6){
  22500. + }
  22501. + else if (cck_power_level <=11){
  22502. + cck_power_table += 8;
  22503. + }
  22504. + else{
  22505. + cck_power_table += (8*2);
  22506. + }
  22507. + }else{
  22508. + if (cck_power_level<=5){
  22509. + }else if(cck_power_level<=11){
  22510. + cck_power_table += 8;
  22511. + }else if(cck_power_level <= 17){
  22512. + cck_power_table += 8*2;
  22513. + }else{
  22514. + cck_power_table += 8*3;
  22515. + }
  22516. + }
  22517. +
  22518. +
  22519. +
  22520. + for(i=0;i<8;i++){
  22521. +
  22522. + power = cck_power_table[i];
  22523. + write_phy_cck(dev, 0x44 + i, power);
  22524. + }
  22525. +
  22526. + //write_nic_byte(dev, TX_GAIN_CCK, power);
  22527. + //2005.11.17,
  22528. + write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]*2));
  22529. +
  22530. +// force_pci_posting(dev);
  22531. +// msleep(1);
  22532. +//in windows the delay was del from 85 to 87,
  22533. +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  22534. +
  22535. + /* OFDM power setting */
  22536. + // Old:
  22537. + // if(ofdm_power_level > max_ofdm_power_level)
  22538. + // ofdm_power_level = 35;
  22539. + // ofdm_power_level += min_ofdm_power_level;
  22540. + // Latest:
  22541. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  22542. + ofdm_power_level = max_ofdm_power_level;
  22543. + else
  22544. + ofdm_power_level += min_ofdm_power_level;
  22545. +
  22546. + ofdm_power_level += priv->ofdm_txpwr_base;
  22547. +
  22548. + if(ofdm_power_level > 35)
  22549. + ofdm_power_level = 35;
  22550. +
  22551. + if(ofdm_power_level < 0)
  22552. + ofdm_power_level = 0;
  22553. + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]*2);
  22554. +
  22555. + if (hw_version == VERSION_8187B_B)
  22556. + {
  22557. + if(ofdm_power_level<=11){
  22558. + write_phy_ofdm(dev, 0x87, 0x60);
  22559. + write_phy_ofdm(dev, 0x89, 0x60);
  22560. + }
  22561. + else{
  22562. + write_phy_ofdm(dev, 0x87, 0x5c);
  22563. + write_phy_ofdm(dev, 0x89, 0x5c);
  22564. + }
  22565. + }else{
  22566. + if(ofdm_power_level<=11){
  22567. + write_phy_ofdm(dev, 0x87, 0x5c);
  22568. + write_phy_ofdm(dev, 0x89, 0x5c);
  22569. + }
  22570. + if(ofdm_power_level<=17){
  22571. + write_phy_ofdm(dev, 0x87, 0x54);
  22572. + write_phy_ofdm(dev, 0x89, 0x54);
  22573. + }
  22574. + else{
  22575. + write_phy_ofdm(dev, 0x87, 0x50);
  22576. + write_phy_ofdm(dev, 0x89, 0x50);
  22577. + }
  22578. + }
  22579. +// force_pci_posting(dev);
  22580. +// msleep(1);
  22581. +//in windows the delay was del from 85 to 87,
  22582. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  22583. + }else if(NIC_8187 == priv->card_8187) {
  22584. + min_cck_power_level = 0;
  22585. + max_cck_power_level = 15;
  22586. + min_ofdm_power_level = 10;
  22587. + max_ofdm_power_level = 25;
  22588. + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
  22589. + cck_power_level = max_cck_power_level;
  22590. + else
  22591. + cck_power_level += min_cck_power_level;
  22592. + cck_power_level += priv->cck_txpwr_base;
  22593. +
  22594. + if(cck_power_level > 35)
  22595. + cck_power_level = 35;
  22596. +
  22597. + if(ch == 14)
  22598. + cck_power_table = rtl8225z2_tx_power_cck_ch14;
  22599. + else
  22600. + cck_power_table = rtl8225z2_tx_power_cck;
  22601. + for(i=0;i<8;i++){
  22602. + power = cck_power_table[i];
  22603. + write_phy_cck(dev, 0x44 + i, power);
  22604. + }
  22605. +
  22606. + //write_nic_byte(dev, TX_GAIN_CCK, power);
  22607. + //2005.11.17,
  22608. + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]);
  22609. +
  22610. +// force_pci_posting(dev);
  22611. +// msleep(1);
  22612. +//in windows the delay was del from 85 to 87,
  22613. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  22614. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  22615. + ofdm_power_level = max_ofdm_power_level;
  22616. + else
  22617. + ofdm_power_level += min_ofdm_power_level;
  22618. +
  22619. + ofdm_power_level += priv->ofdm_txpwr_base;
  22620. +
  22621. + if(ofdm_power_level > 35)
  22622. + ofdm_power_level = 35;
  22623. + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]);
  22624. +
  22625. + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
  22626. +
  22627. + write_phy_ofdm(dev,2,0x42);
  22628. + write_phy_ofdm(dev,5,0);
  22629. + write_phy_ofdm(dev,6,0x40);
  22630. + write_phy_ofdm(dev,7,0);
  22631. + write_phy_ofdm(dev,8,0x40);
  22632. + }
  22633. +
  22634. +}
  22635. +
  22636. +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
  22637. +{
  22638. + struct r8180_priv *priv = ieee80211_priv(dev);
  22639. + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
  22640. + ieee80211_is_54g(priv->ieee80211->current_network)) ||
  22641. + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
  22642. + int eifs_addr;
  22643. +
  22644. + down(&priv->set_chan_sem);
  22645. +
  22646. + if(NIC_8187 == priv->card_8187) {
  22647. + eifs_addr = EIFS_8187;
  22648. + } else {
  22649. + eifs_addr = EIFS_8187B;
  22650. + }
  22651. +
  22652. +#ifdef ENABLE_DOT11D
  22653. + if(!IsLegalChannel(priv->ieee80211, ch) )
  22654. + {
  22655. + printk("channel(%d). is invalide\n", ch);
  22656. + up(&priv->set_chan_sem);
  22657. + return;
  22658. + }
  22659. +#endif
  22660. + //87B not do it FIXME
  22661. + rtl8225z2_SetTXPowerLevel(dev, ch);
  22662. +
  22663. + //write_nic_byte(dev,0x7,(u8)rtl8225_chan[ch]);
  22664. + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
  22665. +
  22666. + force_pci_posting(dev);
  22667. + //mdelay(10);
  22668. +//in windows the delay was del from 85 to 87,
  22669. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  22670. + if(NIC_8187 == priv->card_8187){
  22671. + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
  22672. +
  22673. + if(gset)
  22674. + write_nic_byte(dev,DIFS,20); //DIFS: 20
  22675. + else
  22676. + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
  22677. +
  22678. + if(priv->ieee80211->state == IEEE80211_LINKED &&
  22679. + ieee80211_is_shortslot(priv->ieee80211->current_network))
  22680. + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
  22681. +
  22682. + else
  22683. + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
  22684. +
  22685. +
  22686. + if(gset){
  22687. + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
  22688. + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
  22689. + //DMESG("using G net params");
  22690. + }else{
  22691. + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
  22692. + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
  22693. + //DMESG("using B net params");
  22694. + }
  22695. + }
  22696. +
  22697. + else {
  22698. +#ifdef THOMAS_TURBO
  22699. + if(priv->ieee80211->current_network.Turbo_Enable && priv->ieee80211->iw_mode == IW_MODE_INFRA){
  22700. + write_nic_word(dev,AC_VO_PARAM,0x5114);
  22701. + write_nic_word(dev,AC_VI_PARAM,0x5114);
  22702. + write_nic_word(dev,AC_BE_PARAM,0x5114);
  22703. + write_nic_word(dev,AC_BK_PARAM,0x5114);
  22704. + } else {
  22705. + write_nic_word(dev,AC_VO_PARAM,0x731c);
  22706. + write_nic_word(dev,AC_VI_PARAM,0x731c);
  22707. + write_nic_word(dev,AC_BE_PARAM,0x731c);
  22708. + write_nic_word(dev,AC_BK_PARAM,0x731c);
  22709. + }
  22710. +#endif
  22711. + }
  22712. +
  22713. + up(&priv->set_chan_sem);
  22714. +}
  22715. +void
  22716. +MacConfig_87BASIC_HardCode(struct net_device *dev)
  22717. +{
  22718. + //============================================================================
  22719. + // MACREG.TXT
  22720. + //============================================================================
  22721. + int nLinesRead = 0;
  22722. + u32 u4bRegOffset, u4bRegValue, u4bPageIndex;
  22723. + int i;
  22724. +
  22725. + nLinesRead=(sizeof(MAC_REG_TABLE)/3)/4;
  22726. +
  22727. + for(i = 0; i < nLinesRead; i++)
  22728. + {
  22729. + u4bRegOffset=MAC_REG_TABLE[i][0];
  22730. + u4bRegValue=MAC_REG_TABLE[i][1];
  22731. + u4bPageIndex=MAC_REG_TABLE[i][2];
  22732. +
  22733. + u4bRegOffset|= (u4bPageIndex << 8);
  22734. +
  22735. + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
  22736. + }
  22737. + //============================================================================
  22738. +}
  22739. +
  22740. +static void MacConfig_87BASIC(struct net_device *dev)
  22741. +{
  22742. + MacConfig_87BASIC_HardCode(dev);
  22743. +
  22744. + //============================================================================
  22745. +
  22746. + // Follow TID_AC_MAP of WMac.
  22747. + //PlatformEFIOWrite2Byte(dev, TID_AC_MAP, 0xfa50);
  22748. + write_nic_word(dev, TID_AC_MAP, 0xfa50);
  22749. +
  22750. + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
  22751. + write_nic_word(dev, INT_MIG, 0x0000);
  22752. +
  22753. + // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
  22754. + write_nic_dword(dev, 0x1F0, 0x00000000);
  22755. + write_nic_dword(dev, 0x1F4, 0x00000000);
  22756. + write_nic_byte(dev, 0x1F8, 0x00);
  22757. +
  22758. + // For WiFi 5.2.2.5 Atheros AP performance. Added by Annie, 2006-06-12.
  22759. + // PlatformIOWrite4Byte(dev, RFTiming, 0x0008e00f);
  22760. + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
  22761. + write_nic_dword(dev, RFTiming, 0x00004001);
  22762. +
  22763. +#ifdef TODO
  22764. + // Asked for by Victor, for 87B B-cut Rx FIFO overflow bug, 2006.06.27, by rcnjko.
  22765. + if(dev->NdisUsbDev.CardInfo.USBIsHigh == FALSE)
  22766. + {
  22767. + PlatformEFIOWrite1Byte(dev, 0x24E, 0x01);
  22768. + }
  22769. +#endif
  22770. +}
  22771. +
  22772. +
  22773. +//
  22774. +// Description:
  22775. +// Initialize RFE and read Zebra2 version code.
  22776. +//
  22777. +// 2005-08-01, by Annie.
  22778. +//
  22779. +void
  22780. +SetupRFEInitialTiming(struct net_device* dev)
  22781. +{
  22782. + //u32 data8, data9;
  22783. + struct r8180_priv *priv = ieee80211_priv(dev);
  22784. +
  22785. + // setup initial timing for RFE
  22786. + // Set VCO-PDN pin.
  22787. + write_nic_word(dev, RFPinsOutput, 0x0480);
  22788. + write_nic_word(dev, RFPinsSelect, 0x2488);
  22789. + write_nic_word(dev, RFPinsEnable, 0x1FFF);
  22790. +
  22791. + mdelay(100);
  22792. + // Steven recommends: delay 1 sec for setting RF 1.8V. by Annie, 2005-04-28.
  22793. + mdelay(1000);
  22794. +
  22795. + //
  22796. + // TODO: Read Zebra version code if necessary.
  22797. + //
  22798. + priv->rf_chip = RF_ZEBRA2;
  22799. +}
  22800. +
  22801. +
  22802. +void ZEBRA_Config_87BASIC_HardCode(struct net_device* dev)
  22803. +{
  22804. + u32 i;
  22805. + u32 addr,data;
  22806. + u32 u4bRegOffset, u4bRegValue;
  22807. +
  22808. +
  22809. + //=============================================================================
  22810. + // RADIOCFG.TXT
  22811. + //=============================================================================
  22812. + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1);
  22813. + write_rtl8225(dev, 0x01, 0x0ee0); mdelay(1);
  22814. + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
  22815. + write_rtl8225(dev, 0x03, 0x0441); mdelay(1);
  22816. + write_rtl8225(dev, 0x04, 0x08c3); mdelay(1);
  22817. + write_rtl8225(dev, 0x05, 0x0c72); mdelay(1);
  22818. + write_rtl8225(dev, 0x06, 0x00e6); mdelay(1);
  22819. + write_rtl8225(dev, 0x07, 0x082a); mdelay(1);
  22820. + write_rtl8225(dev, 0x08, 0x003f); mdelay(1);
  22821. + write_rtl8225(dev, 0x09, 0x0335); mdelay(1);
  22822. + write_rtl8225(dev, 0x0a, 0x09d4); mdelay(1);
  22823. + write_rtl8225(dev, 0x0b, 0x07bb); mdelay(1);
  22824. + write_rtl8225(dev, 0x0c, 0x0850); mdelay(1);
  22825. + write_rtl8225(dev, 0x0d, 0x0cdf); mdelay(1);
  22826. + write_rtl8225(dev, 0x0e, 0x002b); mdelay(1);
  22827. + write_rtl8225(dev, 0x0f, 0x0114); mdelay(1);
  22828. +
  22829. + write_rtl8225(dev, 0x00, 0x01b7); mdelay(1);
  22830. +
  22831. +
  22832. + for(i=1;i<=95;i++)
  22833. + {
  22834. + write_rtl8225(dev, 0x01, i);mdelay(1);
  22835. + write_rtl8225(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
  22836. + //DbgPrint("RF - 0x%x = 0x%x\n", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
  22837. + }
  22838. +
  22839. + write_rtl8225(dev, 0x03, 0x0080); mdelay(1); // write reg 18
  22840. + write_rtl8225(dev, 0x05, 0x0004); mdelay(1); // write reg 20
  22841. + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
  22842. + //lzm mod for up take too long time 20081201
  22843. +#ifdef THOMAS_BEACON
  22844. + msleep(1000);// Deay 1 sec. //0xfd
  22845. + //msleep(1000);// Deay 1 sec. //0xfd
  22846. + //msleep(1000);// Deay 1 sec. //0xfd
  22847. + msleep(400);// Deay 1 sec. //0xfd
  22848. +#else
  22849. +
  22850. + mdelay(1000);
  22851. + //mdelay(1000);
  22852. + //mdelay(1000);
  22853. + mdelay(400);
  22854. +#endif
  22855. + write_rtl8225(dev, 0x02, 0x0c4d); mdelay(1);
  22856. + //lzm mod for up take too long time 20081201
  22857. + //mdelay(1000);
  22858. + //mdelay(1000);
  22859. + msleep(100);// Deay 100 ms. //0xfe
  22860. + msleep(100);// Deay 100 ms. //0xfe
  22861. + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
  22862. + write_rtl8225(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
  22863. +
  22864. + //=============================================================================
  22865. +
  22866. + //=============================================================================
  22867. + // CCKCONF.TXT
  22868. + //=============================================================================
  22869. + /*
  22870. + u4bRegOffset=0x41;
  22871. + u4bRegValue=0xc8;
  22872. +
  22873. + //DbgPrint("\nCCK- 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
  22874. + WriteBB(dev, (0x01000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
  22875. + */
  22876. +
  22877. +
  22878. + //=============================================================================
  22879. +
  22880. + //=============================================================================
  22881. + // Follow WMAC RTL8225_Config()
  22882. + //=============================================================================
  22883. +// //
  22884. +// // enable EEM0 and EEM1 in 9346CR
  22885. +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)|0xc0);
  22886. +// // enable PARM_En in Config3
  22887. +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)|0x40);
  22888. +//
  22889. +// PlatformEFIOWrite4Byte(dev, AnaParm2, ANAPARM2_ASIC_ON); //0x727f3f52
  22890. +// PlatformEFIOWrite4Byte(dev, AnaParm, ANAPARM_ASIC_ON); //0x45090658
  22891. +
  22892. + // power control
  22893. + write_nic_byte(dev, CCK_TXAGC, 0x03);
  22894. + write_nic_byte(dev, OFDM_TXAGC, 0x07);
  22895. + write_nic_byte(dev, ANTSEL, 0x03);
  22896. +
  22897. +// // disable PARM_En in Config3
  22898. +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)&0xbf);
  22899. +// // disable EEM0 and EEM1 in 9346CR
  22900. +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)&0x3f);
  22901. + //=============================================================================
  22902. +
  22903. + //=============================================================================
  22904. + // AGC.txt
  22905. + //=============================================================================
  22906. + //write_nic_dword( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
  22907. + //write_phy_ofdm( dev, 0x00, 0x12); // David, 2006-08-01
  22908. + write_phy_ofdm( dev, 0x80, 0x12); // David, 2006-08-09
  22909. +
  22910. + for (i=0; i<128; i++)
  22911. + {
  22912. + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
  22913. +
  22914. + data = ZEBRA_AGC[i+1];
  22915. + data = data << 8;
  22916. + data = data | 0x0000008F;
  22917. +
  22918. + addr = i + 0x80; //enable writing AGC table
  22919. + addr = addr << 8;
  22920. + addr = addr | 0x0000008E;
  22921. +
  22922. + write_phy_ofdm(dev,data&0x7f,(data>>8)&0xff);
  22923. + write_phy_ofdm(dev,addr&0x7f,(addr>>8)&0xff);
  22924. + write_phy_ofdm(dev,0x0E,0x00);
  22925. + }
  22926. +
  22927. + //write_nic_dword(dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
  22928. + //write_phy_ofdm( dev, 0x00, 0x10); // David, 2006-08-01
  22929. + write_phy_ofdm( dev, 0x80, 0x10); // David, 2006-08-09
  22930. +
  22931. + //=============================================================================
  22932. +
  22933. + //=============================================================================
  22934. + // OFDMCONF.TXT
  22935. + //=============================================================================
  22936. +
  22937. + for(i=0; i<60; i++)
  22938. + {
  22939. + u4bRegOffset=i;
  22940. + u4bRegValue=OFDM_CONFIG[i];
  22941. + //u4bRegValue=OFDM_CONFIG3m82[i];
  22942. +
  22943. + // write_nic_dword(dev,PhyAddr,(0x00000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
  22944. + write_phy_ofdm(dev,i,u4bRegValue);
  22945. + }
  22946. +
  22947. +
  22948. + //=============================================================================
  22949. +}
  22950. +
  22951. +void ZEBRA_Config_87BASIC(struct net_device *dev)
  22952. +{
  22953. + ZEBRA_Config_87BASIC_HardCode(dev);
  22954. +}
  22955. +//by amy for DIG
  22956. +//
  22957. +// Description:
  22958. +// Update initial gain into PHY.
  22959. +//
  22960. +void
  22961. +UpdateCCKThreshold(
  22962. + struct net_device *dev
  22963. + )
  22964. +{
  22965. + struct r8180_priv *priv = ieee80211_priv(dev);
  22966. + // Update CCK Power Detection(0x41) value.
  22967. + switch(priv->StageCCKTh)
  22968. + {
  22969. + case 0:
  22970. +// printk("Update CCK Stage 0: 88 \n");
  22971. + write_phy_cck(dev, 0xc1, 0x88);mdelay(1);
  22972. + break;
  22973. +
  22974. + case 1:
  22975. +// printk("Update CCK Stage 1: 98 \n");
  22976. + write_phy_cck(dev, 0xc1, 0x98);mdelay(1);
  22977. + break;
  22978. +
  22979. + case 2:
  22980. +// printk("Update CCK Stage 2: C8 \n");
  22981. + write_phy_cck(dev, 0xc1, 0xC8);mdelay(1);
  22982. + break;
  22983. +
  22984. + case 3:
  22985. +// printk("Update CCK Stage 3: D8 \n");
  22986. + write_phy_cck(dev, 0xc1, 0xD8);mdelay(1);
  22987. + break;
  22988. +
  22989. + default:
  22990. +// printk("Update CCK Stage %d ERROR!\n", pHalData->StageCCKTh);
  22991. + break;
  22992. + }
  22993. +}
  22994. +//
  22995. +// Description:
  22996. +// Update initial gain into PHY.
  22997. +//
  22998. +void
  22999. +UpdateInitialGain(
  23000. + struct net_device *dev
  23001. + )
  23002. +{
  23003. + struct r8180_priv *priv = ieee80211_priv(dev);
  23004. + //u8 u1Tmp=0;
  23005. +
  23006. + //printk("UpdateInitialGain(): InitialGain: %d RFChipID: %d\n", priv->InitialGain, priv->rf_chip);
  23007. +
  23008. + switch(priv->rf_chip)
  23009. + {
  23010. + case RF_ZEBRA:
  23011. + case RF_ZEBRA2:
  23012. +
  23013. + //
  23014. + // Note:
  23015. + // Whenever we update this gain table, we should be careful about those who call it.
  23016. + // Functions which call UpdateInitialGain as follows are important:
  23017. + // (1)StaRateAdaptive87B
  23018. + // (2)DIG_Zebra
  23019. + // (3)ActSetWirelessMode8187 (when the wireless mode is "B" mode, we set the
  23020. + // OFDM[0x17] = 0x26 to improve the Rx sensitivity).
  23021. + // By Bruce, 2007-06-01.
  23022. + //
  23023. +
  23024. + //
  23025. + // SD3 C.M. Lin Initial Gain Table, by Bruce, 2007-06-01.
  23026. + //
  23027. + switch(priv->InitialGain)
  23028. + {
  23029. + case 1: //m861dBm
  23030. +// DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm ");
  23031. + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
  23032. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  23033. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  23034. + break;
  23035. +
  23036. + case 2: //m862dBm
  23037. +// DMESG("RTL8187 + 8225 Initial Gain State 2: -78 dBm ");
  23038. + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  23039. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  23040. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  23041. + break;
  23042. +
  23043. + case 3: //m863dBm
  23044. +// DMESG("RTL8187 + 8225 Initial Gain State 3: -78 dBm ");
  23045. + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  23046. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  23047. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  23048. + break;
  23049. +
  23050. + case 4: //m864dBm
  23051. +// DMESG("RTL8187 + 8225 Initial Gain State 4: -74 dBm ");
  23052. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  23053. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  23054. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  23055. + break;
  23056. +
  23057. + case 5: //m82dBm
  23058. +// DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm ");
  23059. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
  23060. + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
  23061. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  23062. + break;
  23063. +
  23064. + case 6: //m78dBm
  23065. +// DMESG("RTL8187 + 8225 Initial Gain State 6: -70 dBm ");
  23066. + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
  23067. + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
  23068. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  23069. + break;
  23070. +
  23071. + case 7: //m74dBm
  23072. +// DMESG("RTL8187 + 8225 Initial Gain State 7: -70 dBm ");
  23073. + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
  23074. + write_phy_ofdm(dev, 0xa4, 0xa6); mdelay(1);
  23075. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  23076. + break;
  23077. +
  23078. + // By Bruce, 2007-03-29.
  23079. + case 8:
  23080. + write_phy_ofdm(dev, 0x97, 0x66); mdelay(1);
  23081. + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
  23082. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  23083. + break;
  23084. +
  23085. + default: //MP
  23086. +// DMESG("RTL8187 + 8225 Initial Gain State: -82 dBm (default), InitialGain(%d)", priv->InitialGain);
  23087. + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
  23088. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  23089. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  23090. + break;
  23091. + }
  23092. + break;
  23093. +
  23094. + default:
  23095. + break;
  23096. + }
  23097. +}
  23098. +//by amy for DIG
  23099. +void PhyConfig8187(struct net_device *dev)
  23100. +{
  23101. + struct r8180_priv *priv = ieee80211_priv(dev);
  23102. + u8 btConfig4;
  23103. +
  23104. + btConfig4 = read_nic_byte(dev, CONFIG4);
  23105. + priv->RFProgType = (btConfig4 & 0x03);
  23106. +
  23107. +
  23108. +
  23109. + switch(priv->rf_chip)
  23110. + {
  23111. + case RF_ZEBRA2:
  23112. + ZEBRA_Config_87BASIC(dev);
  23113. + break;
  23114. + }
  23115. + if(priv->bDigMechanism)
  23116. + {
  23117. + if(priv->InitialGain == 0)
  23118. + priv->InitialGain = 4;
  23119. + //DMESG("DIG is enabled, set default initial gain index to %d", priv->InitialGain);
  23120. + }
  23121. +
  23122. + // By Bruce, 2007-03-29.
  23123. + UpdateCCKThreshold(dev);
  23124. + // Update initial gain after PhyConfig comleted, asked for by SD3 CMLin.
  23125. + UpdateInitialGain(dev);
  23126. + return ;
  23127. +}
  23128. +
  23129. +u8 GetSupportedWirelessMode8187(struct net_device* dev)
  23130. +{
  23131. + u8 btSupportedWirelessMode;
  23132. + struct r8180_priv *priv = ieee80211_priv(dev);
  23133. +
  23134. + btSupportedWirelessMode = 0;
  23135. +
  23136. + switch(priv->rf_chip)
  23137. + {
  23138. + case RF_ZEBRA:
  23139. + case RF_ZEBRA2:
  23140. + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
  23141. + break;
  23142. + default:
  23143. + btSupportedWirelessMode = WIRELESS_MODE_B;
  23144. + break;
  23145. + }
  23146. + return btSupportedWirelessMode;
  23147. +}
  23148. +
  23149. +void ActUpdateChannelAccessSetting(struct net_device *dev,
  23150. + int WirelessMode,
  23151. + PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
  23152. +{
  23153. + AC_CODING eACI;
  23154. + AC_PARAM AcParam;
  23155. +#ifdef TODO
  23156. + PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
  23157. +#endif
  23158. + //bool bFollowLegacySetting = false;
  23159. +
  23160. +
  23161. + switch( WirelessMode )
  23162. + {
  23163. + case WIRELESS_MODE_A:
  23164. + ChnlAccessSetting->SIFS_Timer = 0x22;
  23165. + ChnlAccessSetting->DIFS_Timer = 34; // 34 = 16 + 2*9. 2006.06.07, by rcnjko.
  23166. + ChnlAccessSetting->SlotTimeTimer = 9;
  23167. + ChnlAccessSetting->EIFS_Timer = 23;
  23168. + ChnlAccessSetting->CWminIndex = 4;
  23169. + ChnlAccessSetting->CWmaxIndex = 10;
  23170. + break;
  23171. +
  23172. + case WIRELESS_MODE_B:
  23173. + ChnlAccessSetting->SIFS_Timer = 0x22;
  23174. + ChnlAccessSetting->DIFS_Timer = 50; // 50 = 10 + 2*20. 2006.06.07, by rcnjko.
  23175. + ChnlAccessSetting->SlotTimeTimer = 20;
  23176. + ChnlAccessSetting->EIFS_Timer = 91;
  23177. + ChnlAccessSetting->CWminIndex = 5;
  23178. + ChnlAccessSetting->CWmaxIndex = 10;
  23179. + break;
  23180. +
  23181. + case WIRELESS_MODE_G:
  23182. + //
  23183. + // <RJ_TODO_8185B>
  23184. + // TODO: We still don't know how to set up these registers, just follow WMAC to
  23185. + // verify 8185B FPAG.
  23186. + //
  23187. + // <RJ_TODO_8185B>
  23188. + // Jong said CWmin/CWmax register are not functional in 8185B,
  23189. + // so we shall fill channel access realted register into AC parameter registers,
  23190. + // even in nQBss.
  23191. + //
  23192. + ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
  23193. + ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.07, by rcnjko.
  23194. + ChnlAccessSetting->DIFS_Timer = 28; // 28 = 10 + 2*9. 2006.06.07, by rcnjko.
  23195. + ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
  23196. +#ifdef TODO
  23197. + switch (Adapter->NdisUsbDev.CWinMaxMin)
  23198. +#else
  23199. + switch (2)
  23200. +#endif
  23201. + {
  23202. + case 0:// 0: [max:7 min:1 ]
  23203. + ChnlAccessSetting->CWminIndex = 1;
  23204. + ChnlAccessSetting->CWmaxIndex = 7;
  23205. + break;
  23206. + case 1:// 1: [max:7 min:2 ]
  23207. + ChnlAccessSetting->CWminIndex = 2;
  23208. + ChnlAccessSetting->CWmaxIndex = 7;
  23209. + break;
  23210. + case 2:// 2: [max:7 min:3 ]
  23211. + ChnlAccessSetting->CWminIndex = 3;
  23212. + ChnlAccessSetting->CWmaxIndex = 7;
  23213. + break;
  23214. + case 3:// 3: [max:9 min:1 ]
  23215. + ChnlAccessSetting->CWminIndex = 1;
  23216. + ChnlAccessSetting->CWmaxIndex = 9;
  23217. + break;
  23218. + case 4:// 4: [max:9 min:2 ]
  23219. + ChnlAccessSetting->CWminIndex = 2;
  23220. + ChnlAccessSetting->CWmaxIndex = 9;
  23221. + break;
  23222. + case 5:// 5: [max:9 min:3 ]
  23223. + ChnlAccessSetting->CWminIndex = 3;
  23224. + ChnlAccessSetting->CWmaxIndex = 9;
  23225. + break;
  23226. + case 6:// 6: [max:A min:5 ]
  23227. + ChnlAccessSetting->CWminIndex = 5;
  23228. + ChnlAccessSetting->CWmaxIndex = 10;
  23229. + break;
  23230. + case 7:// 7: [max:A min:4 ]
  23231. + ChnlAccessSetting->CWminIndex = 4;
  23232. + ChnlAccessSetting->CWmaxIndex = 10;
  23233. + break;
  23234. +
  23235. + default:
  23236. + ChnlAccessSetting->CWminIndex = 1;
  23237. + ChnlAccessSetting->CWmaxIndex = 7;
  23238. + break;
  23239. + }
  23240. +#ifdef TODO
  23241. + if( Adapter->MgntInfo.OpMode == RT_OP_MODE_IBSS)
  23242. + {
  23243. + ChnlAccessSetting->CWminIndex= 4;
  23244. + ChnlAccessSetting->CWmaxIndex= 10;
  23245. + }
  23246. +#endif
  23247. + break;
  23248. + }
  23249. +
  23250. +
  23251. + write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
  23252. +//{ update slot time related by david, 2006-7-21
  23253. + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
  23254. +#ifdef TODO
  23255. + if(pStaQos->CurrentQosMode > QOS_DISABLE)
  23256. + {
  23257. + for(eACI = 0; eACI < AC_MAX; eACI++)
  23258. + {
  23259. + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, \
  23260. + (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
  23261. + }
  23262. + }
  23263. + else
  23264. +#endif
  23265. + {
  23266. + u8 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
  23267. +
  23268. + write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
  23269. + write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
  23270. + write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
  23271. + write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
  23272. + }
  23273. +//}
  23274. +
  23275. + write_nic_byte(dev, EIFS_8187B, ChnlAccessSetting->EIFS_Timer);
  23276. + write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
  23277. +#ifdef TODO
  23278. + // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
  23279. + if( pStaQos->CurrentQosMode > QOS_DISABLE )
  23280. + { // QoS mode.
  23281. + if(pStaQos->QBssWirelessMode == WirelessMode)
  23282. + {
  23283. + // Follow AC Parameters of the QBSS.
  23284. + for(eACI = 0; eACI < AC_MAX; eACI++)
  23285. + {
  23286. + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
  23287. + }
  23288. + }
  23289. + else
  23290. + {
  23291. + // Follow Default WMM AC Parameters.
  23292. + bFollowLegacySetting = TRUE;
  23293. + }
  23294. + }
  23295. + else
  23296. + { // Legacy 802.11.
  23297. + bFollowLegacySetting = TRUE;
  23298. + }
  23299. +
  23300. + if(bFollowLegacySetting)
  23301. +#endif
  23302. + if(true)
  23303. + {
  23304. + //
  23305. + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
  23306. + // 2005.12.01, by rcnjko.
  23307. + //
  23308. + AcParam.longData = 0;
  23309. + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
  23310. + AcParam.f.AciAifsn.f.ACM = 0;
  23311. + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
  23312. + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
  23313. + AcParam.f.TXOPLimit = 0;
  23314. + for(eACI = 0; eACI < AC_MAX; eACI++)
  23315. + {
  23316. + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
  23317. + {
  23318. + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
  23319. + AC_CODING eACI;
  23320. + u8 u1bAIFS;
  23321. + u32 u4bAcParam;
  23322. +
  23323. + // Retrive paramters to udpate.
  23324. + eACI = pAcParam->f.AciAifsn.f.ACI;
  23325. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
  23326. + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  23327. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  23328. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  23329. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  23330. +
  23331. + switch(eACI)
  23332. + {
  23333. + case AC1_BK:
  23334. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  23335. + break;
  23336. +
  23337. + case AC0_BE:
  23338. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  23339. + break;
  23340. +
  23341. + case AC2_VI:
  23342. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  23343. + break;
  23344. +
  23345. + case AC3_VO:
  23346. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  23347. + break;
  23348. +
  23349. + default:
  23350. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  23351. + break;
  23352. + }
  23353. +
  23354. + // Cehck ACM bit.
  23355. + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
  23356. + //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
  23357. + {
  23358. + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
  23359. + AC_CODING eACI = pAciAifsn->f.ACI;
  23360. +
  23361. + //modified Joseph
  23362. + //for 8187B AsynIORead issue
  23363. +#ifdef TODO
  23364. + u8 AcmCtrl = pHalData->AcmControl;
  23365. +#else
  23366. + u8 AcmCtrl = 0;
  23367. +#endif
  23368. + if( pAciAifsn->f.ACM )
  23369. + { // ACM bit is 1.
  23370. + switch(eACI)
  23371. + {
  23372. + case AC0_BE:
  23373. + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
  23374. + break;
  23375. +
  23376. + case AC2_VI:
  23377. + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
  23378. + break;
  23379. +
  23380. + case AC3_VO:
  23381. + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
  23382. + break;
  23383. +
  23384. + default:
  23385. + printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set\
  23386. + failed: eACI is %d\n", eACI );
  23387. + break;
  23388. + }
  23389. + }
  23390. + else
  23391. + { // ACM bit is 0.
  23392. + switch(eACI)
  23393. + {
  23394. + case AC0_BE:
  23395. + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
  23396. + break;
  23397. +
  23398. + case AC2_VI:
  23399. + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
  23400. + break;
  23401. +
  23402. + case AC3_VO:
  23403. + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
  23404. + break;
  23405. +
  23406. + default:
  23407. + break;
  23408. + }
  23409. + }
  23410. +
  23411. + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
  23412. +
  23413. +#ifdef TO_DO
  23414. + pHalData->AcmControl = AcmCtrl;
  23415. +#endif
  23416. + write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
  23417. + }
  23418. + }
  23419. + }
  23420. + }
  23421. +}
  23422. +
  23423. +void ActSetWirelessMode8187(struct net_device* dev, u8 btWirelessMode)
  23424. +{
  23425. + struct r8180_priv *priv = ieee80211_priv(dev);
  23426. + struct ieee80211_device *ieee = priv->ieee80211;
  23427. + //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo);
  23428. + u8 btSupportedWirelessMode = GetSupportedWirelessMode8187(dev);
  23429. +
  23430. + if( (btWirelessMode & btSupportedWirelessMode) == 0 )
  23431. + { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
  23432. + printk(KERN_WARNING "ActSetWirelessMode8187(): WirelessMode(%d) is not supported (%d)!\n",
  23433. + btWirelessMode, btSupportedWirelessMode);
  23434. + return;
  23435. + }
  23436. +
  23437. + // 1. Assign wireless mode to swtich if necessary.
  23438. + if( (btWirelessMode == WIRELESS_MODE_AUTO) ||
  23439. + (btWirelessMode & btSupportedWirelessMode) == 0 )
  23440. + {
  23441. + if((btSupportedWirelessMode & WIRELESS_MODE_A))
  23442. + {
  23443. + btWirelessMode = WIRELESS_MODE_A;
  23444. + }
  23445. + else if((btSupportedWirelessMode & WIRELESS_MODE_G))
  23446. + {
  23447. + btWirelessMode = WIRELESS_MODE_G;
  23448. + }
  23449. + else if((btSupportedWirelessMode & WIRELESS_MODE_B))
  23450. + {
  23451. + btWirelessMode = WIRELESS_MODE_B;
  23452. + }
  23453. + else
  23454. + {
  23455. + printk(KERN_WARNING "MptActSetWirelessMode8187(): No valid wireless mode supported, \
  23456. + btSupportedWirelessMode(%x)!!!\n", btSupportedWirelessMode);
  23457. + btWirelessMode = WIRELESS_MODE_B;
  23458. + }
  23459. + }
  23460. +
  23461. + // 2. Swtich band.
  23462. + switch(priv->rf_chip)
  23463. + {
  23464. + case RF_ZEBRA:
  23465. + case RF_ZEBRA2:
  23466. + {
  23467. + // Update current wireless mode if we swtich to specified band successfully.
  23468. + ieee->mode = (WIRELESS_MODE)btWirelessMode;
  23469. + }
  23470. + break;
  23471. +
  23472. + default:
  23473. + printk(KERN_WARNING "MptActSetWirelessMode8187(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
  23474. + break;
  23475. + }
  23476. +
  23477. + // 4. Change related setting.
  23478. +#if 0
  23479. + if( ieee->mode == WIRELESS_MODE_A ){
  23480. + DMESG("WIRELESS_MODE_A");
  23481. + }
  23482. + else if(ieee->mode == WIRELESS_MODE_B ){
  23483. + DMESG("WIRELESS_MODE_B");
  23484. + }
  23485. + else if( ieee->mode == WIRELESS_MODE_G ){
  23486. + DMESG("WIRELESS_MODE_G");
  23487. + }
  23488. +#endif
  23489. + ActUpdateChannelAccessSetting(dev, ieee->mode, &priv->ChannelAccessSetting );
  23490. +//by amy 0305
  23491. +#ifdef TODO
  23492. + if(ieee->mode == WIRELESS_MODE_B && priv->InitialGain > pHalData->RegBModeGainStage)
  23493. + {
  23494. + pHalData->InitialGain = pHalData->RegBModeGainStage; // B mode, OFDM[0x17] = 26.
  23495. + RT_TRACE(COMP_INIT | COMP_DIG, DBG_LOUD, ("ActSetWirelessMode8187(): update init_gain to index %d for B mode\n",pHalData->InitialGain));
  23496. + PlatformScheduleWorkItem( &(pHalData->UpdateDigWorkItem) );
  23497. + }
  23498. +// pAdapter->MgntInfo.dot11CurrentWirelessMode = pHalData->CurrentWirelessMode;
  23499. +// MgntSetRegdot11OperationalRateSet( pAdapter );
  23500. +#endif
  23501. +//by amy 0305
  23502. +}
  23503. +
  23504. +
  23505. +void
  23506. +InitializeExtraRegsOn8185(struct net_device *dev)
  23507. +{
  23508. + struct r8180_priv *priv = ieee80211_priv(dev);
  23509. + struct ieee80211_device *ieee = priv->ieee80211;
  23510. + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
  23511. + bool bUNIVERSAL_CONTROL_RL = false; // Enable per-packet tx retry, 2005.03.31, by rcnjko.
  23512. + bool bUNIVERSAL_CONTROL_AGC = true;//false;
  23513. + bool bUNIVERSAL_CONTROL_ANT = true;//false;
  23514. + bool bAUTO_RATE_FALLBACK_CTL = true;
  23515. + u8 val8;
  23516. +
  23517. + // Set up ACK rate.
  23518. + // Suggested by wcchu, 2005.08.25, by rcnjko.
  23519. + // 1. Initialize (MinRR, MaxRR) to (6,24) for A/G.
  23520. + // 2. MUST Set RR before BRSR.
  23521. + // 3. CCK must be basic rate.
  23522. + if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
  23523. + {
  23524. + write_nic_word(dev, BRSR_8187B, 0x0fff);
  23525. + }
  23526. + else
  23527. + {
  23528. + write_nic_word(dev, BRSR_8187B, 0x000f);
  23529. + }
  23530. +
  23531. +
  23532. + // Retry limit
  23533. + val8 = read_nic_byte(dev, CW_CONF);
  23534. + if(bUNIVERSAL_CONTROL_RL)
  23535. + {
  23536. + val8 &= (~CW_CONF_PERPACKET_RETRY_LIMIT);
  23537. + }
  23538. + else
  23539. + {
  23540. + val8 |= CW_CONF_PERPACKET_RETRY_LIMIT;
  23541. + }
  23542. +
  23543. + write_nic_byte(dev, CW_CONF, val8);
  23544. +
  23545. + // Tx AGC
  23546. + val8 = read_nic_byte(dev, TX_AGC_CTL);
  23547. + if(bUNIVERSAL_CONTROL_AGC)
  23548. + {
  23549. + val8 &= (~TX_AGC_CTL_PER_PACKET_TXAGC);
  23550. + write_nic_byte(dev, CCK_TXAGC, 128);
  23551. + write_nic_byte(dev, OFDM_TXAGC, 128);
  23552. + }
  23553. + else
  23554. + {
  23555. + val8 |= TX_AGC_CTL_PER_PACKET_TXAGC;
  23556. + }
  23557. + write_nic_byte(dev, TX_AGC_CTL, val8);
  23558. +
  23559. + // Tx Antenna including Feedback control
  23560. + val8 = read_nic_byte(dev, TX_AGC_CTL);
  23561. +
  23562. + if(bUNIVERSAL_CONTROL_ANT)
  23563. + {
  23564. + write_nic_byte(dev, ANTSEL, 0x00);
  23565. + val8 &= (~TXAGC_CTL_PER_PACKET_ANT_SEL);
  23566. + }
  23567. + else
  23568. + {
  23569. + val8 |= TXAGC_CTL_PER_PACKET_ANT_SEL;
  23570. + }
  23571. + write_nic_byte(dev, TX_AGC_CTL, val8);
  23572. +
  23573. + // Auto Rate fallback control
  23574. + val8 = read_nic_byte(dev, RATE_FALLBACK);
  23575. + if( bAUTO_RATE_FALLBACK_CTL )
  23576. + {
  23577. + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP0;
  23578. +
  23579. + // <RJ_TODO_8187B> We shall set up the ARFR according to user's setting.
  23580. + write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
  23581. + }
  23582. + else
  23583. + {
  23584. + val8 &= (~RATE_FALLBACK_CTL_ENABLE);
  23585. + }
  23586. + write_nic_byte(dev, RATE_FALLBACK, val8);
  23587. +
  23588. +}
  23589. +///////////////////////////
  23590. +void rtl8225z2_rf_init(struct net_device *dev)
  23591. +{
  23592. +
  23593. + struct r8180_priv *priv = ieee80211_priv(dev);
  23594. + if (NIC_8187B == priv->card_8187){
  23595. + struct ieee80211_device *ieee = priv->ieee80211;
  23596. + u8 InitWirelessMode;
  23597. + u8 SupportedWirelessMode;
  23598. + bool bInvalidWirelessMode = false;
  23599. + InitializeExtraRegsOn8185(dev);
  23600. +
  23601. + write_nic_byte(dev, MSR, read_nic_byte(dev,MSR) & 0xf3); // default network type to 'No Link'
  23602. + //{to avoid tx stall
  23603. + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR)|MSR_LINK_ENEDCA);//should always set ENDCA bit
  23604. + write_nic_byte(dev, ACM_CONTROL, priv->AcmControl);
  23605. +
  23606. + write_nic_word(dev, BcnIntv, 100);
  23607. + write_nic_word(dev, AtimWnd, 2);
  23608. + write_nic_word(dev, FEMR, 0xFFFF);
  23609. + //LED TYPE
  23610. + {
  23611. + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
  23612. + }
  23613. + write_nic_byte(dev, CR9346, 0x0); // disable config register write
  23614. +
  23615. + //{ add some info here
  23616. + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
  23617. + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
  23618. +
  23619. + write_nic_byte(dev, WPA_CONFIG, 0);
  23620. + //}
  23621. +
  23622. + MacConfig_87BASIC(dev);
  23623. +
  23624. + // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
  23625. + write_nic_word(dev, RFSW_CTRL, 0x569a);
  23626. +#ifdef JOHN_TKIP
  23627. + {
  23628. + void CamResetAllEntry(struct net_device *dev);
  23629. + void EnableHWSecurityConfig8187(struct net_device *dev);
  23630. + CamResetAllEntry(dev);
  23631. + EnableHWSecurityConfig8187(dev);
  23632. + write_nic_word(dev, AESMSK_FC, AESMSK_FC_DEFAULT); mdelay(1);
  23633. + write_nic_word(dev, AESMSK_SC, AESMSK_SC_DEFAULT); mdelay(1);
  23634. + write_nic_word(dev, AESMSK_QC, AESMSK_QC_DEFAULT); mdelay(1);
  23635. + }
  23636. +#endif
  23637. + //-----------------------------------------------------------------------------
  23638. + // Set up PHY related.
  23639. + //-----------------------------------------------------------------------------
  23640. + // Enable Config3.PARAM_En to revise AnaaParm.
  23641. + write_nic_byte(dev, CR9346, 0xC0);
  23642. + write_nic_byte(dev, CONFIG3, read_nic_byte(dev,CONFIG3)|CONFIG3_PARM_En);
  23643. + write_nic_byte(dev, CR9346, 0x0);
  23644. +
  23645. + // Initialize RFE and read Zebra2 version code. Added by Annie, 2005-08-01.
  23646. + SetupRFEInitialTiming(dev);
  23647. + // PHY config.
  23648. + PhyConfig8187(dev);
  23649. +
  23650. + // We assume RegWirelessMode has already been initialized before,
  23651. + // however, we has to validate the wireless mode here and provide a reasonble
  23652. + // initialized value if necessary. 2005.01.13, by rcnjko.
  23653. + SupportedWirelessMode = GetSupportedWirelessMode8187(dev);
  23654. +
  23655. + if((ieee->mode != WIRELESS_MODE_B) &&
  23656. + (ieee->mode != WIRELESS_MODE_G) &&
  23657. + (ieee->mode != WIRELESS_MODE_A) &&
  23658. + (ieee->mode != WIRELESS_MODE_AUTO))
  23659. + { // It should be one of B, G, A, or AUTO.
  23660. + bInvalidWirelessMode = true;
  23661. + }
  23662. + else
  23663. + { // One of B, G, A, or AUTO.
  23664. + // Check if the wireless mode is supported by RF.
  23665. + if( (ieee->mode != WIRELESS_MODE_AUTO) &&
  23666. + (ieee->mode & SupportedWirelessMode) == 0 )
  23667. + {
  23668. + bInvalidWirelessMode = true;
  23669. + }
  23670. + }
  23671. +
  23672. + if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
  23673. + { // Auto or other invalid value.
  23674. + // Assigne a wireless mode to initialize.
  23675. + if((SupportedWirelessMode & WIRELESS_MODE_A))
  23676. + {
  23677. + InitWirelessMode = WIRELESS_MODE_A;
  23678. + }
  23679. + else if((SupportedWirelessMode & WIRELESS_MODE_G))
  23680. + {
  23681. +
  23682. + InitWirelessMode = WIRELESS_MODE_G;
  23683. + }
  23684. + else if((SupportedWirelessMode & WIRELESS_MODE_B))
  23685. + {
  23686. +
  23687. + InitWirelessMode = WIRELESS_MODE_B;
  23688. + }
  23689. + else
  23690. + {
  23691. + printk(KERN_WARNING
  23692. + "InitializeAdapter8187(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
  23693. + SupportedWirelessMode);
  23694. + InitWirelessMode = WIRELESS_MODE_B;
  23695. + }
  23696. +
  23697. + // Initialize RegWirelessMode if it is not a valid one.
  23698. + if(bInvalidWirelessMode)
  23699. + {
  23700. + ieee->mode = (WIRELESS_MODE)InitWirelessMode;
  23701. + }
  23702. + }
  23703. + else
  23704. + { // One of B, G, A.
  23705. + InitWirelessMode = ieee->mode;
  23706. + }
  23707. + ActSetWirelessMode8187(dev, (u8)(InitWirelessMode));
  23708. + {//added for init gain
  23709. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
  23710. + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
  23711. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  23712. + write_phy_cck(dev, 0xc1, 0x88); mdelay(1);
  23713. + }
  23714. +
  23715. + }
  23716. + else{
  23717. + int i;
  23718. + short channel = 1;
  23719. + u16 brsr;
  23720. + u32 data,addr;
  23721. +
  23722. + priv->chan = channel;
  23723. +
  23724. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  23725. +
  23726. + if(priv->card_type == USB)
  23727. + rtl8225_host_usb_init(dev);
  23728. + else
  23729. + rtl8225_host_pci_init(dev);
  23730. +
  23731. + write_nic_dword(dev, RF_TIMING, 0x000a8008);
  23732. +
  23733. + brsr = read_nic_word(dev, BRSR_8187);
  23734. +
  23735. + write_nic_word(dev, BRSR_8187, 0xffff);
  23736. +
  23737. +
  23738. + write_nic_dword(dev, RF_PARA, 0x100044);
  23739. +
  23740. + #if 1 //0->1
  23741. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  23742. + write_nic_byte(dev, CONFIG3, 0x44);
  23743. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  23744. + #endif
  23745. +
  23746. +
  23747. + rtl8185_rf_pins_enable(dev);
  23748. +
  23749. + // mdelay(1000);
  23750. +
  23751. + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
  23752. +
  23753. +
  23754. + write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
  23755. +
  23756. + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
  23757. +
  23758. + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
  23759. +
  23760. +
  23761. + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
  23762. +
  23763. +
  23764. +
  23765. + write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
  23766. + // }
  23767. +
  23768. + write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
  23769. +
  23770. + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
  23771. +
  23772. + write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
  23773. +
  23774. + write_rtl8225(dev, 0x9, 0x335); mdelay(1);
  23775. +
  23776. + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
  23777. +
  23778. + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
  23779. +
  23780. + write_rtl8225(dev, 0xc, 0x850); mdelay(1);
  23781. +
  23782. +
  23783. + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
  23784. +
  23785. + write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
  23786. +
  23787. + write_rtl8225(dev, 0xf, 0x114);
  23788. +
  23789. +
  23790. + mdelay(100);
  23791. +
  23792. +
  23793. + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
  23794. + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  23795. +
  23796. + write_rtl8225(dev, 0x0, 0x1b7);
  23797. +
  23798. + for(i=0;i<95;i++){
  23799. + write_rtl8225(dev, 0x1, (u8)(i+1));
  23800. + /* version B & C & D*/
  23801. + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
  23802. + }
  23803. + //write_rtl8225(dev, 0x3, 0x80);
  23804. + write_rtl8225(dev, 0x3, 0x2);
  23805. + write_rtl8225(dev, 0x5, 0x4);
  23806. +
  23807. + write_rtl8225(dev, 0x0, 0xb7);
  23808. +
  23809. + write_rtl8225(dev, 0x2, 0xc4d);
  23810. +
  23811. + if(priv->card_type == USB){
  23812. + // force_pci_posting(dev);
  23813. + mdelay(200);
  23814. +
  23815. + write_rtl8225(dev, 0x2, 0x44d);
  23816. +
  23817. + // force_pci_posting(dev);
  23818. + mdelay(200);
  23819. +
  23820. + }//End of if(priv->card_type == USB)
  23821. + /* FIXME!! rtl8187 we have to check if calibrarion
  23822. + * is successful and eventually cal. again (repeat
  23823. + * the two write on reg 2)
  23824. + */
  23825. + // Check for calibration status, 2005.11.17,
  23826. + data = read_rtl8225(dev, 6);
  23827. + if (!(data&0x00000080))
  23828. + {
  23829. + write_rtl8225(dev, 0x02, 0x0c4d);
  23830. + force_pci_posting(dev); mdelay(200);
  23831. + write_rtl8225(dev, 0x02, 0x044d);
  23832. + force_pci_posting(dev); mdelay(100);
  23833. + data = read_rtl8225(dev, 6);
  23834. + if (!(data&0x00000080))
  23835. + {
  23836. + DMESGW("RF Calibration Failed!!!!\n");
  23837. + }
  23838. + }
  23839. + //force_pci_posting(dev);
  23840. +
  23841. + mdelay(200); //200 for 8187
  23842. +
  23843. +
  23844. + // //if(priv->card_type != USB){
  23845. + // write_rtl8225(dev, 0x2, 0x44d);
  23846. + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  23847. + // write_rtl8225(dev, 0x2, 0x47d);
  23848. + //
  23849. + // force_pci_posting(dev);
  23850. + // mdelay(100);
  23851. + //
  23852. + // write_rtl8225(dev, 0x2, 0x44d);
  23853. + // //}
  23854. +
  23855. + write_rtl8225(dev, 0x0, 0x2bf);
  23856. +
  23857. + if(priv->card_type != USB)
  23858. + rtl8185_rf_pins_enable(dev);
  23859. + //set up ZEBRA AGC table, 2005.11.17,
  23860. + for(i=0;i<128;i++){
  23861. + data = rtl8225_agc[i];
  23862. +
  23863. + addr = i + 0x80; //enable writing AGC table
  23864. + write_phy_ofdm(dev, 0xb, data);
  23865. +
  23866. + mdelay(1);
  23867. + write_phy_ofdm(dev, 0xa, addr);
  23868. +
  23869. + mdelay(1);
  23870. + }
  23871. +
  23872. + force_pci_posting(dev);
  23873. + mdelay(1);
  23874. +
  23875. + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
  23876. + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
  23877. + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
  23878. + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
  23879. + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
  23880. + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
  23881. + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
  23882. + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
  23883. + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
  23884. + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
  23885. +
  23886. + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
  23887. +
  23888. + //write_phy_ofdm(dev, 0x18, 0xef);
  23889. + // }
  23890. + //}
  23891. + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
  23892. +
  23893. + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
  23894. +
  23895. +
  23896. + //if(priv->card_type != USB)
  23897. + write_phy_ofdm(dev, 0xd, 0x43);
  23898. +
  23899. + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
  23900. +
  23901. + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
  23902. + /*ver D & 8187*/
  23903. + // }
  23904. +
  23905. + // if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  23906. + // write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
  23907. + // else
  23908. + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
  23909. + /*ver C & D & 8187*/
  23910. +
  23911. + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
  23912. + /*agc resp time 700*/
  23913. +
  23914. +
  23915. + // if(priv->card_8185 == 2){
  23916. + /* Ver D & 8187*/
  23917. + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
  23918. +
  23919. + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
  23920. +
  23921. + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
  23922. + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
  23923. + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
  23924. + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
  23925. +
  23926. + // if (priv->card_type == USB)
  23927. + // write_phy_ofdm(dev, 0x18, 0xef);
  23928. +
  23929. + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
  23930. +
  23931. +
  23932. + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
  23933. + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
  23934. + write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
  23935. +
  23936. + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
  23937. +
  23938. + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
  23939. +
  23940. + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
  23941. +
  23942. + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
  23943. +
  23944. + // }
  23945. +
  23946. + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
  23947. +
  23948. + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
  23949. +
  23950. + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
  23951. +
  23952. + // if(priv->card_type != USB)
  23953. + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
  23954. +
  23955. + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
  23956. + write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
  23957. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
  23958. +
  23959. + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
  23960. +
  23961. +
  23962. + // <> Set init. gain to m74dBm.
  23963. +
  23964. + rtl8225z2_set_gain(dev,4);
  23965. + //rtl8225z2_set_gain(dev,2);
  23966. +
  23967. + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
  23968. + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
  23969. + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
  23970. + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
  23971. + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
  23972. + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
  23973. + /* Ver C & D & 8187*/
  23974. + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
  23975. +
  23976. + write_phy_cck(dev, 0x9, 0x11);mdelay(1);
  23977. + write_phy_cck(dev, 0xa, 0x17);mdelay(1);
  23978. + write_phy_cck(dev, 0xb, 0x11);mdelay(1);
  23979. +
  23980. + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
  23981. + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
  23982. + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
  23983. + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
  23984. +
  23985. + write_phy_cck(dev, 0x19, 0x0); mdelay(1);
  23986. + write_phy_cck(dev, 0x1a, 0xa0); mdelay(1);
  23987. + write_phy_cck(dev, 0x1b, 0x8); mdelay(1);
  23988. + write_phy_cck(dev, 0x1d, 0x0); mdelay(1);
  23989. +
  23990. + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ mdelay(1);
  23991. +
  23992. + write_phy_cck(dev, 0x41, 0x9d);mdelay(1);
  23993. +
  23994. +
  23995. + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
  23996. + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
  23997. +
  23998. +
  23999. + write_phy_cck(dev, 0x44, 0x36); mdelay(1);
  24000. + write_phy_cck(dev, 0x45, 0x35); mdelay(1);
  24001. + write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
  24002. + write_phy_cck(dev, 0x47, 0x25); mdelay(1);
  24003. + write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
  24004. + write_phy_cck(dev, 0x49, 0x12); mdelay(1);
  24005. + write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
  24006. + write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
  24007. + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
  24008. +
  24009. +
  24010. + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
  24011. +
  24012. +
  24013. +
  24014. + // <>
  24015. + // // TESTR 0xb 8187
  24016. + // write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
  24017. + //
  24018. + // //if(priv->card_type != USB){
  24019. + // write_phy_ofdm(dev, 0x2, 0x62);
  24020. + // write_phy_ofdm(dev, 0x6, 0x0);
  24021. + // write_phy_ofdm(dev, 0x8, 0x0);
  24022. + // //}
  24023. +
  24024. + rtl8225z2_SetTXPowerLevel(dev, channel);
  24025. +
  24026. + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
  24027. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
  24028. +
  24029. + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
  24030. +
  24031. + /* switch to high-speed 3-wire
  24032. + * last digit. 2 for both cck and ofdm
  24033. + */
  24034. + if(priv->card_type == USB)
  24035. + write_nic_dword(dev, 0x94, 0x3dc00002);
  24036. + else{
  24037. + write_nic_dword(dev, 0x94, 0x15c00002);
  24038. + rtl8185_rf_pins_enable(dev);
  24039. + }
  24040. +
  24041. + // if(priv->card_type != USB)
  24042. + // rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
  24043. + // rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
  24044. + //
  24045. + // /* make sure is waken up! */
  24046. + // write_rtl8225(dev,0x4, 0x9ff);
  24047. + // rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  24048. + // rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  24049. +
  24050. + rtl8225_rf_set_chan(dev, priv->chan);
  24051. +
  24052. + //write_nic_word(dev,BRSR,brsr);
  24053. +
  24054. + //rtl8225z2_rf_set_mode(dev);
  24055. + }
  24056. +}
  24057. +
  24058. +void rtl8225z2_rf_set_mode(struct net_device *dev)
  24059. +{
  24060. + struct r8180_priv *priv = ieee80211_priv(dev);
  24061. +
  24062. + if(priv->ieee80211->mode == IEEE_A)
  24063. + {
  24064. + write_rtl8225(dev, 0x5, 0x1865);
  24065. + write_nic_dword(dev, RF_PARA, 0x10084);
  24066. + write_nic_dword(dev, RF_TIMING, 0xa8008);
  24067. + write_phy_ofdm(dev, 0x0, 0x0);
  24068. + write_phy_ofdm(dev, 0xa, 0x6);
  24069. + write_phy_ofdm(dev, 0xb, 0x99);
  24070. + write_phy_ofdm(dev, 0xf, 0x20);
  24071. + write_phy_ofdm(dev, 0x11, 0x7);
  24072. +
  24073. + rtl8225z2_set_gain(dev,4);
  24074. +
  24075. + write_phy_ofdm(dev,0x15, 0x40);
  24076. + write_phy_ofdm(dev,0x17, 0x40);
  24077. +
  24078. + write_nic_dword(dev, 0x94,0x10000000);
  24079. + }else{
  24080. +
  24081. + write_rtl8225(dev, 0x5, 0x1864);
  24082. + write_nic_dword(dev, RF_PARA, 0x10044);
  24083. + write_nic_dword(dev, RF_TIMING, 0xa8008);
  24084. + write_phy_ofdm(dev, 0x0, 0x1);
  24085. + write_phy_ofdm(dev, 0xa, 0x6);
  24086. + write_phy_ofdm(dev, 0xb, 0x99);
  24087. + write_phy_ofdm(dev, 0xf, 0x20);
  24088. + write_phy_ofdm(dev, 0x11, 0x7);
  24089. +
  24090. + rtl8225z2_set_gain(dev,4);
  24091. +
  24092. + write_phy_ofdm(dev,0x15, 0x40);
  24093. + write_phy_ofdm(dev,0x17, 0x40);
  24094. +
  24095. + write_nic_dword(dev, 0x94,0x04000002);
  24096. + }
  24097. +}
  24098. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.c
  24099. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.c 1970-01-01 01:00:00.000000000 +0100
  24100. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.c 2010-03-06 16:43:22.000000000 +0100
  24101. @@ -0,0 +1,2067 @@
  24102. +/*
  24103. + This file contains wireless extension handlers.
  24104. +
  24105. + This is part of rtl8180 OpenSource driver.
  24106. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  24107. + Released under the terms of GPL (General Public Licence)
  24108. +
  24109. + Parts of this driver are based on the GPL part
  24110. + of the official realtek driver.
  24111. +
  24112. + Parts of this driver are based on the rtl8180 driver skeleton
  24113. + from Patric Schenke & Andres Salomon.
  24114. +
  24115. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  24116. +
  24117. + We want to tanks the Authors of those projects and the Ndiswrapper
  24118. + project Authors.
  24119. +*/
  24120. +
  24121. +
  24122. +
  24123. +#include "r8187.h"
  24124. +#include "r8180_hw.h"
  24125. +//added 1117
  24126. +#include "ieee80211/ieee80211.h"
  24127. +#ifdef ENABLE_DOT11D
  24128. +#include "dot11d.h"
  24129. +#endif
  24130. +
  24131. +
  24132. +//#define RATE_COUNT 4
  24133. +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
  24134. + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
  24135. +#define RATE_COUNT sizeof(rtl8180_rates)/(sizeof(rtl8180_rates[0]))
  24136. +
  24137. +#ifdef _RTL8187_EXT_PATCH_
  24138. +#define IW_MODE_MESH 11
  24139. +static int r8180_wx_join_mesh(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  24140. +int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  24141. +static int r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  24142. +static int r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  24143. +#endif
  24144. +
  24145. +static int r8180_wx_get_freq(struct net_device *dev,
  24146. + struct iw_request_info *a,
  24147. + union iwreq_data *wrqu, char *b)
  24148. +{
  24149. + struct r8180_priv *priv = ieee80211_priv(dev);
  24150. +
  24151. + return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
  24152. +}
  24153. +
  24154. +
  24155. +#if 0
  24156. +
  24157. +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
  24158. + union iwreq_data *wrqu, char *b)
  24159. +{
  24160. + int *parms = (int *)b;
  24161. + int bi = parms[0];
  24162. +
  24163. + struct r8180_priv *priv = ieee80211_priv(dev);
  24164. + if(priv->ieee80211->bHwRadioOff)
  24165. + return 0;
  24166. + down(&priv->wx_sem);
  24167. + DMESG("setting beacon interval to %x",bi);
  24168. +
  24169. + priv->ieee80211->beacon_interval=bi;
  24170. + rtl8180_commit(dev);
  24171. + up(&priv->wx_sem);
  24172. +
  24173. + return 0;
  24174. +}
  24175. +
  24176. +
  24177. +static int r8180_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
  24178. + union iwreq_data *wrqu, char *extra)
  24179. +{
  24180. + struct r8180_priv *priv=ieee80211_priv(dev);
  24181. + int *parms = (int *)extra;
  24182. + if(priv->ieee80211->bHwRadioOff)
  24183. + return 0;
  24184. +
  24185. + priv->ieee80211->force_associate = (parms[0] > 0);
  24186. +
  24187. +
  24188. + return 0;
  24189. +}
  24190. +
  24191. +#endif
  24192. +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
  24193. + union iwreq_data *wrqu, char *b)
  24194. +{
  24195. + struct r8180_priv *priv=ieee80211_priv(dev);
  24196. +
  24197. + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
  24198. +}
  24199. +
  24200. +
  24201. +
  24202. +static int r8180_wx_get_rate(struct net_device *dev,
  24203. + struct iw_request_info *info,
  24204. + union iwreq_data *wrqu, char *extra)
  24205. +{
  24206. + struct r8180_priv *priv = ieee80211_priv(dev);
  24207. + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
  24208. +}
  24209. +
  24210. +
  24211. +
  24212. +static int r8180_wx_set_rate(struct net_device *dev,
  24213. + struct iw_request_info *info,
  24214. + union iwreq_data *wrqu, char *extra)
  24215. +{
  24216. + int ret;
  24217. + struct r8180_priv *priv = ieee80211_priv(dev);
  24218. + if(priv->ieee80211->bHwRadioOff)
  24219. + return 0;
  24220. +
  24221. + down(&priv->wx_sem);
  24222. +
  24223. + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
  24224. +
  24225. + up(&priv->wx_sem);
  24226. +
  24227. + return ret;
  24228. +}
  24229. +#ifdef JOHN_IOCTL
  24230. +u16 read_rtl8225(struct net_device *dev, u8 addr);
  24231. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  24232. +u32 john_read_rtl8225(struct net_device *dev, u8 adr);
  24233. +void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  24234. +
  24235. +static int r8180_wx_read_regs(struct net_device *dev,
  24236. + struct iw_request_info *info,
  24237. + union iwreq_data *wrqu, char *extra)
  24238. +{
  24239. + struct r8180_priv *priv = ieee80211_priv(dev);
  24240. + u8 addr = 0;
  24241. + u16 data1;
  24242. +
  24243. + down(&priv->wx_sem);
  24244. +
  24245. +
  24246. + get_user(addr,(u8*)wrqu->data.pointer);
  24247. + data1 = read_rtl8225(dev, addr);
  24248. + wrqu->data.length = data1;
  24249. +
  24250. + up(&priv->wx_sem);
  24251. + return 0;
  24252. +
  24253. +}
  24254. +
  24255. +static int r8180_wx_write_regs(struct net_device *dev,
  24256. + struct iw_request_info *info,
  24257. + union iwreq_data *wrqu, char *extra)
  24258. +{
  24259. + struct r8180_priv *priv = ieee80211_priv(dev);
  24260. + u8 addr = 0;
  24261. +
  24262. + down(&priv->wx_sem);
  24263. +
  24264. + get_user(addr, (u8*)wrqu->data.pointer);
  24265. + write_rtl8225(dev, addr, wrqu->data.length);
  24266. +
  24267. + up(&priv->wx_sem);
  24268. + return 0;
  24269. +
  24270. +}
  24271. +
  24272. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
  24273. +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
  24274. +
  24275. +static int r8180_wx_read_bb(struct net_device *dev,
  24276. + struct iw_request_info *info,
  24277. + union iwreq_data *wrqu, char *extra)
  24278. +{
  24279. + struct r8180_priv *priv = ieee80211_priv(dev);
  24280. + u8 databb;
  24281. +#if 0
  24282. + int i;
  24283. + for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
  24284. +#endif
  24285. +
  24286. + down(&priv->wx_sem);
  24287. +
  24288. + databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
  24289. + wrqu->data.length = databb;
  24290. +
  24291. + up(&priv->wx_sem);
  24292. + return 0;
  24293. +}
  24294. +
  24295. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
  24296. +static int r8180_wx_write_bb(struct net_device *dev,
  24297. + struct iw_request_info *info,
  24298. + union iwreq_data *wrqu, char *extra)
  24299. +{
  24300. + struct r8180_priv *priv = ieee80211_priv(dev);
  24301. + u8 databb = 0;
  24302. +
  24303. + down(&priv->wx_sem);
  24304. +
  24305. + get_user(databb, (u8*)wrqu->data.pointer);
  24306. + rtl8187_write_phy(dev, wrqu->data.length, databb);
  24307. +
  24308. + up(&priv->wx_sem);
  24309. + return 0;
  24310. +
  24311. +}
  24312. +
  24313. +
  24314. +static int r8180_wx_write_nicb(struct net_device *dev,
  24315. + struct iw_request_info *info,
  24316. + union iwreq_data *wrqu, char *extra)
  24317. +{
  24318. + struct r8180_priv *priv = ieee80211_priv(dev);
  24319. + u32 addr = 0;
  24320. +
  24321. + down(&priv->wx_sem);
  24322. +
  24323. + get_user(addr, (u32*)wrqu->data.pointer);
  24324. + write_nic_byte(dev, addr, wrqu->data.length);
  24325. +
  24326. + up(&priv->wx_sem);
  24327. + return 0;
  24328. +
  24329. +}
  24330. +static int r8180_wx_read_nicb(struct net_device *dev,
  24331. + struct iw_request_info *info,
  24332. + union iwreq_data *wrqu, char *extra)
  24333. +{
  24334. + struct r8180_priv *priv = ieee80211_priv(dev);
  24335. + u32 addr = 0;
  24336. + u16 data1;
  24337. +
  24338. + down(&priv->wx_sem);
  24339. +
  24340. + get_user(addr,(u32*)wrqu->data.pointer);
  24341. + data1 = read_nic_byte(dev, addr);
  24342. + wrqu->data.length = data1;
  24343. +
  24344. + up(&priv->wx_sem);
  24345. + return 0;
  24346. +}
  24347. +
  24348. +static inline int is_same_network(struct ieee80211_network *src,
  24349. + struct ieee80211_network *dst,
  24350. + struct ieee80211_device *ieee)
  24351. +{
  24352. + /* A network is only a duplicate if the channel, BSSID, ESSID
  24353. + * and the capability field (in particular IBSS and BSS) all match.
  24354. + * We treat all <hidden> with the same BSSID and channel
  24355. + * as one network */
  24356. + return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
  24357. + //((src->ssid_len == dst->ssid_len) &&
  24358. + (src->channel == dst->channel) &&
  24359. + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
  24360. + (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
  24361. + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
  24362. + ((src->capability & WLAN_CAPABILITY_IBSS) ==
  24363. + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
  24364. + ((src->capability & WLAN_CAPABILITY_BSS) ==
  24365. + (dst->capability & WLAN_CAPABILITY_BSS)));
  24366. +}
  24367. +
  24368. +static int r8180_wx_get_ap_status(struct net_device *dev,
  24369. + struct iw_request_info *info,
  24370. + union iwreq_data *wrqu, char *extra)
  24371. +{
  24372. + struct r8180_priv *priv = ieee80211_priv(dev);
  24373. + struct ieee80211_device *ieee = priv->ieee80211;
  24374. + struct ieee80211_network *target;
  24375. + int name_len;
  24376. +
  24377. + down(&priv->wx_sem);
  24378. +
  24379. + //count the length of input ssid
  24380. + for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
  24381. +
  24382. + //search for the correspoding info which is received
  24383. + list_for_each_entry(target, &ieee->network_list, list) {
  24384. + if ( (target->ssid_len == name_len) &&
  24385. + (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
  24386. + if( ((jiffies-target->last_scanned)/HZ > 1) && (ieee->state == IEEE80211_LINKED) && (is_same_network(&ieee->current_network,target, ieee)) )
  24387. + wrqu->data.length = 999;
  24388. + else
  24389. + wrqu->data.length = target->SignalStrength;
  24390. + if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
  24391. + //set flags=1 to indicate this ap is WPA
  24392. + wrqu->data.flags = 1;
  24393. + else wrqu->data.flags = 0;
  24394. +
  24395. +
  24396. + break;
  24397. + }
  24398. + }
  24399. +
  24400. + if (&target->list == &ieee->network_list){
  24401. + wrqu->data.flags = 3;
  24402. + }
  24403. + up(&priv->wx_sem);
  24404. + return 0;
  24405. +}
  24406. +
  24407. +
  24408. +
  24409. +#endif
  24410. +
  24411. +static int r8180_wx_set_rawtx(struct net_device *dev,
  24412. + struct iw_request_info *info,
  24413. + union iwreq_data *wrqu, char *extra)
  24414. +{
  24415. + struct r8180_priv *priv = ieee80211_priv(dev);
  24416. + int ret;
  24417. +
  24418. + if(priv->ieee80211->bHwRadioOff)
  24419. + return 0;
  24420. +
  24421. + down(&priv->wx_sem);
  24422. +
  24423. + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
  24424. +
  24425. + up(&priv->wx_sem);
  24426. +
  24427. + return ret;
  24428. +
  24429. +}
  24430. +
  24431. +static int r8180_wx_set_crcmon(struct net_device *dev,
  24432. + struct iw_request_info *info,
  24433. + union iwreq_data *wrqu, char *extra)
  24434. +{
  24435. + struct r8180_priv *priv = ieee80211_priv(dev);
  24436. + int *parms = (int *)extra;
  24437. + int enable = (parms[0] > 0);
  24438. + short prev = priv->crcmon;
  24439. +
  24440. + if(priv->ieee80211->bHwRadioOff)
  24441. + return 0;
  24442. +
  24443. + down(&priv->wx_sem);
  24444. +
  24445. + if(enable)
  24446. + priv->crcmon=1;
  24447. + else
  24448. + priv->crcmon=0;
  24449. +
  24450. + DMESG("bad CRC in monitor mode are %s",
  24451. + priv->crcmon ? "accepted" : "rejected");
  24452. +
  24453. + if(prev != priv->crcmon && priv->up){
  24454. + rtl8180_down(dev);
  24455. + rtl8180_up(dev);
  24456. + }
  24457. +
  24458. + up(&priv->wx_sem);
  24459. +
  24460. + return 0;
  24461. +}
  24462. +
  24463. +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
  24464. + union iwreq_data *wrqu, char *b)
  24465. +{
  24466. + struct r8180_priv *priv = ieee80211_priv(dev);
  24467. + int ret;
  24468. + if(priv->ieee80211->bHwRadioOff)
  24469. + return 0;
  24470. +
  24471. +#ifdef _RTL8187_EXT_PATCH_
  24472. + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)) return 0;
  24473. +#endif
  24474. + down(&priv->wx_sem);
  24475. +
  24476. +#ifdef CONFIG_IPS
  24477. + if(priv->bInactivePs){
  24478. + if(wrqu->mode != IW_MODE_INFRA){
  24479. + down(&priv->ieee80211->ips_sem);
  24480. + IPSLeave(dev);
  24481. + up(&priv->ieee80211->ips_sem);
  24482. + }
  24483. + }
  24484. +#endif
  24485. + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
  24486. +
  24487. + rtl8187_set_rxconf(dev);
  24488. +
  24489. + up(&priv->wx_sem);
  24490. + return ret;
  24491. +}
  24492. +
  24493. +
  24494. +//YJ,add,080819,for hidden ap
  24495. +struct iw_range_with_scan_capa
  24496. +{
  24497. + /* Informative stuff (to choose between different interface) */
  24498. + __u32 throughput; /* To give an idea... */
  24499. + /* In theory this value should be the maximum benchmarked
  24500. + * TCP/IP throughput, because with most of these devices the
  24501. + * bit rate is meaningless (overhead an co) to estimate how
  24502. + * fast the connection will go and pick the fastest one.
  24503. + * I suggest people to play with Netperf or any benchmark...
  24504. + */
  24505. +
  24506. + /* NWID (or domain id) */
  24507. + __u32 min_nwid; /* Minimal NWID we are able to set */
  24508. + __u32 max_nwid; /* Maximal NWID we are able to set */
  24509. +
  24510. + /* Old Frequency (backward compat - moved lower ) */
  24511. + __u16 old_num_channels;
  24512. + __u8 old_num_frequency;
  24513. +
  24514. + /* Scan capabilities */
  24515. + __u8 scan_capa;
  24516. +};
  24517. +//YJ,add,080819,for hidden ap
  24518. +
  24519. +static int rtl8180_wx_get_range(struct net_device *dev,
  24520. + struct iw_request_info *info,
  24521. + union iwreq_data *wrqu, char *extra)
  24522. +{
  24523. + struct iw_range *range = (struct iw_range *)extra;
  24524. + struct r8180_priv *priv = ieee80211_priv(dev);
  24525. + u16 val;
  24526. + int i;
  24527. + struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
  24528. +
  24529. + wrqu->data.length = sizeof(*range);
  24530. + memset(range, 0, sizeof(*range));
  24531. +
  24532. + /* Let's try to keep this struct in the same order as in
  24533. + * linux/include/wireless.h
  24534. + */
  24535. +
  24536. + /* TODO: See what values we can set, and remove the ones we can't
  24537. + * set, or fill them with some default data.
  24538. + */
  24539. +
  24540. + /* ~5 Mb/s real (802.11b) */
  24541. + range->throughput = 5 * 1000 * 1000;
  24542. +
  24543. + // TODO: Not used in 802.11b?
  24544. +// range->min_nwid; /* Minimal NWID we are able to set */
  24545. + // TODO: Not used in 802.11b?
  24546. +// range->max_nwid; /* Maximal NWID we are able to set */
  24547. +
  24548. + /* Old Frequency (backward compat - moved lower ) */
  24549. +// range->old_num_channels;
  24550. +// range->old_num_frequency;
  24551. +// range->old_freq[6]; /* Filler to keep "version" at the same offset */
  24552. + if(priv->rf_set_sens != NULL)
  24553. + range->sensitivity = priv->max_sens; /* signal level threshold range */
  24554. +
  24555. + range->max_qual.qual = 100;
  24556. + /* TODO: Find real max RSSI and stick here */
  24557. + range->max_qual.level = 0;
  24558. + range->max_qual.noise = -98;
  24559. + range->max_qual.updated = 7; /* Updated all three */
  24560. +
  24561. + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
  24562. + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
  24563. + range->avg_qual.level = 20 + -98;
  24564. + range->avg_qual.noise = 0;
  24565. + range->avg_qual.updated = 7; /* Updated all three */
  24566. +
  24567. + range->num_bitrates = RATE_COUNT;
  24568. +
  24569. + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
  24570. + range->bitrate[i] = rtl8180_rates[i];
  24571. + }
  24572. +
  24573. + range->min_frag = MIN_FRAG_THRESHOLD;
  24574. + range->max_frag = MAX_FRAG_THRESHOLD;
  24575. +
  24576. + range->pm_capa = 0;
  24577. +
  24578. + range->we_version_compiled = WIRELESS_EXT;
  24579. + range->we_version_source = 16;
  24580. +
  24581. +// range->retry_capa; /* What retry options are supported */
  24582. +// range->retry_flags; /* How to decode max/min retry limit */
  24583. +// range->r_time_flags; /* How to decode max/min retry life */
  24584. +// range->min_retry; /* Minimal number of retries */
  24585. +// range->max_retry; /* Maximal number of retries */
  24586. +// range->min_r_time; /* Minimal retry lifetime */
  24587. +// range->max_r_time; /* Maximal retry lifetime */
  24588. +
  24589. + range->num_channels = 14;
  24590. +
  24591. + for (i = 0, val = 0; i < 14; i++) {
  24592. +
  24593. + // Include only legal frequencies for some countries
  24594. +#ifdef ENABLE_DOT11D
  24595. + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
  24596. +#else
  24597. + if ((priv->ieee80211->channel_map)[i+1]) {
  24598. +#endif
  24599. + range->freq[val].i = i + 1;
  24600. + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
  24601. + range->freq[val].e = 1;
  24602. + val++;
  24603. + } else {
  24604. + // FIXME: do we need to set anything for channels
  24605. + // we don't use ?
  24606. + }
  24607. +
  24608. + if (val == IW_MAX_FREQUENCIES)
  24609. + break;
  24610. + }
  24611. +
  24612. + range->num_frequency = val;
  24613. + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
  24614. + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
  24615. +
  24616. + tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
  24617. +
  24618. + return 0;
  24619. +}
  24620. +
  24621. +
  24622. +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
  24623. + union iwreq_data *wrqu, char *b)
  24624. +{
  24625. + struct r8180_priv *priv = ieee80211_priv(dev);
  24626. + struct ieee80211_device* ieee = priv->ieee80211;
  24627. + int ret;
  24628. +
  24629. + if(priv->ieee80211->bHwRadioOff)
  24630. + return 0;
  24631. + //printk("==============>%s()\n",__FUNCTION__);
  24632. + if(!priv->up)
  24633. + return -1;
  24634. +
  24635. + if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
  24636. + {
  24637. + struct iw_scan_req* req = (struct iw_scan_req*)b;
  24638. + if (req->essid_len)
  24639. + {
  24640. + ieee->current_network.ssid_len = req->essid_len;
  24641. + memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
  24642. + }
  24643. + }
  24644. +
  24645. + //set Tr switch to hardware control to scan more bss
  24646. + if(priv->TrSwitchState == TR_SW_TX) {
  24647. + //YJ,add,080611
  24648. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  24649. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  24650. + //YJ,add,080611,end
  24651. + priv->TrSwitchState = TR_HW_CONTROLLED;
  24652. + }
  24653. +#ifdef _RTL8187_EXT_PATCH_
  24654. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  24655. + r8180_wx_mesh_scan(dev,a,wrqu,b);
  24656. + ret = 0;
  24657. + }
  24658. + else
  24659. +#endif
  24660. + {
  24661. + down(&priv->wx_sem);
  24662. + if(priv->ieee80211->state != IEEE80211_LINKED){
  24663. + //printk("===>start no link scan\n");
  24664. + //ieee80211_start_scan(priv->ieee80211);
  24665. + //lzm mod 090115 because wq can't scan complete once
  24666. + //because after start protocal wq scan is in doing
  24667. + //so we should stop it first.
  24668. + ieee80211_stop_scan(priv->ieee80211);
  24669. + ieee80211_start_scan_syncro(priv->ieee80211);
  24670. + ret = 0;
  24671. + } else {
  24672. + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
  24673. + }
  24674. + up(&priv->wx_sem);
  24675. + }
  24676. + return ret;
  24677. +}
  24678. +
  24679. +
  24680. +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
  24681. + union iwreq_data *wrqu, char *b)
  24682. +{
  24683. +
  24684. + int ret;
  24685. + struct r8180_priv *priv = ieee80211_priv(dev);
  24686. +
  24687. + if(!priv->up) return -1;
  24688. +#ifdef _RTL8187_EXT_PATCH_
  24689. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  24690. + ret = r8180_wx_get_mesh_list(dev, a, wrqu, b);
  24691. + }
  24692. + else
  24693. +#endif
  24694. + {
  24695. + down(&priv->wx_sem);
  24696. +
  24697. + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
  24698. +
  24699. + up(&priv->wx_sem);
  24700. + }
  24701. + return ret;
  24702. +}
  24703. +
  24704. +
  24705. +static int r8180_wx_set_essid(struct net_device *dev,
  24706. + struct iw_request_info *a,
  24707. + union iwreq_data *wrqu, char *b)
  24708. +{
  24709. + struct r8180_priv *priv = ieee80211_priv(dev);
  24710. + int ret;
  24711. +#ifdef _RTL8187_EXT_PATCH_
  24712. + struct ieee80211_device *ieee = priv->ieee80211;
  24713. + char ch = 0;
  24714. + char tmpmeshid[32];
  24715. + char *p;
  24716. + int tmpmeshid_len=0;
  24717. + int i;
  24718. + short proto_started;
  24719. +#endif
  24720. + if(priv->ieee80211->bHwRadioOff)
  24721. + return 0;
  24722. + //printk("==========>%s()\n",__FUNCTION__);
  24723. + down(&priv->wx_sem);
  24724. +
  24725. +#ifdef _RTL8187_EXT_PATCH_
  24726. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  24727. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  24728. + ret= -E2BIG;
  24729. + goto out;
  24730. + }
  24731. + if (wrqu->essid.flags && (wrqu->essid.length > 1)) {
  24732. + memset(tmpmeshid,0,32);
  24733. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  24734. + tmpmeshid_len=wrqu->essid.length;
  24735. +#else
  24736. + tmpmeshid_len=wrqu->essid.length + 1;
  24737. +#endif
  24738. + p=b+tmpmeshid_len-2;
  24739. + for(i=tmpmeshid_len-1;i>0;i--)
  24740. + {
  24741. + if((*p)=='@')
  24742. + break;
  24743. + p--;
  24744. + }
  24745. + if((i == 0) || (i == 1)){
  24746. + printk("error:wrong meshid\n");
  24747. + ret = -1;
  24748. + goto out;
  24749. + }
  24750. +
  24751. + memcpy(tmpmeshid,b,(i-1));
  24752. + p++;
  24753. + if((tmpmeshid_len-1-i)==1)
  24754. + {
  24755. + if(*p > '9'|| *p <= '0'){
  24756. + goto out;
  24757. + } else {
  24758. + ch = *p - '0';
  24759. + }
  24760. + }
  24761. + else if((tmpmeshid_len-1-i)==2)
  24762. + {
  24763. + if((*p == '1') && (*(p+1) >= '0') && (*(p+1) <= '9'))
  24764. + ch = (*p - '0') * 10 + (*(p+1) - '0');
  24765. + else
  24766. + goto out;
  24767. + }
  24768. + else {
  24769. + ret = 0;
  24770. + goto out;
  24771. + }
  24772. + if(ch > 14)
  24773. + {
  24774. + ret = 0;
  24775. + printk("channel is invalid: %d\n",ch);
  24776. + goto out;
  24777. + }
  24778. + ieee->sync_scan_hurryup = 1;
  24779. +
  24780. + proto_started = ieee->proto_started;
  24781. + if(proto_started)
  24782. + ieee80211_stop_protocol(ieee);
  24783. +
  24784. + printk("==============>tmpmeshid is %s\n",tmpmeshid);
  24785. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, tmpmeshid);
  24786. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  24787. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  24788. + if (proto_started)
  24789. + ieee80211_start_protocol(ieee);
  24790. + }
  24791. + else{
  24792. + printk("BUG:meshid is null\n");
  24793. + ret=0;
  24794. + goto out;
  24795. + }
  24796. +
  24797. + ret = 0;
  24798. + }
  24799. + else
  24800. +#endif
  24801. + {
  24802. + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
  24803. + }
  24804. +
  24805. +#ifdef _RTL8187_EXT_PATCH_
  24806. +out:
  24807. +#endif
  24808. + up(&priv->wx_sem);
  24809. + return ret;
  24810. +}
  24811. +
  24812. +
  24813. +static int r8180_wx_get_essid(struct net_device *dev,
  24814. + struct iw_request_info *a,
  24815. + union iwreq_data *wrqu, char *b)
  24816. +{
  24817. + int ret;
  24818. + struct r8180_priv *priv = ieee80211_priv(dev);
  24819. +
  24820. + down(&priv->wx_sem);
  24821. +
  24822. + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
  24823. +
  24824. + up(&priv->wx_sem);
  24825. +
  24826. + return ret;
  24827. +}
  24828. +
  24829. +
  24830. +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
  24831. + union iwreq_data *wrqu, char *b)
  24832. +{
  24833. + int ret;
  24834. + struct r8180_priv *priv = ieee80211_priv(dev);
  24835. +
  24836. + if(priv->ieee80211->bHwRadioOff)
  24837. + return 0;
  24838. +
  24839. + down(&priv->wx_sem);
  24840. +
  24841. + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
  24842. +
  24843. + up(&priv->wx_sem);
  24844. + return ret;
  24845. +}
  24846. +
  24847. +static int r8180_wx_get_name(struct net_device *dev,
  24848. + struct iw_request_info *info,
  24849. + union iwreq_data *wrqu, char *extra)
  24850. +{
  24851. + struct r8180_priv *priv = ieee80211_priv(dev);
  24852. + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
  24853. +}
  24854. +
  24855. +
  24856. +static int r8180_wx_set_frag(struct net_device *dev,
  24857. + struct iw_request_info *info,
  24858. + union iwreq_data *wrqu, char *extra)
  24859. +{
  24860. + struct r8180_priv *priv = ieee80211_priv(dev);
  24861. +
  24862. + if(priv->ieee80211->bHwRadioOff)
  24863. + return 0;
  24864. +
  24865. + if (wrqu->frag.disabled)
  24866. + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
  24867. + else {
  24868. + if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
  24869. + wrqu->frag.value > MAX_FRAG_THRESHOLD)
  24870. + return -EINVAL;
  24871. +
  24872. + priv->ieee80211->fts = wrqu->frag.value & ~0x1;
  24873. + }
  24874. +
  24875. + return 0;
  24876. +}
  24877. +
  24878. +
  24879. +static int r8180_wx_get_frag(struct net_device *dev,
  24880. + struct iw_request_info *info,
  24881. + union iwreq_data *wrqu, char *extra)
  24882. +{
  24883. + struct r8180_priv *priv = ieee80211_priv(dev);
  24884. +
  24885. + wrqu->frag.value = priv->ieee80211->fts;
  24886. + wrqu->frag.fixed = 0; /* no auto select */
  24887. + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
  24888. +
  24889. + return 0;
  24890. +}
  24891. +
  24892. +
  24893. +static int r8180_wx_set_wap(struct net_device *dev,
  24894. + struct iw_request_info *info,
  24895. + union iwreq_data *awrq,
  24896. + char *extra)
  24897. +{
  24898. + int ret;
  24899. + struct r8180_priv *priv = ieee80211_priv(dev);
  24900. + if(priv->ieee80211->bHwRadioOff)
  24901. + return 0;
  24902. +
  24903. + //printk("in function %s\n",__FUNCTION__);
  24904. +#ifdef _RTL8187_EXT_PATCH_
  24905. + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)){
  24906. + return 0;
  24907. + }
  24908. +#endif
  24909. + down(&priv->wx_sem);
  24910. +
  24911. + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
  24912. +
  24913. + up(&priv->wx_sem);
  24914. + return ret;
  24915. +
  24916. +}
  24917. +
  24918. +
  24919. +static int r8180_wx_get_wap(struct net_device *dev,
  24920. + struct iw_request_info *info,
  24921. + union iwreq_data *wrqu, char *extra)
  24922. +{
  24923. + struct r8180_priv *priv = ieee80211_priv(dev);
  24924. +
  24925. + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
  24926. +}
  24927. +
  24928. +
  24929. +static int r8180_wx_get_enc(struct net_device *dev,
  24930. + struct iw_request_info *info,
  24931. + union iwreq_data *wrqu, char *key)
  24932. +{
  24933. + struct r8180_priv *priv = ieee80211_priv(dev);
  24934. +
  24935. + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
  24936. +}
  24937. +
  24938. +static int r8180_wx_set_enc(struct net_device *dev,
  24939. + struct iw_request_info *info,
  24940. + union iwreq_data *wrqu, char *key)
  24941. +{
  24942. + struct r8180_priv *priv = ieee80211_priv(dev);
  24943. + int ret;
  24944. +#ifdef JOHN_HWSEC
  24945. +// struct ieee80211_device *ieee = priv->ieee80211;
  24946. +// u32 TargetContent;
  24947. + u32 hwkey[4]={0,0,0,0};
  24948. + u8 mask=0xff;
  24949. + u32 key_idx=0;
  24950. + u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
  24951. + u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
  24952. + {0x00,0x00,0x00,0x00,0x00,0x01},
  24953. + {0x00,0x00,0x00,0x00,0x00,0x02},
  24954. + {0x00,0x00,0x00,0x00,0x00,0x03} };
  24955. + int i;
  24956. +
  24957. +#endif
  24958. +
  24959. + if(priv->ieee80211->bHwRadioOff)
  24960. + return 0;
  24961. +
  24962. + down(&priv->wx_sem);
  24963. +
  24964. + DMESG("Setting SW wep key");
  24965. + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
  24966. +
  24967. + up(&priv->wx_sem);
  24968. +
  24969. +#ifdef JOHN_HWSEC
  24970. +
  24971. + //sometimes, the length is zero while we do not type key value
  24972. + if(wrqu->encoding.length!=0){
  24973. +
  24974. + for(i=0 ; i<4 ; i++){
  24975. + hwkey[i] |= key[4*i+0]&mask;
  24976. + if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
  24977. + if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
  24978. + hwkey[i] |= (key[4*i+1]&mask)<<8;
  24979. + hwkey[i] |= (key[4*i+2]&mask)<<16;
  24980. + hwkey[i] |= (key[4*i+3]&mask)<<24;
  24981. + }
  24982. +
  24983. + #define CONF_WEP40 0x4
  24984. + #define CONF_WEP104 0x14
  24985. +
  24986. + switch(wrqu->encoding.flags){
  24987. + case 0:
  24988. + case 1: key_idx = 0; break;
  24989. + case 2: key_idx = 1; break;
  24990. + case 3: key_idx = 2; break;
  24991. + case 4: key_idx = 3; break;
  24992. + default: break;
  24993. + }
  24994. +
  24995. + if(wrqu->encoding.length==0x5){
  24996. + setKey( dev,
  24997. + key_idx, //EntryNo
  24998. + key_idx, //KeyIndex
  24999. + KEY_TYPE_WEP40, //KeyType
  25000. + zero_addr[key_idx],
  25001. + 0, //DefaultKey
  25002. + hwkey); //KeyContent
  25003. +
  25004. + if(key_idx == 0){
  25005. +
  25006. + write_nic_byte(dev, WPA_CONFIG, 7);
  25007. +
  25008. + setKey( dev,
  25009. + 4, //EntryNo
  25010. + key_idx, //KeyIndex
  25011. + KEY_TYPE_WEP40, //KeyType
  25012. + broadcast_addr, //addr
  25013. + 0, //DefaultKey
  25014. + hwkey); //KeyContent
  25015. + }
  25016. + }
  25017. +
  25018. + else if(wrqu->encoding.length==0xd){
  25019. + setKey( dev,
  25020. + key_idx, //EntryNo
  25021. + key_idx, //KeyIndex
  25022. + KEY_TYPE_WEP104, //KeyType
  25023. + zero_addr[key_idx],
  25024. + 0, //DefaultKey
  25025. + hwkey); //KeyContent
  25026. +
  25027. + if(key_idx == 0){
  25028. +
  25029. + write_nic_byte(dev, WPA_CONFIG, 7);
  25030. +
  25031. + setKey( dev,
  25032. + 4, //EntryNo
  25033. + key_idx, //KeyIndex
  25034. + KEY_TYPE_WEP104, //KeyType
  25035. + broadcast_addr, //addr
  25036. + 0, //DefaultKey
  25037. + hwkey); //KeyContent
  25038. + }
  25039. + }
  25040. + else printk("wrong type in WEP, not WEP40 and WEP104\n");
  25041. +
  25042. + }
  25043. +
  25044. + //consider the setting different key index situation
  25045. + //wrqu->encoding.flags = 801 means that we set key with index "1"
  25046. + if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
  25047. +
  25048. + write_nic_byte(dev, WPA_CONFIG, 7);
  25049. +
  25050. + //copy wpa config from default key(key0~key3) to broadcast key(key5)
  25051. + //
  25052. + key_idx = (wrqu->encoding.flags & 0xf)-1 ;
  25053. + write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
  25054. + write_cam(dev, (4*6)+1, 0xffffffff);
  25055. + write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
  25056. + write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
  25057. + write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
  25058. + write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
  25059. + }
  25060. +
  25061. +#endif /*JOHN_HWSEC*/
  25062. + return ret;
  25063. +}
  25064. +
  25065. +
  25066. +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
  25067. + iwreq_data *wrqu, char *p){
  25068. +
  25069. + struct r8180_priv *priv = ieee80211_priv(dev);
  25070. + int *parms=(int*)p;
  25071. + int mode=parms[0];
  25072. +
  25073. + if(priv->ieee80211->bHwRadioOff)
  25074. + return 0;
  25075. +
  25076. + priv->ieee80211->active_scan = mode;
  25077. +
  25078. + return 1;
  25079. +}
  25080. +
  25081. +
  25082. +
  25083. +static int r8180_wx_set_retry(struct net_device *dev,
  25084. + struct iw_request_info *info,
  25085. + union iwreq_data *wrqu, char *extra)
  25086. +{
  25087. + struct r8180_priv *priv = ieee80211_priv(dev);
  25088. + int err = 0;
  25089. +
  25090. + if(priv->ieee80211->bHwRadioOff)
  25091. + return 0;
  25092. +
  25093. + down(&priv->wx_sem);
  25094. +
  25095. + if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
  25096. + wrqu->retry.disabled){
  25097. + err = -EINVAL;
  25098. + goto exit;
  25099. + }
  25100. + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
  25101. + err = -EINVAL;
  25102. + goto exit;
  25103. + }
  25104. +
  25105. + if(wrqu->retry.value > R8180_MAX_RETRY){
  25106. + err= -EINVAL;
  25107. + goto exit;
  25108. + }
  25109. + if (wrqu->retry.flags & IW_RETRY_MAX) {
  25110. + priv->retry_rts = wrqu->retry.value;
  25111. + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
  25112. +
  25113. + }else {
  25114. + priv->retry_data = wrqu->retry.value;
  25115. + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
  25116. + }
  25117. +
  25118. + /* FIXME !
  25119. + * We might try to write directly the TX config register
  25120. + * or to restart just the (R)TX process.
  25121. + * I'm unsure if whole reset is really needed
  25122. + */
  25123. +
  25124. + rtl8180_commit(dev);
  25125. + /*
  25126. + if(priv->up){
  25127. + rtl8180_rtx_disable(dev);
  25128. + rtl8180_rx_enable(dev);
  25129. + rtl8180_tx_enable(dev);
  25130. +
  25131. + }
  25132. + */
  25133. +exit:
  25134. + up(&priv->wx_sem);
  25135. +
  25136. + return err;
  25137. +}
  25138. +
  25139. +static int r8180_wx_get_retry(struct net_device *dev,
  25140. + struct iw_request_info *info,
  25141. + union iwreq_data *wrqu, char *extra)
  25142. +{
  25143. + struct r8180_priv *priv = ieee80211_priv(dev);
  25144. +
  25145. +
  25146. + wrqu->retry.disabled = 0; /* can't be disabled */
  25147. +
  25148. + if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
  25149. + IW_RETRY_LIFETIME)
  25150. + return -EINVAL;
  25151. +
  25152. + if (wrqu->retry.flags & IW_RETRY_MAX) {
  25153. + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
  25154. + wrqu->retry.value = priv->retry_rts;
  25155. + } else {
  25156. + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
  25157. + wrqu->retry.value = priv->retry_data;
  25158. + }
  25159. + //DMESG("returning %d",wrqu->retry.value);
  25160. +
  25161. +
  25162. + return 0;
  25163. +}
  25164. +
  25165. +static int r8180_wx_get_sens(struct net_device *dev,
  25166. + struct iw_request_info *info,
  25167. + union iwreq_data *wrqu, char *extra)
  25168. +{
  25169. + struct r8180_priv *priv = ieee80211_priv(dev);
  25170. + if(priv->rf_set_sens == NULL)
  25171. + return -1; /* we have not this support for this radio */
  25172. + wrqu->sens.value = priv->sens;
  25173. + return 0;
  25174. +}
  25175. +
  25176. +
  25177. +static int r8180_wx_set_sens(struct net_device *dev,
  25178. + struct iw_request_info *info,
  25179. + union iwreq_data *wrqu, char *extra)
  25180. +{
  25181. +
  25182. + struct r8180_priv *priv = ieee80211_priv(dev);
  25183. +
  25184. + short err = 0;
  25185. +
  25186. + if(priv->ieee80211->bHwRadioOff)
  25187. + return 0;
  25188. +
  25189. + down(&priv->wx_sem);
  25190. + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
  25191. + if(priv->rf_set_sens == NULL) {
  25192. + err= -1; /* we have not this support for this radio */
  25193. + goto exit;
  25194. + }
  25195. + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
  25196. + priv->sens = wrqu->sens.value;
  25197. + else
  25198. + err= -EINVAL;
  25199. +
  25200. +exit:
  25201. + up(&priv->wx_sem);
  25202. +
  25203. + return err;
  25204. +}
  25205. +
  25206. +
  25207. +static int dummy(struct net_device *dev, struct iw_request_info *a,
  25208. + union iwreq_data *wrqu,char *b)
  25209. +{
  25210. + return -1;
  25211. +}
  25212. +static int r8180_wx_set_enc_ext(struct net_device *dev,
  25213. + struct iw_request_info *info,
  25214. + union iwreq_data *wrqu, char *extra)
  25215. +{
  25216. +
  25217. + struct r8180_priv *priv = ieee80211_priv(dev);
  25218. + //printk("===>%s()\n", __FUNCTION__);
  25219. +
  25220. + int ret=0;
  25221. +
  25222. + if(priv->ieee80211->bHwRadioOff)
  25223. + return 0;
  25224. +
  25225. + down(&priv->wx_sem);
  25226. + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
  25227. + up(&priv->wx_sem);
  25228. + return ret;
  25229. +
  25230. +}
  25231. +static int r8180_wx_set_auth(struct net_device *dev,
  25232. + struct iw_request_info *info,
  25233. + union iwreq_data* data, char *extra)
  25234. +{
  25235. + //printk("====>%s()\n", __FUNCTION__);
  25236. + struct r8180_priv *priv = ieee80211_priv(dev);
  25237. + int ret=0;
  25238. +
  25239. + if(priv->ieee80211->bHwRadioOff)
  25240. + return 0;
  25241. +
  25242. + down(&priv->wx_sem);
  25243. + ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
  25244. + up(&priv->wx_sem);
  25245. + return ret;
  25246. +}
  25247. +
  25248. +static int r8180_wx_set_mlme(struct net_device *dev,
  25249. + struct iw_request_info *info,
  25250. + union iwreq_data *wrqu, char *extra)
  25251. +{
  25252. + //printk("====>%s()\n", __FUNCTION__);
  25253. +
  25254. + int ret=0;
  25255. + struct r8180_priv *priv = ieee80211_priv(dev);
  25256. +
  25257. + if(priv->ieee80211->bHwRadioOff)
  25258. + return 0;
  25259. +
  25260. + down(&priv->wx_sem);
  25261. +#if 1
  25262. + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
  25263. +#endif
  25264. + up(&priv->wx_sem);
  25265. + return ret;
  25266. +}
  25267. +
  25268. +static int r8180_wx_set_gen_ie(struct net_device *dev,
  25269. + struct iw_request_info *info,
  25270. + union iwreq_data* data, char *extra)
  25271. +{
  25272. + //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
  25273. + int ret=0;
  25274. + struct r8180_priv *priv = ieee80211_priv(dev);
  25275. +
  25276. + if(priv->ieee80211->bHwRadioOff)
  25277. + return 0;
  25278. +
  25279. + down(&priv->wx_sem);
  25280. +#if 1
  25281. + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
  25282. +#endif
  25283. + up(&priv->wx_sem);
  25284. + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
  25285. + return ret;
  25286. +
  25287. +
  25288. +}
  25289. +
  25290. +#ifdef _RTL8187_EXT_PATCH_
  25291. +/*
  25292. + Output:
  25293. + (case 1) Mesh: Enable. MESHID=[%s] (max length of %s is 32 bytes).
  25294. + (case 2) Mesh: Disable.
  25295. +*/
  25296. +static int r8180_wx_get_meshinfo(struct net_device *dev,
  25297. + struct iw_request_info *info,
  25298. + union iwreq_data *wrqu, char *extra)
  25299. +{
  25300. + struct r8180_priv *priv = ieee80211_priv(dev);
  25301. +
  25302. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_meshinfo )
  25303. + return 0;
  25304. + return priv->mshobj->ext_patch_r8180_wx_get_meshinfo(dev, info, wrqu, extra);
  25305. +}
  25306. +
  25307. +
  25308. +static int r8180_wx_enable_mesh(struct net_device *dev,
  25309. + struct iw_request_info *info,
  25310. + union iwreq_data *wrqu, char *extra)
  25311. +{
  25312. + struct r8180_priv *priv = ieee80211_priv(dev);
  25313. + struct ieee80211_device *ieee = priv->ieee80211;
  25314. +
  25315. + int ret = 0;
  25316. +
  25317. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_enable_mesh )
  25318. + return 0;
  25319. +
  25320. + down(&priv->wx_sem);
  25321. + if(priv->mshobj->ext_patch_r8180_wx_enable_mesh(dev))
  25322. + {
  25323. + union iwreq_data tmprqu;
  25324. + tmprqu.mode = ieee->iw_mode;
  25325. + ieee->iw_mode = 0;
  25326. + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
  25327. + rtl8187_set_rxconf(dev);
  25328. + }
  25329. +
  25330. + up(&priv->wx_sem);
  25331. +
  25332. + return ret;
  25333. +
  25334. +}
  25335. +
  25336. +static int r8180_wx_disable_mesh(struct net_device *dev,
  25337. + struct iw_request_info *info,
  25338. + union iwreq_data *wrqu, char *extra)
  25339. +{
  25340. + struct r8180_priv *priv = ieee80211_priv(dev);
  25341. + struct ieee80211_device *ieee = priv->ieee80211;
  25342. +
  25343. + int ret = 0;
  25344. +
  25345. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_disable_mesh )
  25346. + return 0;
  25347. +
  25348. + down(&priv->wx_sem);
  25349. + if(priv->mshobj->ext_patch_r8180_wx_disable_mesh(dev))
  25350. + {
  25351. + union iwreq_data tmprqu;
  25352. + tmprqu.mode = ieee->iw_mode;
  25353. + ieee->iw_mode = 999;
  25354. + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
  25355. + rtl8187_set_rxconf(dev);
  25356. + }
  25357. +
  25358. + up(&priv->wx_sem);
  25359. +
  25360. + return ret;
  25361. +}
  25362. +
  25363. +
  25364. +int r8180_wx_set_channel(struct net_device *dev,
  25365. + struct iw_request_info *info,
  25366. + union iwreq_data *wrqu, char *extra)
  25367. +{
  25368. + int ch = *extra;
  25369. + struct r8180_priv *priv = ieee80211_priv(dev);
  25370. + struct ieee80211_device *ieee = priv->ieee80211;
  25371. +
  25372. + if(priv->ieee80211->bHwRadioOff)
  25373. + return 0;
  25374. +
  25375. + // is 11s ?
  25376. + if (!priv->mshobj || (ieee->iw_mode != ieee->iw_ext_mode) || !priv->mshobj->ext_patch_r8180_wx_set_channel )
  25377. + return 0;
  25378. +
  25379. + printk("set channel = %d\n", ch);
  25380. + if ( ch < 0 )
  25381. + {
  25382. + ieee80211_start_scan(ieee); // auto
  25383. + ieee->meshScanMode =2;
  25384. + }
  25385. + else
  25386. + {
  25387. +//#ifdef NETWORKMANAGER_UI
  25388. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  25389. + }
  25390. +//#else
  25391. + else{
  25392. + down(&priv->wx_sem);}
  25393. +//#endif
  25394. + ieee->meshScanMode =0;
  25395. + // ieee->set_chan(dev, ch);
  25396. +//#ifdef _RTL8187_EXT_PATCH_
  25397. + if(priv->mshobj->ext_patch_r8180_wx_set_channel)
  25398. + {
  25399. + priv->mshobj->ext_patch_r8180_wx_set_channel(ieee, ch);
  25400. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  25401. + }
  25402. +//#endif
  25403. + ieee->set_chan(ieee->dev, ch);
  25404. + ieee->current_network.channel = ch;
  25405. + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
  25406. + ieee80211_ext_send_11s_beacon(ieee);
  25407. +//#ifdef NETWORKMANAGER_UI
  25408. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  25409. + }
  25410. +//#else
  25411. + else{
  25412. + up(&priv->wx_sem);}
  25413. +//#endif
  25414. + //up(&ieee->wx_sem);
  25415. +
  25416. + // ieee80211_stop_scan(ieee); // user set
  25417. + //
  25418. +
  25419. + /*
  25420. + netif_carrier_off(ieee->dev);
  25421. +
  25422. + if (ieee->data_hard_stop)
  25423. + ieee->data_hard_stop(ieee->dev);
  25424. +
  25425. + ieee->state = IEEE80211_NOLINK;
  25426. + ieee->link_change(ieee->dev);
  25427. +
  25428. + ieee->current_network.channel = fwrq->m;
  25429. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  25430. +
  25431. +
  25432. + if (ieee->data_hard_resume)
  25433. + ieee->data_hard_resume(ieee->dev);
  25434. +
  25435. + netif_carrier_on(ieee->dev);
  25436. + */
  25437. +
  25438. + }
  25439. +
  25440. + return 0;
  25441. +}
  25442. +
  25443. +static int r8180_wx_set_meshID(struct net_device *dev,
  25444. + struct iw_request_info *info,
  25445. + union iwreq_data *wrqu, char *extra)
  25446. +{
  25447. + struct r8180_priv *priv = ieee80211_priv(dev);
  25448. +
  25449. + if(priv->ieee80211->bHwRadioOff)
  25450. + return 0;
  25451. +
  25452. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_meshID )
  25453. + return 0;
  25454. +
  25455. + //printk("len=%d\n", wrqu->data.length);
  25456. + //printk("\nCall setMeshid.");
  25457. + return priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, wrqu->data.pointer);
  25458. +}
  25459. +
  25460. +
  25461. +/* reserved for future
  25462. +static int r8180_wx_add_mac_allow(struct net_device *dev,
  25463. + struct iw_request_info *info,
  25464. + union iwreq_data *wrqu, char *extra)
  25465. +{
  25466. + struct r8180_priv *priv = ieee80211_priv(dev);
  25467. +
  25468. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow )
  25469. + return 0;
  25470. +
  25471. + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow(dev, info, wrqu, extra);
  25472. +}
  25473. +
  25474. +static int r8180_wx_del_mac_allow(struct net_device *dev,
  25475. + struct iw_request_info *info,
  25476. + union iwreq_data *wrqu, char *extra)
  25477. +{
  25478. + struct r8180_priv *priv = ieee80211_priv(dev);
  25479. +
  25480. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow )
  25481. + return 0;
  25482. +
  25483. + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow(dev, info, wrqu, extra);
  25484. +}
  25485. +*/
  25486. +static int r8180_wx_add_mac_deny(struct net_device *dev,
  25487. + struct iw_request_info *info,
  25488. + union iwreq_data *wrqu, char *extra)
  25489. +{
  25490. + struct r8180_priv *priv = ieee80211_priv(dev);
  25491. +
  25492. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny )
  25493. + return 0;
  25494. +
  25495. + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny(dev, info, wrqu, extra);
  25496. +}
  25497. +
  25498. +static int r8180_wx_del_mac_deny(struct net_device *dev,
  25499. + struct iw_request_info *info,
  25500. + union iwreq_data *wrqu, char *extra)
  25501. +{
  25502. + struct r8180_priv *priv = ieee80211_priv(dev);
  25503. +
  25504. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny )
  25505. + return 0;
  25506. +
  25507. + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny(dev, info, wrqu, extra);
  25508. +}
  25509. +
  25510. +/* reserved for future
  25511. +static int r8180_wx_get_mac_allow(struct net_device *dev,
  25512. + struct iw_request_info *info,
  25513. + union iwreq_data *wrqu, char *extra)
  25514. +{
  25515. + struct r8180_priv *priv = ieee80211_priv(dev);
  25516. +
  25517. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_allow )
  25518. + return 0;
  25519. +
  25520. + return priv->mshobj->ext_patch_r8180_wx_get_mac_allow(dev, info, wrqu, extra);
  25521. +}
  25522. +*/
  25523. +
  25524. +static int r8180_wx_get_mac_deny(struct net_device *dev,
  25525. + struct iw_request_info *info,
  25526. + union iwreq_data *wrqu, char *extra)
  25527. +{
  25528. + struct r8180_priv *priv = ieee80211_priv(dev);
  25529. +
  25530. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_deny )
  25531. + return 0;
  25532. +
  25533. + return priv->mshobj->ext_patch_r8180_wx_get_mac_deny(dev, info, wrqu, extra);
  25534. +}
  25535. +
  25536. +
  25537. +static int r8180_wx_get_mesh_list(struct net_device *dev,
  25538. + struct iw_request_info *info,
  25539. + union iwreq_data *wrqu, char *extra)
  25540. +{
  25541. + struct r8180_priv *priv = ieee80211_priv(dev);
  25542. +
  25543. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mesh_list )
  25544. + return 0;
  25545. +
  25546. + return priv->mshobj->ext_patch_r8180_wx_get_mesh_list(dev, info, wrqu, extra);
  25547. +}
  25548. +
  25549. +static int r8180_wx_mesh_scan(struct net_device *dev,
  25550. + struct iw_request_info *info,
  25551. + union iwreq_data *wrqu, char *extra)
  25552. +{
  25553. + struct r8180_priv *priv = ieee80211_priv(dev);
  25554. +
  25555. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_mesh_scan )
  25556. + return 0;
  25557. +
  25558. + return priv->mshobj->ext_patch_r8180_wx_mesh_scan(dev, info, wrqu, extra);
  25559. +}
  25560. +
  25561. +static int r8180_wx_join_mesh(struct net_device *dev,
  25562. + struct iw_request_info *info,
  25563. + union iwreq_data *wrqu, char *extra)
  25564. +{
  25565. + struct r8180_priv *priv = ieee80211_priv(dev);
  25566. + int index;
  25567. + int ret=0;
  25568. + char extmeshid[32];
  25569. + int len=0;
  25570. + char id[50], ch;
  25571. +//#ifdef NETWORKMANAGER_UI
  25572. +
  25573. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  25574. + printk("join mesh %s\n",extra);
  25575. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  25576. + ret= -E2BIG;
  25577. + goto out;
  25578. + }
  25579. + //printk("wrqu->essid.length is %d\n",wrqu->essid.length);
  25580. + //printk("wrqu->essid.flags is %d\n",wrqu->essid.flags);
  25581. + if((wrqu->essid.length == 1) && (wrqu->essid.flags == 1)){
  25582. + ret = 0;
  25583. + goto out;
  25584. + }
  25585. + if (wrqu->essid.flags && wrqu->essid.length) {
  25586. + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, extra, &ch))
  25587. + {
  25588. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
  25589. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  25590. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  25591. + }
  25592. + else
  25593. + printk("invalid mesh #\n");
  25594. +
  25595. + }
  25596. +#if 0
  25597. + else{
  25598. + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, 0, &ch))
  25599. + {
  25600. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
  25601. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  25602. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  25603. + }
  25604. + else
  25605. + printk("invalid mesh #\n");
  25606. +
  25607. + }
  25608. +#endif
  25609. + }
  25610. + else{
  25611. +//#else
  25612. + index = *(extra);
  25613. +// printk("index=%d\n", index);
  25614. +
  25615. + if( ! priv->mshobj
  25616. + || !priv->mshobj->ext_patch_r8180_wx_set_meshID
  25617. + || !priv->mshobj->ext_patch_r8180_wx_get_selected_mesh )
  25618. + return 0;
  25619. +
  25620. + if( priv->mshobj->ext_patch_r8180_wx_get_selected_mesh(dev, index, &ch, id) )
  25621. + {
  25622. + // printk("ch=%d, id=%s\n", ch, id);
  25623. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, id);
  25624. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  25625. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  25626. + }
  25627. + else
  25628. + printk("invalid mesh #\n");
  25629. + }
  25630. +//#endif
  25631. +out:
  25632. + return ret;
  25633. +}
  25634. +
  25635. +#endif // _RTL8187_EXT_PATCH_
  25636. +
  25637. +
  25638. +static int r8180_wx_get_radion(struct net_device *dev,
  25639. + struct iw_request_info *info,
  25640. + union iwreq_data *wrqu, char *extra)
  25641. +{
  25642. + struct r8180_priv *priv = ieee80211_priv(dev);
  25643. +// u8 addr;
  25644. +
  25645. + down(&priv->wx_sem);
  25646. + if(priv->radion == 1) {
  25647. + *(int *)extra = 1;
  25648. + } else {
  25649. +
  25650. + *(int *)extra = 0;
  25651. + }
  25652. + up(&priv->wx_sem);
  25653. + return 0;
  25654. +
  25655. +}
  25656. +
  25657. +static int r8180_wx_set_radion(struct net_device *dev,
  25658. + struct iw_request_info *info,
  25659. + union iwreq_data *wrqu, char *extra)
  25660. +{
  25661. + int radion = *extra;
  25662. + struct r8180_priv *priv = ieee80211_priv(dev);
  25663. +// struct ieee80211_device *ieee = priv->ieee80211;
  25664. + u8 btCR9346, btConfig3;
  25665. + int i;
  25666. + u16 u2bTFPC = 0;
  25667. + u8 u1bTmp;
  25668. +
  25669. + if(priv->ieee80211->bHwRadioOff)
  25670. + return 0;
  25671. +
  25672. + down(&priv->wx_sem);
  25673. + printk("set radion = %d\n", radion);
  25674. +
  25675. +#ifdef _RTL8187_EXT_PATCH_
  25676. + if(ieee->iw_mode == ieee->iw_ext_mode) {
  25677. + printk("mesh mode:: could not set radi on/off = %d\n", radion);
  25678. + up(&priv->wx_sem);
  25679. + return 0;
  25680. + }
  25681. +#endif
  25682. + // Set EEM0 and EEM1 in 9346CR.
  25683. + btCR9346 = read_nic_byte(dev, CR9346);
  25684. + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
  25685. + // Set PARM_En in Config3.
  25686. + btConfig3 = read_nic_byte(dev, CONFIG3);
  25687. + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
  25688. +
  25689. + if ( radion == 1) //radion off
  25690. + {
  25691. + printk("==================>RF on\n");
  25692. + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
  25693. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
  25694. + write_nic_byte(dev, CONFIG4, (priv->RFProgType));
  25695. +
  25696. + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
  25697. + write_rtl8225(dev, 0x4, 0x9FF);
  25698. +
  25699. + u1bTmp = read_nic_byte(dev, 0x24E);
  25700. + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
  25701. + priv->radion = 1; //radion on
  25702. + }
  25703. + else
  25704. + {
  25705. + printk("==================>RF off\n");
  25706. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B; i++)
  25707. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  25708. + u2bTFPC = read_nic_word(dev, TFPC);
  25709. + if(u2bTFPC == 0)
  25710. + {
  25711. + break;
  25712. + }
  25713. + else
  25714. + {
  25715. + printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
  25716. + udelay(10);
  25717. + }
  25718. + }
  25719. + if( i == MAX_DOZE_WAITING_TIMES_87B )
  25720. + {
  25721. + printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n",\
  25722. + MAX_DOZE_WAITING_TIMES_87B, u2bTFPC);
  25723. + }
  25724. +
  25725. + u1bTmp = read_nic_byte(dev, 0x24E);
  25726. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  25727. +
  25728. + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  25729. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  25730. +
  25731. + write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  25732. +
  25733. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  25734. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
  25735. + priv->radion = 0; //radion off
  25736. + }
  25737. + // Clear PARM_En in Config3.
  25738. + btConfig3 &= ~(CONFIG3_PARM_En);
  25739. + write_nic_byte(dev, CONFIG3, btConfig3);
  25740. + // Clear EEM0 and EEM1 in 9346CR.
  25741. + btCR9346 &= ~(0xC0);
  25742. + write_nic_byte(dev, CR9346, btCR9346);
  25743. +
  25744. + up(&priv->wx_sem);
  25745. +
  25746. + return 0;
  25747. +}
  25748. +
  25749. +static int r8180_wx_set_ratadpt (struct net_device *dev,
  25750. + struct iw_request_info *info,
  25751. + union iwreq_data *wrqu, char *extra)
  25752. +{
  25753. + int ratadapt = *extra;
  25754. + struct r8180_priv *priv = ieee80211_priv(dev);
  25755. + struct ieee80211_device *ieee = priv->ieee80211;
  25756. +
  25757. + if(priv->ieee80211->bHwRadioOff)
  25758. + return 0;
  25759. +
  25760. + down(&priv->wx_sem);
  25761. + printk("Set rate adaptive %s\n", (ratadapt==0)?"on":"off");
  25762. + if(ratadapt == 0) {
  25763. + del_timer_sync(&priv->rateadapter_timer);
  25764. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  25765. + priv->rateadapter_timer.function((unsigned long)dev);
  25766. + } else {
  25767. + del_timer_sync(&priv->rateadapter_timer);
  25768. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  25769. + printk("force rate to %d\n", ratadapt);
  25770. + ieee->rate = ratadapt;
  25771. + }
  25772. + up(&priv->wx_sem);
  25773. + return 0;
  25774. +}
  25775. +
  25776. +#ifdef ENABLE_TOSHIBA_CONFIG
  25777. +static int r8180_wx_get_tblidx(struct net_device *dev,
  25778. + struct iw_request_info *info,
  25779. + union iwreq_data *wrqu, char *extra)
  25780. +{
  25781. + struct r8180_priv *priv = ieee80211_priv(dev);
  25782. + //extern u8 chan_plan_index;
  25783. + //printk("=========>%s(), %x\n", __FUNCTION__, priv->channel_plan);
  25784. + down(&priv->wx_sem);
  25785. + put_user(priv->channel_plan, (u8*)wrqu->data.pointer);
  25786. + up(&priv->wx_sem);
  25787. + return 0;
  25788. +
  25789. +}
  25790. +
  25791. +//This func will be called after probe auto
  25792. +static int r8180_wx_set_tbl (struct net_device *dev,
  25793. + struct iw_request_info *info,
  25794. + union iwreq_data *wrqu, char *extra)
  25795. +{
  25796. + struct r8180_priv *priv = ieee80211_priv(dev);
  25797. + u8 len = 0;
  25798. + s8 err = -1;
  25799. + extern CHANNEL_LIST Current_tbl;
  25800. + down(&priv->wx_sem);
  25801. + if (!wrqu->data.pointer)
  25802. + {
  25803. + printk("user data pointer is null\n");
  25804. + goto exit;
  25805. + }
  25806. + len = wrqu->data.length;
  25807. + //printk("=========>%s(), len:%d\n", __FUNCTION__, len);
  25808. + //memset(&Current_tbl, 0, sizeof(CHANNEL_LIST));
  25809. + if (copy_from_user((u8*)&Current_tbl, (void*)wrqu->data.pointer, len))
  25810. + {
  25811. + printk("error copy from user\n");
  25812. + goto exit;
  25813. + }
  25814. + {
  25815. + int i;
  25816. + Current_tbl.Len = len;
  25817. + //printk("%d\n", Current_tbl.Len);
  25818. +
  25819. + Dot11d_Init(priv->ieee80211);
  25820. + priv->ieee80211->bGlobalDomain = false;
  25821. + priv->ieee80211->bWorldWide13 = false;
  25822. +
  25823. + //lzm add 081205
  25824. + priv->ieee80211->MinPassiveChnlNum=12;
  25825. + priv->ieee80211->IbssStartChnl= 10;
  25826. +
  25827. + for (i=0; i<Current_tbl.Len; i++){
  25828. + //printk("%2d ", Current_tbl.Channel[i]);
  25829. + if(priv->channel_plan == COUNTRY_CODE_ETSI)
  25830. + {
  25831. + if(Current_tbl.Channel[i] <= 11)
  25832. + {
  25833. +#ifdef ENABLE_DOT11D
  25834. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
  25835. +#else
  25836. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
  25837. +#endif
  25838. + }
  25839. + else if((Current_tbl.Channel[i] >= 11) && (Current_tbl.Channel[i] <= 13))
  25840. + {
  25841. +#ifdef ENABLE_DOT11D
  25842. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 2;
  25843. +#else
  25844. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 2;
  25845. +#endif
  25846. + }
  25847. + }
  25848. + else
  25849. + {
  25850. + if(Current_tbl.Channel[i] <= 14)
  25851. + {
  25852. +#ifdef ENABLE_DOT11D
  25853. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
  25854. +#else
  25855. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
  25856. +#endif
  25857. + }
  25858. + }
  25859. + }
  25860. +#if 0
  25861. + printk("\n");
  25862. + for(i=1; i<MAX_CHANNEL_NUMBER; i++)
  25863. + {
  25864. +#ifdef ENABLE_DOT11D
  25865. + printk("%2d ", GET_DOT11D_INFO(priv->ieee80211)->channel_map[i]);
  25866. +#else
  25867. + printk("%2d ", priv->ieee80211->channel_map[i]);
  25868. +#endif
  25869. + }
  25870. + printk("\n");
  25871. +
  25872. +#endif
  25873. + if(priv->ieee80211->proto_started)
  25874. + {//we need to restart protocol now if it was start before channel map
  25875. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  25876. + //mdelay(1);
  25877. + ieee80211_softmac_start_protocol(priv->ieee80211);
  25878. + }
  25879. + }
  25880. + err = 0;
  25881. +exit:
  25882. + up(&priv->wx_sem);
  25883. + return err;
  25884. +
  25885. +
  25886. +}
  25887. +
  25888. +#endif
  25889. +
  25890. +
  25891. +static iw_handler r8180_wx_handlers[] =
  25892. +{
  25893. + NULL, /* SIOCSIWCOMMIT */
  25894. + r8180_wx_get_name, /* SIOCGIWNAME */
  25895. + dummy, /* SIOCSIWNWID */
  25896. + dummy, /* SIOCGIWNWID */
  25897. + r8180_wx_set_freq, /* SIOCSIWFREQ */
  25898. + r8180_wx_get_freq, /* SIOCGIWFREQ */
  25899. + r8180_wx_set_mode, /* SIOCSIWMODE */
  25900. + r8180_wx_get_mode, /* SIOCGIWMODE */
  25901. + r8180_wx_set_sens, /* SIOCSIWSENS */
  25902. + r8180_wx_get_sens, /* SIOCGIWSENS */
  25903. + NULL, /* SIOCSIWRANGE */
  25904. + rtl8180_wx_get_range, /* SIOCGIWRANGE */
  25905. + NULL, /* SIOCSIWPRIV */
  25906. + NULL, /* SIOCGIWPRIV */
  25907. + NULL, /* SIOCSIWSTATS */
  25908. + NULL, /* SIOCGIWSTATS */
  25909. + dummy, /* SIOCSIWSPY */
  25910. + dummy, /* SIOCGIWSPY */
  25911. + NULL, /* SIOCGIWTHRSPY */
  25912. + NULL, /* SIOCWIWTHRSPY */
  25913. + r8180_wx_set_wap, /* SIOCSIWAP */
  25914. + r8180_wx_get_wap, /* SIOCGIWAP */
  25915. + r8180_wx_set_mlme, //NULL, /* SIOCSIWMLME*/ /* -- hole -- */
  25916. + dummy, /* SIOCGIWAPLIST -- depricated */
  25917. + r8180_wx_set_scan, /* SIOCSIWSCAN */
  25918. + r8180_wx_get_scan, /* SIOCGIWSCAN */
  25919. + r8180_wx_set_essid, /* SIOCSIWESSID */
  25920. + r8180_wx_get_essid, /* SIOCGIWESSID */
  25921. + dummy, /* SIOCSIWNICKN */
  25922. + dummy, /* SIOCGIWNICKN */
  25923. + NULL, /* -- hole -- */
  25924. + NULL, /* -- hole -- */
  25925. + r8180_wx_set_rate, /* SIOCSIWRATE */
  25926. + r8180_wx_get_rate, /* SIOCGIWRATE */
  25927. + dummy, /* SIOCSIWRTS */
  25928. + dummy, /* SIOCGIWRTS */
  25929. + r8180_wx_set_frag, /* SIOCSIWFRAG */
  25930. + r8180_wx_get_frag, /* SIOCGIWFRAG */
  25931. + dummy, /* SIOCSIWTXPOW */
  25932. + dummy, /* SIOCGIWTXPOW */
  25933. + r8180_wx_set_retry, /* SIOCSIWRETRY */
  25934. + r8180_wx_get_retry, /* SIOCGIWRETRY */
  25935. + r8180_wx_set_enc, /* SIOCSIWENCODE */
  25936. + r8180_wx_get_enc, /* SIOCGIWENCODE */
  25937. + dummy, /* SIOCSIWPOWER */
  25938. + dummy, /* SIOCGIWPOWER */
  25939. + NULL, /*---hole---*/
  25940. + NULL, /*---hole---*/
  25941. + r8180_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
  25942. + NULL, /* SIOCSIWGENIE */
  25943. + r8180_wx_set_auth,//NULL, /* SIOCSIWAUTH */
  25944. + NULL,//r8180_wx_get_auth,//NULL, /* SIOCSIWAUTH */
  25945. + r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
  25946. + NULL,//r8180_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
  25947. + NULL, /* SIOCSIWPMKSA */
  25948. + NULL, /*---hole---*/
  25949. +};
  25950. +
  25951. +
  25952. +static const struct iw_priv_args r8180_private_args[] = {
  25953. + {
  25954. + SIOCIWFIRSTPRIV + 0x0,
  25955. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
  25956. + },
  25957. +
  25958. + {
  25959. + SIOCIWFIRSTPRIV + 0x1,
  25960. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
  25961. +
  25962. + },
  25963. + {
  25964. + SIOCIWFIRSTPRIV + 0x2,
  25965. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
  25966. + },
  25967. +#ifdef JOHN_IOCTL
  25968. + {
  25969. + SIOCIWFIRSTPRIV + 0x3,
  25970. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
  25971. + }
  25972. + ,
  25973. + {
  25974. + SIOCIWFIRSTPRIV + 0x4,
  25975. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
  25976. + }
  25977. + ,
  25978. + {
  25979. + SIOCIWFIRSTPRIV + 0x5,
  25980. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
  25981. + }
  25982. + ,
  25983. + {
  25984. + SIOCIWFIRSTPRIV + 0x6,
  25985. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
  25986. + }
  25987. + ,
  25988. + {
  25989. + SIOCIWFIRSTPRIV + 0x7,
  25990. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
  25991. + }
  25992. + ,
  25993. + {
  25994. + SIOCIWFIRSTPRIV + 0x8,
  25995. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
  25996. + }
  25997. + ,
  25998. + {
  25999. + SIOCIWFIRSTPRIV + 0x9,
  26000. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
  26001. + },
  26002. +#endif
  26003. + {
  26004. + SIOCIWFIRSTPRIV + 0xA,
  26005. + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED |1, "getradion"
  26006. + },
  26007. + {
  26008. + SIOCIWFIRSTPRIV + 0xB,
  26009. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setradion"
  26010. + },
  26011. + {
  26012. + SIOCIWFIRSTPRIV + 0xC,
  26013. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ratadpt"
  26014. + },
  26015. +#ifdef ENABLE_TOSHIBA_CONFIG
  26016. + {
  26017. + SIOCIWFIRSTPRIV + 0xD,
  26018. + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettblidx"
  26019. + },
  26020. + {
  26021. + SIOCIWFIRSTPRIV + 0xE,
  26022. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,0, "settblidx"
  26023. + },
  26024. +
  26025. +#endif
  26026. +
  26027. +};
  26028. +
  26029. +/*
  26030. + * Private ioctl interface information
  26031. +
  26032. +struct iw_priv_args
  26033. +{
  26034. +// __u32 cmd;
  26035. +// __u16 set_args;
  26036. +// __u16 get_args;
  26037. +// char name[IFNAMSIZ];
  26038. +//};
  26039. +*/
  26040. +//If get cmd's number is big,there may cause some problemes.
  26041. +//So modified by Lawrence,071120
  26042. +
  26043. +static iw_handler r8180_private_handler[] = {
  26044. +// r8180_wx_set_monitor, /* SIOCIWFIRSTPRIV */
  26045. + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
  26046. +// r8180_wx_set_forceassociate,
  26047. +// r8180_wx_set_beaconinterval,
  26048. +// r8180_wx_set_monitor_type,
  26049. + r8180_wx_set_scan_type,
  26050. + r8180_wx_set_rawtx,
  26051. +
  26052. +#if 0
  26053. +#ifdef _RTL8187_EXT_PATCH_
  26054. + r8180_wx_get_meshinfo,
  26055. + r8180_wx_enable_mesh,
  26056. + r8180_wx_disable_mesh,
  26057. + r8180_wx_set_channel,
  26058. + r8180_wx_set_meshID,
  26059. +
  26060. +// r8180_wx_add_mac_allow,
  26061. +// r8180_wx_get_mac_allow,
  26062. +// r8180_wx_del_mac_allow,
  26063. + r8180_wx_add_mac_deny,
  26064. + r8180_wx_get_mac_deny,
  26065. + r8180_wx_del_mac_deny,
  26066. + r8180_wx_get_mesh_list,
  26067. + r8180_wx_mesh_scan,
  26068. + r8180_wx_join_mesh,
  26069. +#endif
  26070. +#endif
  26071. +
  26072. +#ifdef JOHN_IOCTL
  26073. + r8180_wx_read_regs,
  26074. + r8180_wx_write_regs,
  26075. + r8180_wx_read_bb,
  26076. + r8180_wx_write_bb,
  26077. + r8180_wx_read_nicb,
  26078. + r8180_wx_write_nicb,
  26079. + r8180_wx_get_ap_status,
  26080. +#endif
  26081. + r8180_wx_get_radion,
  26082. + r8180_wx_set_radion,
  26083. + r8180_wx_set_ratadpt,
  26084. +#ifdef ENABLE_TOSHIBA_CONFIG
  26085. + r8180_wx_get_tblidx,
  26086. + r8180_wx_set_tbl,
  26087. +#endif
  26088. +};
  26089. +
  26090. +#if WIRELESS_EXT >= 17
  26091. +//WB modefied to show signal to GUI on 18-01-2008
  26092. +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
  26093. +{
  26094. + struct r8180_priv *priv = ieee80211_priv(dev);
  26095. + struct ieee80211_device* ieee = priv->ieee80211;
  26096. + struct iw_statistics* wstats = &priv->wstats;
  26097. +// struct ieee80211_network* target = NULL;
  26098. + int tmp_level = 0;
  26099. + int tmp_qual = 0;
  26100. + int tmp_noise = 0;
  26101. +// unsigned long flag;
  26102. +
  26103. + if (ieee->state < IEEE80211_LINKED)
  26104. + {
  26105. + wstats->qual.qual = 0;
  26106. + wstats->qual.level = 0;
  26107. + wstats->qual.noise = 0;
  26108. + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
  26109. + return wstats;
  26110. + }
  26111. +#if 0
  26112. + spin_lock_irqsave(&ieee->lock, flag);
  26113. + list_for_each_entry(target, &ieee->network_list, list)
  26114. + {
  26115. + if (is_same_network(target, &ieee->current_network))
  26116. + {
  26117. + printk("it's same network:%s\n", target->ssid);
  26118. +#if 0
  26119. + if (!tmp_level)
  26120. + {
  26121. + tmp_level = target->stats.signalstrength;
  26122. + tmp_qual = target->stats.signal;
  26123. + }
  26124. + else
  26125. + {
  26126. +
  26127. + tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
  26128. + tmp_qual = (15*tmp_qual + target->stats.signal)/16;
  26129. + }
  26130. +#else
  26131. + tmp_level = target->stats.signal;
  26132. + tmp_qual = target->stats.signalstrength;
  26133. + tmp_noise = target->stats.noise;
  26134. + printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
  26135. +#endif
  26136. + break;
  26137. + }
  26138. + }
  26139. + spin_unlock_irqrestore(&ieee->lock, flag);
  26140. +#endif
  26141. + tmp_level = (&ieee->current_network)->stats.signal;
  26142. + tmp_qual = (&ieee->current_network)->stats.signalstrength;
  26143. + tmp_noise = (&ieee->current_network)->stats.noise;
  26144. + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
  26145. +
  26146. + wstats->qual.level = tmp_level;
  26147. + wstats->qual.qual = tmp_qual;
  26148. + wstats->qual.noise = tmp_noise;
  26149. + wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
  26150. + return wstats;
  26151. +}
  26152. +#endif
  26153. +
  26154. +
  26155. +struct iw_handler_def r8180_wx_handlers_def={
  26156. + .standard = r8180_wx_handlers,
  26157. + .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
  26158. + .private = r8180_private_handler,
  26159. + .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
  26160. + .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
  26161. +#if WIRELESS_EXT >= 17
  26162. + .get_wireless_stats = r8180_get_wireless_stats,
  26163. +#endif
  26164. + .private_args = (struct iw_priv_args *)r8180_private_args,
  26165. +};
  26166. +#ifdef _RTL8187_EXT_PATCH_
  26167. +EXPORT_SYMBOL(r8180_wx_set_channel);
  26168. +#endif
  26169. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.h
  26170. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.h 1970-01-01 01:00:00.000000000 +0100
  26171. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.h 2010-03-06 16:43:22.000000000 +0100
  26172. @@ -0,0 +1,21 @@
  26173. +/*
  26174. + This is part of rtl8180 OpenSource driver - v 0.3
  26175. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  26176. + Released under the terms of GPL (General Public Licence)
  26177. +
  26178. + Parts of this driver are based on the GPL part of the official realtek driver
  26179. + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
  26180. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  26181. +
  26182. + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
  26183. +*/
  26184. +
  26185. +/* this file (will) contains wireless extension handlers*/
  26186. +
  26187. +#ifndef R8180_WX_H
  26188. +#define R8180_WX_H
  26189. +#include <linux/wireless.h>
  26190. +#include "ieee80211/ieee80211.h"
  26191. +extern struct iw_handler_def r8180_wx_handlers_def;
  26192. +
  26193. +#endif
  26194. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_core.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_core.c
  26195. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_core.c 1970-01-01 01:00:00.000000000 +0100
  26196. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_core.c 2010-03-06 16:43:22.000000000 +0100
  26197. @@ -0,0 +1,7042 @@
  26198. +/*
  26199. + This is part of rtl8187 OpenSource driver - v 0.1
  26200. + Copyright (C) Andrea Merello 2005 <andreamrl@tiscali.it>
  26201. + Released under the terms of GPL (General Public License)
  26202. +
  26203. +
  26204. + Parts of this driver are based on the rtl8180 driver skeleton
  26205. + from Patric Schenke & Andres Salomon.
  26206. +
  26207. + Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers.
  26208. +
  26209. + some ideas might be derived from David Young rtl8180 netbsd driver.
  26210. +
  26211. + Parts of the usb code are from the r8150.c driver in linux kernel
  26212. +
  26213. + Some ideas borrowed from the 8139too.c driver included in linux kernel.
  26214. +
  26215. + We (I?) want to thanks the Authors of those projecs and also the
  26216. + Ndiswrapper's project Authors.
  26217. +
  26218. + A special big thanks goes also to Realtek corp. for their help in my
  26219. + attempt to add RTL8187 and RTL8225 support, and to David Young also.
  26220. +
  26221. + - Please note that this file is a modified version from rtl8180-sa2400
  26222. + drv. So some other people have contributed to this project, and they are
  26223. + thanked in the rtl8180-sa2400 CHANGELOG.
  26224. +*/
  26225. +
  26226. +#undef LOOP_TEST
  26227. +#undef DUMP_RX
  26228. +#undef DUMP_TX
  26229. +#undef DEBUG_TX_DESC2
  26230. +#undef RX_DONT_PASS_UL
  26231. +#undef DEBUG_EPROM
  26232. +#undef DEBUG_RX_VERBOSE
  26233. +#undef DUMMY_RX
  26234. +#undef DEBUG_ZERO_RX
  26235. +#undef DEBUG_RX_SKB
  26236. +#undef DEBUG_TX_FRAG
  26237. +#undef DEBUG_RX_FRAG
  26238. +#undef DEBUG_TX_FILLDESC
  26239. +#undef DEBUG_TX
  26240. +#undef DEBUG_IRQ
  26241. +#undef DEBUG_RX
  26242. +#undef DEBUG_RXALLOC
  26243. +#undef DEBUG_REGISTERS
  26244. +#undef DEBUG_RING
  26245. +#undef DEBUG_IRQ_TASKLET
  26246. +#undef DEBUG_TX_ALLOC
  26247. +#undef DEBUG_TX_DESC
  26248. +#undef CONFIG_SOFT_BEACON
  26249. +#undef DEBUG_RW_REGISTER
  26250. +
  26251. +#define CONFIG_RTL8180_IO_MAP
  26252. +//#define CONFIG_SOFT_BEACON
  26253. +//#define DEBUG_RW_REGISTER
  26254. +
  26255. +#include "r8180_hw.h"
  26256. +#include "r8187.h"
  26257. +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
  26258. +#include "r8180_93cx6.h" /* Card EEPROM */
  26259. +#include "r8180_wx.h"
  26260. +#include "r8180_dm.h"
  26261. +
  26262. +#include <linux/dmapool.h>
  26263. +
  26264. +#include <linux/usb.h>
  26265. +// FIXME: check if 2.6.7 is ok
  26266. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
  26267. +#define usb_kill_urb usb_unlink_urb
  26268. +#endif
  26269. +
  26270. +#ifdef CONFIG_RTL8180_PM
  26271. +#include "r8180_pm.h"
  26272. +#endif
  26273. +
  26274. +#ifdef ENABLE_DOT11D
  26275. +#include "dot11d.h"
  26276. +#endif
  26277. +
  26278. +#ifndef USB_VENDOR_ID_REALTEK
  26279. +#define USB_VENDOR_ID_REALTEK 0x0bda
  26280. +#endif
  26281. +#ifndef USB_VENDOR_ID_NETGEAR
  26282. +#define USB_VENDOR_ID_NETGEAR 0x0846
  26283. +#endif
  26284. +
  26285. +#define TXISR_SELECT(priority) ((priority == MANAGE_PRIORITY)?rtl8187_managetx_isr:\
  26286. + (priority == BEACON_PRIORITY)?rtl8187_beacontx_isr: \
  26287. + (priority == VO_PRIORITY)?rtl8187_votx_isr: \
  26288. + (priority == VI_PRIORITY)?rtl8187_vitx_isr:\
  26289. + (priority == BE_PRIORITY)?rtl8187_betx_isr:rtl8187_bktx_isr)
  26290. +
  26291. +static struct usb_device_id rtl8187_usb_id_tbl[] = {
  26292. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)},
  26293. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8189)},
  26294. +// {USB_DEVICE_VER(USB_VENDOR_ID_REALTEK, 0x8187,0x0200,0x0200)},
  26295. + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)},
  26296. + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6a00)},
  26297. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8197)},
  26298. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8198)},
  26299. + {}
  26300. +};
  26301. +
  26302. +static char* ifname = "wlan%d";
  26303. +#if 0
  26304. +static int hwseqnum = 0;
  26305. +static int hwwep = 0;
  26306. +#endif
  26307. +static int channels = 0x3fff;
  26308. +//static int channels = 0x7ff;// change by thomas, use 1 - 11 channel 0907-2007
  26309. +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
  26310. +//by amy for rate adaptive
  26311. +#define DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD 300
  26312. +//by amy for rate adaptive
  26313. +//by amy for ps
  26314. +#define IEEE80211_WATCH_DOG_TIME 2000
  26315. +//by amy for ps
  26316. +MODULE_LICENSE("GPL");
  26317. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  26318. +MODULE_VERSION("V 1.1");
  26319. +#endif
  26320. +MODULE_DEVICE_TABLE(usb, rtl8187_usb_id_tbl);
  26321. +MODULE_AUTHOR("Realsil Wlan");
  26322. +MODULE_DESCRIPTION("Linux driver for Realtek RTL8187 WiFi cards");
  26323. +
  26324. +#if 0
  26325. +MODULE_PARM(ifname,"s");
  26326. +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
  26327. +
  26328. +MODULE_PARM(hwseqnum,"i");
  26329. +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
  26330. +
  26331. +MODULE_PARM(hwwep,"i");
  26332. +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
  26333. +
  26334. +MODULE_PARM(channels,"i");
  26335. +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
  26336. +#endif
  26337. +
  26338. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
  26339. +module_param(ifname, charp, S_IRUGO|S_IWUSR );
  26340. +//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
  26341. +//module_param(hwwep,int, S_IRUGO|S_IWUSR);
  26342. +module_param(channels,int, S_IRUGO|S_IWUSR);
  26343. +#else
  26344. +MODULE_PARM(ifname, "s");
  26345. +//MODULE_PARM(hwseqnum,"i");
  26346. +//MODULE_PARM(hwwep,"i");
  26347. +MODULE_PARM(channels,"i");
  26348. +#endif
  26349. +
  26350. +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
  26351. +//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
  26352. +//MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
  26353. +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
  26354. +
  26355. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  26356. +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
  26357. + const struct usb_device_id *id);
  26358. +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
  26359. +#else
  26360. +static void *__devinit rtl8187_usb_probe(struct usb_device *udev,unsigned int ifnum,
  26361. + const struct usb_device_id *id);
  26362. +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr);
  26363. +#endif
  26364. +
  26365. +
  26366. +static struct usb_driver rtl8187_usb_driver = {
  26367. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
  26368. + .owner = THIS_MODULE,
  26369. +#endif
  26370. + .name = RTL8187_MODULE_NAME, /* Driver name */
  26371. + .id_table = rtl8187_usb_id_tbl, /* PCI_ID table */
  26372. + .probe = rtl8187_usb_probe, /* probe fn */
  26373. + .disconnect = rtl8187_usb_disconnect, /* remove fn */
  26374. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
  26375. +#ifdef CONFIG_RTL8180_PM
  26376. + .suspend = rtl8187_suspend, /* PM suspend fn */
  26377. + .resume = rtl8187_resume, /* PM resume fn */
  26378. +#else
  26379. + .suspend = NULL, /* PM suspend fn */
  26380. + .resume = NULL, /* PM resume fn */
  26381. +#endif
  26382. +#endif
  26383. +};
  26384. +
  26385. +#ifdef JOHN_HWSEC
  26386. +void CAM_mark_invalid(struct net_device *dev, u8 ucIndex)
  26387. +{
  26388. + u32 ulContent=0;
  26389. + u32 ulCommand=0;
  26390. + u32 ulEncAlgo=CAM_AES;
  26391. +
  26392. + // keyid must be set in config field
  26393. + ulContent |= (ucIndex&3) | ((u16)(ulEncAlgo)<<2);
  26394. +
  26395. + ulContent |= BIT15;
  26396. + // polling bit, and No Write enable, and address
  26397. + ulCommand= CAM_CONTENT_COUNT*ucIndex;
  26398. + ulCommand= ulCommand | BIT31|BIT16;
  26399. + // write content 0 is equall to mark invalid
  26400. +
  26401. + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
  26402. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A4: %x \n",ulContent));
  26403. + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
  26404. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A0: %x \n",ulCommand));
  26405. +}
  26406. +
  26407. +void CAM_empty_entry(struct net_device *dev, u8 ucIndex)
  26408. +{
  26409. + u32 ulCommand=0;
  26410. + u32 ulContent=0;
  26411. + u8 i;
  26412. + u32 ulEncAlgo=CAM_AES;
  26413. +
  26414. + for(i=0;i<6;i++)
  26415. + {
  26416. +
  26417. + // filled id in CAM config 2 byte
  26418. + if( i == 0)
  26419. + {
  26420. + ulContent |=(ucIndex & 0x03) | (ulEncAlgo<<2);
  26421. + ulContent |= BIT15;
  26422. +
  26423. + }
  26424. + else
  26425. + {
  26426. + ulContent = 0;
  26427. + }
  26428. + // polling bit, and No Write enable, and address
  26429. + ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
  26430. + ulCommand= ulCommand | BIT31|BIT16;
  26431. + // write content 0 is equall to mark invalid
  26432. + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
  26433. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %x \n",ulContent));
  26434. + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
  26435. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %x \n",ulCommand));
  26436. + }
  26437. +}
  26438. +
  26439. +void CamResetAllEntry(struct net_device *dev)
  26440. +{
  26441. + u8 ucIndex;
  26442. +
  26443. + //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
  26444. + // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
  26445. + // In this condition, Cam can not be reset because upper layer will not set this static key again.
  26446. + //if(Adapter->EncAlgorithm == WEP_Encryption)
  26447. + // return;
  26448. + //debug
  26449. + //DbgPrint("========================================\n");
  26450. + //DbgPrint(" Call ResetAllEntry \n");
  26451. + //DbgPrint("========================================\n\n");
  26452. +
  26453. + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
  26454. + CAM_mark_invalid(dev, ucIndex);
  26455. + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
  26456. + CAM_empty_entry(dev, ucIndex);
  26457. +
  26458. +}
  26459. +
  26460. +
  26461. +void write_cam(struct net_device *dev, u8 addr, u32 data)
  26462. +{
  26463. + write_nic_dword(dev, WCAMI, data);
  26464. + write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
  26465. +}
  26466. +u32 read_cam(struct net_device *dev, u8 addr)
  26467. +{
  26468. + write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
  26469. + return read_nic_dword(dev, 0xa8);
  26470. +}
  26471. +#endif /*JOHN_HWSEC*/
  26472. +
  26473. +#ifdef DEBUG_RW_REGISTER
  26474. +//lzm add for write time out test
  26475. +void add_into_rw_registers(struct net_device *dev, u32 addr, u32 cont, u8 flag)
  26476. +{
  26477. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26478. + int reg_index = (priv->write_read_register_index % 200) ;
  26479. +
  26480. + priv->write_read_registers[reg_index].address = 0;
  26481. + priv->write_read_registers[reg_index].content = 0;
  26482. + priv->write_read_registers[reg_index].flag = 0;
  26483. +
  26484. + priv->write_read_registers[reg_index].address = addr;
  26485. + priv->write_read_registers[reg_index].content = cont;
  26486. + priv->write_read_registers[reg_index].flag = flag;
  26487. +
  26488. + priv->write_read_register_index = (priv->write_read_register_index + 1) % 200;
  26489. +}
  26490. +
  26491. +bool print_once = 0;
  26492. +
  26493. +void print_rw_registers(struct net_device *dev)
  26494. +{
  26495. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26496. + int reg_index = 0;
  26497. + int watchdog = 0;
  26498. + if(print_once == false)
  26499. + {
  26500. + print_once = true;
  26501. + for(reg_index = ((priv->write_read_register_index + 1) % 200); watchdog <= 199; reg_index++)
  26502. + {
  26503. + watchdog++;
  26504. + printk("====>reg_addr:0x%x, reg_cont:0x%x, read_or_write:0x%d\n",
  26505. + priv->write_read_registers[reg_index].address,
  26506. + priv->write_read_registers[reg_index].content,
  26507. + priv->write_read_registers[reg_index].flag);
  26508. + }
  26509. + }
  26510. +}
  26511. +//lzm add for write time out test
  26512. +#endif
  26513. +
  26514. +#ifdef CPU_64BIT
  26515. +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
  26516. +{
  26517. + int status;
  26518. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26519. + struct usb_device *udev = priv->udev;
  26520. +
  26521. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26522. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26523. + indx|0xfe00, 0, &data, 1, HZ / 2);
  26524. +
  26525. +//lzm add for write time out test
  26526. +#ifdef DEBUG_RW_REGISTER
  26527. + add_into_rw_registers(dev, indx, data, 2);
  26528. +#endif
  26529. +
  26530. + if (status < 0)
  26531. + {
  26532. + printk("write_nic_byte_E TimeOut!addr:%x, status:%x\n", indx, status);
  26533. +#ifdef DEBUG_RW_REGISTER
  26534. + print_rw_registers(dev);
  26535. +#endif
  26536. + }
  26537. +}
  26538. +
  26539. +u8 read_nic_byte_E(struct net_device *dev, int indx)
  26540. +{
  26541. + int status;
  26542. + u8 data, *buf;
  26543. + dma_addr_t dma_handle;
  26544. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26545. + struct usb_device *udev = priv->udev;
  26546. +
  26547. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  26548. + if (!buf) {
  26549. + printk("read_nic_byte_E out of memory\n");
  26550. + return -ENOMEM;
  26551. + }
  26552. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26553. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26554. + indx|0xfe00, 0, buf, 1, HZ / 2);
  26555. +//lzm add for write time out test
  26556. +#ifdef DEBUG_RW_REGISTER
  26557. + add_into_rw_registers(dev, indx, buf[0], 1);
  26558. +#endif
  26559. +
  26560. + if (status < 0)
  26561. + {
  26562. + printk("read_nic_byte_E TimeOut!addr:%x, status:%x\n",indx, status);
  26563. +#ifdef DEBUG_RW_REGISTER
  26564. + print_rw_registers(dev);
  26565. +#endif
  26566. + }
  26567. +
  26568. + data = buf[0];
  26569. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  26570. + return data;
  26571. +}
  26572. +
  26573. +void write_nic_byte(struct net_device *dev, int indx, u8 data)
  26574. +{
  26575. + int status;
  26576. +
  26577. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26578. + struct usb_device *udev = priv->udev;
  26579. +
  26580. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26581. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26582. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
  26583. +
  26584. +//lzm add for write time out test
  26585. +#ifdef DEBUG_RW_REGISTER
  26586. + add_into_rw_registers(dev, indx, data, 2);
  26587. +#endif
  26588. + if (status < 0)
  26589. + {
  26590. + printk("write_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
  26591. +#ifdef DEBUG_RW_REGISTER
  26592. + print_rw_registers(dev);
  26593. +#endif
  26594. + }
  26595. +
  26596. +
  26597. +}
  26598. +
  26599. +void write_nic_word(struct net_device *dev, int indx, u16 data)
  26600. +{
  26601. +
  26602. + int status;
  26603. +
  26604. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26605. + struct usb_device *udev = priv->udev;
  26606. +
  26607. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26608. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26609. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
  26610. +
  26611. +//lzm add for write time out test
  26612. +#ifdef DEBUG_RW_REGISTER
  26613. + add_into_rw_registers(dev, indx, data, 2);
  26614. +
  26615. + if(priv->write_read_register_index == 199)
  26616. + {
  26617. + //print_rw_registers(dev);
  26618. + }
  26619. +#endif
  26620. + if (status < 0)
  26621. + {
  26622. + printk("write_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
  26623. +#ifdef DEBUG_RW_REGISTER
  26624. + print_rw_registers(dev);
  26625. +#endif
  26626. + }
  26627. +
  26628. +}
  26629. +
  26630. +void write_nic_dword(struct net_device *dev, int indx, u32 data)
  26631. +{
  26632. +
  26633. + int status;
  26634. +
  26635. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26636. + struct usb_device *udev = priv->udev;
  26637. +
  26638. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26639. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26640. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
  26641. +//lzm add for write time out test
  26642. +#ifdef DEBUG_RW_REGISTER
  26643. + add_into_rw_registers(dev, indx, data, 2);
  26644. +#endif
  26645. +
  26646. +
  26647. + if (status < 0)
  26648. + {
  26649. + printk("write_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
  26650. +#ifdef DEBUG_RW_REGISTER
  26651. + print_rw_registers(dev);
  26652. +#endif
  26653. + }
  26654. +
  26655. +}
  26656. +
  26657. + u8 read_nic_byte(struct net_device *dev, int indx)
  26658. +{
  26659. + u8 data, *buf;
  26660. + int status;
  26661. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26662. + struct usb_device *udev = priv->udev;
  26663. + dma_addr_t dma_handle;
  26664. +
  26665. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  26666. + if (!buf) {
  26667. + printk("read_nic_byte: out of memory\n");
  26668. + return -ENOMEM;
  26669. + }
  26670. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26671. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26672. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
  26673. +//lzm add for write time out test
  26674. +#ifdef DEBUG_RW_REGISTER
  26675. + add_into_rw_registers(dev, indx, buf[0], 1);
  26676. +#endif
  26677. +
  26678. + if (status < 0)
  26679. + {
  26680. + printk("read_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
  26681. +#ifdef DEBUG_RW_REGISTER
  26682. + print_rw_registers(dev);
  26683. +#endif
  26684. + }
  26685. +
  26686. + data = buf[0];
  26687. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  26688. + return data;
  26689. +}
  26690. +
  26691. +u16 read_nic_word(struct net_device *dev, int indx)
  26692. +{
  26693. + u16 data, *buf;
  26694. + int status;
  26695. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26696. + struct usb_device *udev = priv->udev;
  26697. + dma_addr_t dma_handle;
  26698. +
  26699. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  26700. + if (!buf) {
  26701. + printk("read_nic_word: out of memory\n");
  26702. + return -ENOMEM;
  26703. + }
  26704. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26705. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26706. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
  26707. +//lzm add for write time out test
  26708. +#ifdef DEBUG_RW_REGISTER
  26709. + add_into_rw_registers(dev, indx, buf[0], 1);
  26710. +#endif
  26711. +
  26712. + if (status < 0)
  26713. + {
  26714. + printk("read_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
  26715. +#ifdef DEBUG_RW_REGISTER
  26716. + print_rw_registers(dev);
  26717. +#endif
  26718. + }
  26719. +
  26720. +
  26721. + data = buf[0];
  26722. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  26723. + return data;
  26724. +}
  26725. +
  26726. +u32 read_nic_dword(struct net_device *dev, int indx)
  26727. +{
  26728. + u32 data, *buf;
  26729. + int status;
  26730. + dma_addr_t dma_handle;
  26731. +// int result;
  26732. +
  26733. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26734. + struct usb_device *udev = priv->udev;
  26735. +
  26736. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  26737. + if (!buf){
  26738. + printk("read_nic_dword: out of memory\n");
  26739. + return -ENOMEM;
  26740. + }
  26741. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26742. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26743. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
  26744. +//lzm add for write time out test
  26745. +#ifdef DEBUG_RW_REGISTER
  26746. + add_into_rw_registers(dev, indx, buf[0], 1);
  26747. +#endif
  26748. +
  26749. + if (status < 0)
  26750. + {
  26751. + printk("read_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
  26752. +#ifdef DEBUG_RW_REGISTER
  26753. + print_rw_registers(dev);
  26754. +#endif
  26755. + }
  26756. +
  26757. +
  26758. +
  26759. + data = buf[0];
  26760. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  26761. + return data;
  26762. +}
  26763. +#else
  26764. +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
  26765. +{
  26766. + int status;
  26767. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26768. + struct usb_device *udev = priv->udev;
  26769. +
  26770. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26771. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26772. + indx|0xfe00, 0, &data, 1, HZ / 2);
  26773. +
  26774. + if (status < 0)
  26775. + {
  26776. + printk("write_nic_byte_E TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data,status);
  26777. + }
  26778. +}
  26779. +
  26780. +u8 read_nic_byte_E(struct net_device *dev, int indx)
  26781. +{
  26782. + int status;
  26783. + u8 data = 0;
  26784. + u8 buf[64];
  26785. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26786. + struct usb_device *udev = priv->udev;
  26787. +
  26788. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26789. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26790. + indx|0xfe00, 0, buf, 1, HZ / 2);
  26791. +
  26792. + if (status < 0)
  26793. + {
  26794. + printk("read_nic_byte_E TimeOut!addr:0x%x, status:%x\n", indx, status);
  26795. + }
  26796. +
  26797. + data = *(u8*)buf;
  26798. + return data;
  26799. +}
  26800. +
  26801. +void write_nic_byte(struct net_device *dev, int indx, u8 data)
  26802. +{
  26803. + int status;
  26804. +
  26805. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26806. + struct usb_device *udev = priv->udev;
  26807. +
  26808. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26809. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26810. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
  26811. +
  26812. + if (status < 0)
  26813. + {
  26814. + printk("write_nic_byte TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  26815. + }
  26816. +
  26817. +
  26818. +}
  26819. +
  26820. +void write_nic_word(struct net_device *dev, int indx, u16 data)
  26821. +{
  26822. +
  26823. + int status;
  26824. +
  26825. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26826. + struct usb_device *udev = priv->udev;
  26827. +
  26828. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26829. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26830. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
  26831. +
  26832. + if (status < 0)
  26833. + {
  26834. + printk("write_nic_word TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  26835. + }
  26836. +
  26837. +}
  26838. +
  26839. +void write_nic_dword(struct net_device *dev, int indx, u32 data)
  26840. +{
  26841. +
  26842. + int status;
  26843. +
  26844. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26845. + struct usb_device *udev = priv->udev;
  26846. +
  26847. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  26848. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  26849. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
  26850. +
  26851. +
  26852. + if (status < 0)
  26853. + {
  26854. + printk("write_nic_dword TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  26855. + }
  26856. +
  26857. +}
  26858. +
  26859. +u8 read_nic_byte(struct net_device *dev, int indx)
  26860. +{
  26861. + u8 data = 0;
  26862. + u8 buf[64];
  26863. + int status;
  26864. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26865. + struct usb_device *udev = priv->udev;
  26866. +
  26867. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26868. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26869. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
  26870. +
  26871. + if (status < 0)
  26872. + {
  26873. + printk("read_nic_byte TimeOut!addr:0x%x,status:%x\n", indx,status);
  26874. + }
  26875. +
  26876. +
  26877. + data = *(u8*)buf;
  26878. + return data;
  26879. +}
  26880. +
  26881. +u16 read_nic_word(struct net_device *dev, int indx)
  26882. +{
  26883. + u16 data = 0;
  26884. + u8 buf[64];
  26885. + int status;
  26886. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26887. + struct usb_device *udev = priv->udev;
  26888. +
  26889. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26890. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26891. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
  26892. +
  26893. + if (status < 0)
  26894. + {
  26895. + printk("read_nic_word TimeOut!addr:0x%x,status:%x\n", indx,status);
  26896. + }
  26897. +
  26898. + data = *(u16*)buf;
  26899. + return data;
  26900. +}
  26901. +
  26902. +u32 read_nic_dword(struct net_device *dev, int indx)
  26903. +{
  26904. + u32 data = 0;
  26905. + u8 buf[64];
  26906. + int status;
  26907. +
  26908. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26909. + struct usb_device *udev = priv->udev;
  26910. +
  26911. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  26912. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  26913. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
  26914. +
  26915. + if (status < 0)
  26916. + {
  26917. + printk("read_nic_dword TimeOut!addr:0x%x,status:%x\n", indx, status);
  26918. + }
  26919. +
  26920. +
  26921. + data = *(u32*)buf;
  26922. + return data;
  26923. +}
  26924. +#endif
  26925. +
  26926. +
  26927. +u8 read_phy_cck(struct net_device *dev, u8 adr);
  26928. +u8 read_phy_ofdm(struct net_device *dev, u8 adr);
  26929. +/* this might still called in what was the PHY rtl8185/rtl8187 common code
  26930. + * plans are to possibilty turn it again in one common code...
  26931. + */
  26932. +inline void force_pci_posting(struct net_device *dev)
  26933. +{
  26934. +}
  26935. +
  26936. +
  26937. +static struct net_device_stats *rtl8180_stats(struct net_device *dev);
  26938. +void rtl8180_commit(struct net_device *dev);
  26939. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  26940. +void rtl8180_restart(struct work_struct *work);
  26941. +#else
  26942. +void rtl8180_restart(struct net_device *dev);
  26943. +#endif
  26944. +/****************************************************************************
  26945. + -----------------------------PROCFS STUFF-------------------------
  26946. +*****************************************************************************/
  26947. +
  26948. +static struct proc_dir_entry *rtl8180_proc = NULL;
  26949. +static int proc_get_stats_ap(char *page, char **start,
  26950. + off_t offset, int count,
  26951. + int *eof, void *data)
  26952. +{
  26953. + struct net_device *dev = data;
  26954. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  26955. + struct ieee80211_device *ieee = priv->ieee80211;
  26956. + struct ieee80211_network *target;
  26957. +
  26958. + int len = 0;
  26959. +
  26960. + list_for_each_entry(target, &ieee->network_list, list) {
  26961. +
  26962. + len += snprintf(page + len, count - len,
  26963. + "%s ", target->ssid);
  26964. + len += snprintf(page + len, count - len,
  26965. + "%ld ", (jiffies-target->last_scanned)/HZ);
  26966. +
  26967. +
  26968. +
  26969. + if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
  26970. + len += snprintf(page + len, count - len,
  26971. + "WPA\n");
  26972. + }
  26973. + else{
  26974. + len += snprintf(page + len, count - len,
  26975. + "non_WPA\n");
  26976. + }
  26977. +
  26978. + }
  26979. +
  26980. + *eof = 1;
  26981. + return len;
  26982. +}
  26983. +
  26984. +static int proc_get_registers(char *page, char **start,
  26985. + off_t offset, int count,
  26986. + int *eof, void *data)
  26987. +{
  26988. + struct net_device *dev = data;
  26989. +
  26990. + int len = 0;
  26991. + int i,n;
  26992. +
  26993. + int max=0xff;
  26994. +
  26995. + /* This dump the current register page */
  26996. +len += snprintf(page + len, count - len,
  26997. + "\n####################page 0##################\n ");
  26998. +
  26999. + for(n=0;n<=max;)
  27000. + {
  27001. + //printk( "\nD: %2x> ", n);
  27002. + len += snprintf(page + len, count - len,
  27003. + "\nD: %2x > ",n);
  27004. +
  27005. + for(i=0;i<16 && n<=max;i++,n++)
  27006. + len += snprintf(page + len, count - len,
  27007. + "%2x ",read_nic_byte(dev,n));
  27008. +
  27009. + // printk("%2x ",read_nic_byte(dev,n));
  27010. + }
  27011. + len += snprintf(page + len, count - len,"\n");
  27012. +len += snprintf(page + len, count - len,
  27013. + "\n####################page 1##################\n ");
  27014. + for(n=0;n<=max;)
  27015. + {
  27016. + //printk( "\nD: %2x> ", n);
  27017. + len += snprintf(page + len, count - len,
  27018. + "\nD: %2x > ",n);
  27019. +
  27020. + for(i=0;i<16 && n<=max;i++,n++)
  27021. + len += snprintf(page + len, count - len,
  27022. + "%2x ",read_nic_byte(dev,0x100|n));
  27023. +
  27024. + // printk("%2x ",read_nic_byte(dev,n));
  27025. + }
  27026. +len += snprintf(page + len, count - len,
  27027. + "\n####################page 2##################\n ");
  27028. + for(n=0;n<=max;)
  27029. + {
  27030. + //printk( "\nD: %2x> ", n);
  27031. + len += snprintf(page + len, count - len,
  27032. + "\nD: %2x > ",n);
  27033. +
  27034. + for(i=0;i<16 && n<=max;i++,n++)
  27035. + len += snprintf(page + len, count - len,
  27036. + "%2x ",read_nic_byte(dev,0x200|n));
  27037. +
  27038. + // printk("%2x ",read_nic_byte(dev,n));
  27039. + }
  27040. +
  27041. +
  27042. +
  27043. + *eof = 1;
  27044. + return len;
  27045. +
  27046. +}
  27047. +
  27048. +
  27049. +static int proc_get_cck_reg(char *page, char **start,
  27050. + off_t offset, int count,
  27051. + int *eof, void *data)
  27052. +{
  27053. + struct net_device *dev = data;
  27054. +
  27055. + int len = 0;
  27056. + int i,n;
  27057. +
  27058. + int max = 0x5F;
  27059. +
  27060. + /* This dump the current register page */
  27061. + for(n=0;n<=max;)
  27062. + {
  27063. + //printk( "\nD: %2x> ", n);
  27064. + len += snprintf(page + len, count - len,
  27065. + "\nD: %2x > ",n);
  27066. +
  27067. + for(i=0;i<16 && n<=max;i++,n++)
  27068. + len += snprintf(page + len, count - len,
  27069. + "%2x ",read_phy_cck(dev,n));
  27070. +
  27071. + // printk("%2x ",read_nic_byte(dev,n));
  27072. + }
  27073. + len += snprintf(page + len, count - len,"\n");
  27074. +
  27075. +
  27076. + *eof = 1;
  27077. + return len;
  27078. +
  27079. +}
  27080. +
  27081. +
  27082. +static int proc_get_ofdm_reg(char *page, char **start,
  27083. + off_t offset, int count,
  27084. + int *eof, void *data)
  27085. +{
  27086. + struct net_device *dev = data;
  27087. +
  27088. + int len = 0;
  27089. + int i,n;
  27090. +
  27091. + //int max=0xff;
  27092. + int max = 0x40;
  27093. +
  27094. + /* This dump the current register page */
  27095. + for(n=0;n<=max;)
  27096. + {
  27097. + //printk( "\nD: %2x> ", n);
  27098. + len += snprintf(page + len, count - len,
  27099. + "\nD: %2x > ",n);
  27100. +
  27101. + for(i=0;i<16 && n<=max;i++,n++)
  27102. + len += snprintf(page + len, count - len,
  27103. + "%2x ",read_phy_ofdm(dev,n));
  27104. +
  27105. + // printk("%2x ",read_nic_byte(dev,n));
  27106. + }
  27107. + len += snprintf(page + len, count - len,"\n");
  27108. +
  27109. +
  27110. +
  27111. + *eof = 1;
  27112. + return len;
  27113. +
  27114. +}
  27115. +
  27116. +
  27117. +#if 0
  27118. +static int proc_get_stats_hw(char *page, char **start,
  27119. + off_t offset, int count,
  27120. + int *eof, void *data)
  27121. +{
  27122. + struct net_device *dev = data;
  27123. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27124. +
  27125. + int len = 0;
  27126. +
  27127. + len += snprintf(page + len, count - len,
  27128. + "NIC int: %lu\n"
  27129. + "Total int: %lu\n",
  27130. + priv->stats.ints,
  27131. + priv->stats.shints);
  27132. +
  27133. + *eof = 1;
  27134. + return len;
  27135. +}
  27136. +#endif
  27137. +
  27138. +static int proc_get_stats_tx(char *page, char **start,
  27139. + off_t offset, int count,
  27140. + int *eof, void *data)
  27141. +{
  27142. + struct net_device *dev = data;
  27143. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27144. +
  27145. + int len = 0;
  27146. +
  27147. + len += snprintf(page + len, count - len,
  27148. + "TX VI priority ok int: %lu\n"
  27149. + "TX VI priority error int: %lu\n"
  27150. + "TX VO priority ok int: %lu\n"
  27151. + "TX VO priority error int: %lu\n"
  27152. + "TX BE priority ok int: %lu\n"
  27153. + "TX BE priority error int: %lu\n"
  27154. + "TX BK priority ok int: %lu\n"
  27155. + "TX BK priority error int: %lu\n"
  27156. + "TX MANAGE priority ok int: %lu\n"
  27157. + "TX MANAGE priority error int: %lu\n"
  27158. + "TX BEACON priority ok int: %lu\n"
  27159. + "TX BEACON priority error int: %lu\n"
  27160. +// "TX high priority ok int: %lu\n"
  27161. +// "TX high priority failed error int: %lu\n"
  27162. + "TX queue resume: %lu\n"
  27163. + "TX queue stopped?: %d\n"
  27164. + "TX fifo overflow: %lu\n"
  27165. +// "TX beacon: %lu\n"
  27166. + "TX VI queue: %d\n"
  27167. + "TX VO queue: %d\n"
  27168. + "TX BE queue: %d\n"
  27169. + "TX BK queue: %d\n"
  27170. + "TX BEACON queue: %d\n"
  27171. + "TX MANAGE queue: %d\n"
  27172. +// "TX HW queue: %d\n"
  27173. + "TX VI dropped: %lu\n"
  27174. + "TX VO dropped: %lu\n"
  27175. + "TX BE dropped: %lu\n"
  27176. + "TX BK dropped: %lu\n"
  27177. + "TX total data packets %lu\n",
  27178. +// "TX beacon aborted: %lu\n",
  27179. + priv->stats.txviokint,
  27180. + priv->stats.txvierr,
  27181. + priv->stats.txvookint,
  27182. + priv->stats.txvoerr,
  27183. + priv->stats.txbeokint,
  27184. + priv->stats.txbeerr,
  27185. + priv->stats.txbkokint,
  27186. + priv->stats.txbkerr,
  27187. + priv->stats.txmanageokint,
  27188. + priv->stats.txmanageerr,
  27189. + priv->stats.txbeaconokint,
  27190. + priv->stats.txbeaconerr,
  27191. +// priv->stats.txhpokint,
  27192. +// priv->stats.txhperr,
  27193. + priv->stats.txresumed,
  27194. + netif_queue_stopped(dev),
  27195. + priv->stats.txoverflow,
  27196. +// priv->stats.txbeacon,
  27197. + atomic_read(&(priv->tx_pending[VI_PRIORITY])),
  27198. + atomic_read(&(priv->tx_pending[VO_PRIORITY])),
  27199. + atomic_read(&(priv->tx_pending[BE_PRIORITY])),
  27200. + atomic_read(&(priv->tx_pending[BK_PRIORITY])),
  27201. + atomic_read(&(priv->tx_pending[BEACON_PRIORITY])),
  27202. + atomic_read(&(priv->tx_pending[MANAGE_PRIORITY])),
  27203. +// read_nic_byte(dev, TXFIFOCOUNT),
  27204. + priv->stats.txvidrop,
  27205. + priv->stats.txvodrop,
  27206. + priv->stats.txbedrop,
  27207. + priv->stats.txbkdrop,
  27208. + priv->stats.txdatapkt
  27209. +// priv->stats.txbeaconerr
  27210. + );
  27211. +
  27212. + *eof = 1;
  27213. + return len;
  27214. +}
  27215. +
  27216. +
  27217. +
  27218. +static int proc_get_stats_rx(char *page, char **start,
  27219. + off_t offset, int count,
  27220. + int *eof, void *data)
  27221. +{
  27222. + struct net_device *dev = data;
  27223. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27224. +
  27225. + int len = 0;
  27226. +
  27227. + len += snprintf(page + len, count - len,
  27228. + "RX packets: %lu\n"
  27229. + "RX urb status error: %lu\n"
  27230. + "RX invalid urb error: %lu\n",
  27231. + priv->stats.rxok,
  27232. + priv->stats.rxstaterr,
  27233. + priv->stats.rxurberr);
  27234. +
  27235. + *eof = 1;
  27236. + return len;
  27237. +}
  27238. +
  27239. +#if WIRELESS_EXT < 17
  27240. +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
  27241. +{
  27242. + struct r8180_priv *priv = ieee80211_priv(dev);
  27243. +
  27244. + return &priv->wstats;
  27245. +}
  27246. +#endif
  27247. +
  27248. +void rtl8180_proc_module_init(void)
  27249. +{
  27250. + DMESG("Initializing proc filesystem");
  27251. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  27252. + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net);
  27253. +#else
  27254. + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
  27255. +#endif
  27256. +}
  27257. +
  27258. +
  27259. +void rtl8180_proc_module_remove(void)
  27260. +{
  27261. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  27262. + remove_proc_entry(RTL8187_MODULE_NAME, proc_net);
  27263. +#else
  27264. + remove_proc_entry(RTL8187_MODULE_NAME, init_net.proc_net);
  27265. +#endif
  27266. +}
  27267. +
  27268. +
  27269. +void rtl8180_proc_remove_one(struct net_device *dev)
  27270. +{
  27271. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27272. + if (priv->dir_dev) {
  27273. + // remove_proc_entry("stats-hw", priv->dir_dev);
  27274. + remove_proc_entry("stats-tx", priv->dir_dev);
  27275. + remove_proc_entry("stats-rx", priv->dir_dev);
  27276. + // remove_proc_entry("stats-ieee", priv->dir_dev);
  27277. + remove_proc_entry("stats-ap", priv->dir_dev);
  27278. + remove_proc_entry("registers", priv->dir_dev);
  27279. + remove_proc_entry("cck-registers",priv->dir_dev);
  27280. + remove_proc_entry("ofdm-registers",priv->dir_dev);
  27281. + remove_proc_entry(dev->name, rtl8180_proc);
  27282. + priv->dir_dev = NULL;
  27283. + }
  27284. +}
  27285. +
  27286. +
  27287. +void rtl8180_proc_init_one(struct net_device *dev)
  27288. +{
  27289. + struct proc_dir_entry *e;
  27290. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27291. + priv->dir_dev = create_proc_entry(dev->name,
  27292. + S_IFDIR | S_IRUGO | S_IXUGO,
  27293. + rtl8180_proc);
  27294. + if (!priv->dir_dev) {
  27295. + DMESGE("Unable to initialize /proc/net/rtl8187/%s\n",
  27296. + dev->name);
  27297. + return;
  27298. + }
  27299. + #if 0
  27300. + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
  27301. + priv->dir_dev, proc_get_stats_hw, dev);
  27302. +
  27303. + if (!e) {
  27304. + DMESGE("Unable to initialize "
  27305. + "/proc/net/rtl8187/%s/stats-hw\n",
  27306. + dev->name);
  27307. + }
  27308. + #endif
  27309. + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
  27310. + priv->dir_dev, proc_get_stats_rx, dev);
  27311. +
  27312. + if (!e) {
  27313. + DMESGE("Unable to initialize "
  27314. + "/proc/net/rtl8187/%s/stats-rx\n",
  27315. + dev->name);
  27316. + }
  27317. +
  27318. +
  27319. + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
  27320. + priv->dir_dev, proc_get_stats_tx, dev);
  27321. +
  27322. + if (!e) {
  27323. + DMESGE("Unable to initialize "
  27324. + "/proc/net/rtl8187/%s/stats-tx\n",
  27325. + dev->name);
  27326. + }
  27327. + #if 0
  27328. + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
  27329. + priv->dir_dev, proc_get_stats_ieee, dev);
  27330. +
  27331. + if (!e) {
  27332. + DMESGE("Unable to initialize "
  27333. + "/proc/net/rtl8187/%s/stats-ieee\n",
  27334. + dev->name);
  27335. + }
  27336. +
  27337. + #endif
  27338. +
  27339. + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
  27340. + priv->dir_dev, proc_get_stats_ap, dev);
  27341. +
  27342. + if (!e) {
  27343. + DMESGE("Unable to initialize "
  27344. + "/proc/net/rtl8187/%s/stats-ap\n",
  27345. + dev->name);
  27346. + }
  27347. +
  27348. + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
  27349. + priv->dir_dev, proc_get_registers, dev);
  27350. + if (!e) {
  27351. + DMESGE("Unable to initialize "
  27352. + "/proc/net/rtl8187/%s/registers\n",
  27353. + dev->name);
  27354. + }
  27355. +
  27356. + e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
  27357. + priv->dir_dev, proc_get_cck_reg, dev);
  27358. + if (!e) {
  27359. + DMESGE("Unable to initialize "
  27360. + "/proc/net/rtl8187/%s/cck-registers\n",
  27361. + dev->name);
  27362. + }
  27363. +
  27364. + e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
  27365. + priv->dir_dev, proc_get_ofdm_reg, dev);
  27366. + if (!e) {
  27367. + DMESGE("Unable to initialize "
  27368. + "/proc/net/rtl8187/%s/ofdm-registers\n",
  27369. + dev->name);
  27370. + }
  27371. +
  27372. +#ifdef _RTL8187_EXT_PATCH_
  27373. + if( priv->mshobj && priv->mshobj->ext_patch_create_proc )
  27374. + priv->mshobj->ext_patch_create_proc(priv);
  27375. +#endif
  27376. +
  27377. +}
  27378. +/****************************************************************************
  27379. + -----------------------------MISC STUFF-------------------------
  27380. +*****************************************************************************/
  27381. +
  27382. +/* this is only for debugging */
  27383. +void print_buffer(u32 *buffer, int len)
  27384. +{
  27385. + int i;
  27386. + u8 *buf =(u8*)buffer;
  27387. +
  27388. + printk("ASCII BUFFER DUMP (len: %x):\n",len);
  27389. +
  27390. + for(i=0;i<len;i++)
  27391. + printk("%c",buf[i]);
  27392. +
  27393. + printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
  27394. +
  27395. + for(i=0;i<len;i++)
  27396. + printk("%x",buf[i]);
  27397. +
  27398. + printk("\n");
  27399. +}
  27400. +
  27401. +short check_nic_enought_desc(struct net_device *dev, priority_t priority)
  27402. +{
  27403. + struct r8180_priv *priv = ieee80211_priv(dev);
  27404. + //int used = atomic_read((priority == NORM_PRIORITY) ?
  27405. + // &priv->tx_np_pending : &priv->tx_lp_pending);
  27406. + int used = atomic_read(&priv->tx_pending[priority]);
  27407. +
  27408. + return (used < MAX_TX_URB);
  27409. +}
  27410. +
  27411. +void tx_timeout(struct net_device *dev)
  27412. +{
  27413. + struct r8180_priv *priv = ieee80211_priv(dev);
  27414. + //rtl8180_commit(dev);
  27415. + printk("@@@@ Transmit timeout at %ld, latency %ld\n", jiffies,
  27416. + jiffies - dev->trans_start);
  27417. +
  27418. + printk("@@@@ netif_queue_stopped = %d\n", netif_queue_stopped(dev));
  27419. +
  27420. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  27421. + schedule_work(&priv->reset_wq);
  27422. +#else
  27423. + schedule_task(&priv->reset_wq);
  27424. +#endif
  27425. + //DMESG("TXTIMEOUT");
  27426. +}
  27427. +
  27428. +
  27429. +/* this is only for debug */
  27430. +void dump_eprom(struct net_device *dev)
  27431. +{
  27432. + int i;
  27433. + for(i=0; i<63; i++)
  27434. + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
  27435. +}
  27436. +
  27437. +/* this is only for debug */
  27438. +void rtl8180_dump_reg(struct net_device *dev)
  27439. +{
  27440. + int i;
  27441. + int n;
  27442. + int max=0xff;
  27443. +
  27444. + DMESG("Dumping NIC register map");
  27445. +
  27446. + for(n=0;n<=max;)
  27447. + {
  27448. + printk( "\nD: %2x> ", n);
  27449. + for(i=0;i<16 && n<=max;i++,n++)
  27450. + printk("%2x ",read_nic_byte(dev,n));
  27451. + }
  27452. + printk("\n");
  27453. +}
  27454. +
  27455. +/****************************************************************************
  27456. + ------------------------------HW STUFF---------------------------
  27457. +*****************************************************************************/
  27458. +
  27459. +
  27460. +void rtl8180_irq_enable(struct net_device *dev)
  27461. +{
  27462. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27463. + //priv->irq_enabled = 1;
  27464. +
  27465. + //write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |
  27466. + // INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |
  27467. + // INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |
  27468. + // INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
  27469. +
  27470. + write_nic_word(dev,INTA_MASK, priv->irq_mask);
  27471. +}
  27472. +
  27473. +
  27474. +void rtl8180_irq_disable(struct net_device *dev)
  27475. +{
  27476. + write_nic_word(dev,INTA_MASK,0);
  27477. + force_pci_posting(dev);
  27478. +// priv->irq_enabled = 0;
  27479. +}
  27480. +
  27481. +
  27482. +void rtl8180_set_mode(struct net_device *dev,int mode)
  27483. +{
  27484. + u8 ecmd;
  27485. + ecmd=read_nic_byte(dev, EPROM_CMD);
  27486. + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
  27487. + ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
  27488. + ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
  27489. + ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
  27490. + write_nic_byte(dev, EPROM_CMD, ecmd);
  27491. +}
  27492. +
  27493. +
  27494. +void rtl8180_update_msr(struct net_device *dev)
  27495. +{
  27496. + struct r8180_priv *priv = ieee80211_priv(dev);
  27497. + u8 msr;
  27498. +
  27499. + msr = read_nic_byte(dev, MSR);
  27500. + msr &= ~ MSR_LINK_MASK;
  27501. +
  27502. + /* do not change in link_state != WLAN_LINK_ASSOCIATED.
  27503. + * msr must be updated if the state is ASSOCIATING.
  27504. + * this is intentional and make sense for ad-hoc and
  27505. + * master (see the create BSS/IBSS func)
  27506. + */
  27507. + if (priv->ieee80211->state == IEEE80211_LINKED){
  27508. +
  27509. + if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
  27510. + msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
  27511. + else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
  27512. + msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
  27513. + else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
  27514. + msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
  27515. +
  27516. + }else
  27517. + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
  27518. +
  27519. + write_nic_byte(dev, MSR, msr);
  27520. +}
  27521. +
  27522. +void rtl8180_set_chan(struct net_device *dev,short ch)
  27523. +{
  27524. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27525. + u32 tx;
  27526. +
  27527. + priv->chan=ch;
  27528. + #if 0
  27529. + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
  27530. + priv->ieee80211->iw_mode == IW_MODE_MASTER){
  27531. +
  27532. + priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
  27533. + priv->ieee80211->master_chan = ch;
  27534. + rtl8180_update_beacon_ch(dev);
  27535. + }
  27536. + #endif
  27537. +
  27538. + /* this hack should avoid frame TX during channel setting*/
  27539. + tx = read_nic_dword(dev,TX_CONF);
  27540. + tx &= ~TX_LOOPBACK_MASK;
  27541. +
  27542. +#ifndef LOOP_TEST
  27543. + write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
  27544. + priv->rf_set_chan(dev,priv->chan);
  27545. + //mdelay(10); //CPU occupany is too high. LZM 31/10/2008
  27546. + write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
  27547. +#endif
  27548. +}
  27549. +
  27550. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  27551. +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs);
  27552. +#else
  27553. +void rtl8187_rx_isr(struct urb* rx_urb);
  27554. +#endif
  27555. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  27556. +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs);
  27557. +#else
  27558. +void rtl8187_rx_manage_isr(struct urb* rx_urb);
  27559. +#endif
  27560. +
  27561. +
  27562. +
  27563. +void rtl8187_rx_urbsubmit(struct net_device *dev, struct urb* rx_urb)
  27564. +{
  27565. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27566. + int err;
  27567. +
  27568. + usb_fill_bulk_urb(rx_urb,priv->udev,
  27569. + usb_rcvbulkpipe(priv->udev,(NIC_8187 == priv->card_8187)?0x81:0x83),
  27570. + rx_urb->transfer_buffer,
  27571. + RX_URB_SIZE,
  27572. + rtl8187_rx_isr,
  27573. + dev);
  27574. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  27575. + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
  27576. +#else
  27577. + err = usb_submit_urb(rx_urb);
  27578. +#endif
  27579. + if(err && err != -EPERM){
  27580. + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
  27581. + }
  27582. +}
  27583. +
  27584. +
  27585. +void rtl8187_rx_manage_urbsubmit(struct net_device *dev, struct urb* rx_urb)
  27586. +{
  27587. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27588. + int err;
  27589. +#ifdef THOMAS_BEACON
  27590. + usb_fill_bulk_urb(rx_urb,priv->udev,
  27591. + usb_rcvbulkpipe(priv->udev,0x09),
  27592. + rx_urb->transfer_buffer,
  27593. + rx_urb->transfer_buffer_length,
  27594. + rtl8187_rx_manage_isr, dev);
  27595. +#endif
  27596. +
  27597. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  27598. + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
  27599. +#else
  27600. + err = usb_submit_urb(rx_urb);
  27601. +#endif
  27602. + if(err && err != -EPERM){
  27603. + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
  27604. + }
  27605. +}
  27606. +
  27607. +
  27608. +
  27609. +void rtl8187_rx_initiate(struct net_device *dev)
  27610. +{
  27611. + int i;
  27612. + unsigned long flags;
  27613. + struct urb *purb;
  27614. +
  27615. + struct sk_buff *pskb;
  27616. +
  27617. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27618. +
  27619. + priv->tx_urb_index = 0;
  27620. +
  27621. + if ((!priv->rx_urb) || (!priv->pp_rxskb)) {
  27622. +
  27623. + DMESGE("Cannot intiate RX urb mechanism");
  27624. + return;
  27625. +
  27626. + }
  27627. +
  27628. + priv->rx_inx = 0;
  27629. +#ifdef THOMAS_TASKLET
  27630. + atomic_set(&priv->irt_counter,0);
  27631. +#endif
  27632. + for(i = 0;i < MAX_RX_URB; i++){
  27633. +
  27634. + purb = priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
  27635. +
  27636. + if(!priv->rx_urb[i])
  27637. + goto destroy;
  27638. +
  27639. + pskb = priv->pp_rxskb[i] = dev_alloc_skb (RX_URB_SIZE);
  27640. +
  27641. + if (pskb == NULL)
  27642. + goto destroy;
  27643. +
  27644. + purb->transfer_buffer_length = RX_URB_SIZE;
  27645. + purb->transfer_buffer = pskb->data;
  27646. + }
  27647. +
  27648. + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
  27649. +
  27650. + for(i=0;i<MAX_RX_URB;i++)
  27651. + rtl8187_rx_urbsubmit(dev,priv->rx_urb[i]);
  27652. +
  27653. + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
  27654. +
  27655. + return;
  27656. +
  27657. +destroy:
  27658. +
  27659. + for(i = 0; i < MAX_RX_URB; i++) {
  27660. +
  27661. + purb = priv->rx_urb[i];
  27662. +
  27663. + if (purb)
  27664. + usb_free_urb(purb);
  27665. +
  27666. + pskb = priv->pp_rxskb[i];
  27667. +
  27668. + if (pskb)
  27669. + dev_kfree_skb_any(pskb);
  27670. +
  27671. + }
  27672. +
  27673. + return;
  27674. +}
  27675. +
  27676. +
  27677. +void rtl8187_rx_manage_initiate(struct net_device *dev)
  27678. +{
  27679. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27680. + if(!priv->rx_urb)
  27681. + DMESGE("Cannot intiate RX urb mechanism");
  27682. +
  27683. + rtl8187_rx_manage_urbsubmit(dev,priv->rx_urb[MAX_RX_URB]);
  27684. +
  27685. +}
  27686. +
  27687. +
  27688. +void rtl8187_set_rxconf(struct net_device *dev)
  27689. +{
  27690. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27691. + u32 rxconf;
  27692. +
  27693. + rxconf=read_nic_dword(dev,RX_CONF);
  27694. + rxconf = rxconf &~ MAC_FILTER_MASK;
  27695. + rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
  27696. + rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
  27697. + rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
  27698. + rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
  27699. + //rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
  27700. +#ifdef SW_ANTE_DIVERSITY
  27701. + rxconf = rxconf | priv->EEPROMCSMethod;//for antenna
  27702. +#endif
  27703. +
  27704. + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
  27705. +
  27706. + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
  27707. + dev->flags & IFF_PROMISC){
  27708. + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
  27709. + } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
  27710. + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
  27711. + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
  27712. + }*/else{
  27713. + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
  27714. + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
  27715. + }
  27716. +
  27717. +
  27718. + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
  27719. + rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
  27720. + rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
  27721. + }
  27722. +
  27723. + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
  27724. + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
  27725. +
  27726. +
  27727. + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
  27728. + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
  27729. + rxconf = rxconf &~ MAX_RX_DMA_MASK;
  27730. + rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
  27731. +
  27732. + rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
  27733. + rxconf = rxconf | RCR_ONLYERLPKT;
  27734. +
  27735. + //rxconf = rxconf &~ RCR_CS_MASK;
  27736. + //rxconf = rxconf | (1<<RCR_CS_SHIFT);
  27737. +
  27738. + write_nic_dword(dev, RX_CONF, rxconf);
  27739. +
  27740. + #ifdef DEBUG_RX
  27741. + DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
  27742. + #endif
  27743. +}
  27744. +
  27745. +void rtl8180_rx_enable(struct net_device *dev)
  27746. +{
  27747. + u8 cmd;
  27748. +
  27749. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27750. +
  27751. + rtl8187_rx_initiate(dev);
  27752. + rtl8187_set_rxconf(dev);
  27753. +
  27754. + if(NIC_8187 == priv->card_8187) {
  27755. + cmd=read_nic_byte(dev,CMD);
  27756. + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
  27757. + } else {
  27758. + //write_nic_dword(dev, RCR, priv->ReceiveConfig);
  27759. + }
  27760. +}
  27761. +
  27762. +
  27763. +void rtl8180_tx_enable(struct net_device *dev)
  27764. +{
  27765. + u8 cmd;
  27766. + u8 byte;
  27767. + u32 txconf = 0;
  27768. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27769. +
  27770. + if(NIC_8187B == priv->card_8187){
  27771. + write_nic_dword(dev, TCR, priv->TransmitConfig);
  27772. + byte = read_nic_byte(dev, MSR);
  27773. + byte |= MSR_LINK_ENEDCA;
  27774. + write_nic_byte(dev, MSR, byte);
  27775. +#ifdef LOOP_TEST
  27776. + txconf= read_nic_dword(dev,TX_CONF);
  27777. + txconf = txconf | (TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT);
  27778. + write_nic_dword(dev,TX_CONF,txconf);
  27779. +#endif
  27780. + } else {
  27781. + byte = read_nic_byte(dev,CW_CONF);
  27782. + byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
  27783. + byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
  27784. + write_nic_byte(dev, CW_CONF, byte);
  27785. +
  27786. + byte = read_nic_byte(dev, TX_AGC_CTL);
  27787. + byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
  27788. + byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
  27789. + byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
  27790. + write_nic_byte(dev, TX_AGC_CTL, byte);
  27791. +
  27792. + txconf= read_nic_dword(dev,TX_CONF);
  27793. +
  27794. +
  27795. + txconf = txconf &~ TX_LOOPBACK_MASK;
  27796. +
  27797. +#ifndef LOOP_TEST
  27798. + txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
  27799. +#else
  27800. + txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
  27801. +#endif
  27802. + txconf = txconf &~ TCR_SRL_MASK;
  27803. + txconf = txconf &~ TCR_LRL_MASK;
  27804. +
  27805. + txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
  27806. + txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
  27807. +
  27808. + txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
  27809. +
  27810. + txconf = txconf &~ TCR_MXDMA_MASK;
  27811. + txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
  27812. +
  27813. + txconf = txconf | TCR_DISReqQsize;
  27814. + txconf = txconf | TCR_DISCW;
  27815. + txconf = txconf &~ TCR_SWPLCPLEN;
  27816. +
  27817. + txconf=txconf | (1<<TX_NOICV_SHIFT);
  27818. +
  27819. + write_nic_dword(dev,TX_CONF,txconf);
  27820. +
  27821. +#ifdef DEBUG_TX
  27822. + DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
  27823. +#endif
  27824. +
  27825. + cmd=read_nic_byte(dev,CMD);
  27826. + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
  27827. + }
  27828. +}
  27829. +
  27830. +#if 0
  27831. +void rtl8180_beacon_tx_enable(struct net_device *dev)
  27832. +{
  27833. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27834. + priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
  27835. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  27836. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  27837. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  27838. +}
  27839. +
  27840. +
  27841. +void rtl8180_
  27842. +_disable(struct net_device *dev)
  27843. +{
  27844. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27845. + priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
  27846. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  27847. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  27848. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  27849. +}
  27850. +
  27851. +#endif
  27852. +
  27853. +
  27854. +void rtl8180_rtx_disable(struct net_device *dev)
  27855. +{
  27856. + u8 cmd;
  27857. + int i;
  27858. + struct r8180_priv *priv = ieee80211_priv(dev);
  27859. +
  27860. + cmd=read_nic_byte(dev,CMD);
  27861. + write_nic_byte(dev, CMD, cmd &~ \
  27862. + ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
  27863. + force_pci_posting(dev);
  27864. + mdelay(10);
  27865. +
  27866. +#ifdef THOMAS_BEACON
  27867. + {
  27868. + int index = priv->rx_inx;//0
  27869. + i=0;
  27870. + if(priv->rx_urb){
  27871. + while(i<MAX_RX_URB){
  27872. + if(priv->rx_urb[index]){
  27873. + usb_kill_urb(priv->rx_urb[index]);
  27874. + }
  27875. + if( index == (MAX_RX_URB-1) )
  27876. + index=0;
  27877. + else
  27878. + index=index+1;
  27879. + i++;
  27880. + }
  27881. + if(priv->rx_urb[MAX_RX_URB])
  27882. + usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
  27883. + }
  27884. + }
  27885. +#endif
  27886. +}
  27887. +
  27888. +
  27889. +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
  27890. +{
  27891. + #if 0
  27892. + int i;
  27893. + u32 *tmp;
  27894. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  27895. +
  27896. + priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
  27897. + sizeof(u32)*8*count,
  27898. + &priv->txbeaconringdma);
  27899. + if (!priv->txbeaconring) return -1;
  27900. + for (tmp=priv->txbeaconring,i=0;i<count;i++){
  27901. + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
  27902. + /*
  27903. + *(tmp+2) = (u32)dma_tmp;
  27904. + *(tmp+3) = bufsize;
  27905. + */
  27906. + if(i+1<count)
  27907. + *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
  27908. + else
  27909. + *(tmp+4) = (u32)priv->txbeaconringdma;
  27910. +
  27911. + tmp=tmp+8;
  27912. + }
  27913. + #endif
  27914. + return 0;
  27915. +}
  27916. +
  27917. +long NetgearSignalStrengthTranslate(long LastSS,long CurrSS)
  27918. +{
  27919. + long RetSS;
  27920. +
  27921. + // Step 1. Scale mapping.
  27922. + if(CurrSS >= 71 && CurrSS <= 100){
  27923. + RetSS = 90 + ((CurrSS - 70) / 3);
  27924. + }else if(CurrSS >= 41 && CurrSS <= 70){
  27925. + RetSS = 78 + ((CurrSS - 40) / 3);
  27926. + }else if(CurrSS >= 31 && CurrSS <= 40){
  27927. + RetSS = 66 + (CurrSS - 30);
  27928. + }else if(CurrSS >= 21 && CurrSS <= 30){
  27929. + RetSS = 54 + (CurrSS - 20);
  27930. + }else if(CurrSS >= 5 && CurrSS <= 20){
  27931. + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
  27932. + }else if(CurrSS == 4){
  27933. + RetSS = 36;
  27934. + }else if(CurrSS == 3){
  27935. + RetSS = 27;
  27936. + }else if(CurrSS == 2){
  27937. + RetSS = 18;
  27938. + }else if(CurrSS == 1){
  27939. + RetSS = 9;
  27940. + }else{
  27941. + RetSS = CurrSS;
  27942. + }
  27943. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  27944. +
  27945. + // Step 2. Smoothing.
  27946. + if(LastSS > 0){
  27947. + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
  27948. + }
  27949. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  27950. +
  27951. + return RetSS;
  27952. +}
  27953. +
  27954. +extern long TranslateToDbm8187(u8 SignalStrengthIndex); // 0-100 index.
  27955. +//long TranslateToDbm8187(u8 SignalStrengthIndex) // 0-100 index.
  27956. +//{
  27957. + // long SignalPower; // in dBm.
  27958. +
  27959. + // Translate to dBm (x=0.5y-95).
  27960. + // SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
  27961. + // SignalPower -= 95;
  27962. +
  27963. + // return SignalPower;
  27964. +//}
  27965. +
  27966. +
  27967. +void rtl8180_reset(struct net_device *dev)
  27968. +{
  27969. +
  27970. + struct r8180_priv *priv = ieee80211_priv(dev);
  27971. + u8 cr;
  27972. + int i;
  27973. +
  27974. +
  27975. + /* make sure the analog power is on before
  27976. + * reset, otherwise reset may fail
  27977. + */
  27978. + if(NIC_8187 == priv->card_8187) {
  27979. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  27980. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  27981. + rtl8180_irq_disable(dev);
  27982. + mdelay(200);
  27983. + write_nic_byte_E(dev,0x18,0x10);
  27984. + write_nic_byte_E(dev,0x18,0x11);
  27985. + write_nic_byte_E(dev,0x18,0x00);
  27986. + mdelay(200);
  27987. + }
  27988. +
  27989. +
  27990. + cr=read_nic_byte(dev,CMD);
  27991. + cr = cr & 2;
  27992. + cr = cr | (1<<CMD_RST_SHIFT);
  27993. + write_nic_byte(dev,CMD,cr);
  27994. +
  27995. + //lzm mod for up take too long time 20081201
  27996. + //force_pci_posting(dev);
  27997. + //mdelay(200);
  27998. + udelay(20);
  27999. +
  28000. + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
  28001. + DMESGW("Card reset timeout!");
  28002. +
  28003. + if(NIC_8187 == priv->card_8187) {
  28004. +
  28005. + //printk("This is RTL8187 Reset procedure\n");
  28006. + rtl8180_set_mode(dev,EPROM_CMD_LOAD);
  28007. + force_pci_posting(dev);
  28008. + mdelay(200);
  28009. +
  28010. + /* after the eeprom load cycle, make sure we have
  28011. + * correct anaparams
  28012. + */
  28013. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  28014. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  28015. + }
  28016. + else {
  28017. + //printk("This is RTL8187B Reset procedure\n");
  28018. + //test pending bug, john 20070815
  28019. + //initialize tx_pending
  28020. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  28021. +
  28022. + }
  28023. +
  28024. +}
  28025. +
  28026. +inline u16 ieeerate2rtlrate(int rate)
  28027. +{
  28028. + switch(rate){
  28029. + case 10:
  28030. + return 0;
  28031. + case 20:
  28032. + return 1;
  28033. + case 55:
  28034. + return 2;
  28035. + case 110:
  28036. + return 3;
  28037. + case 60:
  28038. + return 4;
  28039. + case 90:
  28040. + return 5;
  28041. + case 120:
  28042. + return 6;
  28043. + case 180:
  28044. + return 7;
  28045. + case 240:
  28046. + return 8;
  28047. + case 360:
  28048. + return 9;
  28049. + case 480:
  28050. + return 10;
  28051. + case 540:
  28052. + return 11;
  28053. + default:
  28054. + return 3;
  28055. +
  28056. + }
  28057. +}
  28058. +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
  28059. +inline u16 rtl8180_rate2rate(short rate)
  28060. +{
  28061. + if (rate >12) return 10;
  28062. + return rtl_rate[rate];
  28063. +}
  28064. +
  28065. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
  28066. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28067. +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs)
  28068. +#else
  28069. +void rtl8187_rx_isr(struct urb* rx_urb)
  28070. +#endif
  28071. +{
  28072. + struct net_device *dev = (struct net_device*)rx_urb->context;
  28073. + struct r8180_priv *priv = ieee80211_priv(dev);
  28074. + priv->rxurb_task = rx_urb;
  28075. +
  28076. +
  28077. + //DMESGW("David: Rx tasklet start!");
  28078. +
  28079. +#ifdef THOMAS_TASKLET
  28080. + atomic_inc( &priv->irt_counter );
  28081. +
  28082. + //if( likely(priv->irt_counter_head+1 != priv->irt_counter_tail) ){
  28083. + // priv->irt_counter_head = (priv->irt_counter_head+1)&0xffff ;
  28084. + tasklet_schedule(&priv->irq_rx_tasklet);
  28085. + //} else{
  28086. + //DMESG("error: priv->irt_counter_head is going to pass through priv->irt_counter_tail\n");
  28087. + /*
  28088. + skb = priv->pp_rxskb[priv->rx_inx];
  28089. + dev_kfree_skb_any(skb);
  28090. +
  28091. + skb = dev_alloc_skb(RX_URB_SIZE);
  28092. + if (skb == NULL)
  28093. + panic("No Skb For RX!/n");
  28094. +
  28095. + rx_urb->transfer_buffer = skb->data;
  28096. +
  28097. + priv->pp_rxskb[priv->rx_inx] = skb;
  28098. + if(status == 0)
  28099. + rtl8187_rx_urbsubmit(dev,rx_urb);
  28100. + else {
  28101. + priv->pp_rxskb[priv->rx_inx] = NULL;
  28102. + dev_kfree_skb_any(skb);
  28103. + printk("RX process aborted due to explicit shutdown (%x) ", status);
  28104. + }
  28105. +
  28106. + if (*prx_inx == (MAX_RX_URB -1))
  28107. + *prx_inx = 0;
  28108. + else
  28109. + *prx_inx = *prx_inx + 1;
  28110. +
  28111. + */
  28112. + //}
  28113. +#endif
  28114. +
  28115. +}
  28116. +
  28117. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28118. +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs)
  28119. +#else
  28120. +void rtl8187_rx_manage_isr(struct urb* rx_urb)
  28121. +#endif
  28122. +{
  28123. + struct net_device *dev = (struct net_device*)rx_urb->context;
  28124. + struct r8180_priv *priv = ieee80211_priv(dev);
  28125. + int status,cmd;
  28126. + struct sk_buff *skb;
  28127. + u32 *desc;
  28128. + int ret;
  28129. + unsigned long flag;
  28130. +
  28131. + //DMESG("RX %d ",rx_urb->status);
  28132. + status = rx_urb->status;
  28133. + if(status == 0){
  28134. +
  28135. + desc = (u32*)(rx_urb->transfer_buffer);
  28136. + cmd = (desc[0] >> 30) & 0x03;
  28137. + //printk(KERN_ALERT "buffersize = %d, length = %d, pipe = %p\n",
  28138. + //rx_urb->transfer_buffer_length, rx_urb->actual_length, rx_urb->pipe>>15);
  28139. +
  28140. + if(cmd == 0x00) {//beacon interrupt
  28141. + //send beacon packet
  28142. +
  28143. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  28144. + if(priv->flag_beacon == true){
  28145. + //printk("rtl8187_rx_manage_isr(): CMD_TYPE0_BCN_INTR\n");
  28146. +
  28147. + skb = ieee80211_get_beacon(priv->ieee80211);
  28148. + if(!skb){
  28149. + DMESG("not enought memory for allocating beacon");
  28150. + return;
  28151. + }
  28152. + //printk(KERN_WARNING "to send beacon packet through beacon endpoint!\n");
  28153. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, BEACON_PRIORITY,
  28154. + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
  28155. +
  28156. + if( ret != 0 ){
  28157. + printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
  28158. + }
  28159. + dev_kfree_skb_any(skb);
  28160. +
  28161. + //} else {//0x00
  28162. + //{ log the device information
  28163. + // At present, It is not implemented just now.
  28164. + //}
  28165. + //}
  28166. +
  28167. + }
  28168. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  28169. + }
  28170. + else if(cmd == 0x01){
  28171. + //printk("rtl8187_rx_manage_isr(): CMD_TYPE1_TX_CLOSE\n");
  28172. + priv->CurrRetryCnt += (u16)desc[0]&0x000000ff;
  28173. + //printk("priv->CurrRetryCnt is %d\n",priv->CurrRetryCnt);
  28174. + }
  28175. + else
  28176. + printk("HalUsbInCommandComplete8187B(): unknown Type(%#X) !!!\n", cmd);
  28177. +
  28178. + }else{
  28179. + priv->stats.rxstaterr++;
  28180. + priv->ieee80211->stats.rx_errors++;
  28181. + }
  28182. +
  28183. +
  28184. + if( status == 0 )
  28185. + //if(status != -ENOENT)
  28186. + rtl8187_rx_manage_urbsubmit(dev, rx_urb);
  28187. + else
  28188. + ;//DMESG("Mangement RX process aborted due to explicit shutdown");
  28189. +}
  28190. +
  28191. +#if 0
  28192. +void rtl8180_tx_queues_stop(struct net_device *dev)
  28193. +{
  28194. + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  28195. + u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  28196. + dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
  28197. + dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
  28198. + dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
  28199. +
  28200. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  28201. + write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
  28202. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  28203. +}
  28204. +#endif
  28205. +
  28206. +void rtl8180_data_hard_stop(struct net_device *dev)
  28207. +{
  28208. + //FIXME !!
  28209. + #if 0
  28210. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  28211. + priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  28212. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  28213. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  28214. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  28215. + #endif
  28216. +}
  28217. +
  28218. +
  28219. +void rtl8180_data_hard_resume(struct net_device *dev)
  28220. +{
  28221. + // FIXME !!
  28222. + #if 0
  28223. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  28224. + priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  28225. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  28226. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  28227. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  28228. + #endif
  28229. +}
  28230. +
  28231. +unsigned int PRI2EP[4] = {0x06,0x07,0x05,0x04};
  28232. +// this function TX data frames when the ieee80211 stack requires this.
  28233. +// It checks also if we need to stop the ieee tx queue, eventually do it
  28234. +void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
  28235. +{
  28236. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  28237. +
  28238. + short morefrag = 0;
  28239. + unsigned long flags;
  28240. + struct ieee80211_hdr *h = (struct ieee80211_hdr *) skb->data;
  28241. +
  28242. + unsigned char ep;
  28243. + short ret; //john
  28244. +
  28245. + if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
  28246. + morefrag = 1;
  28247. + //DMESG("%x %x", h->frame_ctl, h->seq_ctl);
  28248. + /*
  28249. + * This function doesn't require lock because we make
  28250. + * sure it's called with the tx_lock already acquired.
  28251. + * this come from the kernel's hard_xmit callback (trought
  28252. + * the ieee stack, or from the try_wake_queue (again trought
  28253. + * the ieee stack.
  28254. + */
  28255. + spin_lock_irqsave(&priv->tx_lock,flags);
  28256. +
  28257. + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
  28258. + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
  28259. + {
  28260. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  28261. +
  28262. + return;
  28263. + }
  28264. +
  28265. + if(NIC_8187B == priv->card_8187){
  28266. + ep = PRI2EP[skb->priority];
  28267. + } else {
  28268. + ep = LOW_PRIORITY;
  28269. + }
  28270. + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
  28271. + if (!check_nic_enought_desc(dev, ep)){
  28272. + DMESG("Error: no TX slot ");
  28273. + ieee80211_stop_queue(priv->ieee80211);
  28274. + }
  28275. +
  28276. +#ifdef LED_SHIN
  28277. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_TX);
  28278. +#endif
  28279. +
  28280. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, ep, morefrag,ieeerate2rtlrate(rate));
  28281. + if(ret!=0) DMESG("Error: rtl8180_tx failed in rtl8180_hard_data_xmit\n");//john
  28282. +
  28283. + priv->stats.txdatapkt++;
  28284. +
  28285. + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
  28286. + if (!check_nic_enought_desc(dev, ep)){
  28287. + ieee80211_stop_queue(priv->ieee80211);
  28288. + }
  28289. +
  28290. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  28291. +
  28292. +}
  28293. +
  28294. +//This is a rough attempt to TX a frame
  28295. +//This is called by the ieee 80211 stack to TX management frames.
  28296. +//If the ring is full packet are dropped (for data frame the queue
  28297. +//is stopped before this can happen).
  28298. +
  28299. +int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
  28300. +{
  28301. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  28302. + struct ieee80211_device *ieee = priv->ieee80211;
  28303. + int ret;
  28304. + unsigned long flags;
  28305. + spin_lock_irqsave(&priv->tx_lock,flags);
  28306. +
  28307. + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
  28308. + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
  28309. + {
  28310. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  28311. + return 0;
  28312. + }
  28313. +
  28314. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, MANAGE_PRIORITY, 0, ieeerate2rtlrate(ieee->basic_rate));
  28315. +
  28316. + priv->ieee80211->stats.tx_bytes+=skb->len;
  28317. + priv->ieee80211->stats.tx_packets++;
  28318. +
  28319. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  28320. +
  28321. + return ret;
  28322. +}
  28323. +
  28324. +
  28325. +#if 0
  28326. +// longpre 144+48 shortpre 72+24
  28327. +u16 rtl8180_len2duration(u32 len, short rate,short* ext)
  28328. +{
  28329. + u16 duration;
  28330. + u16 drift;
  28331. + *ext=0;
  28332. +
  28333. + switch(rate){
  28334. + case 0://1mbps
  28335. + *ext=0;
  28336. + duration = ((len+4)<<4) /0x2;
  28337. + drift = ((len+4)<<4) % 0x2;
  28338. + if(drift ==0 ) break;
  28339. + duration++;
  28340. + break;
  28341. +
  28342. + case 1://2mbps
  28343. + *ext=0;
  28344. + duration = ((len+4)<<4) /0x4;
  28345. + drift = ((len+4)<<4) % 0x4;
  28346. + if(drift ==0 ) break;
  28347. + duration++;
  28348. + break;
  28349. +
  28350. + case 2: //5.5mbps
  28351. + *ext=0;
  28352. + duration = ((len+4)<<4) /0xb;
  28353. + drift = ((len+4)<<4) % 0xb;
  28354. + if(drift ==0 )
  28355. + break;
  28356. + duration++;
  28357. + break;
  28358. +
  28359. + default:
  28360. + case 3://11mbps
  28361. + *ext=0;
  28362. + duration = ((len+4)<<4) /0x16;
  28363. + drift = ((len+4)<<4) % 0x16;
  28364. + if(drift ==0 )
  28365. + break;
  28366. + duration++;
  28367. + if(drift > 6)
  28368. + break;
  28369. + *ext=1;
  28370. + break;
  28371. + }
  28372. +
  28373. + return duration;
  28374. +}
  28375. +#endif
  28376. +
  28377. +void rtl8180_try_wake_queue(struct net_device *dev, int pri);
  28378. +
  28379. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28380. +void rtl8187_lptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28381. +#else
  28382. +void rtl8187_lptx_isr(struct urb* tx_urb)
  28383. +#endif
  28384. +{
  28385. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28386. + struct r8180_priv *priv = ieee80211_priv(dev);
  28387. +
  28388. + if(tx_urb->status == 0){
  28389. + dev->trans_start = jiffies; //john
  28390. + priv->stats.txlpokint++;
  28391. + priv->txokbytestotal+=tx_urb->actual_length;
  28392. + }else{
  28393. + priv->stats.txlperr++;
  28394. + }
  28395. +
  28396. + kfree(tx_urb->transfer_buffer);
  28397. + usb_free_urb(tx_urb);
  28398. +
  28399. + if(atomic_read(&priv->tx_pending[LOW_PRIORITY]) >= 1)
  28400. + atomic_dec(&priv->tx_pending[LOW_PRIORITY]);
  28401. +
  28402. + rtl8180_try_wake_queue(dev,LOW_PRIORITY);
  28403. +}
  28404. +
  28405. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28406. +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28407. +#else
  28408. +void rtl8187_nptx_isr(struct urb* tx_urb)
  28409. +#endif
  28410. +{
  28411. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28412. + struct r8180_priv *priv = ieee80211_priv(dev);
  28413. +
  28414. + if(tx_urb->status == 0){
  28415. + dev->trans_start = jiffies; //john
  28416. + priv->stats.txnpokint++;
  28417. + }else{
  28418. + priv->stats.txnperr++;
  28419. + }
  28420. +
  28421. + kfree(tx_urb->transfer_buffer);
  28422. + usb_free_urb(tx_urb);
  28423. +
  28424. + if(atomic_read(&priv->tx_pending[NORM_PRIORITY]) >= 1)
  28425. + atomic_dec(&priv->tx_pending[NORM_PRIORITY]);
  28426. + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
  28427. +}
  28428. +
  28429. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28430. +void rtl8187_votx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28431. +#else
  28432. +void rtl8187_votx_isr(struct urb* tx_urb)
  28433. +#endif
  28434. +{
  28435. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28436. + struct r8180_priv *priv = ieee80211_priv(dev);
  28437. +
  28438. + if(tx_urb->status == 0){
  28439. + dev->trans_start = jiffies; //john
  28440. + priv->stats.txvookint++;
  28441. + priv->txokbytestotal+=tx_urb->actual_length;
  28442. + }else{
  28443. + priv->stats.txvoerr++;
  28444. + }
  28445. +
  28446. + kfree(tx_urb->transfer_buffer);
  28447. + usb_free_urb(tx_urb);
  28448. +
  28449. + if(atomic_read(&priv->tx_pending[VO_PRIORITY]) >= 1)
  28450. + atomic_dec(&priv->tx_pending[VO_PRIORITY]);
  28451. + rtl8180_try_wake_queue(dev,VO_PRIORITY);
  28452. +}
  28453. +
  28454. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28455. +void rtl8187_vitx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28456. +#else
  28457. +void rtl8187_vitx_isr(struct urb* tx_urb)
  28458. +#endif
  28459. +{
  28460. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28461. + struct r8180_priv *priv = ieee80211_priv(dev);
  28462. +
  28463. + if(tx_urb->status == 0){
  28464. + dev->trans_start = jiffies; //john
  28465. + priv->stats.txviokint++;
  28466. + priv->txokbytestotal+=tx_urb->actual_length;
  28467. + }else{
  28468. + priv->stats.txvierr++;
  28469. + }
  28470. +
  28471. + kfree(tx_urb->transfer_buffer);
  28472. + usb_free_urb(tx_urb);
  28473. +
  28474. + if(atomic_read(&priv->tx_pending[VI_PRIORITY]) >= 1)
  28475. + atomic_dec(&priv->tx_pending[VI_PRIORITY]);
  28476. + rtl8180_try_wake_queue(dev,VI_PRIORITY);
  28477. +}
  28478. +
  28479. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28480. +void rtl8187_betx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28481. +#else
  28482. +void rtl8187_betx_isr(struct urb* tx_urb)
  28483. +#endif
  28484. +{
  28485. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28486. + struct r8180_priv *priv = ieee80211_priv(dev);
  28487. +
  28488. + if(tx_urb->status == 0){
  28489. + dev->trans_start = jiffies; //john
  28490. + priv->stats.txbeokint++;
  28491. + priv->txokbytestotal+=tx_urb->actual_length;
  28492. + }else{
  28493. + priv->stats.txbeerr++;
  28494. + }
  28495. +
  28496. + kfree(tx_urb->transfer_buffer);
  28497. + usb_free_urb(tx_urb);
  28498. +
  28499. + if(atomic_read(&priv->tx_pending[BE_PRIORITY]) >= 1)
  28500. + atomic_dec(&priv->tx_pending[BE_PRIORITY]);
  28501. + rtl8180_try_wake_queue(dev, BE_PRIORITY);
  28502. +}
  28503. +
  28504. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28505. +void rtl8187_bktx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28506. +#else
  28507. +void rtl8187_bktx_isr(struct urb* tx_urb)
  28508. +#endif
  28509. +{
  28510. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28511. + struct r8180_priv *priv = ieee80211_priv(dev);
  28512. +
  28513. + if(tx_urb->status == 0){
  28514. + dev->trans_start = jiffies; //john
  28515. + priv->stats.txbkokint++;
  28516. + }else{
  28517. + priv->stats.txbkerr++;
  28518. + }
  28519. +
  28520. + kfree(tx_urb->transfer_buffer);
  28521. + usb_free_urb(tx_urb);
  28522. +
  28523. + if(atomic_read(&priv->tx_pending[BK_PRIORITY]) >= 1)
  28524. + atomic_dec(&priv->tx_pending[BK_PRIORITY]);
  28525. + rtl8180_try_wake_queue(dev,BK_PRIORITY);
  28526. +}
  28527. +
  28528. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28529. +void rtl8187_beacontx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28530. +#else
  28531. +void rtl8187_beacontx_isr(struct urb* tx_urb)
  28532. +#endif
  28533. +{
  28534. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28535. + struct r8180_priv *priv = ieee80211_priv(dev);
  28536. +
  28537. + if(tx_urb->status == 0){
  28538. + dev->trans_start = jiffies; //john
  28539. + priv->stats.txbeaconokint++;
  28540. + priv->txokbytestotal+=tx_urb->actual_length;
  28541. + }else{
  28542. + priv->stats.txbeaconerr++;
  28543. + }
  28544. +
  28545. + kfree(tx_urb->transfer_buffer);
  28546. + usb_free_urb(tx_urb);
  28547. +
  28548. + if(atomic_read(&priv->tx_pending[BEACON_PRIORITY]) >= 1)
  28549. + atomic_dec(&priv->tx_pending[BEACON_PRIORITY]);
  28550. + //rtl8180_try_wake_queue(dev,BEACON_PRIORITY);
  28551. +}
  28552. +
  28553. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28554. +void rtl8187_managetx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28555. +#else
  28556. +void rtl8187_managetx_isr(struct urb* tx_urb)
  28557. +#endif
  28558. +{
  28559. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28560. + struct r8180_priv *priv = ieee80211_priv(dev);
  28561. +
  28562. + if(tx_urb->status == 0){
  28563. + dev->trans_start = jiffies; //john
  28564. + priv->stats.txmanageokint++;
  28565. + priv->txokbytestotal+=tx_urb->actual_length;
  28566. + }else{
  28567. + priv->stats.txmanageerr++;
  28568. + }
  28569. +
  28570. + kfree(tx_urb->transfer_buffer);
  28571. + usb_free_urb(tx_urb);
  28572. +
  28573. + if(atomic_read(&priv->tx_pending[MANAGE_PRIORITY]) >= 1)
  28574. + atomic_dec(&priv->tx_pending[MANAGE_PRIORITY]);
  28575. +// rtl8180_try_wake_queue(dev,MANAGE_PRIORITY);
  28576. +}
  28577. +
  28578. +void rtl8187_beacon_stop(struct net_device *dev)
  28579. +{
  28580. + u8 msr, msrm, msr2;
  28581. + struct r8180_priv *priv = ieee80211_priv(dev);
  28582. + unsigned long flag;
  28583. + msr = read_nic_byte(dev, MSR);
  28584. + msrm = msr & MSR_LINK_MASK;
  28585. + msr2 = msr & ~MSR_LINK_MASK;
  28586. + if(NIC_8187B == priv->card_8187) {
  28587. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  28588. + priv->flag_beacon = false;
  28589. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  28590. + }
  28591. + if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
  28592. + (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
  28593. + write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
  28594. + write_nic_byte(dev, MSR, msr);
  28595. + }
  28596. +}
  28597. +
  28598. +
  28599. +void rtl8187_net_update(struct net_device *dev)
  28600. +{
  28601. +
  28602. + struct r8180_priv *priv = ieee80211_priv(dev);
  28603. + struct ieee80211_network *net;
  28604. + net = & priv->ieee80211->current_network;
  28605. +
  28606. +
  28607. + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
  28608. + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
  28609. +
  28610. + rtl8180_update_msr(dev);
  28611. +
  28612. + //rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  28613. + write_nic_word(dev, AtimWnd, 2);
  28614. + write_nic_word(dev, AtimtrItv, 100);
  28615. + write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval);
  28616. + //write_nic_word(dev, BcnIntTime, 100);
  28617. + write_nic_word(dev, BcnIntTime, 0x3FF);
  28618. +
  28619. +
  28620. +}
  28621. +
  28622. +void rtl8187_beacon_tx(struct net_device *dev)
  28623. +{
  28624. + struct r8180_priv *priv = ieee80211_priv(dev);
  28625. + struct sk_buff *skb;
  28626. + int i = 0;
  28627. + u8 cr;
  28628. + unsigned long flag;
  28629. + rtl8187_net_update(dev);
  28630. +
  28631. + if(NIC_8187B == priv->card_8187) {
  28632. + //Cause TSF timer of MAC reset to 0
  28633. + cr=read_nic_byte(dev,CMD);
  28634. + cr = cr | (1<<CMD_RST_SHIFT);
  28635. + write_nic_byte(dev,CMD,cr);
  28636. +
  28637. + //lzm mod 20081201
  28638. + //mdelay(200);
  28639. + mdelay(20);
  28640. +
  28641. + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
  28642. + DMESGW("Card reset timeout for ad-hoc!");
  28643. + else
  28644. + DMESG("Card successfully reset for ad-hoc");
  28645. +
  28646. + write_nic_byte(dev,CMD, (read_nic_byte(dev,CMD)|CR_RE|CR_TE));
  28647. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  28648. + priv->flag_beacon = true;
  28649. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  28650. +
  28651. + //rtl8187_rx_manage_initiate(dev);
  28652. + } else {
  28653. + printk(KERN_WARNING "get the beacon!\n");
  28654. + skb = ieee80211_get_beacon(priv->ieee80211);
  28655. + if(!skb){
  28656. + DMESG("not enought memory for allocating beacon");
  28657. + return;
  28658. + }
  28659. +
  28660. + write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
  28661. +
  28662. + i=0;
  28663. + //while(!read_nic_byte(dev,BQREQ & (1<<7)))
  28664. + while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
  28665. + {
  28666. + msleep_interruptible_rtl(HZ/2);
  28667. + if(i++ > 10){
  28668. + DMESGW("get stuck to wait HW beacon to be ready");
  28669. + return ;
  28670. + }
  28671. + }
  28672. + //tx
  28673. + rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY,
  28674. + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
  28675. + if(skb)
  28676. + dev_kfree_skb_any(skb);
  28677. + }
  28678. +}
  28679. +
  28680. +#if 0
  28681. +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  28682. +{
  28683. + struct net_device *dev = (struct net_device*)tx_urb->context;
  28684. + struct r8180_priv *priv = ieee80211_priv(dev);
  28685. +
  28686. + if(tx_urb->status == 0)
  28687. + priv->stats.txnpokint++;
  28688. + else
  28689. + priv->stats.txnperr++;
  28690. + kfree(tx_urb->transfer_buffer);
  28691. + usb_free_urb(tx_urb);
  28692. + atomic_dec(&priv->tx_np_pending);
  28693. + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
  28694. +}
  28695. +#endif
  28696. +inline u8 rtl8180_IsWirelessBMode(u16 rate)
  28697. +{
  28698. + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
  28699. + return 1;
  28700. + else return 0;
  28701. +}
  28702. +
  28703. +u16 N_DBPSOfRate(u16 DataRate);
  28704. +
  28705. +u16 ComputeTxTime(
  28706. + u16 FrameLength,
  28707. + u16 DataRate,
  28708. + u8 bManagementFrame,
  28709. + u8 bShortPreamble
  28710. + )
  28711. +{
  28712. + u16 FrameTime;
  28713. + u16 N_DBPS;
  28714. + u16 Ceiling;
  28715. +
  28716. + if( rtl8180_IsWirelessBMode(DataRate) )
  28717. + {
  28718. + if( bManagementFrame || !bShortPreamble || DataRate == 10 ){ // long preamble
  28719. + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
  28720. + }else{ // Short preamble
  28721. + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
  28722. + }
  28723. + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
  28724. + FrameTime ++;
  28725. + } else { //802.11g DSSS-OFDM PLCP length field calculation.
  28726. + N_DBPS = N_DBPSOfRate(DataRate);
  28727. + Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
  28728. + + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
  28729. + FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
  28730. + }
  28731. + return FrameTime;
  28732. +}
  28733. +
  28734. +u16 N_DBPSOfRate(u16 DataRate)
  28735. +{
  28736. + u16 N_DBPS = 24;
  28737. +
  28738. + switch(DataRate)
  28739. + {
  28740. + case 60:
  28741. + N_DBPS = 24;
  28742. + break;
  28743. +
  28744. + case 90:
  28745. + N_DBPS = 36;
  28746. + break;
  28747. +
  28748. + case 120:
  28749. + N_DBPS = 48;
  28750. + break;
  28751. +
  28752. + case 180:
  28753. + N_DBPS = 72;
  28754. + break;
  28755. +
  28756. + case 240:
  28757. + N_DBPS = 96;
  28758. + break;
  28759. +
  28760. + case 360:
  28761. + N_DBPS = 144;
  28762. + break;
  28763. +
  28764. + case 480:
  28765. + N_DBPS = 192;
  28766. + break;
  28767. +
  28768. + case 540:
  28769. + N_DBPS = 216;
  28770. + break;
  28771. +
  28772. + default:
  28773. + break;
  28774. + }
  28775. +
  28776. + return N_DBPS;
  28777. +}
  28778. +// NOte!!!
  28779. +// the rate filled in is the rtl_rate.
  28780. +// while the priv->ieee80211->basic_rate,used in the following code is ieee80211 rate.
  28781. +
  28782. +#ifdef JUST_FOR_87SEMESH
  28783. +#define ActionHeadLen 30
  28784. +#endif
  28785. +#define sCrcLng 4
  28786. +#define sAckCtsLng 112 // bits in ACK and CTS frames
  28787. +short rtl8180_tx(struct net_device *dev, u32* txbuf, int len, priority_t priority,
  28788. + short morefrag, short rate)
  28789. +{
  28790. + u32 *tx;
  28791. + int pend ;
  28792. + int status;
  28793. + struct urb *tx_urb;
  28794. + int urb_len;
  28795. + struct r8180_priv *priv = ieee80211_priv(dev);
  28796. + struct ieee80211_hdr_3addr_QOS *frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
  28797. + struct ieee80211_device *ieee;//added for descriptor
  28798. + u8 dest[ETH_ALEN];
  28799. +
  28800. + bool bUseShortPreamble = false;
  28801. + bool bCTSEnable = false;
  28802. + bool bRTSEnable = false;
  28803. + u16 Duration = 0;
  28804. + u16 RtsDur = 0;
  28805. + u16 ThisFrameTime = 0;
  28806. + u16 TxDescDuration = 0;
  28807. +
  28808. + ieee = priv->ieee80211;
  28809. +#if 0
  28810. +//{added by david for filter the packet listed in the filter table
  28811. +#ifdef _RTL8187_EXT_PATCH_
  28812. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
  28813. + {
  28814. + if(!ieee->ext_patch_ieee80211_acl_query(ieee, frag_hdr->addr1)) {
  28815. + return 0;
  28816. + }
  28817. + }
  28818. +#endif
  28819. +//}
  28820. +#endif
  28821. +
  28822. +#ifdef JUST_FOR_87SEMESH
  28823. +//#ifdef Lawrence_Mesh
  28824. + u8* meshtype = (u8*)txbuf;
  28825. + if(*meshtype == 0xA8)
  28826. + {
  28827. + //overflow??
  28828. + //memcpy(meshtype+ActionHeadLen+2,meshtype+ActionHeadLen,Len-ActionHeadLen);
  28829. + //memcpy(meshtype+ActionHeadLen,0,2);
  28830. + u8 actionframe[256];
  28831. + memset(actionframe,0,256);
  28832. + memcpy(actionframe,meshtype,ActionHeadLen);
  28833. + memcpy(actionframe+ActionHeadLen+2,meshtype+ActionHeadLen,len-ActionHeadLen);
  28834. + txbuf = (u32*)actionframe;
  28835. + len=len+2;
  28836. + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
  28837. + }
  28838. +#endif
  28839. +
  28840. + //pend = atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
  28841. + pend = atomic_read(&priv->tx_pending[priority]);
  28842. + /* we are locked here so the two atomic_read and inc are executed without interleaves */
  28843. + if( pend > MAX_TX_URB){
  28844. + if(NIC_8187 == priv->card_8187) {
  28845. + if(priority == NORM_PRIORITY)
  28846. + priv->stats.txnpdrop++;
  28847. + else
  28848. + priv->stats.txlpdrop++;
  28849. +
  28850. + } else {
  28851. + switch (priority) {
  28852. + case VO_PRIORITY:
  28853. + priv->stats.txvodrop++;
  28854. + break;
  28855. + case VI_PRIORITY:
  28856. + priv->stats.txvidrop++;
  28857. + break;
  28858. + case BE_PRIORITY:
  28859. + priv->stats.txbedrop++;
  28860. + break;
  28861. + case MANAGE_PRIORITY: //lzm for MANAGE_PRIORITY pending
  28862. + if(priv->commit == 0)
  28863. + {
  28864. + priv->commit = 1;
  28865. + printk(KERN_INFO "manage pkt pending will commit now....\n");
  28866. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  28867. + schedule_work(&priv->reset_wq);
  28868. +#else
  28869. + schedule_task(&priv->reset_wq);
  28870. +#endif
  28871. + }
  28872. + break;
  28873. + default://BK_PRIORITY
  28874. + priv->stats.txbkdrop++;
  28875. + break;
  28876. + }
  28877. + }
  28878. + //printk(KERN_INFO "tx_pending: %d > MAX_TX_URB\n", priority);
  28879. + return -1;
  28880. + }
  28881. +
  28882. + urb_len = len + ((NIC_8187 == priv->card_8187)?(4*3):(4*8));
  28883. + if((0 == (urb_len&63))||(0 == (urb_len&511))) {
  28884. + urb_len += 1;
  28885. + }
  28886. +
  28887. + tx = kmalloc(urb_len, GFP_ATOMIC);
  28888. + if(!tx) return -ENOMEM;
  28889. + memset(tx, 0, sizeof(u32) * 8);
  28890. +
  28891. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  28892. + tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
  28893. +#else
  28894. + tx_urb = usb_alloc_urb(0);
  28895. +#endif
  28896. +
  28897. + if(!tx_urb){
  28898. + kfree(tx);
  28899. + return -ENOMEM;
  28900. + }
  28901. +
  28902. + // Check multicast/broadcast
  28903. + if (ieee->iw_mode == IW_MODE_INFRA) {
  28904. + /* To DS: Addr1 = BSSID, Addr2 = SA,
  28905. + Addr3 = DA */
  28906. + //memcpy(&dest, frag_hdr->addr3, ETH_ALEN);
  28907. + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
  28908. + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
  28909. + /* not From/To DS: Addr1 = DA, Addr2 = SA,
  28910. + Addr3 = BSSID */
  28911. + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
  28912. + }
  28913. +
  28914. + if (is_multicast_ether_addr(dest) ||is_broadcast_ether_addr(dest))
  28915. + {
  28916. + Duration = 0;
  28917. + RtsDur = 0;
  28918. + bRTSEnable = false;
  28919. + bCTSEnable = false;
  28920. +
  28921. + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
  28922. + TxDescDuration = ThisFrameTime;
  28923. + } else {// Unicast packet
  28924. + //u8 AckRate;
  28925. + u16 AckTime;
  28926. +
  28927. + // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
  28928. + //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
  28929. + // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
  28930. + //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
  28931. + //For simplicity, just use the 1M basic rate
  28932. + AckTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
  28933. + //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
  28934. +
  28935. + if ( ((len + sCrcLng) > priv->rts) && priv->rts ){ // RTS/CTS.
  28936. + u16 RtsTime, CtsTime;
  28937. + //u16 CtsRate;
  28938. + bRTSEnable = true;
  28939. + bCTSEnable = false;
  28940. +
  28941. + // Rate and time required for RTS.
  28942. + RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, false, false);
  28943. + // Rate and time required for CTS.
  28944. + CtsTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
  28945. +
  28946. + // Figure out time required to transmit this frame.
  28947. + ThisFrameTime = ComputeTxTime(len + sCrcLng,
  28948. + rtl8180_rate2rate(rate),
  28949. + false,
  28950. + bUseShortPreamble);
  28951. +
  28952. + // RTS-CTS-ThisFrame-ACK.
  28953. + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
  28954. +
  28955. + TxDescDuration = RtsTime + RtsDur;
  28956. + }else {// Normal case.
  28957. + bCTSEnable = false;
  28958. + bRTSEnable = false;
  28959. + RtsDur = 0;
  28960. +
  28961. + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
  28962. + TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
  28963. + }
  28964. +
  28965. + if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
  28966. + // ThisFrame-ACK.
  28967. + Duration = aSifsTime + AckTime;
  28968. + } else { // One or more fragments remained.
  28969. + u16 NextFragTime;
  28970. + NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
  28971. + rtl8180_rate2rate(rate),
  28972. + false, bUseShortPreamble );
  28973. +
  28974. + //ThisFrag-ACk-NextFrag-ACK.
  28975. + Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
  28976. + }
  28977. +
  28978. + } // End of Unicast packet
  28979. +
  28980. +
  28981. + //fill the tx desriptor
  28982. + tx[0] |= len & 0xfff;
  28983. +#ifdef JOHN_HWSEC
  28984. + if(frag_hdr->frame_ctl & IEEE80211_FCTL_WEP ){
  28985. + tx[0] &= 0xffff7fff;
  28986. + //group key may be different from pairwise key
  28987. + if( frag_hdr->addr1[0]==0xff &&
  28988. + frag_hdr->addr1[0]==0xff &&
  28989. + frag_hdr->addr1[0]==0xff &&
  28990. + frag_hdr->addr1[0]==0xff &&
  28991. + frag_hdr->addr1[0]==0xff &&
  28992. + frag_hdr->addr1[0]==0xff ){
  28993. + if(ieee->broadcast_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//ccmp
  28994. + else tx[7] |= 0x1;//wep and tkip
  28995. + }
  28996. + else {
  28997. + if(ieee->pairwise_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//CCMP
  28998. + else tx[7] |= 0x1;//WEP and TKIP
  28999. + }
  29000. + }
  29001. + else
  29002. +#endif /*JOHN_HWSEC*/
  29003. +
  29004. + tx[0] |= (1<<15);
  29005. +
  29006. + if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE){
  29007. + if (priv->plcp_preamble_mode==1 && rate!=0) { // short mode now, not long!
  29008. + tx[0] |= (1<<16);
  29009. + } // enable short preamble mode.
  29010. + }
  29011. +
  29012. + if(morefrag) tx[0] |= (1<<17);
  29013. + //printk(KERN_WARNING "rtl_rate = %d\n", rate);
  29014. + tx[0] |= (rate << 24); //TX rate
  29015. + frag_hdr->duration_id = Duration;
  29016. +
  29017. + if(NIC_8187B == priv->card_8187) {
  29018. + if(bCTSEnable) {
  29019. + tx[0] |= (1<<18);
  29020. + }
  29021. +
  29022. + if(bRTSEnable) //rts enable
  29023. + {
  29024. + tx[0] |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
  29025. + tx[0] |= (1<<23);//rts enable
  29026. + tx[1] |= RtsDur;//RTS Duration
  29027. + }
  29028. + tx[3] |= (TxDescDuration<<16); //DURATION
  29029. + if( WLAN_FC_GET_STYPE(le16_to_cpu(frag_hdr->frame_ctl)) == IEEE80211_STYPE_PROBE_RESP )
  29030. + tx[5] |= (1<<8);//(priv->retry_data<<8); //retry lim ;
  29031. + else
  29032. + tx[5] |= (11<<8);//(priv->retry_data<<8); //retry lim ;
  29033. +
  29034. + //frag_hdr->duration_id = Duration;
  29035. + memcpy(tx+8,txbuf,len);
  29036. + } else {
  29037. + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
  29038. + tx[0] |= (1<<23); //enalbe RTS function
  29039. + tx[1] |= RtsDur; //Need to edit here! ----hikaru
  29040. + }
  29041. + else {
  29042. + tx[1]=0;
  29043. + }
  29044. + tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */
  29045. +
  29046. + tx[2] = 3; // CW min
  29047. + tx[2] |= (7<<4); //CW max
  29048. + tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim
  29049. +
  29050. + // printk("%x\n%x\n",tx[0],tx[1]);
  29051. +
  29052. +#ifdef DUMP_TX
  29053. + int i;
  29054. + printk("<Tx pkt>--rate %x---",rate);
  29055. + for (i = 0; i < (len + 3); i++)
  29056. + printk("%2x", ((u8*)tx)[i]);
  29057. + printk("---------------\n");
  29058. +#endif
  29059. + memcpy(tx+3,txbuf,len);
  29060. + }
  29061. +
  29062. +#ifdef JOHN_DUMP_TXDESC
  29063. + int i;
  29064. + printk("<Tx descriptor>--rate %x---",rate);
  29065. + for (i = 0; i < 8; i++)
  29066. + printk("%8x ", tx[i]);
  29067. + printk("\n");
  29068. +#endif
  29069. +#ifdef JOHN_DUMP_TXPKT
  29070. + {
  29071. + int j;
  29072. + printk("\n---------------------------------------------------------------------\n");
  29073. + printk("<Tx packet>--rate %x--urb_len in decimal %d",rate, urb_len);
  29074. + for (j = 32; j < (urb_len); j++){
  29075. + if( ( (j-32)%24 )==0 ) printk("\n");
  29076. + printk("%2x ", ((u8*)tx)[j]);
  29077. + }
  29078. + printk("\n---------------------------------------------------------------------\n");
  29079. +
  29080. + }
  29081. +#endif
  29082. +
  29083. + if(NIC_8187 == priv->card_8187) {
  29084. + usb_fill_bulk_urb(tx_urb,priv->udev,
  29085. + usb_sndbulkpipe(priv->udev,priority), tx,
  29086. + urb_len, (priority == LOW_PRIORITY)?rtl8187_lptx_isr:rtl8187_nptx_isr, dev);
  29087. +
  29088. + } else {
  29089. + //printk(KERN_WARNING "Tx packet use by submit urb!\n");
  29090. + /* FIXME check what EP is for low/norm PRI */
  29091. + usb_fill_bulk_urb(tx_urb,priv->udev,
  29092. + usb_sndbulkpipe(priv->udev,priority), tx,
  29093. + urb_len, TXISR_SELECT(priority), dev);
  29094. + }
  29095. +
  29096. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  29097. + status = usb_submit_urb(tx_urb, GFP_ATOMIC);
  29098. +#else
  29099. + status = usb_submit_urb(tx_urb);
  29100. +#endif
  29101. +
  29102. + if (!status){
  29103. + //atomic_inc((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
  29104. + atomic_inc(&priv->tx_pending[priority]);
  29105. + dev->trans_start = jiffies;
  29106. + //printk("=====> tx_pending[%d]=%d\n", priority, atomic_read(&priv->tx_pending[priority]));
  29107. + return 0;
  29108. + }else{
  29109. + DMESGE("Error TX URB %d, error pending %d",
  29110. + //atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending),
  29111. + atomic_read(&priv->tx_pending[priority]),
  29112. + status);
  29113. + return -1;
  29114. + }
  29115. +}
  29116. +
  29117. + short rtl8187_usb_initendpoints(struct net_device *dev)
  29118. +{
  29119. + struct r8180_priv *priv = ieee80211_priv(dev);
  29120. +
  29121. + priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
  29122. +
  29123. + memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
  29124. +
  29125. +#ifdef JACKSON_NEW_RX
  29126. + priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
  29127. + if (priv->pp_rxskb == NULL)
  29128. + goto destroy;
  29129. +
  29130. + memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
  29131. +#endif
  29132. +#ifdef THOMAS_BEACON
  29133. + {
  29134. + int align;
  29135. + unsigned long oldaddr,newaddr; //lzm mod for 64bit cpu crash 20081107
  29136. + priv->rx_urb[MAX_RX_URB] = usb_alloc_urb(0, GFP_KERNEL);
  29137. + priv->oldaddr = kmalloc(16, GFP_KERNEL);
  29138. + oldaddr = (unsigned long)priv->oldaddr;
  29139. + align = oldaddr&3;
  29140. + if(align != 0 ){
  29141. + newaddr = oldaddr + 4 - align;
  29142. + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16-4+align;
  29143. + }
  29144. + else{
  29145. + newaddr = oldaddr;
  29146. + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16;
  29147. + }
  29148. + priv->rx_urb[MAX_RX_URB]->transfer_buffer = (u32*)newaddr;
  29149. + }
  29150. +#endif
  29151. +
  29152. +
  29153. + goto _middle;
  29154. +
  29155. +
  29156. +destroy:
  29157. +
  29158. +#ifdef JACKSON_NEW_RX
  29159. + if (priv->pp_rxskb) {
  29160. + kfree(priv->pp_rxskb);
  29161. + priv->pp_rxskb = NULL;
  29162. +
  29163. + }
  29164. +#endif
  29165. + if (priv->rx_urb) {
  29166. + kfree(priv->rx_urb);
  29167. + }
  29168. + priv->rx_urb = NULL;
  29169. +
  29170. + DMESGE("Endpoint Alloc Failure");
  29171. + return -ENOMEM;
  29172. +
  29173. +
  29174. +_middle:
  29175. +
  29176. + return 0;
  29177. +
  29178. +}
  29179. +#ifdef THOMAS_BEACON
  29180. +void rtl8187_usb_deleteendpoints(struct net_device *dev)
  29181. +{
  29182. + int i;
  29183. + struct r8180_priv *priv = ieee80211_priv(dev);
  29184. +
  29185. + if( in_interrupt() )
  29186. + printk(KERN_ALERT " %ld in interrupt \n",in_interrupt() );
  29187. + if(priv->rx_urb){
  29188. + for(i=0;i<(MAX_RX_URB+1);i++){
  29189. + if(priv->rx_urb[i]) {
  29190. + usb_kill_urb(priv->rx_urb[i]);
  29191. + usb_free_urb(priv->rx_urb[i]);
  29192. + }
  29193. + }
  29194. + kfree(priv->rx_urb);
  29195. + priv->rx_urb = NULL;
  29196. + }
  29197. + if(priv->oldaddr){
  29198. + kfree(priv->oldaddr);
  29199. + priv->oldaddr = NULL;
  29200. + }
  29201. + if (priv->pp_rxskb) {
  29202. + kfree(priv->pp_rxskb);
  29203. + priv->pp_rxskb = 0;
  29204. + }
  29205. +}
  29206. +#endif
  29207. +
  29208. +void rtl8187_set_rate(struct net_device *dev)
  29209. +{
  29210. + int i;
  29211. + u16 word;
  29212. + int basic_rate,min_rr_rate,max_rr_rate;
  29213. +
  29214. + //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
  29215. + // priv->ieee80211->state == IEEE80211_LINKED){
  29216. + basic_rate = ieeerate2rtlrate(240);
  29217. + min_rr_rate = ieeerate2rtlrate(60);
  29218. + max_rr_rate = ieeerate2rtlrate(240);
  29219. +
  29220. + /*
  29221. + }else{
  29222. + basic_rate = ieeerate2rtlrate(20);
  29223. + min_rr_rate = ieeerate2rtlrate(10);
  29224. + max_rr_rate = ieeerate2rtlrate(110);
  29225. + }
  29226. + */
  29227. +
  29228. + write_nic_byte(dev, RESP_RATE,
  29229. + max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
  29230. +
  29231. + //word = read_nic_word(dev, BRSR);
  29232. + word = read_nic_word(dev, BRSR_8187);
  29233. + word &= ~BRSR_MBR_8185;
  29234. +
  29235. +
  29236. + for(i=0;i<=basic_rate;i++)
  29237. + word |= (1<<i);
  29238. +
  29239. + //write_nic_word(dev, BRSR, word);
  29240. + write_nic_word(dev, BRSR_8187, word);
  29241. +}
  29242. +
  29243. +
  29244. +void rtl8187_link_change(struct net_device *dev)
  29245. +{
  29246. + struct r8180_priv *priv = ieee80211_priv(dev);
  29247. + //write_nic_word(dev, BintrItv, net->beacon_interval);
  29248. + rtl8187_net_update(dev);
  29249. + /*update timing params*/
  29250. + rtl8180_set_chan(dev, priv->chan);
  29251. + rtl8187_set_rxconf(dev);
  29252. +}
  29253. +
  29254. +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
  29255. +void rtl8180_wmm_param_update(struct work_struct* work)
  29256. +{
  29257. + struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
  29258. + struct net_device *dev = ieee->dev;
  29259. + struct r8180_priv *priv = ieee80211_priv(dev);
  29260. +#else
  29261. +void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
  29262. +{
  29263. + struct net_device *dev = ieee->dev;
  29264. + struct r8180_priv *priv = ieee80211_priv(dev);
  29265. +#endif
  29266. + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
  29267. + u8 mode = ieee->current_network.mode;
  29268. + AC_CODING eACI;
  29269. + AC_PARAM AcParam;
  29270. + PAC_PARAM pAcParam;
  29271. + u8 i;
  29272. +
  29273. + //8187 need not to update wmm param, added by David, 2006.9.8
  29274. + if(NIC_8187 == priv->card_8187) {
  29275. + return;
  29276. + }
  29277. +
  29278. + if(!ieee->current_network.QoS_Enable)
  29279. + {
  29280. + //legacy ac_xx_param update
  29281. +
  29282. + AcParam.longData = 0;
  29283. + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
  29284. + AcParam.f.AciAifsn.f.ACM = 0;
  29285. + AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
  29286. + AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
  29287. + AcParam.f.TXOPLimit = 0;
  29288. + for(eACI = 0; eACI < AC_MAX; eACI++)
  29289. + {
  29290. + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
  29291. + {
  29292. + u8 u1bAIFS;
  29293. + u32 u4bAcParam;
  29294. +
  29295. +
  29296. + pAcParam = (PAC_PARAM)(&AcParam);
  29297. + // Retrive paramters to udpate.
  29298. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
  29299. + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  29300. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  29301. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  29302. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  29303. +
  29304. + switch(eACI)
  29305. + {
  29306. + case AC1_BK:
  29307. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  29308. + break;
  29309. +
  29310. + case AC0_BE:
  29311. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  29312. + break;
  29313. +
  29314. + case AC2_VI:
  29315. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  29316. + break;
  29317. +
  29318. + case AC3_VO:
  29319. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  29320. + break;
  29321. +
  29322. + default:
  29323. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  29324. + break;
  29325. + }
  29326. + }
  29327. + }
  29328. +
  29329. + return;
  29330. + }
  29331. + //
  29332. + for(i = 0; i < AC_MAX; i++){
  29333. + pAcParam = (AC_PARAM * )ac_param;
  29334. + {
  29335. + AC_CODING eACI;
  29336. + u8 u1bAIFS;
  29337. + u32 u4bAcParam;
  29338. +
  29339. + // Retrive paramters to udpate.
  29340. + eACI = pAcParam->f.AciAifsn.f.ACI;
  29341. + //Mode G/A: slotTimeTimer = 9; Mode B: 20
  29342. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
  29343. + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  29344. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  29345. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  29346. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  29347. +
  29348. + switch(eACI)
  29349. + {
  29350. + case AC1_BK:
  29351. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  29352. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BK_PARAM,read_nic_dword(dev, AC_BK_PARAM));
  29353. + break;
  29354. +
  29355. + case AC0_BE:
  29356. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  29357. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BE_PARAM,read_nic_dword(dev, AC_BE_PARAM));
  29358. + break;
  29359. +
  29360. + case AC2_VI:
  29361. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  29362. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VI_PARAM,read_nic_dword(dev, AC_VI_PARAM));
  29363. + break;
  29364. +
  29365. + case AC3_VO:
  29366. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  29367. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VO_PARAM,read_nic_dword(dev, AC_VO_PARAM));
  29368. + break;
  29369. +
  29370. + default:
  29371. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  29372. + break;
  29373. + }
  29374. + }
  29375. + ac_param += (sizeof(AC_PARAM));
  29376. + }
  29377. +}
  29378. +
  29379. +int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate )
  29380. +{
  29381. + u8 rate_len;
  29382. + u8 rate_ex_len;
  29383. + u8 RateMask = 0x7F;
  29384. + u8 idx;
  29385. + unsigned short Found = 0;
  29386. + u8 NaiveTxRate = TxRate&RateMask;
  29387. +
  29388. + rate_len = priv->ieee80211->current_network.rates_len;
  29389. + rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
  29390. +
  29391. + for( idx=0; idx< rate_len; idx++ ){
  29392. + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) {
  29393. + Found = 1;
  29394. + goto found_rate;
  29395. + }
  29396. + }
  29397. +
  29398. + for( idx=0; idx< rate_ex_len; idx++ ) {
  29399. + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) {
  29400. + Found = 1;
  29401. + goto found_rate;
  29402. + }
  29403. + }
  29404. +
  29405. + return Found;
  29406. + found_rate:
  29407. + return Found;
  29408. +}
  29409. +//
  29410. +// Description:
  29411. +// Get the Tx rate one degree up form the input rate in the supported rates.
  29412. +// Return the upgrade rate if it is successed, otherwise return the input rate.
  29413. +// By Bruce, 2007-06-05.
  29414. +//
  29415. +u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
  29416. +{
  29417. + struct r8180_priv *priv = ieee80211_priv(dev);
  29418. + u8 UpRate;
  29419. +
  29420. + // Upgrade 1 degree.
  29421. + switch(rate)
  29422. + {
  29423. + case 108: // Up to 54Mbps.
  29424. + UpRate = 108;
  29425. + break;
  29426. +
  29427. + case 96: // Up to 54Mbps.
  29428. + UpRate = 108;
  29429. + break;
  29430. +
  29431. + case 72: // Up to 48Mbps.
  29432. + UpRate = 96;
  29433. + break;
  29434. +
  29435. + case 48: // Up to 36Mbps.
  29436. + UpRate = 72;
  29437. + break;
  29438. +
  29439. + case 36: // Up to 24Mbps.
  29440. + UpRate = 48;
  29441. + break;
  29442. +
  29443. + case 22: // Up to 18Mbps.
  29444. + UpRate = 36;
  29445. + break;
  29446. +
  29447. + case 11: // Up to 11Mbps.
  29448. + UpRate = 22;
  29449. + break;
  29450. +
  29451. + case 4: // Up to 5.5Mbps.
  29452. + UpRate = 11;
  29453. + break;
  29454. +
  29455. + case 2: // Up to 2Mbps.
  29456. + UpRate = 4;
  29457. + break;
  29458. +
  29459. + default:
  29460. + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
  29461. + return rate;
  29462. + }
  29463. + // Check if the rate is valid.
  29464. + if(IncludedInSupportedRates(priv, UpRate))
  29465. + {
  29466. +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
  29467. + return UpRate;
  29468. + }
  29469. + else
  29470. + {
  29471. + printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
  29472. + return rate;
  29473. + }
  29474. + return rate;
  29475. +}
  29476. +//
  29477. +// Description:
  29478. +// Get the Tx rate one degree down form the input rate in the supported rates.
  29479. +// Return the degrade rate if it is successed, otherwise return the input rate.
  29480. +// By Bruce, 2007-06-05.
  29481. +//
  29482. +u8 GetDegradeTxRate( struct net_device *dev, u8 rate)
  29483. +{
  29484. + struct r8180_priv *priv = ieee80211_priv(dev);
  29485. + u8 DownRate;
  29486. +
  29487. + // Upgrade 1 degree.
  29488. + switch(rate)
  29489. + {
  29490. + case 108: // Down to 48Mbps.
  29491. + DownRate = 96;
  29492. + break;
  29493. +
  29494. + case 96: // Down to 36Mbps.
  29495. + DownRate = 72;
  29496. + break;
  29497. +
  29498. + case 72: // Down to 24Mbps.
  29499. + DownRate = 48;
  29500. + break;
  29501. +
  29502. + case 48: // Down to 18Mbps.
  29503. + DownRate = 36;
  29504. + break;
  29505. +
  29506. + case 36: // Down to 11Mbps.
  29507. + DownRate = 22;
  29508. + break;
  29509. +
  29510. + case 22: // Down to 5.5Mbps.
  29511. + DownRate = 11;
  29512. + break;
  29513. +
  29514. + case 11: // Down to 2Mbps.
  29515. + DownRate = 4;
  29516. + break;
  29517. +
  29518. + case 4: // Down to 1Mbps.
  29519. + DownRate = 2;
  29520. + break;
  29521. +
  29522. + case 2: // Down to 1Mbps.
  29523. + DownRate = 2;
  29524. + break;
  29525. +
  29526. + default:
  29527. + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
  29528. + return rate;
  29529. + }
  29530. + // Check if the rate is valid.
  29531. + if(IncludedInSupportedRates(priv, DownRate)){
  29532. +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
  29533. + return DownRate;
  29534. + }else{
  29535. + printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
  29536. + return rate;
  29537. + }
  29538. + return rate;
  29539. +}
  29540. +
  29541. +//
  29542. +// Helper function to determine if specified data rate is
  29543. +// CCK rate.
  29544. +// 2005.01.25, by rcnjko.
  29545. +//
  29546. +bool MgntIsCckRate(u16 rate )
  29547. +{
  29548. + bool bReturn = false;
  29549. +
  29550. + if((rate <= 22) && (rate != 12) && (rate != 18)){
  29551. + bReturn = true;
  29552. + }
  29553. +
  29554. + return bReturn;
  29555. +}
  29556. +//by amy for rate adaptive
  29557. +//
  29558. +// Description:
  29559. +// Core logic to adjust Tx data rate in STA mode according to
  29560. +// OFDM retry count ratio.
  29561. +//
  29562. +// Note:
  29563. +// RTL8187 : pHalData->CurrRetryCnt = TallyCnt
  29564. +// RTL8187B : pHalData->CurrRetryCnt = PktRetryCnt in TxClosedCommand
  29565. +//
  29566. +void sta_rateadaptive8187B(struct net_device *dev)
  29567. +{
  29568. + struct r8180_priv *priv = ieee80211_priv(dev);
  29569. + unsigned long CurrTxokCnt;
  29570. + u16 CurrRetryCnt;
  29571. + u16 CurrRetryRate;
  29572. + unsigned long CurrRxokCnt;
  29573. + bool bTryUp = false;
  29574. + bool bTryDown = false;
  29575. + u8 TryUpTh = 1;
  29576. + u8 TryDownTh = 2;
  29577. + u32 TxThroughput;
  29578. + long CurrSignalStrength;
  29579. + bool bUpdateInitialGain = false;
  29580. + CurrRetryCnt = priv->CurrRetryCnt;
  29581. + CurrTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
  29582. + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint)- priv->LastTxokCnt;
  29583. + CurrRxokCnt = priv->stats.rxok - priv->LastRxokCnt;
  29584. + CurrSignalStrength = priv->RecvSignalPower;
  29585. + TxThroughput = (u32)(priv->txokbytestotal - priv->LastTxOKBytes);
  29586. + priv->LastTxOKBytes = priv->txokbytestotal;
  29587. + priv->CurrentOperaRate = priv->ieee80211->rate / 5;
  29588. + //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
  29589. +
  29590. +#if 1
  29591. + //2 Compute retry ratio.
  29592. + if (CurrTxokCnt>0)
  29593. + {
  29594. + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
  29595. + }
  29596. + else
  29597. + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
  29598. + CurrRetryRate = (u16)(CurrRetryCnt*100/1);
  29599. + }
  29600. +#endif
  29601. +
  29602. +
  29603. + //printk("\n(1) priv->LastRetryRate: %d \n",priv->LastRetryRate);
  29604. + //printk("(2) CurrRetryCnt = %d \n", CurrRetryCnt);
  29605. + //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
  29606. + //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
  29607. + //printk("(5) SignalStrength = %d \n",priv->RecvSignalPower);
  29608. +
  29609. + priv->LastRetryCnt = priv->CurrRetryCnt;
  29610. + priv->LastTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
  29611. + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint);
  29612. + priv->LastRxokCnt = priv->stats.rxok;
  29613. + priv->CurrRetryCnt = 0;
  29614. + //2No Tx packets, return to init_rate or not?
  29615. + if (CurrRetryRate==0 && CurrTxokCnt == 0)
  29616. + {
  29617. + //
  29618. + // 2007.04.09, by Roger. after 4.5 seconds in this condition, we try to raise rate.
  29619. + //
  29620. + priv->TryupingCountNoData++;
  29621. +
  29622. + //printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
  29623. + //printk("(6) priv->CurrentOperaRate =%d\n", priv->CurrentOperaRate);
  29624. +
  29625. + if (priv->TryupingCountNoData>15)
  29626. + {
  29627. + priv->TryupingCountNoData = 0;
  29628. + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
  29629. + // Reset Fail Record
  29630. + priv->LastFailTxRate = 0;
  29631. + priv->LastFailTxRateSS = -200;
  29632. + priv->FailTxRateCount = 0;
  29633. + }
  29634. + goto SetInitialGain;
  29635. + }
  29636. + else
  29637. + {
  29638. + priv->TryupingCountNoData=0; //Reset trying up times.
  29639. + }
  29640. +
  29641. + //
  29642. + // For Netgear case, I comment out the following signal strength estimation,
  29643. + // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
  29644. + // 2007.04.09, by Roger.
  29645. + //
  29646. +#if 1
  29647. + // If sample is not enough, we use signalstrength.
  29648. + if ( CurrTxokCnt<10|| CurrRetryCnt<10)
  29649. + {
  29650. + //printk("Sample is not enough, we use signalstrength for rate adaptive\n");
  29651. + //After 3 sec, and trying up.
  29652. + priv->TryupingCountNoData++;
  29653. + if (priv->TryupingCountNoData>10)
  29654. + {
  29655. + //printk("Sample is not enough and After 3 sec try up\n");
  29656. + priv->TryupingCountNoData=0;
  29657. +
  29658. + //
  29659. + // Added by Roger, 2007.01.04.
  29660. + // Signal strength plus 3 for air link.
  29661. + //
  29662. +
  29663. + if ( CurrSignalStrength>-68 )//&& IncludedInSupportedRates(Adapter, 108) )
  29664. + {
  29665. + priv->ieee80211->rate = 540;
  29666. + //pMgntInfo->CurrentOperaRate = 108;
  29667. + }
  29668. + else if (CurrSignalStrength>-70)// && IncludedInSupportedRates(Adapter, 96) )
  29669. + {
  29670. + priv->ieee80211->rate = 480;
  29671. + //pMgntInfo->CurrentOperaRate = 96;
  29672. + }
  29673. + else if (CurrSignalStrength>-73)// && IncludedInSupportedRates(Adapter, 72) )
  29674. + {
  29675. + priv->ieee80211->rate = 360;
  29676. + //pMgntInfo->CurrentOperaRate = 72;
  29677. + }
  29678. + else if (CurrSignalStrength>-79)// && IncludedInSupportedRates(Adapter, 48) )
  29679. + {
  29680. + priv->ieee80211->rate = 240;
  29681. + //pMgntInfo->CurrentOperaRate = 48;
  29682. + }
  29683. + else if (CurrSignalStrength>-81)// && IncludedInSupportedRates(Adapter, 36) )
  29684. + {
  29685. + priv->ieee80211->rate = 180;
  29686. + //pMgntInfo->CurrentOperaRate = 36;
  29687. + }
  29688. + else if (CurrSignalStrength>-83)// && IncludedInSupportedRates(Adapter, 22) )
  29689. + {
  29690. + priv->ieee80211->rate = 110;
  29691. + //pMgntInfo->CurrentOperaRate = 22;
  29692. + }
  29693. + else if (CurrSignalStrength>-85)// && IncludedInSupportedRates(Adapter, 11) )
  29694. + {
  29695. + priv->ieee80211->rate = 55;
  29696. + //pMgntInfo->CurrentOperaRate = 11;
  29697. + }
  29698. + else if (CurrSignalStrength>-89)// && IncludedInSupportedRates(Adapter, 4) )
  29699. + {
  29700. + priv->ieee80211->rate = 20;
  29701. + //pMgntInfo->CurrentOperaRate = 4;
  29702. + }
  29703. +
  29704. +
  29705. + }
  29706. +
  29707. + //2004.12.23 skip record for 0
  29708. + //pHalData->LastRetryRate = CurrRetryRate;
  29709. + //printk("pMgntInfo->CurrentOperaRate =%d\n",priv->ieee80211->rate);
  29710. + return;
  29711. + }
  29712. + else
  29713. + {
  29714. + priv->TryupingCountNoData=0;
  29715. + }
  29716. +#endif
  29717. + //
  29718. + // Restructure rate adaptive as the following main stages:
  29719. + // (1) Add retry threshold in 54M upgrading condition with signal strength.
  29720. + // (2) Add the mechanism to degrade to CCK rate according to signal strength
  29721. + // and retry rate.
  29722. + // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
  29723. + // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
  29724. + // (4) Add the mehanism of trying to upgrade tx rate.
  29725. + // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
  29726. + // By Bruce, 2007-06-05.
  29727. + //
  29728. + //
  29729. +
  29730. + // 11Mbps or 36Mbps
  29731. + // Check more times in these rate(key rates).
  29732. + //
  29733. + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
  29734. + {
  29735. + TryUpTh += 9;
  29736. + }
  29737. + //
  29738. + // Let these rates down more difficult.
  29739. + //
  29740. + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
  29741. + {
  29742. + TryDownTh += 1;
  29743. + }
  29744. +
  29745. + //1 Adjust Rate.
  29746. + if (priv->bTryuping == true)
  29747. + {
  29748. + //2 For Test Upgrading mechanism
  29749. + // Note:
  29750. + // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
  29751. + // thus the low data rate does not improve the performance.
  29752. + // We randomly upgrade the data rate and check if the retry rate is improved.
  29753. +
  29754. + // Upgrading rate did not improve the retry rate, fallback to the original rate.
  29755. + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
  29756. + {
  29757. + //Not necessary raising rate, fall back rate.
  29758. + bTryDown = true;
  29759. + //printk("Not necessary raising rate, fall back rate....\n");
  29760. + //printk("(7) priv->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
  29761. + // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
  29762. + }
  29763. + else
  29764. + {
  29765. + priv->bTryuping = false;
  29766. + }
  29767. + }
  29768. + else if (CurrSignalStrength > -51 && (CurrRetryRate < 100))
  29769. + {
  29770. + //2For High Power
  29771. + //
  29772. + // Added by Roger, 2007.04.09.
  29773. + // Return to highest data rate, if signal strength is good enough.
  29774. + // SignalStrength threshold(-50dbm) is for RTL8186.
  29775. + // Revise SignalStrength threshold to -51dbm.
  29776. + //
  29777. + // Also need to check retry rate for safety, by Bruce, 2007-06-05.
  29778. + if(priv->CurrentOperaRate != 108)
  29779. + {
  29780. + bTryUp = true;
  29781. + // Upgrade Tx Rate directly.
  29782. + priv->TryupingCount += TryUpTh;
  29783. + //printk("StaRateAdaptive87B: Power(%d) is high enough!!. \n", CurrSignalStrength);
  29784. + }
  29785. + }
  29786. + // To avoid unstable rate jumping, comment out this condition, by Bruce, 2007-06-26.
  29787. + /*
  29788. + else if(CurrSignalStrength < -86 && CurrRetryRate >= 100)
  29789. + {
  29790. + //2 For Low Power
  29791. + //
  29792. + // Low signal strength and high current tx rate may cause Tx rate to degrade too slowly.
  29793. + // Update Tx rate to CCK rate directly.
  29794. + // By Bruce, 2007-06-05.
  29795. + //
  29796. + if(!MgntIsCckRate(pMgntInfo->CurrentOperaRate))
  29797. + {
  29798. + if(CurrSignalStrength > -88 && IncludedInSupportedRates(Adapter, 22)) // 11M
  29799. + pMgntInfo->CurrentOperaRate = 22;
  29800. + else if(CurrSignalStrength > -90 && IncludedInSupportedRates(Adapter, 11)) // 5.5M
  29801. + pMgntInfo->CurrentOperaRate = 11;
  29802. + else if(CurrSignalStrength > -92 && IncludedInSupportedRates(Adapter, 4)) // 2M
  29803. + pMgntInfo->CurrentOperaRate = 4;
  29804. + else // 1M
  29805. + pMgntInfo->CurrentOperaRate = 2;
  29806. + }
  29807. + else if(CurrRetryRate >= 200)
  29808. + {
  29809. + pMgntInfo->CurrentOperaRate = GetDegradeTxRate(Adapter, pMgntInfo->CurrentOperaRate);
  29810. + }
  29811. + RT_TRACE(COMP_RATE, DBG_LOUD, ("RA: Low Power(%d), or High Retry Rate(%d), set rate to CCK rate (%d). \n",
  29812. + CurrSignalStrength, CurrRetryRate, pMgntInfo->CurrentOperaRate));
  29813. + bUpdateInitialGain = TRUE;
  29814. + // Reset Fail Record
  29815. + pHalData->LastFailTxRate = 0;
  29816. + pHalData->LastFailTxRateSS = -200;
  29817. + pHalData->FailTxRateCount = 0;
  29818. + goto SetInitialGain;
  29819. + }
  29820. + */
  29821. + else if(CurrTxokCnt< 100 && CurrRetryRate >= 600)
  29822. + {
  29823. + //2 For Serious Retry
  29824. + //
  29825. + // Traffic is not busy but our Tx retry is serious.
  29826. + //
  29827. + bTryDown = true;
  29828. + // Let Rate Mechanism to degrade tx rate directly.
  29829. + priv->TryDownCountLowData += TryDownTh;
  29830. + //printk("RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
  29831. + }
  29832. + else if ( priv->CurrentOperaRate == 108 )
  29833. + {
  29834. + //2For 54Mbps
  29835. + // if ( (CurrRetryRate>38)&&(pHalData->LastRetryRate>35))
  29836. + if ( (CurrRetryRate>33)&&(priv->LastRetryRate>32))
  29837. + {
  29838. + //(30,25) for cable link threshold. (38,35) for air link.
  29839. + //Down to rate 48Mbps.
  29840. + bTryDown = true;
  29841. + }
  29842. + }
  29843. + else if ( priv->CurrentOperaRate == 96 )
  29844. + {
  29845. + //2For 48Mbps
  29846. + // if ( ((CurrRetryRate>73) && (pHalData->LastRetryRate>72)) && IncludedInSupportedRates(Adapter, 72) )
  29847. + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
  29848. + {
  29849. + //(73, 72) for temp used.
  29850. + //(25, 23) for cable link, (60,59) for air link.
  29851. + //CurrRetryRate plus 25 and 26 respectively for air link.
  29852. + //Down to rate 36Mbps.
  29853. + bTryDown = true;
  29854. + }
  29855. + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
  29856. + {
  29857. + bTryUp = true;
  29858. + }
  29859. + }
  29860. + else if ( priv->CurrentOperaRate == 72 )
  29861. + {
  29862. + //2For 36Mbps
  29863. + //if ( (CurrRetryRate>97) && (pHalData->LastRetryRate>97))
  29864. + if ( (CurrRetryRate>55) && (priv->LastRetryRate>54))
  29865. + {
  29866. + //(30,25) for cable link threshold respectively. (103,10) for air link respectively.
  29867. + //CurrRetryRate plus 65 and 69 respectively for air link threshold.
  29868. + //Down to rate 24Mbps.
  29869. + bTryDown = true;
  29870. + }
  29871. + // else if ( (CurrRetryRate<20) && (pHalData->LastRetryRate<20) && IncludedInSupportedRates(Adapter, 96) )//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
  29872. + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
  29873. + {
  29874. + bTryUp = true;
  29875. + }
  29876. + }
  29877. + else if ( priv->CurrentOperaRate == 48 )
  29878. + {
  29879. + //2For 24Mbps
  29880. + // if ( ((CurrRetryRate>119) && (pHalData->LastRetryRate>119) && IncludedInSupportedRates(Adapter, 36)))
  29881. + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
  29882. + {
  29883. + //(15,15) for cable link threshold respectively. (119, 119) for air link threshold.
  29884. + //Plus 84 for air link threshold.
  29885. + //Down to rate 18Mbps.
  29886. + bTryDown = true;
  29887. + }
  29888. + // else if ( (CurrRetryRate<14) && (pHalData->LastRetryRate<15) && IncludedInSupportedRates(Adapter, 72)) //TO DO: need to consider (RSSI)
  29889. + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
  29890. + {
  29891. + bTryUp = true;
  29892. + }
  29893. + }
  29894. + else if ( priv->CurrentOperaRate == 36 )
  29895. + {
  29896. + //2For 18Mbps
  29897. + if ( ((CurrRetryRate>109) && (priv->LastRetryRate>109)))
  29898. + {
  29899. + //(99,99) for cable link, (109,109) for air link.
  29900. + //Down to rate 11Mbps.
  29901. + bTryDown = true;
  29902. + }
  29903. + // else if ( (CurrRetryRate<15) && (pHalData->LastRetryRate<16) && IncludedInSupportedRates(Adapter, 48)) //TO DO: need to consider (RSSI)
  29904. + else if ( (CurrRetryRate<25) && (priv->LastRetryRate<26)) //TO DO: need to consider (RSSI)
  29905. + {
  29906. + bTryUp = true;
  29907. + }
  29908. + }
  29909. + else if ( priv->CurrentOperaRate == 22 )
  29910. + {
  29911. + //2For 11Mbps
  29912. + // if (CurrRetryRate>299 && IncludedInSupportedRates(Adapter, 11))
  29913. + if (CurrRetryRate>95)
  29914. + {
  29915. + bTryDown = true;
  29916. + }
  29917. + else if (CurrRetryRate<55)//&& (device->LastRetryRate<55) ) //TO DO: need to consider (RSSI)
  29918. + {
  29919. + bTryUp = true;
  29920. + }
  29921. + }
  29922. + else if ( priv->CurrentOperaRate == 11 )
  29923. + {
  29924. + //2For 5.5Mbps
  29925. + // if (CurrRetryRate>159 && IncludedInSupportedRates(Adapter, 4) )
  29926. + if (CurrRetryRate>149)
  29927. + {
  29928. + bTryDown = true;
  29929. + }
  29930. + // else if ( (CurrRetryRate<30) && (pHalData->LastRetryRate<30) && IncludedInSupportedRates(Adapter, 22) )
  29931. + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
  29932. + {
  29933. + bTryUp = true;
  29934. + }
  29935. + }
  29936. + else if ( priv->CurrentOperaRate == 4 )
  29937. + {
  29938. + //2For 2 Mbps
  29939. + if((CurrRetryRate>99) && (priv->LastRetryRate>99))
  29940. + {
  29941. + bTryDown = true;
  29942. + }
  29943. + // else if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 11) )
  29944. + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
  29945. + {
  29946. + bTryUp = true;
  29947. + }
  29948. + }
  29949. + else if ( priv->CurrentOperaRate == 2 )
  29950. + {
  29951. + //2For 1 Mbps
  29952. + // if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 4))
  29953. + if ( (CurrRetryRate<70) && (priv->LastRetryRate<75))
  29954. + {
  29955. + bTryUp = true;
  29956. + }
  29957. + }
  29958. + if(bTryUp && bTryDown)
  29959. + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
  29960. +
  29961. + //1 Test Upgrading Tx Rate
  29962. + // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
  29963. + // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
  29964. + if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
  29965. + && priv->CurrentOperaRate != 108 && priv->FailTxRateCount < 2)
  29966. + {
  29967. +#if 1
  29968. + if(jiffies% (CurrRetryRate + 101) == 0)
  29969. + {
  29970. + bTryUp = true;
  29971. + priv->bTryuping = true;
  29972. + printk("======================================================>StaRateAdaptive87B(): Randomly try upgrading...\n");
  29973. + }
  29974. +#endif
  29975. + }
  29976. + //1 Rate Mechanism
  29977. + if(bTryUp)
  29978. + {
  29979. + priv->TryupingCount++;
  29980. + priv->TryDownCountLowData = 0;
  29981. +
  29982. + //
  29983. + // Check more times if we need to upgrade indeed.
  29984. + // Because the largest value of pHalData->TryupingCount is 0xFFFF and
  29985. + // the largest value of pHalData->FailTxRateCount is 0x14,
  29986. + // this condition will be satisfied at most every 2 min.
  29987. + //
  29988. + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
  29989. + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
  29990. + {
  29991. + priv->TryupingCount = 0;
  29992. + //
  29993. + // When transfering from CCK to OFDM, DIG is an important issue.
  29994. + //
  29995. + if(priv->CurrentOperaRate == 22)
  29996. + bUpdateInitialGain = true;
  29997. + // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
  29998. + // (2)If the signal strength is increased, it may be able to upgrade.
  29999. + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
  30000. + //printk("StaRateAdaptive87B(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
  30001. +
  30002. + // Update Fail Tx rate and count.
  30003. + if(priv->LastFailTxRate != priv->CurrentOperaRate)
  30004. + {
  30005. + priv->LastFailTxRate = priv->CurrentOperaRate;
  30006. + priv->FailTxRateCount = 0;
  30007. + priv->LastFailTxRateSS = -200; // Set lowest power.
  30008. + }
  30009. + }
  30010. + }
  30011. + else
  30012. + {
  30013. + if(priv->TryupingCount > 0)
  30014. + priv->TryupingCount --;
  30015. + }
  30016. +
  30017. + if(bTryDown)
  30018. + {
  30019. + priv->TryDownCountLowData++;
  30020. + priv->TryupingCount = 0;
  30021. +
  30022. +
  30023. + //Check if Tx rate can be degraded or Test trying upgrading should fallback.
  30024. + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
  30025. + {
  30026. + priv->TryDownCountLowData = 0;
  30027. + priv->bTryuping = false;
  30028. + // Update fail information.
  30029. + if(priv->LastFailTxRate == priv->CurrentOperaRate)
  30030. + {
  30031. + priv->FailTxRateCount ++;
  30032. + // Record the Tx fail rate signal strength.
  30033. + if(CurrSignalStrength > priv->LastFailTxRateSS)
  30034. + {
  30035. + priv->LastFailTxRateSS = CurrSignalStrength;
  30036. + }
  30037. + }
  30038. + else
  30039. + {
  30040. + priv->LastFailTxRate = priv->CurrentOperaRate;
  30041. + priv->FailTxRateCount = 1;
  30042. + priv->LastFailTxRateSS = CurrSignalStrength;
  30043. + }
  30044. + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
  30045. + //
  30046. + // When it is CCK rate, it may need to update initial gain to receive lower power packets.
  30047. + //
  30048. + if(MgntIsCckRate(priv->CurrentOperaRate))
  30049. + {
  30050. + bUpdateInitialGain = true;
  30051. + }
  30052. + //printk("StaRateAdaptive87B(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
  30053. + }
  30054. + }
  30055. + else
  30056. + {
  30057. + if(priv->TryDownCountLowData > 0)
  30058. + priv->TryDownCountLowData --;
  30059. + }
  30060. + // Keep the Tx fail rate count to equal to 0x15 at most.
  30061. + // Reduce the fail count at least to 10 sec if tx rate is tending stable.
  30062. + if(priv->FailTxRateCount >= 0x15 ||
  30063. + (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
  30064. + {
  30065. + priv->FailTxRateCount --;
  30066. + }
  30067. +
  30068. + //
  30069. + // We need update initial gain when we set tx rate "from OFDM to CCK" or
  30070. + // "from CCK to OFDM".
  30071. + //
  30072. +SetInitialGain:
  30073. +#if 1 //to be done
  30074. + if(bUpdateInitialGain)
  30075. + {
  30076. + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
  30077. + {
  30078. + if(priv->InitialGain > priv->RegBModeGainStage)
  30079. + {
  30080. + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
  30081. + {
  30082. + priv->InitialGain = priv->RegBModeGainStage;
  30083. + }
  30084. + else if(priv->InitialGain > priv->RegBModeGainStage + 1)
  30085. + {
  30086. + priv->InitialGain -= 2;
  30087. + }
  30088. + else
  30089. + {
  30090. + priv->InitialGain --;
  30091. + }
  30092. + UpdateInitialGain(dev);
  30093. + }
  30094. + }
  30095. + else // OFDM
  30096. + {
  30097. + if(priv->InitialGain < 4)
  30098. + {
  30099. + priv->InitialGain ++;
  30100. + UpdateInitialGain(dev);
  30101. + }
  30102. + }
  30103. + }
  30104. +#endif
  30105. + //Record the related info
  30106. + priv->LastRetryRate = CurrRetryRate;
  30107. + priv->LastTxThroughput = TxThroughput;
  30108. + priv->ieee80211->rate = priv->CurrentOperaRate * 5;
  30109. +}
  30110. +
  30111. +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
  30112. +void rtl8180_rate_adapter(struct work_struct * work)
  30113. +{
  30114. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  30115. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
  30116. + struct net_device *dev = ieee->dev;
  30117. +#else
  30118. +void rtl8180_rate_adapter(struct net_device *dev)
  30119. +{
  30120. +
  30121. +#endif
  30122. + sta_rateadaptive8187B(dev);
  30123. +}
  30124. +
  30125. +void timer_rate_adaptive(unsigned long data)
  30126. +{
  30127. + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
  30128. + //DMESG("---->timer_rate_adaptive()\n");
  30129. + if(!priv->up)
  30130. + {
  30131. + //DMESG("<----timer_rate_adaptive():driver is not up!\n");
  30132. + return;
  30133. + }
  30134. + if( (priv->ieee80211->mode != IEEE_B) &&
  30135. + (priv->ieee80211->iw_mode != IW_MODE_MASTER)
  30136. + && ((priv->ieee80211->state == IEEE80211_LINKED)||(priv->ieee80211->state == IEEE80211_MESH_LINKED)))
  30137. + {
  30138. + //DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
  30139. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  30140. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq, 0);
  30141. +#else
  30142. + queue_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq);
  30143. +#endif
  30144. + }
  30145. +
  30146. + mod_timer(&priv->rateadapter_timer, jiffies + MSECS(DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD));
  30147. + //DMESG("<----timer_rate_adaptive()\n");
  30148. +}
  30149. +//by amy for rate adaptive
  30150. +
  30151. +
  30152. +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv);
  30153. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
  30154. +
  30155. +//YJ,add,080828,for KeepAlive
  30156. +#if 0
  30157. +static void MgntLinkKeepAlive(struct r8180_priv *priv )
  30158. +{
  30159. + if (priv->keepAliveLevel == 0)
  30160. + return;
  30161. +
  30162. + if(priv->ieee80211->state == IEEE80211_LINKED)
  30163. + {
  30164. + //
  30165. + // Keep-Alive.
  30166. + //
  30167. + //printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount);
  30168. +
  30169. + if ( (priv->keepAliveLevel== 2) ||
  30170. + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
  30171. + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
  30172. + )
  30173. + {
  30174. + priv->link_detect.IdleCount++;
  30175. +
  30176. + //
  30177. + // Send a Keep-Alive packet packet to AP if we had been idle for a while.
  30178. + //
  30179. + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
  30180. + {
  30181. + priv->link_detect.IdleCount = 0;
  30182. + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
  30183. + }
  30184. + }
  30185. + else
  30186. + {
  30187. + priv->link_detect.IdleCount = 0;
  30188. + }
  30189. + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
  30190. + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
  30191. + }
  30192. +}
  30193. +//YJ,add,080828,for KeepAlive,end
  30194. +#endif
  30195. +void InactivePowerSave(struct net_device *dev)
  30196. +{
  30197. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30198. +
  30199. + //
  30200. + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
  30201. + // is really scheduled.
  30202. + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
  30203. + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
  30204. + // blocks the IPS procedure of switching RF.
  30205. + // By Bruce, 2007-12-25.
  30206. + //
  30207. + priv->bSwRfProcessing = true;
  30208. + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
  30209. +
  30210. + //
  30211. + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
  30212. + //
  30213. +#if 0
  30214. + while( index < 4 )
  30215. + {
  30216. + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
  30217. + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
  30218. + {
  30219. + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
  30220. + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
  30221. +
  30222. + }
  30223. + index++;
  30224. + }
  30225. +#endif
  30226. + priv->bSwRfProcessing = false;
  30227. +}
  30228. +
  30229. +//
  30230. +// Description:
  30231. +// Enter the inactive power save mode. RF will be off
  30232. +// 2007.08.17, by shien chang.
  30233. +//
  30234. +void IPSEnter(struct net_device *dev)
  30235. +{
  30236. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30237. + RT_RF_POWER_STATE rtState;
  30238. +
  30239. + if (priv->bInactivePs)
  30240. + {
  30241. + rtState = priv->eRFPowerState;
  30242. +
  30243. + //
  30244. + // Added by Bruce, 2007-12-25.
  30245. + // Do not enter IPS in the following conditions:
  30246. + // (1) RF is already OFF or Sleep
  30247. + // (2) bSwRfProcessing (indicates the IPS is still under going)
  30248. + // (3) Connectted (only disconnected can trigger IPS)
  30249. + // (4) IBSS (send Beacon)
  30250. + // (5) AP mode (send Beacon)
  30251. + //
  30252. + if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)
  30253. + && (priv->ieee80211->state != IEEE80211_LINKED ))
  30254. + {
  30255. +#ifdef CONFIG_RADIO_DEBUG
  30256. + DMESG("IPSEnter(): Turn off RF.");
  30257. +#endif
  30258. + priv->eInactivePowerState = eRfOff;
  30259. + InactivePowerSave(dev);
  30260. + //SetRFPowerState(dev, priv->eInactivePowerState);
  30261. + //MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
  30262. + }
  30263. + }
  30264. + //printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
  30265. +}
  30266. +
  30267. +void IPSLeave(struct net_device *dev)
  30268. +{
  30269. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30270. + RT_RF_POWER_STATE rtState;
  30271. + if (priv->bInactivePs)
  30272. + {
  30273. + rtState = priv->eRFPowerState;
  30274. + if (rtState == eRfOff && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
  30275. + {
  30276. +#ifdef CONFIG_RADIO_DEBUG
  30277. + DMESG("ISLeave(): Turn on RF.");
  30278. +#endif
  30279. + priv->eInactivePowerState = eRfOn;
  30280. + InactivePowerSave(dev);
  30281. + }
  30282. + }
  30283. +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
  30284. +}
  30285. +//by amy for power save
  30286. +
  30287. +//YJ,add,081230
  30288. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  30289. +void IPSLeave_wq (struct work_struct *work)
  30290. +{
  30291. + struct ieee80211_device *ieee = container_of(work,struct ieee80211_device,ips_leave_wq);
  30292. + struct net_device *dev = ieee->dev;
  30293. +#else
  30294. +void IPSLeave_wq(struct net_device *dev)
  30295. +{
  30296. +#endif
  30297. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30298. + down(&priv->ieee80211->ips_sem);
  30299. + IPSLeave(dev);
  30300. + up(&priv->ieee80211->ips_sem);
  30301. +}
  30302. +
  30303. +void ieee80211_ips_leave(struct net_device *dev)
  30304. +{
  30305. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30306. + if(priv->bInactivePs){
  30307. + if(priv->eRFPowerState == eRfOff)
  30308. + {
  30309. + //DMESG("%s", __FUNCTION__);
  30310. + queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
  30311. + }
  30312. + }
  30313. +}
  30314. +//YJ,add,081230,end
  30315. +
  30316. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  30317. +void rtl8180_watch_dog_wq (struct work_struct *work)
  30318. +{
  30319. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  30320. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,watch_dog_wq);
  30321. + struct net_device *dev = ieee->dev;
  30322. +#else
  30323. +void rtl8180_watch_dog_wq(struct net_device *dev)
  30324. +{
  30325. +#endif
  30326. + struct r8180_priv *priv = ieee80211_priv(dev);
  30327. + //bool bEnterPS = false;
  30328. + //bool bBusyTraffic = false;
  30329. + u32 TotalRxNum = 0;
  30330. + u16 SlotIndex = 0, i=0;
  30331. + //YJ,add,080828,for link state check
  30332. + if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
  30333. + SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
  30334. + priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
  30335. + for( i=0; i<priv->link_detect.SlotNum; i++ )
  30336. + TotalRxNum+= priv->link_detect.RxFrameNum[i];
  30337. +#if 0 //for roaming temp del
  30338. + if(TotalRxNum == 0){
  30339. + priv->ieee80211->state = IEEE80211_ASSOCIATING;
  30340. + printk("=========>turn to another AP\n");
  30341. + queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
  30342. + }
  30343. +#endif
  30344. + }
  30345. + priv->link_detect.NumRxOkInPeriod = 0;
  30346. + priv->link_detect.NumTxOkInPeriod = 0;
  30347. + priv->ieee80211->NumRxDataInPeriod = 0;
  30348. + priv->ieee80211->NumRxBcnInPeriod = 0;
  30349. +
  30350. +#ifdef CONFIG_IPS
  30351. + if(priv->ieee80211->actscanning == false){
  30352. + if((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
  30353. + (priv->ieee80211->state == IEEE80211_NOLINK) &&
  30354. + (priv->eRFPowerState == eRfOn))
  30355. + {
  30356. + //printk("actscanning:%d, state:%d, eRFPowerState:%d\n",
  30357. + // priv->ieee80211->actscanning,
  30358. + // priv->ieee80211->state,
  30359. + // priv->eRFPowerState);
  30360. +
  30361. + down(&priv->ieee80211->ips_sem);
  30362. + IPSEnter(dev);
  30363. + up(&priv->ieee80211->ips_sem);
  30364. + }
  30365. + }
  30366. + //queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,IEEE80211_WATCH_DOG_TIME);
  30367. +#endif
  30368. +
  30369. + //printk("========================>leave rtl8180_watch_dog_wq()\n");
  30370. +}
  30371. +
  30372. +void watch_dog_adaptive(unsigned long data)
  30373. +{
  30374. + struct net_device* dev = (struct net_device*)data;
  30375. + struct r8180_priv* priv = ieee80211_priv(dev);
  30376. + //DMESG("---->watch_dog_adaptive()\n");
  30377. + if(!priv->up){
  30378. + //DMESG("<----watch_dog_adaptive():driver is not up!\n");
  30379. + return;
  30380. + }
  30381. + // Tx and Rx High Power Mechanism.
  30382. + if(CheckHighPower(dev)){
  30383. + //printk("===============================> high power!\n");
  30384. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  30385. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq, 0);
  30386. +#else
  30387. + queue_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq);
  30388. +#endif
  30389. + }
  30390. +
  30391. + // Schedule an workitem to perform DIG
  30392. + if(CheckDig(dev) == true){
  30393. +
  30394. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  30395. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq,0);
  30396. +#else
  30397. + queue_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq);
  30398. +#endif
  30399. + }
  30400. +
  30401. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  30402. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,0);
  30403. +#else
  30404. + queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
  30405. +#endif
  30406. +
  30407. + mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
  30408. + //DMESG("<----watch_dog_adaptive()\n");
  30409. +}
  30410. +
  30411. +#ifdef ENABLE_DOT11D
  30412. +
  30413. +CHANNEL_LIST Current_tbl;
  30414. +
  30415. +static CHANNEL_LIST ChannelPlan[] = {
  30416. + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
  30417. + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
  30418. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
  30419. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
  30420. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
  30421. + {{14,36,40,44,48,52,56,60,64},9}, //MKK
  30422. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
  30423. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
  30424. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
  30425. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
  30426. + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 081205
  30427. +};
  30428. +
  30429. +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
  30430. +{
  30431. + int i;
  30432. +
  30433. + //lzm add 081205
  30434. + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
  30435. + ieee->IbssStartChnl=0;
  30436. +
  30437. + switch (channel_plan)
  30438. + {
  30439. + case COUNTRY_CODE_FCC:
  30440. + case COUNTRY_CODE_IC:
  30441. + case COUNTRY_CODE_ETSI:
  30442. + case COUNTRY_CODE_SPAIN:
  30443. + case COUNTRY_CODE_FRANCE:
  30444. + case COUNTRY_CODE_MKK:
  30445. + case COUNTRY_CODE_MKK1:
  30446. + case COUNTRY_CODE_ISRAEL:
  30447. + case COUNTRY_CODE_TELEC:
  30448. + {
  30449. + Dot11d_Init(ieee);
  30450. + ieee->bGlobalDomain = false;
  30451. + ieee->bWorldWide13 = false;
  30452. + if (ChannelPlan[channel_plan].Len != 0){
  30453. + // Clear old channel map
  30454. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  30455. + // Set new channel map
  30456. + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
  30457. + {
  30458. + if(ChannelPlan[channel_plan].Channel[i] <= 14)
  30459. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
  30460. + }
  30461. + }
  30462. + break;
  30463. + }
  30464. + case COUNTRY_CODE_GLOBAL_DOMAIN:
  30465. + {
  30466. + GET_DOT11D_INFO(ieee)->bEnabled = 0;
  30467. + Dot11d_Reset(ieee);
  30468. + ieee->bGlobalDomain = true;
  30469. + ieee->bWorldWide13 = false;
  30470. +
  30471. + //lzm add 081205
  30472. + ieee->MinPassiveChnlNum=12;
  30473. + ieee->IbssStartChnl= 10;
  30474. +
  30475. + break;
  30476. + }
  30477. + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 081205
  30478. + {
  30479. + Dot11d_Init(ieee);
  30480. + ieee->bGlobalDomain = false;
  30481. + ieee->bWorldWide13 = true;
  30482. +
  30483. + //lzm add 081205
  30484. + ieee->MinPassiveChnlNum=12;
  30485. + ieee->IbssStartChnl= 10;
  30486. +
  30487. + if (ChannelPlan[channel_plan].Len != 0){
  30488. + // Clear old channel map
  30489. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  30490. + // Set new channel map
  30491. + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
  30492. + {
  30493. + if(ChannelPlan[channel_plan].Channel[i] <= 11)//ch1~ch11 active scan
  30494. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
  30495. + else//ch12~13 passive scan
  30496. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 2;
  30497. + }
  30498. + }
  30499. +
  30500. + break;
  30501. + }
  30502. + default:
  30503. + {
  30504. + Dot11d_Init(ieee);
  30505. + ieee->bGlobalDomain = false;
  30506. + ieee->bWorldWide13 = false;
  30507. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  30508. + for (i=1;i<=14;i++)
  30509. + {
  30510. + GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
  30511. + }
  30512. + break;
  30513. + }
  30514. + }
  30515. +}
  30516. +#endif
  30517. +
  30518. +
  30519. +static void rtl8180_link_detect_init(plink_detect_t plink_detect)
  30520. +{
  30521. + memset(plink_detect, 0, sizeof(link_detect_t));
  30522. + plink_detect->SlotNum = DEFAULT_SLOT_NUM;
  30523. +}
  30524. +
  30525. +#ifdef SW_ANTE_DIVERSITY
  30526. +static void rtl8187_antenna_diversity_read(struct net_device *dev)
  30527. +{
  30528. + struct r8180_priv *priv = ieee80211_priv(dev);
  30529. + u16 usValue;
  30530. +
  30531. + //2 Read CustomerID
  30532. + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET>>1);
  30533. + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
  30534. + //DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID);
  30535. +
  30536. + //2 Read AntennaDiversity
  30537. + // SW Antenna Diversity.
  30538. + if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE ){
  30539. + priv->EEPROMSwAntennaDiversity = false;
  30540. + DMESG("EEPROM Disable SW Antenna Diversity");
  30541. + }else{
  30542. + priv->EEPROMSwAntennaDiversity = true;
  30543. + DMESG("EEPROM Enable SW Antenna Diversity");
  30544. + }
  30545. + // Default Antenna to use.
  30546. + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 ) {
  30547. + priv->EEPROMDefaultAntenna1 = false;
  30548. + DMESG("EEPROM Default Main Antenna 0");
  30549. + }else{
  30550. + priv->EEPROMDefaultAntenna1 = false;
  30551. + DMESG( "EEPROM Default Aux Antenna 1");
  30552. + }
  30553. +
  30554. + //
  30555. + // Antenna diversity mechanism. Added by Roger, 2007.11.05.
  30556. + //
  30557. + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto //set it to 0 when init
  30558. + {// 0: default from EEPROM.
  30559. + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
  30560. + }else{// 1:disable antenna diversity, 2: enable antenna diversity.
  30561. + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
  30562. + }
  30563. + //DMESG("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
  30564. +
  30565. +
  30566. + //
  30567. + // Default antenna settings. Added by Roger, 2007.11.05.
  30568. + //
  30569. + if( priv->RegDefaultAntenna == 0)//set it to 0 when init
  30570. + { // 0: default from EEPROM.
  30571. + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
  30572. + }else{// 1: main, 2: aux.
  30573. + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
  30574. + }
  30575. + //DMESG("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
  30576. +
  30577. +//by amy for antenna
  30578. +}
  30579. +#endif
  30580. +
  30581. +short rtl8180_init(struct net_device *dev)
  30582. +{
  30583. + struct r8180_priv *priv = ieee80211_priv(dev);
  30584. + int i, j;
  30585. + u16 word;
  30586. + //int ch;
  30587. + //u16 version;
  30588. + u8 hw_version;
  30589. + //u8 config3;
  30590. + struct usb_device *udev;
  30591. + u16 idProduct;
  30592. + u16 bcdDevice;
  30593. + //u8 chan_plan_index;
  30594. +
  30595. + //FIXME: these constants are placed in a bad pleace.
  30596. +
  30597. + //priv->txbuffsize = 1024;
  30598. + //priv->txringcount = 32;
  30599. + //priv->rxbuffersize = 1024;
  30600. + //priv->rxringcount = 32;
  30601. + //priv->txbeaconcount = 3;
  30602. + //priv->rx_skb_complete = 1;
  30603. + //priv->txnp_pending.ispending=0;
  30604. + /* ^^ the SKB does not containt a partial RXed packet (is empty) */
  30605. +
  30606. + //memcpy(priv->stats,0,sizeof(struct Stats));
  30607. +
  30608. + //priv->irq_enabled=0;
  30609. + priv->driver_upping = 0;
  30610. + priv->commit = 0;
  30611. +
  30612. + //priv->stats.rxdmafail=0;
  30613. + priv->stats.txrdu=0;
  30614. + //priv->stats.rxrdu=0;
  30615. + //priv->stats.rxnolast=0;
  30616. + //priv->stats.rxnodata=0;
  30617. + //priv->stats.rxreset=0;
  30618. + //priv->stats.rxwrkaround=0;
  30619. + //priv->stats.rxnopointer=0;
  30620. + priv->stats.txbeerr=0;
  30621. + priv->stats.txbkerr=0;
  30622. + priv->stats.txvierr=0;
  30623. + priv->stats.txvoerr=0;
  30624. + priv->stats.txmanageerr=0;
  30625. + priv->stats.txbeaconerr=0;
  30626. + priv->stats.txresumed=0;
  30627. + //priv->stats.rxerr=0;
  30628. + //priv->stats.rxoverflow=0;
  30629. + //priv->stats.rxint=0;
  30630. + priv->stats.txbeokint=0;
  30631. + priv->stats.txbkokint=0;
  30632. + priv->stats.txviokint=0;
  30633. + priv->stats.txvookint=0;
  30634. + priv->stats.txmanageokint=0;
  30635. + priv->stats.txbeaconokint=0;
  30636. + /*priv->stats.txhpokint=0;
  30637. + priv->stats.txhperr=0;*/
  30638. + priv->stats.rxurberr=0;
  30639. + priv->stats.rxstaterr=0;
  30640. + priv->stats.txoverflow=0;
  30641. + priv->stats.rxok=0;
  30642. + //priv->stats.txbeaconerr=0;
  30643. + //priv->stats.txlperr=0;
  30644. + //priv->stats.txlpokint=0;
  30645. +//john
  30646. + priv->stats.txnpdrop=0;
  30647. + priv->stats.txlpdrop =0;
  30648. + priv->stats.txbedrop =0;
  30649. + priv->stats.txbkdrop =0;
  30650. + priv->stats.txvidrop =0;
  30651. + priv->stats.txvodrop =0;
  30652. + priv->stats.txbeacondrop =0;
  30653. + priv->stats.txmanagedrop =0;
  30654. +
  30655. + // priv->stats.txokbytestotal =0;
  30656. +//by amy
  30657. + priv->LastSignalStrengthInPercent=0;
  30658. + priv->SignalStrength=0;
  30659. + priv->SignalQuality=0;
  30660. + priv->antenna_flag=0;
  30661. + priv->flag_beacon = false;
  30662. +//by amy
  30663. +//david
  30664. + //radion on defaultly
  30665. + priv->radion = 1;
  30666. +//david
  30667. +//by amy for rate adaptive
  30668. + priv->CurrRetryCnt=0;
  30669. + priv->LastRetryCnt=0;
  30670. + priv->LastTxokCnt=0;
  30671. + priv->LastRxokCnt=0;
  30672. + priv->LastRetryRate=0;
  30673. + priv->bTryuping=0;
  30674. + priv->CurrTxRate=0;
  30675. + priv->CurrRetryRate=0;
  30676. + priv->TryupingCount=0;
  30677. + priv->TryupingCountNoData=0;
  30678. + priv->TryDownCountLowData=0;
  30679. + priv->RecvSignalPower=0;
  30680. + priv->LastTxOKBytes=0;
  30681. + priv->LastFailTxRate=0;
  30682. + priv->LastFailTxRateSS=0;
  30683. + priv->FailTxRateCount=0;
  30684. + priv->LastTxThroughput=0;
  30685. + priv->txokbytestotal=0;
  30686. +//by amy for rate adaptive
  30687. +//by amy for ps
  30688. + priv->RFChangeInProgress = false;
  30689. + priv->SetRFPowerStateInProgress = false;
  30690. + priv->RFProgType = 0;
  30691. + priv->bInHctTest = false;
  30692. + priv->bInactivePs = true;//false;
  30693. + priv->ieee80211->bInactivePs = priv->bInactivePs;
  30694. + priv->eInactivePowerState = eRfOn;//lzm add for IPS and Polling methord
  30695. + priv->bSwRfProcessing = false;
  30696. + priv->eRFPowerState = eRfOff;
  30697. + priv->RfOffReason = 0;
  30698. + priv->NumRxOkInPeriod = 0;
  30699. + priv->NumTxOkInPeriod = 0;
  30700. + priv->bLeisurePs = true;
  30701. + priv->dot11PowerSaveMode = eActive;
  30702. + priv->RegThreeWireMode=HW_THREE_WIRE_BY_8051;
  30703. + priv->ps_mode = false;
  30704. +//by amy for ps
  30705. +//by amy for DIG
  30706. + priv->bDigMechanism = 1;
  30707. + priv->bCCKThMechanism = 0;
  30708. + priv->InitialGain = 0;
  30709. + priv->StageCCKTh = 0;
  30710. + priv->RegBModeGainStage = 2;
  30711. +//by amy for DIG
  30712. +// {by david for DIG, 2008.3.6
  30713. + priv->RegDigOfdmFaUpTh = 0x0c;
  30714. + priv->RegBModeGainStage = 0x02;
  30715. + priv->DIG_NumberFallbackVote = 0;
  30716. + priv->DIG_NumberUpgradeVote = 0;
  30717. + priv->CCKUpperTh = 0x100;
  30718. + priv->CCKLowerTh = 0x20;
  30719. +//}
  30720. +//{added by david for High tx power, 2008.3.11
  30721. + priv->bRegHighPowerMechanism = true;
  30722. + priv->bToUpdateTxPwr = false;
  30723. +
  30724. + priv->Z2HiPwrUpperTh = 77;
  30725. + priv->Z2HiPwrLowerTh = 75;
  30726. + priv->Z2RSSIHiPwrUpperTh = 70;
  30727. + priv->Z2RSSIHiPwrLowerTh = 20;
  30728. + //specify for rtl8187B
  30729. + priv->wMacRegRfPinsOutput = 0x0480;
  30730. + priv->wMacRegRfPinsSelect = 0x2488;
  30731. + //
  30732. + // Note that, we just set TrSwState to TR_HW_CONTROLLED here instead of changing
  30733. + // HW setting because we assume it should be inialized as HW controlled. 061010, by rcnjko.
  30734. + //
  30735. + priv->TrSwitchState = TR_HW_CONTROLLED;
  30736. +//}
  30737. + priv->ieee80211->iw_mode = IW_MODE_INFRA;
  30738. +//test pending bug, john 20070815
  30739. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  30740. +//by lizhaoming for LED
  30741. +#ifdef LED
  30742. + priv->ieee80211->ieee80211_led_contorl = LedControl8187;
  30743. +#endif
  30744. +#ifdef CONFIG_IPS
  30745. + priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;//IPSLeave;
  30746. +#endif
  30747. +
  30748. +#ifdef SW_ANTE_DIVERSITY
  30749. + priv->antb=0;
  30750. + priv->diversity=1;
  30751. + priv->LastRxPktAntenna = 0;
  30752. + priv->AdMinCheckPeriod = 5;
  30753. + priv->AdMaxCheckPeriod = 10;
  30754. + // Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
  30755. + priv->AdMaxRxSsThreshold = 30;//60->30
  30756. + priv->AdRxSsThreshold = 20;//50->20
  30757. + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
  30758. + priv->AdTickCount = 0;
  30759. + priv->AdRxSignalStrength = -1;
  30760. + priv->RegSwAntennaDiversityMechanism = 0;
  30761. + priv->RegDefaultAntenna = 0;
  30762. + priv->SignalStrength = 0;
  30763. + priv->AdRxOkCnt = 0;
  30764. + priv->CurrAntennaIndex = 0;
  30765. + priv->AdRxSsBeforeSwitched = 0;
  30766. + init_timer(&priv->SwAntennaDiversityTimer);
  30767. + priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
  30768. + priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
  30769. +#endif
  30770. +
  30771. + priv->retry_rts = DEFAULT_RETRY_RTS;
  30772. + priv->retry_data = DEFAULT_RETRY_DATA;
  30773. + priv->ieee80211->rate = 110; //11 mbps
  30774. + priv->CurrentOperaRate=priv->ieee80211->rate/5;
  30775. + priv->ieee80211->short_slot = 1;
  30776. + priv->ieee80211->mode = IEEE_G;
  30777. + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
  30778. +
  30779. + rtl8180_link_detect_init(&priv->link_detect);
  30780. +
  30781. + spin_lock_init(&priv->tx_lock);
  30782. + spin_lock_init(&priv->irq_lock);//added by thomas
  30783. + spin_lock_init(&priv->rf_ps_lock);
  30784. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  30785. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  30786. + INIT_WORK(&priv->reset_wq, (void*)rtl8180_restart);
  30787. + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); //YJ,add,081230,for IPS
  30788. + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);
  30789. + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);
  30790. + INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq);
  30791. + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);
  30792. +
  30793. +#ifdef SW_ANTE_DIVERSITY
  30794. + INIT_DELAYED_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback);
  30795. +#endif
  30796. +
  30797. +#else
  30798. + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart,dev);
  30799. + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq,dev); //YJ,add,081230,for IPS
  30800. + INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);
  30801. + INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);
  30802. + INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq,dev);
  30803. + INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);
  30804. +
  30805. +#ifdef SW_ANTE_DIVERSITY
  30806. + INIT_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback, dev);
  30807. +#endif
  30808. +
  30809. +#endif
  30810. +#else
  30811. + tq_init(&priv->reset_wq,(void*) rtl8180_restart,dev);
  30812. +#endif
  30813. + sema_init(&priv->wx_sem,1);
  30814. + sema_init(&priv->set_chan_sem,1);
  30815. +#ifdef THOMAS_TASKLET
  30816. + tasklet_init(&priv->irq_rx_tasklet,
  30817. + (void(*)(unsigned long))rtl8180_irq_rx_tasklet_new,
  30818. + (unsigned long)priv);
  30819. +#else
  30820. + tasklet_init(&priv->irq_rx_tasklet,
  30821. + (void(*)(unsigned long))rtl8180_irq_rx_tasklet,
  30822. + (unsigned long)priv);
  30823. +#endif
  30824. +//by amy for rate adaptive
  30825. + init_timer(&priv->rateadapter_timer);
  30826. + priv->rateadapter_timer.data = (unsigned long)dev;
  30827. + priv->rateadapter_timer.function = timer_rate_adaptive;
  30828. +//by amy for rate adaptive
  30829. +//by amy for ps
  30830. + init_timer(&priv->watch_dog_timer);
  30831. + priv->watch_dog_timer.data = (unsigned long)dev;
  30832. + priv->watch_dog_timer.function = watch_dog_adaptive;
  30833. +//by amy
  30834. +//by amy for ps
  30835. + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
  30836. + priv->ieee80211->iw_mode = IW_MODE_INFRA;
  30837. + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
  30838. + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
  30839. +#ifdef CONFIG_SOFT_BEACON
  30840. + IEEE_SOFTMAC_BEACONS | //IEEE_SOFTMAC_SINGLE_QUEUE;
  30841. +#endif
  30842. + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
  30843. +
  30844. + priv->ieee80211->active_scan = 1;
  30845. + //priv->ieee80211->ch_lock = 0;
  30846. + priv->ieee80211->rate = 110; //11 mbps
  30847. + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
  30848. + priv->ieee80211->host_encrypt = 1;
  30849. + priv->ieee80211->host_decrypt = 1;
  30850. +#ifdef CONFIG_SOFT_BEACON
  30851. + priv->ieee80211->start_send_beacons = NULL;
  30852. + priv->ieee80211->stop_send_beacons = NULL;
  30853. +#else
  30854. + priv->ieee80211->start_send_beacons = rtl8187_beacon_tx;
  30855. + priv->ieee80211->stop_send_beacons = rtl8187_beacon_stop;
  30856. +#endif
  30857. + priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
  30858. + priv->ieee80211->set_chan = rtl8180_set_chan;
  30859. + priv->ieee80211->link_change = rtl8187_link_change;
  30860. + priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
  30861. + priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
  30862. + priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
  30863. +
  30864. +#ifdef _RTL8187_EXT_PATCH_
  30865. + priv->ieee80211->meshScanMode = 0;
  30866. + priv->mshobj = alloc_mshobj(priv);
  30867. + if(priv->mshobj)
  30868. + {
  30869. + priv->ieee80211->ext_patch_ieee80211_start_protocol = priv->mshobj->ext_patch_ieee80211_start_protocol;
  30870. + priv->ieee80211->ext_patch_ieee80211_stop_protocol = priv->mshobj->ext_patch_ieee80211_stop_protocol;
  30871. +//by amy for mesh
  30872. + priv->ieee80211->ext_patch_ieee80211_start_mesh = priv->mshobj->ext_patch_ieee80211_start_mesh;
  30873. +//by amy for mesh
  30874. + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = priv->mshobj->ext_patch_ieee80211_probe_req_1;
  30875. + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = priv->mshobj->ext_patch_ieee80211_probe_req_2;
  30876. + priv->ieee80211->ext_patch_ieee80211_association_req_1 = priv->mshobj->ext_patch_ieee80211_association_req_1;
  30877. + priv->ieee80211->ext_patch_ieee80211_association_req_2 = priv->mshobj->ext_patch_ieee80211_association_req_2;
  30878. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_1;
  30879. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_2;
  30880. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_auth;
  30881. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_deauth;
  30882. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req;
  30883. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp;
  30884. + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = priv->mshobj->ext_patch_ieee80211_ext_stop_scan_wq_set_channel;
  30885. + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = priv->mshobj->ext_patch_ieee80211_process_probe_response_1;
  30886. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = priv->mshobj->ext_patch_ieee80211_rx_mgt_on_probe_req;
  30887. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = priv->mshobj->ext_patch_ieee80211_rx_mgt_update_expire;
  30888. + priv->ieee80211->ext_patch_get_beacon_get_probersp = priv->mshobj->ext_patch_get_beacon_get_probersp;
  30889. + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = priv->mshobj->ext_patch_ieee80211_rx_on_rx;
  30890. + priv->ieee80211->ext_patch_ieee80211_xmit = priv->mshobj->ext_patch_ieee80211_xmit;
  30891. + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = priv->mshobj->ext_patch_ieee80211_rx_frame_get_hdrlen;
  30892. + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = priv->mshobj->ext_patch_ieee80211_rx_is_valid_framectl;
  30893. + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = priv->mshobj->ext_patch_ieee80211_rx_process_dataframe;
  30894. + // priv->ieee80211->ext_patch_is_duplicate_packet = priv->mshobj->ext_patch_is_duplicate_packet;
  30895. + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = priv->mshobj->ext_patch_ieee80211_softmac_xmit_get_rate;
  30896. + /* added by david for setting acl dynamically */
  30897. + priv->ieee80211->ext_patch_ieee80211_acl_query = priv->mshobj->ext_patch_ieee80211_acl_query;
  30898. + }
  30899. +
  30900. +#endif // _RTL8187_EXT_PATCH_
  30901. +
  30902. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  30903. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  30904. + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
  30905. + (void(*)(void*)) rtl8180_wmm_param_update,\
  30906. + priv->ieee80211);
  30907. +#else
  30908. + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
  30909. + rtl8180_wmm_param_update);
  30910. +#endif
  30911. +#else
  30912. + tq_init(&priv->ieee80211->wmm_param_update_wq,\
  30913. + (void(*)(void*)) rtl8180_wmm_param_update,\
  30914. + priv->ieee80211);
  30915. +#endif
  30916. + priv->ieee80211->init_wmmparam_flag = 0;
  30917. + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
  30918. +
  30919. + //priv->card_8185 = 2;
  30920. + priv->phy_ver = 2;
  30921. + priv->card_type = USB;
  30922. +//{add for 87B
  30923. + priv->ShortRetryLimit = 7;
  30924. + priv->LongRetryLimit = 7;
  30925. + priv->EarlyRxThreshold = 7;
  30926. +
  30927. + priv->TransmitConfig =
  30928. + TCR_DurProcMode | //for RTL8185B, duration setting by HW
  30929. + TCR_DISReqQsize |
  30930. + (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
  30931. + (priv->ShortRetryLimit<<TX_SRLRETRY_SHIFT)| // Short retry limit
  30932. + (priv->LongRetryLimit<<TX_LRLRETRY_SHIFT) | // Long retry limit
  30933. + (false ? TCR_SWPLCPLEN : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
  30934. +
  30935. + priv->ReceiveConfig =
  30936. + RCR_AMF | RCR_ADF | //accept management/data
  30937. + RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
  30938. + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
  30939. + //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
  30940. + RCR_MXDMA | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
  30941. + (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
  30942. + (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
  30943. +
  30944. + priv->AcmControl = 0;
  30945. +//}
  30946. + priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID);
  30947. + //DMESG("rf_chip:%x\n", priv->rf_chip);
  30948. + if (!priv->rf_chip)
  30949. + {
  30950. + DMESG("Can't get rf chip ID from EEPROM");
  30951. + DMESGW("So set rf chip ID to defalut EPROM_RFCHIPID_RTL8225U");
  30952. + DMESGW("use it with care and at your own risk and");
  30953. + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
  30954. + priv->rf_chip = EPROM_RFCHIPID_RTL8225U;
  30955. +
  30956. + }
  30957. +
  30958. +
  30959. +//{put the card to detect different card here, mainly I/O processing
  30960. + udev = priv->udev;
  30961. + idProduct = le16_to_cpu(udev->descriptor.idProduct);
  30962. + //idProduct = 0x8197;
  30963. + bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
  30964. + DMESG("idProduct:0x%x, bcdDevice:0x%x", idProduct,bcdDevice);
  30965. + switch (idProduct) {
  30966. + case 0x8189:
  30967. + case 0x8197:
  30968. + case 0x8198:
  30969. + /* check RF frontend chipset */
  30970. + priv->card_8187 = NIC_8187B;
  30971. + priv->rf_init = rtl8225z2_rf_init;
  30972. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  30973. + priv->rf_set_sens = NULL;
  30974. + break;
  30975. +
  30976. + case 0x8187:
  30977. + if(bcdDevice == 0x0200){
  30978. + priv->card_8187 = NIC_8187B;
  30979. + priv->rf_init = rtl8225z2_rf_init;
  30980. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  30981. + priv->rf_set_sens = NULL;
  30982. + break;
  30983. + }else{
  30984. + //0x0100 is for 8187
  30985. + //legacy 8187 NIC
  30986. + //delet
  30987. + ;
  30988. + }
  30989. + default:
  30990. + /* check RF frontend chipset */
  30991. + priv->ieee80211->softmac_features |= IEEE_SOFTMAC_SINGLE_QUEUE;
  30992. + priv->card_8187 = NIC_8187;
  30993. + switch (priv->rf_chip) {
  30994. + case EPROM_RFCHIPID_RTL8225U:
  30995. + DMESG("Card reports RF frontend Realtek 8225");
  30996. + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
  30997. + DMESGW("use it with care and at your own risk and");
  30998. + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
  30999. + if(rtl8225_is_V_z2(dev)){
  31000. + priv->rf_init = rtl8225z2_rf_init;
  31001. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  31002. + priv->rf_set_sens = NULL;
  31003. + DMESG("This seems a new V2 radio");
  31004. + }else{
  31005. + priv->rf_init = rtl8225_rf_init;
  31006. + priv->rf_set_chan = rtl8225_rf_set_chan;
  31007. + priv->rf_set_sens = rtl8225_rf_set_sens;
  31008. + DMESG("This seems a legacy 1st version radio");
  31009. + }
  31010. + break;
  31011. +
  31012. + case EPROM_RFCHIPID_RTL8225U_VF:
  31013. + priv->rf_init = rtl8225z2_rf_init;
  31014. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  31015. + priv->rf_set_sens = NULL;
  31016. + DMESG("This seems a new V2 radio");
  31017. + break;
  31018. +
  31019. + default:
  31020. + DMESGW("Unknown RF module %x",priv->rf_chip);
  31021. + DMESGW("Exiting...");
  31022. + return -1;
  31023. + }
  31024. + break;
  31025. + }
  31026. +
  31027. + priv->rf_close = rtl8225_rf_close;
  31028. + priv->max_sens = RTL8225_RF_MAX_SENS;
  31029. + priv->sens = RTL8225_RF_DEF_SENS;
  31030. +
  31031. +#ifdef ENABLE_DOT11D
  31032. +#if 0
  31033. + for(i=0;i<0xFF;i++) {
  31034. + if(i%16 == 0)
  31035. + printk("\n[%x]: ", i/16);
  31036. + printk("\t%4.4x", eprom_read(dev,i));
  31037. + }
  31038. +#endif
  31039. + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xFF;
  31040. + //DMESG("EPROM_CHANNEL_PLAN is %x", priv->channel_plan);
  31041. +
  31042. + // lzm add 081205 for Toshiba:
  31043. + // For Toshiba,reading the value from EEPROM 0x6h bit[7] to determine the priority of
  31044. + // channel plan to be defined.
  31045. + // -If bit[7] is true, then the channel plan is defined by EEPROM but no user defined.
  31046. + // -If bit[7] is false, then the channel plan is defined by user first.
  31047. + //
  31048. + if(priv->channel_plan & 0x80) {
  31049. + DMESG("Toshiba channel plan is defined by EEPROM");
  31050. + priv->channel_plan &= 0xf;
  31051. + }
  31052. + else
  31053. + priv->channel_plan = 0;
  31054. +
  31055. + //if(priv->channel_plan > COUNTRY_CODE_WORLD_WIDE_13_INDEX){
  31056. + if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
  31057. + DMESG("rtl8180_init:Error channel plan! Set to default.\n");
  31058. + priv->channel_plan = 0;
  31059. + }
  31060. +
  31061. + //priv->channel_plan = 9; //Global Domain
  31062. + //priv->channel_plan = 2; //ETSI
  31063. +
  31064. +
  31065. + DMESG("Channel plan is %d ",priv->channel_plan);
  31066. +
  31067. + //for Toshiba card we read channel plan from ChanPlanBin
  31068. + if((idProduct != 0x8197) && (idProduct != 0x8198))
  31069. + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
  31070. +#else
  31071. + int ch;
  31072. + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xff;
  31073. + if(priv->channel_plan & 0x80) {
  31074. + priv->channel_plan &= 0x7f;
  31075. + if (ChannelPlan[priv->channel_plan].Len != 0){
  31076. + // force channel plan map
  31077. + for (i=0;i<ChannelPlan[priv->channel_plan].Len;i++)
  31078. + priv->ieee80211->channel_map[ChannelPlan[priv->channel_plan].Channel[i]] = 1;
  31079. + } else {
  31080. + DMESG("No channels, aborting");
  31081. + return -1;
  31082. + }
  31083. + } else {
  31084. + //default channel plan setting
  31085. + if(!channels){
  31086. + DMESG("No channels, aborting");
  31087. + return -1;
  31088. + }
  31089. + ch=channels;
  31090. + // set channels 1..14 allowed in given locale
  31091. + for (i=1; i<=14; i++) {
  31092. + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
  31093. + ch >>= 1;
  31094. + }
  31095. + }
  31096. +#endif
  31097. +
  31098. + if((idProduct == 0x8197) || (idProduct == 0x8198)) {
  31099. + // lzm add 081205 for Toshiba:
  31100. + // 0x77h bit[0]=1: use GPIO bit[2], bit[0]=0: use GPIO bit[1]
  31101. + priv->EEPROMSelectNewGPIO =((u8)((eprom_read(dev,EPROM_SELECT_GPIO) & 0xff00) >> 8)) ? true : false;
  31102. + DMESG("EPROM_SELECT_GPIO:%d", priv->EEPROMSelectNewGPIO);
  31103. + } else {
  31104. + priv->EEPROMSelectNewGPIO = false;
  31105. + }
  31106. +
  31107. +
  31108. + if (NIC_8187 == priv->card_8187){
  31109. + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
  31110. + switch (hw_version) {
  31111. + case 0x06:
  31112. + //priv->card_8187_Bversion = VERSION_8187B_B;
  31113. + break;
  31114. + case 0x05:
  31115. + priv->card_8187_Bversion = VERSION_8187_D;
  31116. + break;
  31117. + default:
  31118. + priv->card_8187_Bversion = VERSION_8187_B;
  31119. + break;
  31120. + }
  31121. + }else{
  31122. + hw_version = read_nic_byte(dev, 0xe1); //87B hw version reg
  31123. + switch (hw_version){
  31124. + case 0x00:
  31125. + priv->card_8187_Bversion = VERSION_8187B_B;
  31126. + break;
  31127. + case 0x01:
  31128. + priv->card_8187_Bversion = VERSION_8187B_D;
  31129. + break;
  31130. + case 0x02:
  31131. + priv->card_8187_Bversion = VERSION_8187B_E;
  31132. + break;
  31133. + default:
  31134. + priv->card_8187_Bversion = VERSION_8187B_B; //defalt
  31135. + break;
  31136. + }
  31137. + }
  31138. +
  31139. + //printk("=====hw_version:%x\n", priv->card_8187_Bversion);
  31140. + priv->enable_gpio0 = 0;
  31141. +
  31142. + /*the eeprom type is stored in RCR register bit #6 */
  31143. + if (RCR_9356SEL & read_nic_dword(dev, RCR)){
  31144. + priv->epromtype=EPROM_93c56;
  31145. + DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
  31146. + }else{
  31147. + priv->epromtype=EPROM_93c46;
  31148. + DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
  31149. + }
  31150. +
  31151. + dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
  31152. + dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
  31153. + dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
  31154. + dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
  31155. + dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
  31156. + dev->dev_addr[5]=((eprom_read(dev,MAC_ADR+2) & 0xff00)>>8)+1;
  31157. +
  31158. + DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
  31159. +
  31160. + for(i=1,j=0; i<6; i+=2,j++){
  31161. +
  31162. + word = eprom_read(dev,EPROM_TXPW0 + j);
  31163. + priv->chtxpwr[i]=word & 0xf;
  31164. + priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4;
  31165. + priv->chtxpwr[i+1]=(word & 0xf00)>>8;
  31166. + priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12;
  31167. + }
  31168. +
  31169. + for(i=1,j=0; i<4; i+=2,j++){
  31170. +
  31171. + word = eprom_read(dev,EPROM_TXPW1 + j);
  31172. + priv->chtxpwr[i+6]=word & 0xf;
  31173. + priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4;
  31174. + priv->chtxpwr[i+6+1]=(word & 0xf00)>>8;
  31175. + priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12;
  31176. + }
  31177. + if (priv->card_8187 == NIC_8187){
  31178. + for(i=1,j=0; i<4; i+=2,j++){
  31179. + word = eprom_read(dev,EPROM_TXPW2 + j);
  31180. + priv->chtxpwr[i+6+4]=word & 0xf;
  31181. + priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4;
  31182. + priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8;
  31183. + priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12;
  31184. + }
  31185. + } else{
  31186. + word = eprom_read(dev, 0x1B) & 0xff; //channel 11;
  31187. + priv->chtxpwr[11]=word & 0xf;
  31188. + priv->chtxpwr_ofdm[11] = (word & 0xf0)>>4;
  31189. +
  31190. + word = eprom_read(dev, 0xA) & 0xff; //channel 12;
  31191. + priv->chtxpwr[12]=word & 0xf;
  31192. + priv->chtxpwr_ofdm[12] = (word & 0xf0)>>4;
  31193. +
  31194. + word = eprom_read(dev, 0x1c) ; //channel 13 ,14;
  31195. + priv->chtxpwr[13]=word & 0xf;
  31196. + priv->chtxpwr_ofdm[13] = (word & 0xf0)>>4;
  31197. + priv->chtxpwr[14]=(word & 0xf00)>>8;
  31198. + priv->chtxpwr_ofdm[14] = (word & 0xf000)>>12;
  31199. + }
  31200. +
  31201. + word = eprom_read(dev,EPROM_TXPW_BASE);
  31202. + priv->cck_txpwr_base = word & 0xf;
  31203. + priv->ofdm_txpwr_base = (word>>4) & 0xf;
  31204. +
  31205. + //DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7);
  31206. +
  31207. +#ifdef SW_ANTE_DIVERSITY
  31208. + rtl8187_antenna_diversity_read(dev);
  31209. +#endif
  31210. +
  31211. + if(rtl8187_usb_initendpoints(dev)!=0){
  31212. + DMESG("Endopoints initialization failed");
  31213. + return -ENOMEM;
  31214. + }
  31215. +#ifdef LED
  31216. + InitSwLeds(dev);
  31217. +#endif
  31218. +#ifdef DEBUG_EPROM
  31219. + dump_eprom(dev);
  31220. +#endif
  31221. + return 0;
  31222. +
  31223. +}
  31224. +
  31225. +void rtl8185_rf_pins_enable(struct net_device *dev)
  31226. +{
  31227. +/* u16 tmp;
  31228. + tmp = read_nic_word(dev, RFPinsEnable);*/
  31229. + write_nic_word(dev, RFPinsEnable, 0x1ff7);// | tmp);
  31230. +}
  31231. +
  31232. +
  31233. +void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
  31234. +{
  31235. + u8 conf3;
  31236. +
  31237. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  31238. +
  31239. + conf3 = read_nic_byte(dev, CONFIG3);
  31240. + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
  31241. +
  31242. + write_nic_dword(dev, ANAPARAM2, a);
  31243. +
  31244. + conf3 = read_nic_byte(dev, CONFIG3);
  31245. + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
  31246. +
  31247. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  31248. +
  31249. +}
  31250. +
  31251. +
  31252. +void rtl8180_set_anaparam(struct net_device *dev, u32 a)
  31253. +{
  31254. + u8 conf3;
  31255. +
  31256. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  31257. +
  31258. + conf3 = read_nic_byte(dev, CONFIG3);
  31259. + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
  31260. +
  31261. + write_nic_dword(dev, ANAPARAM, a);
  31262. +
  31263. + conf3 = read_nic_byte(dev, CONFIG3);
  31264. + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
  31265. +
  31266. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  31267. +
  31268. +}
  31269. +
  31270. +
  31271. +void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
  31272. +{
  31273. + write_nic_byte(dev, ANTSEL, ant);
  31274. + //lzm mod for up take too long time 20081201
  31275. + //mdelay(1);
  31276. +}
  31277. +
  31278. +
  31279. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data)
  31280. +{
  31281. + u32 phyw;
  31282. +
  31283. + adr |= 0x80;
  31284. +
  31285. + phyw= ((data<<8) | adr);
  31286. +
  31287. +
  31288. +
  31289. + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
  31290. + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
  31291. + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
  31292. + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
  31293. + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
  31294. +
  31295. + //read_nic_dword(dev, PHY_ADR);
  31296. +#if 0
  31297. + for(i=0;i<10;i++){
  31298. + write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
  31299. + phyr = read_nic_byte(dev, PHY_READ);
  31300. + if(phyr == (data&0xff)) break;
  31301. +
  31302. + }
  31303. +#endif
  31304. + /* this is ok to fail when we write AGC table. check for AGC table might be
  31305. + * done by masking with 0x7f instead of 0xff */
  31306. + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr);
  31307. + //msdelay(1);//CPU occupany is too high. LZM 31/10/2008
  31308. +}
  31309. +
  31310. +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data)
  31311. +{
  31312. + u32 phyw;
  31313. +
  31314. + adr &= ~0x80;
  31315. + phyw= ((data<<8) | adr);
  31316. +
  31317. +
  31318. + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
  31319. + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
  31320. + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
  31321. + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
  31322. + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
  31323. +
  31324. + return(read_nic_byte(dev,0x7e));
  31325. +
  31326. +}
  31327. +
  31328. +u8 read_phy_ofdm(struct net_device *dev, u8 adr)
  31329. +{
  31330. + return(rtl8187_read_phy(dev, adr, 0x000000));
  31331. +}
  31332. +
  31333. +u8 read_phy_cck(struct net_device *dev, u8 adr)
  31334. +{
  31335. + return(rtl8187_read_phy(dev, adr, 0x10000));
  31336. +}
  31337. +
  31338. +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
  31339. +{
  31340. + data = data & 0xff;
  31341. + rtl8187_write_phy(dev, adr, data);
  31342. +}
  31343. +
  31344. +
  31345. +void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
  31346. +{
  31347. + data = data & 0xff;
  31348. + rtl8187_write_phy(dev, adr, data | 0x10000);
  31349. +}
  31350. +//
  31351. +// Description: Change ZEBRA's power state.
  31352. +//
  31353. +// Assumption: This function must be executed in PASSIVE_LEVEL.
  31354. +//
  31355. +// 061214, by rcnjko.
  31356. +//
  31357. +//#define MAX_DOZE_WAITING_TIMES_87B 1000//500
  31358. +#define MAX_DOZE_WAITING_TIMES_87B_MOD 500
  31359. +
  31360. +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
  31361. +{
  31362. + struct r8180_priv *priv = ieee80211_priv(dev);
  31363. + u8 btCR9346, btConfig3;
  31364. + bool bResult = true;
  31365. + int i;
  31366. + u16 u2bTFPC = 0;
  31367. + u8 u1bTmp;
  31368. +
  31369. + // Set EEM0 and EEM1 in 9346CR.
  31370. + btCR9346 = read_nic_byte(dev, CR9346);
  31371. + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
  31372. + // Set PARM_En in Config3.
  31373. + btConfig3 = read_nic_byte(dev, CONFIG3);
  31374. + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
  31375. + // BB and RF related operations:
  31376. + switch(eRFPowerState)
  31377. + {
  31378. + case eRfOn:
  31379. +#ifdef CONFIG_RADIO_DEBUG
  31380. + DMESG("Now Radio ON!");
  31381. +#endif
  31382. + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
  31383. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
  31384. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType));
  31385. +
  31386. + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
  31387. + write_rtl8225(dev, 0x4, 0x9FF);
  31388. + mdelay(1);
  31389. + //
  31390. + // <Roger_Notes> We reset PLL to reduce power consumption about 30 mA. 2008.01.16.
  31391. + //
  31392. + {
  31393. + u8 Reg62;
  31394. +
  31395. + write_nic_byte(dev, 0x61, 0x10);
  31396. + Reg62 = read_nic_byte(dev, 0x62);
  31397. + write_nic_byte(dev, 0x62, (Reg62 & (~BIT5)) );
  31398. + write_nic_byte(dev, 0x62, (Reg62 | BIT5) ); // Enable PLL.
  31399. + }
  31400. +
  31401. + u1bTmp = read_nic_byte(dev, 0x24E);
  31402. + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
  31403. + break;
  31404. +
  31405. + case eRfSleep:
  31406. +#ifdef CONFIG_RADIO_DEBUG
  31407. + DMESG("Now Radio Sleep!");
  31408. +#endif
  31409. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
  31410. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  31411. + u2bTFPC = read_nic_word(dev, TFPC);
  31412. + if(u2bTFPC == 0){
  31413. + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
  31414. + break;
  31415. + }else{
  31416. + //printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
  31417. + udelay(10);
  31418. + }
  31419. + }
  31420. +
  31421. + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD ){
  31422. + //printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
  31423. + }
  31424. +
  31425. + u1bTmp = read_nic_byte(dev, 0x24E);
  31426. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  31427. +
  31428. + write_rtl8225(dev, 0x4, 0xDFF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  31429. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  31430. +
  31431. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  31432. +
  31433. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  31434. + write_nic_dword(dev, ANAPARAM2, 0x72303f70); // 070126, by SD1 William.
  31435. + break;
  31436. +
  31437. + case eRfOff:
  31438. +#ifdef CONFIG_RADIO_DEBUG
  31439. + DMESG("Now Radio OFF!");
  31440. +#endif
  31441. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
  31442. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  31443. + u2bTFPC = read_nic_word(dev, TFPC);
  31444. + if(u2bTFPC == 0) {
  31445. + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
  31446. + break;
  31447. + }else{
  31448. + //printk("%d times TFPC: 0x%x != 0 before doze!\n", (i+1), u2bTFPC);
  31449. + udelay(10);
  31450. + }
  31451. + }
  31452. +
  31453. + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD){
  31454. + //printk("\n\n\nSetZebraRFPowerState8187B(): %d times TFPC: 0x%x != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
  31455. + }
  31456. +
  31457. + u1bTmp = read_nic_byte(dev, 0x24E);
  31458. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  31459. +
  31460. + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  31461. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  31462. +
  31463. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  31464. +
  31465. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  31466. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
  31467. + break;
  31468. +
  31469. + default:
  31470. + bResult = false;
  31471. + //printk("SetZebraRFPowerState8187B(): unknow state to set: 0x%X!!!\n", eRFPowerState);
  31472. + break;
  31473. + }
  31474. +
  31475. + // Clear PARM_En in Config3.
  31476. + btConfig3 &= ~(CONFIG3_PARM_En);
  31477. + write_nic_byte(dev, CONFIG3, btConfig3);
  31478. + // Clear EEM0 and EEM1 in 9346CR.
  31479. + btCR9346 &= ~(0xC0);
  31480. + write_nic_byte(dev, CR9346, btCR9346);
  31481. +
  31482. + if(bResult){
  31483. + // Update current RF state variable.
  31484. + priv->eRFPowerState = eRFPowerState;
  31485. + }
  31486. +
  31487. + return bResult;
  31488. +}
  31489. +//by amy for ps
  31490. +//
  31491. +// Description: Chang RF Power State.
  31492. +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
  31493. +//
  31494. +// Assumption:PASSIVE LEVEL.
  31495. +//
  31496. +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
  31497. +{
  31498. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31499. + bool bResult = false;
  31500. +
  31501. + //printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
  31502. + if(eRFPowerState == priv->eRFPowerState)
  31503. + {
  31504. + //printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
  31505. + return bResult;
  31506. + }
  31507. +
  31508. + switch(priv->rf_chip)
  31509. + {
  31510. + case RF_ZEBRA2:
  31511. + bResult = SetZebraRFPowerState8187B(dev, eRFPowerState);
  31512. + break;
  31513. +
  31514. + default:
  31515. + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
  31516. + break;;
  31517. + }
  31518. + //printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
  31519. +
  31520. + return bResult;
  31521. +}
  31522. +
  31523. +bool
  31524. +MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource)
  31525. +{
  31526. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31527. + bool bActionAllowed = false;
  31528. + bool bConnectBySSID = false;
  31529. + RT_RF_POWER_STATE rtState;
  31530. + u16 RFWaitCounter = 0;
  31531. + unsigned long flag;
  31532. + // printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
  31533. + //
  31534. + // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
  31535. + // Only one thread can change the RF state at one time, and others should wait to be executed.
  31536. + //
  31537. +#if 1
  31538. + while(true)
  31539. + {
  31540. + //down(&priv->rf_state);
  31541. + spin_lock_irqsave(&priv->rf_ps_lock,flag);
  31542. + if(priv->RFChangeInProgress)
  31543. + {
  31544. + //up(&priv->rf_state);
  31545. + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
  31546. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  31547. + // Set RF after the previous action is done.
  31548. + while(priv->RFChangeInProgress)
  31549. + {
  31550. + RFWaitCounter ++;
  31551. + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
  31552. + udelay(1000); // 1 ms
  31553. +
  31554. + // Wait too long, return FALSE to avoid to be stuck here.
  31555. + if(RFWaitCounter > 1000) // 1sec
  31556. + {
  31557. + // DMESG("MgntActSet_RF_State(): Wait too long to set RF");
  31558. + // TODO: Reset RF state?
  31559. + return false;
  31560. + }
  31561. + }
  31562. + }
  31563. + else
  31564. + {
  31565. + priv->RFChangeInProgress = true;
  31566. +// up(&priv->rf_state);
  31567. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  31568. + break;
  31569. + }
  31570. + }
  31571. +#endif
  31572. + rtState = priv->eRFPowerState;
  31573. +
  31574. + switch(StateToSet)
  31575. + {
  31576. + case eRfOn:
  31577. + //
  31578. + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
  31579. + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
  31580. + //
  31581. + // leave last reasons and kick this reason till priv->RfOffReason = 0;
  31582. + // if one reason turn radio off check if off->on reason is the same.if so turn, or reject it.
  31583. + // if more than 1 reasons turn radio off we only turn on radio when all reasons turn on radio,
  31584. + // so first turn on trys will reject till priv->RfOffReason = 0;
  31585. + priv->RfOffReason &= (~ChangeSource);
  31586. +
  31587. + if(! priv->RfOffReason)
  31588. + {
  31589. + priv->RfOffReason = 0;
  31590. + bActionAllowed = true;
  31591. +
  31592. + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
  31593. + {
  31594. + bConnectBySSID = true;
  31595. + }
  31596. + } else {
  31597. + ;//lzm must or TX_PENDING 12>MAX_TX_URB
  31598. + //printk("Turn Radio On Reject because RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
  31599. + }
  31600. + break;
  31601. +
  31602. + case eRfOff:
  31603. + // 070125, rcnjko: we always keep connected in AP mode.
  31604. + if (priv->RfOffReason > RF_CHANGE_BY_IPS)
  31605. + {
  31606. + //
  31607. + // 060808, Annie:
  31608. + // Disconnect to current BSS when radio off. Asked by QuanTa.
  31609. + //
  31610. +
  31611. + //
  31612. + // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
  31613. + // because we do NOT need to set ssid to dummy ones.
  31614. + // Revised by Roger, 2007.12.04.
  31615. + //
  31616. +//by amy not supported
  31617. + //MgntDisconnect( dev, disas_lv_ss );
  31618. +
  31619. + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
  31620. + // 2007.05.28, by shien chang.
  31621. + //PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
  31622. + //pMgntInfo->NumBssDesc = 0;
  31623. + //PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
  31624. + //pMgntInfo->NumBssDesc4Query = 0;
  31625. + }
  31626. +
  31627. +
  31628. +
  31629. + priv->RfOffReason |= ChangeSource;
  31630. + bActionAllowed = true;
  31631. + //printk("Turn Radio Off RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
  31632. + break;
  31633. +
  31634. + case eRfSleep:
  31635. + priv->RfOffReason |= ChangeSource;
  31636. + bActionAllowed = true;
  31637. + break;
  31638. +
  31639. + default:
  31640. + break;
  31641. + }
  31642. +
  31643. + if(bActionAllowed)
  31644. + {
  31645. + // Config HW to the specified mode.
  31646. + //printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
  31647. + SetRFPowerState(dev, StateToSet);
  31648. + // Turn on RF.
  31649. + if(StateToSet == eRfOn)
  31650. + {
  31651. + //HalEnableRx8185Dummy(dev);
  31652. + if(bConnectBySSID)
  31653. + {
  31654. + // by amy not supported
  31655. + //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
  31656. + }
  31657. + }
  31658. + // Turn off RF.
  31659. + else if(StateToSet == eRfOff)
  31660. + {
  31661. + //HalDisableRx8185Dummy(dev);
  31662. + }
  31663. + }
  31664. + else
  31665. + {
  31666. + //printk("Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n",
  31667. + // StateToSet, ChangeSource, priv->RfOffReason);
  31668. + }
  31669. +
  31670. + // Release RF spinlock
  31671. + //down(&priv->rf_state);
  31672. + spin_lock_irqsave(&priv->rf_ps_lock,flag);
  31673. + priv->RFChangeInProgress = false;
  31674. + //up(&priv->rf_state);
  31675. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  31676. + return bActionAllowed;
  31677. +}
  31678. +//by amy for ps
  31679. +
  31680. +void rtl8180_adapter_start(struct net_device *dev)
  31681. +{
  31682. + struct r8180_priv *priv = ieee80211_priv(dev);
  31683. +// struct ieee80211_device *ieee = priv->ieee80211;
  31684. +// u8 InitWirelessMode;
  31685. +// u8 SupportedWirelessMode;
  31686. +// bool bInvalidWirelessMode = false;
  31687. +
  31688. +
  31689. + if(NIC_8187 == priv->card_8187) {
  31690. + //rtl8180_rtx_disable(dev);
  31691. + rtl8180_reset(dev);
  31692. +
  31693. + write_nic_byte(dev,0x85,0);
  31694. + write_nic_byte(dev,0x91,0);
  31695. +
  31696. + /* light blink! */
  31697. + write_nic_byte(dev,0x85,4);
  31698. + write_nic_byte(dev,0x91,1);
  31699. + write_nic_byte(dev,0x90,0);
  31700. +
  31701. + //by lizhaoming for LED POWR ON
  31702. + //LedControl8187(dev, LED_CTL_POWER_ON);
  31703. +
  31704. + /*
  31705. + write_nic_byte(dev, CR9346, 0xC0);
  31706. + //LED TYPE
  31707. + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
  31708. + write_nic_byte(dev, CR9346, 0x0); // disable config register write
  31709. + */
  31710. + priv->irq_mask = 0xffff;
  31711. + /*
  31712. + priv->dma_poll_mask = 0;
  31713. + priv->dma_poll_mask|= (1<<TX_DMA_STOP_BEACON_SHIFT);
  31714. + */
  31715. + // rtl8180_beacon_tx_disable(dev);
  31716. +
  31717. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  31718. + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
  31719. + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
  31720. +
  31721. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  31722. + rtl8180_update_msr(dev);
  31723. +
  31724. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  31725. +
  31726. + write_nic_word(dev,0xf4,0xffff);
  31727. + write_nic_byte(dev,
  31728. + CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);
  31729. +
  31730. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  31731. +
  31732. + write_nic_dword(dev,INT_TIMEOUT,0);
  31733. +
  31734. +#ifdef DEBUG_REGISTERS
  31735. + rtl8180_dump_reg(dev);
  31736. +#endif
  31737. +
  31738. +
  31739. + write_nic_byte(dev, WPA_CONFIG, 0);
  31740. +
  31741. + write_nic_byte(dev, RATE_FALLBACK, 0x81);
  31742. + rtl8187_set_rate(dev);
  31743. +
  31744. + priv->rf_init(dev);
  31745. +
  31746. + if(priv->rf_set_sens != NULL) {
  31747. + priv->rf_set_sens(dev,priv->sens);
  31748. + }
  31749. +
  31750. + write_nic_word(dev,0x5e,1);
  31751. + //mdelay(1);
  31752. + write_nic_word(dev,0xfe,0x10);
  31753. + // mdelay(1);
  31754. + write_nic_byte(dev, TALLY_SEL, 0x80);//Set NQ retry count
  31755. + write_nic_byte(dev, 0xff, 0x60);
  31756. + write_nic_word(dev,0x5e,0);
  31757. +
  31758. + rtl8180_irq_enable(dev);
  31759. + } else {
  31760. + /**
  31761. + * IO part migrated from Windows Driver.
  31762. + */
  31763. + priv->irq_mask = 0xffff;
  31764. + // Enable Config3.PARAM_En.
  31765. + write_nic_byte(dev, CR9346, 0xC0);
  31766. +
  31767. + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)| CONFIG3_PARM_En|CONFIG3_GNTSel));
  31768. + // Turn on Analog power.
  31769. + // setup A/D D/A parameter for 8185 b2
  31770. + // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
  31771. + write_nic_dword(dev, ANA_PARAM2, ANAPARM2_ASIC_ON);
  31772. + write_nic_dword(dev, ANA_PARAM, ANAPARM_ASIC_ON);
  31773. + write_nic_byte(dev, ANA_PARAM3, 0x00);
  31774. +
  31775. + //by lizhaoming for LED POWR ON
  31776. + //LedControl8187(dev, LED_CTL_POWER_ON);
  31777. +
  31778. + {//added for reset PLL
  31779. + u8 bReg62;
  31780. + write_nic_byte(dev, 0x61, 0x10);
  31781. + bReg62 = read_nic_byte(dev, 0x62);
  31782. + write_nic_byte(dev, 0x62, bReg62&(~(0x1<<5)));
  31783. + write_nic_byte(dev, 0x62, bReg62|(0x1<<5));
  31784. + }
  31785. + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
  31786. + write_nic_byte(dev, CR9346, 0x00);
  31787. +
  31788. + //rtl8180_rtx_disable(dev);
  31789. + rtl8180_reset(dev);
  31790. + write_nic_byte(dev, CR9346, 0xc0); // enable config register write
  31791. + priv->rf_init(dev);
  31792. + // Enable tx/rx
  31793. +
  31794. + write_nic_byte(dev, CMD, (CR_RE|CR_TE));// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
  31795. +
  31796. + //add this is for 8187B Rx stall problem
  31797. +
  31798. + rtl8180_irq_enable(dev);
  31799. +
  31800. + write_nic_byte_E(dev, 0x41, 0xF4);
  31801. + write_nic_byte_E(dev, 0x40, 0x00);
  31802. + write_nic_byte_E(dev, 0x42, 0x00);
  31803. + write_nic_byte_E(dev, 0x42, 0x01);
  31804. + write_nic_byte_E(dev, 0x40, 0x0F);
  31805. + write_nic_byte_E(dev, 0x42, 0x00);
  31806. + write_nic_byte_E(dev, 0x42, 0x01);
  31807. +
  31808. + // 8187B demo board MAC and AFE power saving parameters from SD1 William, 2006.07.20.
  31809. + // Parameter revised by SD1 William, 2006.08.21:
  31810. + // 373h -> 0x4F // Original: 0x0F
  31811. + // 377h -> 0x59 // Original: 0x4F
  31812. + // Victor 2006/8/21: 竅�繒q簞�翹�竄��糧繕瞼SD3 簞穠禮C繚� and cable link test OK瞻~瞼聶礎癒 release,瞻瞿竄��糧瞻�禮�
  31813. + // 2006/9/5, Victor & ED: it is OK to use.
  31814. + //if(pHalData->RegBoardType == BT_DEMO_BOARD)
  31815. + //{
  31816. + // AFE.
  31817. + //
  31818. + // Revise the content of Reg0x372, 0x374, 0x378 and 0x37a to fix unusual electronic current
  31819. + // while CTS-To-Self occurs, by DZ's request.
  31820. + // Modified by Roger, 2007.06.22.
  31821. + //
  31822. + write_nic_byte(dev, 0x0DB, (read_nic_byte(dev, 0x0DB)|(BIT2)));
  31823. + write_nic_word(dev, 0x372, 0x59FA); // 0x4FFA-> 0x59FA.
  31824. + write_nic_word(dev, 0x374, 0x59D2); // 0x4FD2-> 0x59D2.
  31825. + write_nic_word(dev, 0x376, 0x59D2);
  31826. + write_nic_word(dev, 0x378, 0x19FA); // 0x0FFA-> 0x19FA.
  31827. + write_nic_word(dev, 0x37A, 0x19FA); // 0x0FFA-> 0x19FA.
  31828. + write_nic_word(dev, 0x37C, 0x00D0);
  31829. +
  31830. + write_nic_byte(dev, 0x061, 0x00);
  31831. +
  31832. + // MAC.
  31833. + write_nic_byte(dev, 0x180, 0x0F);
  31834. + write_nic_byte(dev, 0x183, 0x03);
  31835. + // 061218, lanhsin: for victorh request
  31836. + write_nic_byte(dev, 0x0DA, 0x10);
  31837. + //}
  31838. +
  31839. + //
  31840. + // 061213, rcnjko:
  31841. + // Set MAC.0x24D to 0x00 to prevent cts-to-self Tx/Rx stall symptom.
  31842. + // If we set MAC 0x24D to 0x08, OFDM and CCK will turn off
  31843. + // if not in use, and there is a bug about this action when
  31844. + // we try to send CCK CTS and OFDM data together.
  31845. + //
  31846. + //PlatformEFIOWrite1Byte(Adapter, 0x24D, 0x00);
  31847. + // 061218, lanhsin: for victorh request
  31848. + write_nic_byte(dev, 0x24D, 0x08);
  31849. +
  31850. + //
  31851. + // 061215, rcnjko:
  31852. + // Follow SD3 RTL8185B_87B_MacPhy_Register.doc v0.4.
  31853. + //
  31854. + write_nic_dword(dev, HSSI_PARA, 0x0600321B);
  31855. + //
  31856. + // 061226, rcnjko:
  31857. + // Babble found in HCT 2c_simultaneous test, server with 87B might
  31858. + // receive a packet size about 2xxx bytes.
  31859. + // So, we restrict RMS to 2048 (0x800), while as IC default value is 0xC00.
  31860. + //
  31861. + write_nic_word(dev, RMS, 0x0800);
  31862. +
  31863. + /*****20070321 Resolve HW page bug on system logo test
  31864. + u8 faketemp=read_nic_byte(dev, 0x50);*/
  31865. + }
  31866. +}
  31867. +
  31868. +/* this configures registers for beacon tx and enables it via
  31869. + * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
  31870. + * be used to stop beacon transmission
  31871. + */
  31872. +#if 0
  31873. +void rtl8180_start_tx_beacon(struct net_device *dev)
  31874. +{
  31875. + int i;
  31876. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31877. + u16 word;
  31878. + DMESG("Enabling beacon TX");
  31879. + //write_nic_byte(dev, 0x42,0xe6);// TCR
  31880. + //rtl8180_init_beacon(dev);
  31881. + //set_nic_txring(dev);
  31882. +// rtl8180_prepare_beacon(dev);
  31883. + rtl8180_irq_disable(dev);
  31884. +// rtl8180_beacon_tx_enable(dev);
  31885. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  31886. + //write_nic_byte(dev,0x9d,0x20); //DMA Poll
  31887. + //write_nic_word(dev,0x7a,0);
  31888. + //write_nic_word(dev,0x7a,0x8000);
  31889. +
  31890. +
  31891. + word = read_nic_word(dev, BcnItv);
  31892. + word &= ~BcnItv_BcnItv; // clear Bcn_Itv
  31893. + write_nic_word(dev, BcnItv, word);
  31894. +
  31895. + write_nic_word(dev, AtimWnd,
  31896. + read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
  31897. +
  31898. + word = read_nic_word(dev, BintrItv);
  31899. + word &= ~BintrItv_BintrItv;
  31900. +
  31901. + //word |= priv->ieee80211->beacon_interval *
  31902. + // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
  31903. + // FIXME:FIXME check if correct ^^ worked with 0x3e8;
  31904. +
  31905. + write_nic_word(dev, BintrItv, word);
  31906. +
  31907. + //write_nic_word(dev,0x2e,0xe002);
  31908. + //write_nic_dword(dev,0x30,0xb8c7832e);
  31909. + for(i=0; i<ETH_ALEN; i++)
  31910. + write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
  31911. +
  31912. +// rtl8180_update_msr(dev);
  31913. +
  31914. +
  31915. + //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
  31916. +
  31917. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  31918. +
  31919. + rtl8180_irq_enable(dev);
  31920. +
  31921. + /* VV !!!!!!!!!! VV*/
  31922. + /*
  31923. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  31924. + write_nic_byte(dev,0x9d,0x00);
  31925. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  31926. +*/
  31927. +}
  31928. +#endif
  31929. +/***************************************************************************
  31930. + -------------------------------NET STUFF---------------------------
  31931. +***************************************************************************/
  31932. +static struct net_device_stats *rtl8180_stats(struct net_device *dev)
  31933. +{
  31934. + struct r8180_priv *priv = ieee80211_priv(dev);
  31935. +
  31936. + return &priv->ieee80211->stats;
  31937. +}
  31938. +
  31939. +int _rtl8180_up(struct net_device *dev)
  31940. +{
  31941. + struct r8180_priv *priv = ieee80211_priv(dev);
  31942. + //int i;
  31943. +
  31944. + priv->driver_upping = 1;
  31945. + priv->up=1;
  31946. +
  31947. +#ifdef LED
  31948. + if(priv->ieee80211->bHwRadioOff == false)
  31949. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON);
  31950. +#endif
  31951. + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_SW);
  31952. +
  31953. + rtl8180_adapter_start(dev);
  31954. + rtl8180_rx_enable(dev);
  31955. + rtl8180_tx_enable(dev);
  31956. +//by amy for rate adaptive
  31957. + timer_rate_adaptive((unsigned long)dev);
  31958. +//by amy for rate adaptive
  31959. +
  31960. +#ifdef SW_ANTE_DIVERSITY
  31961. + if(priv->bSwAntennaDiverity){
  31962. + //DMESG("SW Antenna Diversity Enable!");
  31963. + SwAntennaDiversityTimerCallback(dev);
  31964. + }
  31965. +#endif
  31966. +
  31967. + ieee80211_softmac_start_protocol(priv->ieee80211);
  31968. +
  31969. +//by amy for ps
  31970. + watch_dog_adaptive((unsigned long)dev);
  31971. +//by amy for ps
  31972. +
  31973. + ieee80211_reset_queue(priv->ieee80211);
  31974. + if(!netif_queue_stopped(dev))
  31975. + netif_start_queue(dev);
  31976. + else
  31977. + netif_wake_queue(dev);
  31978. +
  31979. +#ifndef CONFIG_SOFT_BEACON
  31980. + if(NIC_8187B == priv->card_8187)
  31981. + rtl8187_rx_manage_initiate(dev);
  31982. +#endif
  31983. +
  31984. +#ifdef _RTL8187_EXT_PATCH_
  31985. + if(priv->mshobj && priv->mshobj->ext_patch_rtl8180_up )
  31986. + priv->mshobj->ext_patch_rtl8180_up(priv->mshobj);
  31987. +#endif
  31988. +
  31989. +
  31990. + priv->driver_upping = 0;
  31991. + //DMESG("rtl8187_open process complete");
  31992. + return 0;
  31993. +}
  31994. +
  31995. +
  31996. +int rtl8180_open(struct net_device *dev)
  31997. +{
  31998. + struct r8180_priv *priv = ieee80211_priv(dev);
  31999. + int ret;
  32000. +//changed by lizhaoming for power on/off
  32001. + if(priv->ieee80211->bHwRadioOff == false){
  32002. + //DMESG("rtl8187_open process ");
  32003. + down(&priv->wx_sem);
  32004. + ret = rtl8180_up(dev);
  32005. + up(&priv->wx_sem);
  32006. + return ret;
  32007. + }else{
  32008. + DMESG("rtl8187_open process failed because radio off");
  32009. + return -1;
  32010. + }
  32011. +
  32012. +}
  32013. +
  32014. +
  32015. +int rtl8180_up(struct net_device *dev)
  32016. +{
  32017. + struct r8180_priv *priv = ieee80211_priv(dev);
  32018. +
  32019. + if (priv->up == 1) return -1;
  32020. +
  32021. + return _rtl8180_up(dev);
  32022. +}
  32023. +
  32024. +
  32025. +int rtl8180_close(struct net_device *dev)
  32026. +{
  32027. + struct r8180_priv *priv = ieee80211_priv(dev);
  32028. + int ret;
  32029. +
  32030. + if (priv->up == 0) return -1;
  32031. +
  32032. + down(&priv->wx_sem);
  32033. +
  32034. + //DMESG("rtl8187_close process");
  32035. + ret = rtl8180_down(dev);
  32036. +#ifdef LED
  32037. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF);
  32038. +#endif
  32039. + up(&priv->wx_sem);
  32040. +
  32041. + return ret;
  32042. +
  32043. +}
  32044. +
  32045. +int rtl8180_down(struct net_device *dev)
  32046. +{
  32047. + struct r8180_priv *priv = ieee80211_priv(dev);
  32048. +
  32049. + if (priv->up == 0) return -1;
  32050. +
  32051. + priv->up=0;
  32052. +
  32053. +/* FIXME */
  32054. + if (!netif_queue_stopped(dev))
  32055. + netif_stop_queue(dev);
  32056. +
  32057. + //DMESG("rtl8180_down process");
  32058. + rtl8180_rtx_disable(dev);
  32059. + rtl8180_irq_disable(dev);
  32060. +//by amy for rate adaptive
  32061. + del_timer_sync(&priv->rateadapter_timer);
  32062. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  32063. +//by amy for rate adaptive
  32064. + del_timer_sync(&priv->watch_dog_timer);
  32065. + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
  32066. + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
  32067. + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
  32068. +
  32069. +#ifdef SW_ANTE_DIVERSITY
  32070. + del_timer_sync(&priv->SwAntennaDiversityTimer);
  32071. + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
  32072. +#endif
  32073. +
  32074. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  32075. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
  32076. + //amy,081212
  32077. + memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
  32078. + return 0;
  32079. +}
  32080. +
  32081. +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
  32082. +
  32083. +void rtl8180_commit(struct net_device *dev)
  32084. +{
  32085. + struct r8180_priv *priv = ieee80211_priv(dev);
  32086. + int i;
  32087. +
  32088. + if (priv->up == 0) return ;
  32089. + printk("==========>%s()\n", __FUNCTION__);
  32090. +
  32091. + /* FIXME */
  32092. + if (!netif_queue_stopped(dev))
  32093. + netif_stop_queue(dev);
  32094. +
  32095. +//by amy for rate adaptive
  32096. + del_timer_sync(&priv->rateadapter_timer);
  32097. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  32098. +//by amy for rate adaptive
  32099. + del_timer_sync(&priv->watch_dog_timer);
  32100. + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
  32101. + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
  32102. + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
  32103. +
  32104. +#ifdef SW_ANTE_DIVERSITY
  32105. + del_timer_sync(&priv->SwAntennaDiversityTimer);
  32106. + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
  32107. +#endif
  32108. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  32109. +
  32110. +#if 0
  32111. + if(priv->ieee80211->bHwRadioOff == false){
  32112. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_HW);
  32113. + mdelay(10);
  32114. + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_HW);
  32115. + }
  32116. +#endif
  32117. +
  32118. + rtl8180_irq_disable(dev);
  32119. + rtl8180_rtx_disable(dev);
  32120. +
  32121. + //test pending bug, john 20070815
  32122. + //initialize tx_pending
  32123. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  32124. +
  32125. + _rtl8180_up(dev);
  32126. + priv->commit = 0;
  32127. +}
  32128. +
  32129. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  32130. +void rtl8180_restart(struct work_struct *work)
  32131. +{
  32132. + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
  32133. + struct ieee80211_device* ieee = priv->ieee80211;//for commit crash
  32134. + struct net_device *dev = ieee->dev;//for commit crash
  32135. +#else
  32136. +void rtl8180_restart(struct net_device *dev)
  32137. +{
  32138. +
  32139. + struct r8180_priv *priv = ieee80211_priv(dev);
  32140. +#endif
  32141. +
  32142. + down(&priv->wx_sem);
  32143. +
  32144. + rtl8180_commit(dev);
  32145. +
  32146. + up(&priv->wx_sem);
  32147. +}
  32148. +
  32149. +static void r8180_set_multicast(struct net_device *dev)
  32150. +{
  32151. + struct r8180_priv *priv = ieee80211_priv(dev);
  32152. + short promisc;
  32153. +
  32154. + //down(&priv->wx_sem);
  32155. +
  32156. + /* FIXME FIXME */
  32157. +
  32158. + promisc = (dev->flags & IFF_PROMISC) ? 1:0;
  32159. +
  32160. + if (promisc != priv->promisc)
  32161. + // rtl8180_commit(dev);
  32162. +
  32163. + priv->promisc = promisc;
  32164. +
  32165. + //schedule_work(&priv->reset_wq);
  32166. + //up(&priv->wx_sem);
  32167. +}
  32168. +
  32169. +
  32170. +int r8180_set_mac_adr(struct net_device *dev, void *mac)
  32171. +{
  32172. + struct r8180_priv *priv = ieee80211_priv(dev);
  32173. + struct sockaddr *addr = mac;
  32174. +
  32175. + down(&priv->wx_sem);
  32176. +
  32177. + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
  32178. +
  32179. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  32180. + schedule_work(&priv->reset_wq);
  32181. +#else
  32182. + schedule_task(&priv->reset_wq);
  32183. +#endif
  32184. + up(&priv->wx_sem);
  32185. +
  32186. + return 0;
  32187. +}
  32188. +
  32189. +struct ipw_param {
  32190. + u32 cmd;
  32191. + u8 sta_addr[ETH_ALEN];
  32192. + union {
  32193. + struct {
  32194. + u8 name;
  32195. + u32 value;
  32196. + } wpa_param;
  32197. + struct {
  32198. + u32 len;
  32199. + u8 reserved[32];
  32200. + u8 data[0];
  32201. + } wpa_ie;
  32202. + struct{
  32203. + u32 command;
  32204. + u32 reason_code;
  32205. + } mlme;
  32206. + struct {
  32207. + u8 alg[16];
  32208. + u8 set_tx;
  32209. + u32 err;
  32210. + u8 idx;
  32211. + u8 seq[8];
  32212. + u16 key_len;
  32213. + u8 key[0];
  32214. + } crypt;
  32215. +
  32216. + } u;
  32217. +};
  32218. +
  32219. +
  32220. +/* based on ipw2200 driver */
  32221. +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  32222. +{
  32223. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32224. + struct iwreq *wrq = (struct iwreq *)rq;
  32225. + int ret=-1;
  32226. +
  32227. +#ifdef JOHN_TKIP
  32228. + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
  32229. +
  32230. + struct ieee80211_device *ieee = priv->ieee80211;
  32231. + struct ipw_param *ipw = (struct ipw_param *)wrq->u.data.pointer;
  32232. + u32 key[4];
  32233. +
  32234. +#endif
  32235. +
  32236. +#ifdef _RTL8187_EXT_PATCH_
  32237. + if(priv->mshobj && (priv->ieee80211->iw_mode == priv->ieee80211->iw_ext_mode) && priv->mshobj->ext_patch_rtl8180_ioctl)
  32238. + {
  32239. + // DO NOT put the belowing function in critical section, due to it uses "spin lock"
  32240. + if((ret = priv->mshobj->ext_patch_rtl8180_ioctl(dev, rq, cmd)) != -EOPNOTSUPP)
  32241. + return ret;
  32242. + }
  32243. +#endif
  32244. +
  32245. + down(&priv->wx_sem);
  32246. +
  32247. + switch (cmd) {
  32248. + case RTL_IOCTL_WPA_SUPPLICANT:
  32249. +#ifdef JOHN_TKIP
  32250. +
  32251. +//the following code is specified for ipw driver in wpa_supplicant
  32252. + if( ((u32*)wrq->u.data.pointer)[0]==3 ){
  32253. +
  32254. +
  32255. + if( ((u32*)wrq->u.data.pointer)[7] &&
  32256. + ( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ||
  32257. + ((u32*)wrq->u.data.pointer)[3]==0x50494b54 )) {//50494b54 tkip and 504d4343 ccmp
  32258. +
  32259. + //enable HW security of TKIP and CCMP
  32260. + write_nic_byte(dev, WPA_CONFIG, SCR_TxSecEnable | SCR_RxSecEnable );
  32261. +
  32262. + //copy key from wpa_supplicant ioctl info
  32263. + key[0] = ((u32*)wrq->u.data.pointer)[12];
  32264. + key[1] = ((u32*)wrq->u.data.pointer)[13];
  32265. + key[2] = ((u32*)wrq->u.data.pointer)[14];
  32266. + key[3] = ((u32*)wrq->u.data.pointer)[15];
  32267. + switch (ieee->pairwise_key_type){
  32268. + case KEY_TYPE_TKIP:
  32269. + setKey( dev,
  32270. + 0, //EntryNo
  32271. + ipw->u.crypt.idx, //KeyIndex
  32272. + KEY_TYPE_TKIP, //KeyType
  32273. + (u8*)ieee->ap_mac_addr, //MacAddr
  32274. + 0, //DefaultKey
  32275. + key); //KeyContent
  32276. + break;
  32277. +
  32278. + case KEY_TYPE_CCMP:
  32279. + setKey( dev,
  32280. + 0, //EntryNo
  32281. + ipw->u.crypt.idx, //KeyIndex
  32282. + KEY_TYPE_CCMP, //KeyType
  32283. + (u8*)ieee->ap_mac_addr, //MacAddr
  32284. + 0, //DefaultKey
  32285. + key); //KeyContent
  32286. + break
  32287. +;
  32288. + default:
  32289. + printk("error on key_type: %d\n", ieee->pairwise_key_type);
  32290. + break;
  32291. + }
  32292. + }
  32293. +
  32294. + //group key for broadcast
  32295. + if( ((u32*)wrq->u.data.pointer)[9] ) {
  32296. +
  32297. + key[0] = ((u32*)wrq->u.data.pointer)[12];
  32298. + key[1] = ((u32*)wrq->u.data.pointer)[13];
  32299. + key[2] = ((u32*)wrq->u.data.pointer)[14];
  32300. + key[3] = ((u32*)wrq->u.data.pointer)[15];
  32301. +
  32302. + if( ((u32*)wrq->u.data.pointer)[3]==0x50494b54 ){//50494b54 is the ASCII code of TKIP in reversed order
  32303. + setKey( dev,
  32304. + 1, //EntryNo
  32305. + ipw->u.crypt.idx,//KeyIndex
  32306. + KEY_TYPE_TKIP, //KeyType
  32307. + broadcast_addr, //MacAddr
  32308. + 0, //DefaultKey
  32309. + key); //KeyContent
  32310. + }
  32311. + else if( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ){//CCMP
  32312. + setKey( dev,
  32313. + 1, //EntryNo
  32314. + ipw->u.crypt.idx,//KeyIndex
  32315. + KEY_TYPE_CCMP, //KeyType
  32316. + broadcast_addr, //MacAddr
  32317. + 0, //DefaultKey
  32318. + key); //KeyContent
  32319. + }
  32320. + else if( ((u32*)wrq->u.data.pointer)[3]==0x656e6f6e ){//none
  32321. + //do nothing
  32322. + }
  32323. + else if( ((u32*)wrq->u.data.pointer)[3]==0x504557 ){//WEP
  32324. + setKey( dev,
  32325. + 1, //EntryNo
  32326. + ipw->u.crypt.idx,//KeyIndex
  32327. + KEY_TYPE_WEP40, //KeyType
  32328. + broadcast_addr, //MacAddr
  32329. + 0, //DefaultKey
  32330. + key); //KeyContent
  32331. + }
  32332. + else printk("undefine group key type: %8x\n", ((u32*)wrq->u.data.pointer)[3]);
  32333. + }
  32334. +
  32335. + }
  32336. +#endif /*JOHN_TKIP*/
  32337. +
  32338. +
  32339. +#ifdef JOHN_HWSEC_DEBUG
  32340. + {
  32341. + int i;
  32342. + //john's test 0711
  32343. + printk("@@ wrq->u pointer = ");
  32344. + for(i=0;i<wrq->u.data.length;i++){
  32345. + if(i%10==0) printk("\n");
  32346. + printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
  32347. + }
  32348. + printk("\n");
  32349. + }
  32350. +#endif /*JOHN_HWSEC_DEBUG*/
  32351. + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
  32352. + break;
  32353. +
  32354. + default:
  32355. + ret = -EOPNOTSUPP;
  32356. + break;
  32357. + }
  32358. +
  32359. + up(&priv->wx_sem);
  32360. +
  32361. + return ret;
  32362. +}
  32363. +
  32364. +
  32365. +struct tx_desc {
  32366. +
  32367. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  32368. +
  32369. +
  32370. +//dword 0
  32371. +unsigned int tpktsize:12;
  32372. +unsigned int rsvd0:3;
  32373. +unsigned int no_encrypt:1;
  32374. +unsigned int splcp:1;
  32375. +unsigned int morefrag:1;
  32376. +unsigned int ctsen:1;
  32377. +unsigned int rtsrate:4;
  32378. +unsigned int rtsen:1;
  32379. +unsigned int txrate:4;
  32380. +unsigned int last:1;
  32381. +unsigned int first:1;
  32382. +unsigned int dmaok:1;
  32383. +unsigned int own:1;
  32384. +
  32385. +//dword 1
  32386. +unsigned short rtsdur;
  32387. +unsigned short length:15;
  32388. +unsigned short l_ext:1;
  32389. +
  32390. +//dword 2
  32391. +unsigned int bufaddr;
  32392. +
  32393. +
  32394. +//dword 3
  32395. +unsigned short rxlen:12;
  32396. +unsigned short rsvd1:3;
  32397. +unsigned short miccal:1;
  32398. +unsigned short dur;
  32399. +
  32400. +//dword 4
  32401. +unsigned int nextdescaddr;
  32402. +
  32403. +//dword 5
  32404. +unsigned char rtsagc;
  32405. +unsigned char retrylimit;
  32406. +unsigned short rtdb:1;
  32407. +unsigned short noacm:1;
  32408. +unsigned short pifs:1;
  32409. +unsigned short rsvd2:4;
  32410. +unsigned short rtsratefallback:4;
  32411. +unsigned short ratefallback:5;
  32412. +
  32413. +//dword 6
  32414. +unsigned short delaybound;
  32415. +unsigned short rsvd3:4;
  32416. +unsigned short agc:8;
  32417. +unsigned short antenna:1;
  32418. +unsigned short spc:2;
  32419. +unsigned short rsvd4:1;
  32420. +
  32421. +//dword 7
  32422. +unsigned char len_adjust:2;
  32423. +unsigned char rsvd5:1;
  32424. +unsigned char tpcdesen:1;
  32425. +unsigned char tpcpolarity:2;
  32426. +unsigned char tpcen:1;
  32427. +unsigned char pten:1;
  32428. +
  32429. +unsigned char bckey:6;
  32430. +unsigned char enbckey:1;
  32431. +unsigned char enpmpd:1;
  32432. +unsigned short fragqsz;
  32433. +
  32434. +
  32435. +#else
  32436. +
  32437. +#error "please modify tx_desc to your own\n"
  32438. +
  32439. +#endif
  32440. +
  32441. +
  32442. +} __attribute__((packed));
  32443. +
  32444. +struct rx_desc_rtl8187b {
  32445. +
  32446. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  32447. +
  32448. +//dword 0
  32449. +unsigned int rxlen:12;
  32450. +unsigned int icv:1;
  32451. +unsigned int crc32:1;
  32452. +unsigned int pwrmgt:1;
  32453. +unsigned int res:1;
  32454. +unsigned int bar:1;
  32455. +unsigned int pam:1;
  32456. +unsigned int mar:1;
  32457. +unsigned int qos:1;
  32458. +unsigned int rxrate:4;
  32459. +unsigned int trsw:1;
  32460. +unsigned int splcp:1;
  32461. +unsigned int fovf:1;
  32462. +unsigned int dmafail:1;
  32463. +unsigned int last:1;
  32464. +unsigned int first:1;
  32465. +unsigned int eor:1;
  32466. +unsigned int own:1;
  32467. +
  32468. +
  32469. +//dword 1
  32470. +unsigned int tsftl;
  32471. +
  32472. +
  32473. +//dword 2
  32474. +unsigned int tsfth;
  32475. +
  32476. +
  32477. +//dword 3
  32478. +unsigned char sq;
  32479. +unsigned char rssi:7;
  32480. +unsigned char antenna:1;
  32481. +
  32482. +unsigned char agc;
  32483. +unsigned char decrypted:1;
  32484. +unsigned char wakeup:1;
  32485. +unsigned char shift:1;
  32486. +unsigned char rsvd0:5;
  32487. +
  32488. +//dword 4
  32489. +unsigned int num_mcsi:4;
  32490. +unsigned int snr_long2end:6;
  32491. +unsigned int cfo_bias:6;
  32492. +
  32493. +int pwdb_g12:8;
  32494. +unsigned int fot:8;
  32495. +
  32496. +
  32497. +
  32498. +
  32499. +#else
  32500. +
  32501. +#error "please modify tx_desc to your own\n"
  32502. +
  32503. +#endif
  32504. +
  32505. +}__attribute__((packed));
  32506. +
  32507. +
  32508. +
  32509. +struct rx_desc_rtl8187 {
  32510. +
  32511. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  32512. +
  32513. +//dword 0
  32514. +unsigned int rxlen:12;
  32515. +unsigned int icv:1;
  32516. +unsigned int crc32:1;
  32517. +unsigned int pwrmgt:1;
  32518. +unsigned int res:1;
  32519. +unsigned int bar:1;
  32520. +unsigned int pam:1;
  32521. +unsigned int mar:1;
  32522. +unsigned int qos:1;
  32523. +unsigned int rxrate:4;
  32524. +unsigned int trsw:1;
  32525. +unsigned int splcp:1;
  32526. +unsigned int fovf:1;
  32527. +unsigned int dmafail:1;
  32528. +unsigned int last:1;
  32529. +unsigned int first:1;
  32530. +unsigned int eor:1;
  32531. +unsigned int own:1;
  32532. +
  32533. +//dword 1
  32534. +unsigned char sq;
  32535. +unsigned char rssi:7;
  32536. +unsigned char antenna:1;
  32537. +
  32538. +unsigned char agc;
  32539. +unsigned char decrypted:1;
  32540. +unsigned char wakeup:1;
  32541. +unsigned char shift:1;
  32542. +unsigned char rsvd0:5;
  32543. +
  32544. +//dword 2
  32545. +unsigned int tsftl;
  32546. +
  32547. +//dword 3
  32548. +unsigned int tsfth;
  32549. +
  32550. +
  32551. +
  32552. +#else
  32553. +
  32554. +#error "please modify tx_desc to your own\n"
  32555. +
  32556. +#endif
  32557. +
  32558. +
  32559. +}__attribute__((packed));
  32560. +
  32561. +
  32562. +
  32563. +union rx_desc {
  32564. +
  32565. +struct rx_desc_rtl8187b desc_87b;
  32566. +struct rx_desc_rtl8187 desc_87;
  32567. +
  32568. +}__attribute__((packed));
  32569. +
  32570. +//
  32571. +// Description:
  32572. +// Perform signal smoothing for dynamic mechanism.
  32573. +// This is different with PerformSignalSmoothing8187 in smoothing fomula.
  32574. +// No dramatic adjustion is apply because dynamic mechanism need some degree
  32575. +// of correctness.
  32576. +// 2007.01.23, by shien chang.
  32577. +//
  32578. +void PerformUndecoratedSignalSmoothing8187(struct net_device *dev, struct ieee80211_rx_stats *stats)
  32579. +{
  32580. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32581. + bool bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats->rate));
  32582. +
  32583. + if(NIC_8187 == priv->card_8187) {
  32584. + if(priv->UndecoratedSmoothedSS >= 0) {
  32585. + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 50) + (stats->signalstrength * 11)) / 60;
  32586. + }else{
  32587. + priv->UndecoratedSmoothedSS = stats->signalstrength;
  32588. + }
  32589. + } else {
  32590. + // Determin the current packet is CCK rate, by Bruce, 2007-04-12.
  32591. + priv->bCurCCKPkt = bCckRate;
  32592. +
  32593. + // Tesing for SD3 DZ, by Bruce, 2007-04-11.
  32594. + if(priv->UndecoratedSmoothedSS >= 0) {
  32595. + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (stats->signalstrength * 10)) / 6;
  32596. + }else{
  32597. + priv->UndecoratedSmoothedSS = stats->signalstrength * 10;
  32598. + }
  32599. +
  32600. + //
  32601. + // Bacause the AGC parameter is not exactly correct under high power (AGC saturation), we need to record the RSSI value to be
  32602. + // referenced by DoRxHighPower. It is not necessary to record this value when this packet is sent by OFDM rate.
  32603. + // Advised by SD3 DZ, by Bruce, 2007-04-12.
  32604. + //
  32605. + if(bCckRate){
  32606. + priv->CurCCKRSSI = stats->signal;
  32607. + }else{
  32608. + priv->CurCCKRSSI = 0;
  32609. + }
  32610. + }
  32611. + //printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", stats->signalstrength, priv->UndecoratedSmoothedSS);
  32612. +}
  32613. +
  32614. +#ifdef THOMAS_SKB
  32615. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
  32616. +{
  32617. + int status,len,flen;
  32618. +
  32619. +#ifdef SW_ANTE_DIVERSITY
  32620. + u8 Antenna = 0;
  32621. +#endif
  32622. + u32 SignalStrength = 0;
  32623. + u32 quality = 0;
  32624. + bool bCckRate = false;
  32625. + char RX_PWDB = 0;
  32626. + long RecvSignalPower=0;
  32627. + struct sk_buff *skb;
  32628. + struct sk_buff *skb2;//skb for check out of memory
  32629. + union rx_desc *desc;
  32630. + //struct urb *rx_urb = priv->rxurb_task;
  32631. + struct ieee80211_hdr *hdr;//by amy
  32632. + u16 fc,type;
  32633. + u8 bHwError=0,bCRC=0,bICV=0;
  32634. + long SignalStrengthIndex = 0;
  32635. + struct ieee80211_rx_stats stats = {
  32636. + .signal = 0,
  32637. + .noise = -98,
  32638. + .rate = 0,
  32639. + //.mac_time = jiffies,
  32640. + .freq = IEEE80211_24GHZ_BAND,
  32641. + };
  32642. +
  32643. + int *prx_inx=&priv->rx_inx;
  32644. + struct urb *rx_urb=priv->rx_urb[*prx_inx]; //changed by jackson
  32645. + struct net_device *dev = (struct net_device*)rx_urb->context;
  32646. + //DMESG("=====>RX %x ",rx_urb->status);
  32647. +
  32648. + skb = priv->pp_rxskb[*prx_inx];
  32649. + status = rx_urb->status;
  32650. + skb2 = dev_alloc_skb(RX_URB_SIZE);
  32651. +
  32652. + if (skb2 == NULL){
  32653. + printk(KERN_ALERT "No Skb For RX!/n");
  32654. + //rx_urb->transfer_buffer = skb->data;
  32655. + //priv->pp_rxskb[*prx_inx] = skb;
  32656. + } else {
  32657. +
  32658. + if(status == 0)
  32659. + {
  32660. + if(NIC_8187B == priv->card_8187)
  32661. + {
  32662. + stats.nic_type = NIC_8187B;
  32663. + len = rx_urb->actual_length;
  32664. + len -= sizeof (struct rx_desc_rtl8187b);
  32665. + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
  32666. + flen = desc->desc_87b.rxlen ;
  32667. +
  32668. + if( flen <= rx_urb->actual_length){
  32669. +#if 1
  32670. +#ifdef SW_ANTE_DIVERSITY
  32671. + Antenna = desc->desc_87b.antenna;
  32672. +#endif
  32673. + stats.mac_time[0] = desc->desc_87b.tsftl;
  32674. + stats.mac_time[1] = desc->desc_87b.tsfth;
  32675. +
  32676. + stats.signal = desc->desc_87b.rssi;
  32677. + //stats.noise = desc->desc_87b.sq;
  32678. + quality = desc->desc_87b.sq;
  32679. + stats.rate = desc->desc_87b.rxrate;
  32680. + bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats.rate));
  32681. +
  32682. + if(!bCckRate) { // OFDM rate.
  32683. + if(desc->desc_87b.pwdb_g12 < -106)
  32684. + SignalStrength = 0;
  32685. + else
  32686. + SignalStrength = desc->desc_87b.pwdb_g12 + 106;
  32687. + RX_PWDB = (desc->desc_87b.pwdb_g12)/2 -42;
  32688. + } else { // CCK rate.
  32689. + if(desc->desc_87b.agc> 174)
  32690. + SignalStrength = 0;
  32691. + else
  32692. + SignalStrength = 174 - desc->desc_87b.agc;
  32693. + RX_PWDB = ((desc->desc_87b.agc)/2)*(-1) - 8;
  32694. + }
  32695. +
  32696. + //lzm mod 081028 based on windows driver
  32697. + //compensate SignalStrength when switch TR to SW controled
  32698. + if(priv->TrSwitchState == TR_SW_TX) {
  32699. + SignalStrength = SignalStrength + 54;
  32700. + RX_PWDB = RX_PWDB + 27;
  32701. + }
  32702. +
  32703. + if(SignalStrength > 100)
  32704. + SignalStrength = 100;
  32705. + SignalStrength = (SignalStrength * 70) / 100 + 30;
  32706. +
  32707. + if(SignalStrength > 50)
  32708. + SignalStrength = SignalStrength + 10;
  32709. + if(SignalStrength > 100)
  32710. + SignalStrength = 100;
  32711. +
  32712. + RecvSignalPower = RX_PWDB;
  32713. + //printk("SignalStrength = %d \n",SignalStrength);
  32714. + bHwError = (desc->desc_87b.fovf | desc->desc_87b.icv | desc->desc_87b.crc32);
  32715. + bCRC = desc->desc_87b.crc32;
  32716. + bICV = desc->desc_87b.icv;
  32717. + priv->wstats.qual.level = (u8)SignalStrength;
  32718. +
  32719. + if(!bCckRate){
  32720. + if (quality > 127)
  32721. + quality = 0;
  32722. + else if (quality <27)
  32723. + quality = 100;
  32724. + else
  32725. + quality = 127 - quality;
  32726. + } else {
  32727. + if(quality > 64)
  32728. + quality = 0;
  32729. + else
  32730. + quality = ((64-quality)*100)/64;
  32731. + }
  32732. +
  32733. +
  32734. + priv ->wstats.qual.qual = quality;
  32735. + priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
  32736. +
  32737. + stats.signalstrength = (u8)SignalStrength;
  32738. + stats.signal = (u8)quality;
  32739. + stats.noise = desc->desc_87b.snr_long2end;
  32740. +
  32741. + skb_put(skb,flen-4);
  32742. +
  32743. + priv->stats.rxok++;
  32744. + //by amy
  32745. + hdr = (struct ieee80211_hdr *)skb->data;
  32746. + fc = le16_to_cpu(hdr->frame_ctl);
  32747. + type = WLAN_FC_GET_TYPE(fc);
  32748. +
  32749. + if((IEEE80211_FTYPE_CTL != type) &&
  32750. + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV))
  32751. + {
  32752. + // Perform signal smoothing for dynamic mechanism on demand.
  32753. + // This is different with PerformSignalSmoothing8187 in smoothing fomula.
  32754. + // No dramatic adjustion is apply because dynamic mechanism need some degree
  32755. + // of correctness. 2007.01.23, by shien chang.
  32756. + PerformUndecoratedSignalSmoothing8187(dev, &stats);
  32757. +
  32758. + //Update signal strength and realted into private RxStats for UI query.
  32759. + SignalStrengthIndex = NetgearSignalStrengthTranslate(priv->LastSignalStrengthInPercent, priv->wstats.qual.level);
  32760. + priv->LastSignalStrengthInPercent = SignalStrengthIndex;
  32761. + priv->SignalStrength = TranslateToDbm8187((u8)SignalStrengthIndex);
  32762. + priv->SignalQuality = (priv->SignalQuality*5+quality+5)/6;
  32763. + priv->RecvSignalPower = (priv->RecvSignalPower * 5 + RecvSignalPower - 1) / 6;
  32764. +#ifdef SW_ANTE_DIVERSITY
  32765. + priv->LastRxPktAntenna = Antenna ? 1:0;
  32766. + SwAntennaDiversityRxOk8185(dev, SignalStrength);
  32767. +#endif
  32768. + }
  32769. + //by amy
  32770. +#endif
  32771. + if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
  32772. + dev_kfree_skb_any(skb);
  32773. + }
  32774. + }else {
  32775. + priv->stats.rxurberr++;
  32776. + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
  32777. + dev_kfree_skb_any(skb);
  32778. + }
  32779. + } else {
  32780. + stats.nic_type = NIC_8187;
  32781. + len = rx_urb->actual_length;
  32782. + len -= sizeof (struct rx_desc_rtl8187);
  32783. + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
  32784. + flen = desc->desc_87.rxlen ;
  32785. +
  32786. + if(flen <= rx_urb->actual_length){
  32787. + stats.signal = desc->desc_87.rssi;
  32788. + stats.noise = desc->desc_87.sq;
  32789. + stats.rate = desc->desc_87.rxrate;
  32790. + stats.mac_time[0] = desc->desc_87.tsftl;
  32791. + stats.mac_time[1] = desc->desc_87.tsfth;
  32792. + SignalStrength = (desc->desc_87.agc&0xfe) >> 1;
  32793. + if( ((stats.rate <= 22) && (stats.rate != 12) && (stats.rate != 18)) || (stats.rate == 44) )//need to translate to real rate here
  32794. + bCckRate= TRUE;
  32795. + if (!bCckRate)
  32796. + {
  32797. + if (SignalStrength > 90) SignalStrength = 90;
  32798. + else if (SignalStrength < 25) SignalStrength = 25;
  32799. + SignalStrength = ((90 - SignalStrength)*100)/65;
  32800. + }
  32801. + else
  32802. + {
  32803. + if (SignalStrength >95) SignalStrength = 95;
  32804. + else if (SignalStrength < 30) SignalStrength = 30;
  32805. + SignalStrength = ((95 - SignalStrength)*100)/65;
  32806. + }
  32807. + stats.signalstrength = (u8)SignalStrength;
  32808. +
  32809. + skb_put(skb,flen-4);
  32810. +
  32811. + priv->stats.rxok++;
  32812. +
  32813. + if(!ieee80211_rx(priv->ieee80211,skb, &stats))
  32814. + dev_kfree_skb_any(skb);
  32815. +
  32816. +
  32817. + }else {
  32818. + priv->stats.rxurberr++;
  32819. + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
  32820. + dev_kfree_skb_any(skb);
  32821. + }
  32822. + }
  32823. + }else{
  32824. +
  32825. + //printk("RX Status Error!\n");
  32826. + priv->stats.rxstaterr++;
  32827. + priv->ieee80211->stats.rx_errors++;
  32828. + dev_kfree_skb_any(skb);
  32829. +
  32830. + }
  32831. +
  32832. + rx_urb->transfer_buffer = skb2->data;
  32833. +
  32834. + priv->pp_rxskb[*prx_inx] = skb2;
  32835. + }
  32836. +
  32837. + if(status != -ENOENT ){
  32838. + rtl8187_rx_urbsubmit(dev,rx_urb);
  32839. + } else {
  32840. + priv->pp_rxskb[*prx_inx] = NULL;
  32841. + dev_kfree_skb_any(skb2);
  32842. + //printk("RX process %d aborted due to explicit shutdown (%x)(%d)\n ", *prx_inx, status, status);
  32843. + }
  32844. +
  32845. + if (*prx_inx == (MAX_RX_URB -1))
  32846. + *prx_inx = 0;
  32847. + else
  32848. + *prx_inx = *prx_inx + 1;
  32849. +}
  32850. +#endif
  32851. +
  32852. +#ifdef THOMAS_TASKLET
  32853. +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv){
  32854. + unsigned long flags;
  32855. + while( atomic_read( &priv->irt_counter ) ){
  32856. + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
  32857. + rtl8180_irq_rx_tasklet(priv);
  32858. + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
  32859. + if(atomic_read(&priv->irt_counter) >= 1)
  32860. + atomic_dec( &priv->irt_counter );
  32861. + }
  32862. +}
  32863. +#endif
  32864. +/****************************************************************************
  32865. + ---------------------------- USB_STUFF---------------------------
  32866. +*****************************************************************************/
  32867. +
  32868. +static const struct net_device_ops rtl8187_netdev_ops = {
  32869. + .ndo_open = rtl8180_open,
  32870. + .ndo_stop = rtl8180_close,
  32871. + .ndo_tx_timeout = tx_timeout,
  32872. + .ndo_do_ioctl = rtl8180_ioctl,
  32873. + .ndo_set_multicast_list = r8180_set_multicast,
  32874. + .ndo_set_mac_address = r8180_set_mac_adr,
  32875. + .ndo_validate_addr = eth_validate_addr,
  32876. + .ndo_change_mtu = eth_change_mtu,
  32877. + .ndo_start_xmit = ieee80211_xmit,
  32878. + .ndo_get_stats = rtl8180_stats,
  32879. +};
  32880. +
  32881. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32882. +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
  32883. + const struct usb_device_id *id)
  32884. +#else
  32885. +static void * __devinit rtl8187_usb_probe(struct usb_device *udev,
  32886. + unsigned int ifnum,
  32887. + const struct usb_device_id *id)
  32888. +#endif
  32889. +{
  32890. + struct net_device *dev = NULL;
  32891. + struct r8180_priv *priv= NULL;
  32892. +
  32893. +
  32894. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32895. + struct usb_device *udev = interface_to_usbdev(intf);
  32896. +#endif
  32897. +
  32898. + dev = alloc_ieee80211(sizeof(struct r8180_priv));
  32899. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  32900. + SET_MODULE_OWNER(dev);
  32901. +#endif
  32902. +
  32903. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32904. + usb_set_intfdata(intf, dev);
  32905. + SET_NETDEV_DEV(dev, &intf->dev);
  32906. +#endif
  32907. + priv = ieee80211_priv(dev);
  32908. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32909. + priv->ieee80211 = netdev_priv(dev);
  32910. +#else
  32911. + priv->ieee80211 = (struct net_device *)dev->priv;
  32912. +#endif
  32913. + priv->udev=udev;
  32914. +#ifdef CPU_64BIT
  32915. + priv->usb_buf = kmalloc(0x200, GFP_KERNEL);
  32916. + priv->usb_pool = dma_pool_create("rtl8187b", NULL, 64, 64, 0);
  32917. +#endif
  32918. +//lzm add for write time out test
  32919. +#ifdef DEBUG_RW_REGISTER
  32920. + {
  32921. + int reg_index = 0;
  32922. + for(reg_index = 0; reg_index <= 199; reg_index++)
  32923. + {
  32924. + priv->write_read_registers[reg_index].address = 0;
  32925. + priv->write_read_registers[reg_index].content = 0;
  32926. + priv->write_read_registers[reg_index].flag = 0;
  32927. + }
  32928. + priv->write_read_register_index = 0;
  32929. + }
  32930. +#endif
  32931. + //init netdev_ops, added by falcon....
  32932. + dev->netdev_ops = &rtl8187_netdev_ops;
  32933. +
  32934. + dev->wireless_handlers = &r8180_wx_handlers_def;
  32935. +#if WIRELESS_EXT >= 12
  32936. +#if WIRELESS_EXT < 17
  32937. + dev->get_wireless_stats = r8180_get_wireless_stats;
  32938. +#endif
  32939. + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
  32940. +#endif
  32941. +
  32942. + dev->type=ARPHRD_ETHER;
  32943. + dev->watchdog_timeo = HZ*3; //modified by john, 0805
  32944. +
  32945. + if (dev_alloc_name(dev, ifname) < 0){
  32946. + DMESG("Oops: devname already taken! Trying wlan%%d...\n");
  32947. + ifname = "wlan%d";
  32948. + dev_alloc_name(dev, ifname);
  32949. + }
  32950. +
  32951. + if(rtl8180_init(dev)!=0){
  32952. + DMESG("Initialization failed");
  32953. + goto fail;
  32954. + }
  32955. +
  32956. + netif_carrier_off(dev);
  32957. + netif_stop_queue(dev);
  32958. +
  32959. + register_netdev(dev);
  32960. +
  32961. + rtl8180_proc_init_one(dev);
  32962. +
  32963. + /* init rfkill */
  32964. + r8187b_rfkill_init(dev);
  32965. +
  32966. + DMESG("Driver probe completed");
  32967. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  32968. + return dev;
  32969. +#else
  32970. + return 0;
  32971. +#endif
  32972. +
  32973. +
  32974. +fail:
  32975. + free_ieee80211(dev);
  32976. +
  32977. + DMESG("wlan driver load failed\n");
  32978. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  32979. + return NULL;
  32980. +#else
  32981. + return -ENODEV;
  32982. +#endif
  32983. +
  32984. +}
  32985. +
  32986. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32987. +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf)
  32988. +#else
  32989. +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr)
  32990. +#endif
  32991. +{
  32992. + struct r8180_priv *priv = NULL;
  32993. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32994. + struct net_device *dev = usb_get_intfdata(intf);
  32995. +#else
  32996. + struct net_device *dev = (struct net_device *)ptr;
  32997. +#endif
  32998. + if(dev){
  32999. + unregister_netdev(dev);
  33000. +
  33001. + priv=ieee80211_priv(dev);
  33002. +
  33003. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
  33004. +
  33005. +#ifdef _RTL8187_EXT_PATCH_
  33006. + if(priv && priv->mshobj)
  33007. + {
  33008. + if(priv->mshobj->ext_patch_remove_proc)
  33009. + priv->mshobj->ext_patch_remove_proc(priv);
  33010. + priv->ieee80211->ext_patch_ieee80211_start_protocol = 0;
  33011. + priv->ieee80211->ext_patch_ieee80211_stop_protocol = 0;
  33012. + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = 0;
  33013. + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = 0;
  33014. + priv->ieee80211->ext_patch_ieee80211_association_req_1 = 0;
  33015. + priv->ieee80211->ext_patch_ieee80211_association_req_2 = 0;
  33016. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = 0;
  33017. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = 0;
  33018. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth =0;
  33019. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth =0;
  33020. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = 0;
  33021. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = 0;
  33022. + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = 0;
  33023. + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = 0;
  33024. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = 0;
  33025. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = 0;
  33026. + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = 0;
  33027. + priv->ieee80211->ext_patch_get_beacon_get_probersp = 0;
  33028. + priv->ieee80211->ext_patch_ieee80211_xmit = 0;
  33029. + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = 0;
  33030. + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = 0;
  33031. + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = 0;
  33032. + // priv->ieee80211->ext_patch_is_duplicate_packet = 0;
  33033. + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = 0;
  33034. + free_mshobj(&priv->mshobj);
  33035. + }
  33036. +#endif // _RTL8187_EXT_PATCH_
  33037. +
  33038. + rtl8180_proc_remove_one(dev);
  33039. +
  33040. + rtl8180_down(dev);
  33041. + priv->rf_close(dev);
  33042. +
  33043. + //rtl8180_rtx_disable(dev);
  33044. + rtl8187_usb_deleteendpoints(dev);
  33045. +#ifdef LED
  33046. + DeInitSwLeds(dev);
  33047. +#endif
  33048. + rtl8180_irq_disable(dev);
  33049. + rtl8180_reset(dev);
  33050. + mdelay(10);
  33051. +
  33052. + }
  33053. +
  33054. +#ifdef CPU_64BIT
  33055. + if(priv->usb_buf)
  33056. + kfree(priv->usb_buf);
  33057. + if(priv->usb_pool) {
  33058. + dma_pool_destroy(priv->usb_pool);
  33059. + priv->usb_pool = NULL;
  33060. + }
  33061. +#endif
  33062. + free_ieee80211(dev);
  33063. + DMESG("wlan driver removed");
  33064. +}
  33065. +
  33066. +/* fun with the built-in ieee80211 stack... */
  33067. +extern int ieee80211_crypto_init(void);
  33068. +extern void ieee80211_crypto_deinit(void);
  33069. +extern int ieee80211_crypto_tkip_init(void);
  33070. +extern void ieee80211_crypto_tkip_exit(void);
  33071. +extern int ieee80211_crypto_ccmp_init(void);
  33072. +extern void ieee80211_crypto_ccmp_exit(void);
  33073. +extern int ieee80211_crypto_wep_init(void);
  33074. +extern void ieee80211_crypto_wep_exit(void);
  33075. +
  33076. +static int __init rtl8187_usb_module_init(void)
  33077. +{
  33078. + int ret;
  33079. +
  33080. + ret = ieee80211_crypto_init();
  33081. + if (ret) {
  33082. + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
  33083. + return ret;
  33084. + }
  33085. + ret = ieee80211_crypto_tkip_init();
  33086. + if (ret) {
  33087. + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
  33088. + return ret;
  33089. + }
  33090. + ret = ieee80211_crypto_ccmp_init();
  33091. + if (ret) {
  33092. + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
  33093. + return ret;
  33094. + }
  33095. + ret = ieee80211_crypto_wep_init();
  33096. + if (ret) {
  33097. + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
  33098. + return ret;
  33099. + }
  33100. +
  33101. + printk("\nLinux kernel driver for RTL8187/RTL8187B based WLAN cards\n");
  33102. + printk("Copyright (c) 2004-2008, Realsil Wlan\n");
  33103. + DMESG("Initializing module");
  33104. + DMESG("Wireless extensions version %d", WIRELESS_EXT);
  33105. + rtl8180_proc_module_init();
  33106. + return usb_register(&rtl8187_usb_driver);
  33107. +}
  33108. +
  33109. +static void __exit rtl8187_usb_module_exit(void)
  33110. +{
  33111. + r8187b_rfkill_exit();
  33112. + usb_deregister(&rtl8187_usb_driver);
  33113. + rtl8180_proc_module_remove();
  33114. + ieee80211_crypto_tkip_exit();
  33115. + ieee80211_crypto_ccmp_exit();
  33116. + ieee80211_crypto_wep_exit();
  33117. + ieee80211_crypto_deinit();
  33118. +
  33119. + DMESG("Exiting\n");
  33120. +}
  33121. +
  33122. +
  33123. +void rtl8180_try_wake_queue(struct net_device *dev, int pri)
  33124. +{
  33125. + unsigned long flags;
  33126. + short enough_desc;
  33127. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  33128. +
  33129. + spin_lock_irqsave(&priv->tx_lock,flags);
  33130. + enough_desc = check_nic_enought_desc(dev,pri);
  33131. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  33132. +
  33133. + if(enough_desc)
  33134. + ieee80211_wake_queue(priv->ieee80211);
  33135. +}
  33136. +
  33137. +#ifdef JOHN_HWSEC
  33138. +void EnableHWSecurityConfig8187(struct net_device *dev)
  33139. +{
  33140. + u8 SECR_value = 0x0;
  33141. + SECR_value = SCR_TxSecEnable | SCR_RxSecEnable;
  33142. + {
  33143. + write_nic_byte(dev, WPA_CONFIG, 0x7);//SECR_value | SCR_UseDK );
  33144. + }
  33145. +}
  33146. +
  33147. +void setKey(struct net_device *dev,
  33148. + u8 EntryNo,
  33149. + u8 KeyIndex,
  33150. + u16 KeyType,
  33151. + u8 *MacAddr,
  33152. + u8 DefaultKey,
  33153. + u32 *KeyContent )
  33154. +{
  33155. + u32 TargetCommand = 0;
  33156. + u32 TargetContent = 0;
  33157. + u16 usConfig = 0;
  33158. + int i;
  33159. + usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
  33160. +
  33161. +
  33162. + for(i=0 ; i<6 ; i++){
  33163. + TargetCommand = i+6*EntryNo;
  33164. + TargetCommand |= BIT31|BIT16;
  33165. +
  33166. + if(i==0){//MAC|Config
  33167. + TargetContent = (u32)(*(MacAddr+0)) << 16|
  33168. + (u32)(*(MacAddr+1)) << 24|
  33169. + (u32)usConfig;
  33170. +
  33171. + write_nic_dword(dev, WCAMI, TargetContent);
  33172. + write_nic_dword(dev, RWCAM, TargetCommand);
  33173. + //printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
  33174. + } else if(i==1){//MAC
  33175. + TargetContent = (u32)(*(MacAddr+2)) |
  33176. + (u32)(*(MacAddr+3)) << 8|
  33177. + (u32)(*(MacAddr+4)) << 16|
  33178. + (u32)(*(MacAddr+5)) << 24;
  33179. + write_nic_dword(dev, WCAMI, TargetContent);
  33180. + write_nic_dword(dev, RWCAM, TargetCommand);
  33181. + } else { //Key Material
  33182. + write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
  33183. + write_nic_dword(dev, RWCAM, TargetCommand);
  33184. + }
  33185. + }
  33186. +
  33187. +}
  33188. +#endif
  33189. +
  33190. +/****************************************************************************
  33191. + --------------------------- RF power on/power off -----------------
  33192. +*****************************************************************************/
  33193. +
  33194. +/*
  33195. + * the interface for changing the rfkill state
  33196. + * @dev: the device of r8187b
  33197. + * @eRfPowerStateToSet: the state we need to change,
  33198. + * eRfOn: power on
  33199. + * eRfOff: power off
  33200. + *
  33201. + * This function should be called by the SCI interrupt handler when the
  33202. + * KEY_WLAN event happen(or install to the notify function of the SCI
  33203. + * interrupt) or called in the wifi_set function of the rfkill interface for
  33204. + * user-space, and also, it can be called to initialize the wifi state, and
  33205. + * called when suspend/resume.
  33206. + */
  33207. +
  33208. +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet)
  33209. +{
  33210. + struct r8180_priv *priv = ieee80211_priv(dev);
  33211. +
  33212. + if (eRfPowerStateToSet == eRfOn)
  33213. + priv->ieee80211->bHwRadioOff = false;
  33214. + else
  33215. + priv->ieee80211->bHwRadioOff = true;
  33216. +
  33217. +#ifdef CONFIG_RADIO_DEBUG
  33218. + DMESG("SCI interrupt Methord Will Turn Radio %s",
  33219. + (priv->ieee80211->bHwRadioOff == true) ? "Off" : "On");
  33220. +#endif
  33221. +
  33222. +#ifdef LED //by lizhaoming
  33223. + if (priv->ieee80211->bHwRadioOff)
  33224. + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_OFF);
  33225. + else
  33226. + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_ON);
  33227. +#endif
  33228. +
  33229. + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
  33230. +
  33231. + /* report the rfkill state to the user-space via uevent interface */
  33232. + r8187b_wifi_report_state(priv);
  33233. +}
  33234. +
  33235. +/***************************************************************************
  33236. + ------------------- module init / exit stubs ----------------
  33237. +****************************************************************************/
  33238. +module_init(rtl8187_usb_module_init);
  33239. +module_exit(rtl8187_usb_module_exit);
  33240. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187.h linux-lemote/drivers/net/wireless/rtl8187b/r8187.h
  33241. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187.h 1970-01-01 01:00:00.000000000 +0100
  33242. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187.h 2010-03-06 16:43:22.000000000 +0100
  33243. @@ -0,0 +1,811 @@
  33244. +/*
  33245. + This is part of rtl8187 OpenSource driver.
  33246. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  33247. + Released under the terms of GPL (General Public Licence)
  33248. +
  33249. + Parts of this driver are based on the GPL part of the
  33250. + official realtek driver
  33251. +
  33252. + Parts of this driver are based on the rtl8180 driver skeleton
  33253. + from Patric Schenke & Andres Salomon
  33254. +
  33255. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  33256. +
  33257. + We want to tanks the Authors of those projects and the Ndiswrapper
  33258. + project Authors.
  33259. +*/
  33260. +
  33261. +#ifndef R8180H
  33262. +#define R8180H
  33263. +
  33264. +
  33265. +#define RTL8187_MODULE_NAME "rtl8187"
  33266. +#define DMESG(x,a...) printk(KERN_INFO RTL8187_MODULE_NAME ": " x "\n", ## a)
  33267. +#define DMESGW(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": WW:" x "\n", ## a)
  33268. +#define DMESGE(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": EE:" x "\n", ## a)
  33269. +
  33270. +#include <linux/module.h>
  33271. +#include <linux/kernel.h>
  33272. +//#include <linux/config.h>
  33273. +#include <linux/init.h>
  33274. +#include <linux/ioport.h>
  33275. +#include <linux/sched.h>
  33276. +#include <linux/types.h>
  33277. +#include <linux/slab.h>
  33278. +#include <linux/netdevice.h>
  33279. +//#include <linux/pci.h>
  33280. +#include <linux/usb.h>
  33281. +#include <linux/etherdevice.h>
  33282. +#include <linux/delay.h>
  33283. +#include <linux/rtnetlink.h> //for rtnl_lock()
  33284. +#include <linux/wireless.h>
  33285. +#include <linux/timer.h>
  33286. +#include <linux/proc_fs.h> // Necessary because we use the proc fs
  33287. +#include <linux/if_arp.h>
  33288. +#include <linux/random.h>
  33289. +#include <linux/version.h>
  33290. +#include <asm/io.h>
  33291. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
  33292. +#include <asm/semaphore.h>
  33293. +#endif
  33294. +#include "ieee80211/ieee80211.h"
  33295. +#ifdef _RTL8187_EXT_PATCH_
  33296. +#include "msh_class.h"
  33297. +#endif
  33298. +#ifdef LED
  33299. +#include "r8187_led.h"
  33300. +#endif
  33301. +
  33302. +//added for HW security, john.0629
  33303. +#define FALSE 0
  33304. +#define TRUE 1
  33305. +#define MAX_KEY_LEN 61
  33306. +#define KEY_BUF_SIZE 5
  33307. +
  33308. +#define BIT0 0x00000001
  33309. +#define BIT1 0x00000002
  33310. +#define BIT2 0x00000004
  33311. +#define BIT3 0x00000008
  33312. +#define BIT4 0x00000010
  33313. +#define BIT5 0x00000020
  33314. +#define BIT6 0x00000040
  33315. +#define BIT7 0x00000080
  33316. +#define BIT8 0x00000100
  33317. +#define BIT9 0x00000200
  33318. +#define BIT10 0x00000400
  33319. +#define BIT11 0x00000800
  33320. +#define BIT12 0x00001000
  33321. +#define BIT13 0x00002000
  33322. +#define BIT14 0x00004000
  33323. +#define BIT15 0x00008000
  33324. +#define BIT16 0x00010000
  33325. +#define BIT17 0x00020000
  33326. +#define BIT18 0x00040000
  33327. +#define BIT19 0x00080000
  33328. +#define BIT20 0x00100000
  33329. +#define BIT21 0x00200000
  33330. +#define BIT22 0x00400000
  33331. +#define BIT23 0x00800000
  33332. +#define BIT24 0x01000000
  33333. +#define BIT25 0x02000000
  33334. +#define BIT26 0x04000000
  33335. +#define BIT27 0x08000000
  33336. +#define BIT28 0x10000000
  33337. +#define BIT29 0x20000000
  33338. +#define BIT30 0x40000000
  33339. +#define BIT31 0x80000000
  33340. +
  33341. +//8187B Security
  33342. +#define RWCAM 0xA0 // Software read/write CAM config
  33343. +#define WCAMI 0xA4 // Software write CAM input content
  33344. +#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting
  33345. +#define DCAM 0xAC // Debug CAM Interface
  33346. +#define SECR 0xB0 // Security configuration register
  33347. +#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06.
  33348. +#define AESMSK_SC 0x1FC // AES Mask for Sequence Control (0x1FC~0X1FD). Added by Annie, 2006-03-06.
  33349. +#define AESMSK_QC 0x1CE // AES Mask register for QoS Control when computing AES MIC, default = 0x000F. (2 bytes)
  33350. +
  33351. +#define AESMSK_FC_DEFAULT 0xC78F // default value of AES MASK for Frame Control Field. (2 bytes)
  33352. +#define AESMSK_SC_DEFAULT 0x000F // default value of AES MASK for Sequence Control Field. (2 bytes)
  33353. +#define AESMSK_QC_DEFAULT 0x000F // default value of AES MASK for QoS Control Field. (2 bytes)
  33354. +
  33355. +#define CAM_CONTENT_COUNT 6
  33356. +#define CFG_DEFAULT_KEY BIT5
  33357. +#define CFG_VALID BIT15
  33358. +
  33359. +//----------------------------------------------------------------------------
  33360. +// 8187B WPA Config Register (offset 0xb0, 1 byte)
  33361. +//----------------------------------------------------------------------------
  33362. +#define SCR_UseDK 0x01
  33363. +#define SCR_TxSecEnable 0x02
  33364. +#define SCR_RxSecEnable 0x04
  33365. +
  33366. +//----------------------------------------------------------------------------
  33367. +// 8187B CAM Config Setting (offset 0xb0, 1 byte)
  33368. +//----------------------------------------------------------------------------
  33369. +#define CAM_VALID 0x8000
  33370. +#define CAM_NOTVALID 0x0000
  33371. +#define CAM_USEDK 0x0020
  33372. +
  33373. +
  33374. +#define CAM_NONE 0x0
  33375. +#define CAM_WEP40 0x01
  33376. +#define CAM_TKIP 0x02
  33377. +#define CAM_AES 0x04
  33378. +#define CAM_WEP104 0x05
  33379. +
  33380. +
  33381. +//#define CAM_SIZE 16
  33382. +#define TOTAL_CAM_ENTRY 16
  33383. +#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25.
  33384. +#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u4Byte)) // 24, unit: in u1byte. Added by Annie, 2006-05-25.
  33385. +
  33386. +#define CAM_CONFIG_USEDK 1
  33387. +#define CAM_CONFIG_NO_USEDK 0
  33388. +
  33389. +#define CAM_WRITE 0x00010000
  33390. +#define CAM_READ 0x00000000
  33391. +#define CAM_POLLINIG 0x80000000
  33392. +
  33393. +//=================================================================
  33394. +//=================================================================
  33395. +
  33396. +#define EPROM_93c46 0
  33397. +#define EPROM_93c56 1
  33398. +
  33399. +#define DEFAULT_FRAG_THRESHOLD 2342U
  33400. +#define MIN_FRAG_THRESHOLD 256U
  33401. +#define DEFAULT_BEACONINTERVAL 0x64U
  33402. +#define DEFAULT_BEACON_ESSID "Rtl8187"
  33403. +
  33404. +#define DEFAULT_SSID ""
  33405. +#define DEFAULT_RETRY_RTS 7
  33406. +#define DEFAULT_RETRY_DATA 7
  33407. +#define PRISM_HDR_SIZE 64
  33408. +
  33409. +typedef enum _WIRELESS_MODE {
  33410. + WIRELESS_MODE_UNKNOWN = 0x00,
  33411. + WIRELESS_MODE_A = 0x01,
  33412. + WIRELESS_MODE_B = 0x02,
  33413. + WIRELESS_MODE_G = 0x04,
  33414. + WIRELESS_MODE_AUTO = 0x08,
  33415. +} WIRELESS_MODE;
  33416. +
  33417. +typedef enum _TR_SWITCH_STATE{
  33418. + TR_HW_CONTROLLED = 0,
  33419. + TR_SW_TX = 1,
  33420. +}TR_SWITCH_STATE, *PTR_SWITCH_STATE;
  33421. +
  33422. +
  33423. +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
  33424. +
  33425. +typedef struct buffer
  33426. +{
  33427. + struct buffer *next;
  33428. + u32 *buf;
  33429. +
  33430. +} buffer;
  33431. +
  33432. +typedef struct rtl_reg_debug{
  33433. + unsigned int cmd;
  33434. + struct {
  33435. + unsigned char type;
  33436. + unsigned char addr;
  33437. + unsigned char page;
  33438. + unsigned char length;
  33439. + } head;
  33440. + unsigned char buf[0xff];
  33441. +}rtl_reg_debug;
  33442. +typedef struct _CHANNEL_LIST{
  33443. + u8 Channel[MAX_CHANNEL_NUMBER + 1];
  33444. + u8 Len;
  33445. +}CHANNEL_LIST, *PCHANNEL_LIST;
  33446. +
  33447. +#define MAX_LD_SLOT_NUM 10
  33448. +#define DEFAULT_SLOT_NUM 2
  33449. +#define KEEP_ALIVE_INTERVAL 20 // in seconds.
  33450. +#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
  33451. +#define DEFAULT_KEEP_ALIVE_LEVEL 1
  33452. +
  33453. +typedef struct _link_detect_t
  33454. +{
  33455. + u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
  33456. + u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
  33457. + u16 SlotIndex;
  33458. +
  33459. + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
  33460. + u32 NumRxOkInPeriod; //number of packet received during CheckForHang
  33461. +
  33462. + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
  33463. + u32 LastNumTxUnicast;
  33464. + u32 LastNumRxUnicast;
  33465. +
  33466. + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
  33467. +}link_detect_t, *plink_detect_t;
  33468. +
  33469. +#if 0
  33470. +
  33471. +typedef struct tx_pendingbuf
  33472. +{
  33473. + struct ieee80211_txb *txb;
  33474. + short ispending;
  33475. + short descfrag;
  33476. +} tx_pendigbuf;
  33477. +
  33478. +#endif
  33479. +
  33480. +typedef struct Stats
  33481. +{
  33482. + unsigned long txrdu;
  33483. +// unsigned long rxrdu;
  33484. + //unsigned long rxnolast;
  33485. + //unsigned long rxnodata;
  33486. +// unsigned long rxreset;
  33487. +// unsigned long rxwrkaround;
  33488. +// unsigned long rxnopointer;
  33489. + unsigned long rxok;
  33490. + unsigned long rxurberr;
  33491. + unsigned long rxstaterr;
  33492. + unsigned long txnperr;
  33493. + unsigned long txnpdrop;
  33494. + unsigned long txresumed;
  33495. +// unsigned long rxerr;
  33496. +// unsigned long rxoverflow;
  33497. +// unsigned long rxint;
  33498. + unsigned long txnpokint;
  33499. +// unsigned long txhpokint;
  33500. +// unsigned long txhperr;
  33501. +// unsigned long ints;
  33502. +// unsigned long shints;
  33503. + unsigned long txoverflow;
  33504. +// unsigned long rxdmafail;
  33505. +// unsigned long txbeacon;
  33506. +// unsigned long txbeaconerr;
  33507. + unsigned long txlpokint;
  33508. + unsigned long txlpdrop;
  33509. + unsigned long txlperr;
  33510. + unsigned long txbeokint;
  33511. + unsigned long txbedrop;
  33512. + unsigned long txbeerr;
  33513. + unsigned long txbkokint;
  33514. + unsigned long txbkdrop;
  33515. + unsigned long txbkerr;
  33516. + unsigned long txviokint;
  33517. + unsigned long txvidrop;
  33518. + unsigned long txvierr;
  33519. + unsigned long txvookint;
  33520. + unsigned long txvodrop;
  33521. + unsigned long txvoerr;
  33522. + unsigned long txbeaconokint;
  33523. + unsigned long txbeacondrop;
  33524. + unsigned long txbeaconerr;
  33525. + unsigned long txmanageokint;
  33526. + unsigned long txmanagedrop;
  33527. + unsigned long txmanageerr;
  33528. + unsigned long txdatapkt;
  33529. +} Stats;
  33530. +
  33531. +typedef struct ChnlAccessSetting {
  33532. + u16 SIFS_Timer;
  33533. + u16 DIFS_Timer;
  33534. + u16 SlotTimeTimer;
  33535. + u16 EIFS_Timer;
  33536. + u16 CWminIndex;
  33537. + u16 CWmaxIndex;
  33538. +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
  33539. +
  33540. +
  33541. +typedef enum _RT_RF_POWER_STATE
  33542. +{
  33543. + eRfOn,
  33544. + eRfSleep,
  33545. + eRfOff
  33546. +}RT_RF_POWER_STATE;
  33547. +typedef enum _RT_PS_MODE
  33548. +{
  33549. + eActive, // Active/Continuous access.
  33550. + eMaxPs, // Max power save mode.
  33551. + eFastPs // Fast power save mode.
  33552. +}RT_PS_MODE;
  33553. +//
  33554. +// Three wire mode.
  33555. +//
  33556. +#define IC_DEFAULT_THREE_WIRE 0
  33557. +#define SW_THREE_WIRE 1
  33558. +//RTL818xB
  33559. +#define SW_THREE_WIRE_BY_8051 2
  33560. +#define HW_THREE_WIRE 3
  33561. +#define HW_THREE_WIRE_BY_8051 4
  33562. +//lzm add for write time out test
  33563. +typedef struct write_read_register
  33564. +{
  33565. + u32 address;
  33566. + u32 content;
  33567. + u32 flag;
  33568. +} write_read_register;
  33569. +//lzm add for write time out test
  33570. +typedef struct r8180_priv
  33571. +{
  33572. +//lzm add for write time out test
  33573. + struct write_read_register write_read_registers[200];
  33574. + u8 write_read_register_index;
  33575. +//lzm add for write time out test
  33576. +
  33577. + struct usb_device *udev;
  33578. + short epromtype;
  33579. + int irq;
  33580. + struct ieee80211_device *ieee80211;
  33581. +
  33582. + short card_8187; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */
  33583. + short card_8187_Bversion; /* if TCR reports card V B/C this discriminates */
  33584. + short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
  33585. + short enable_gpio0;
  33586. + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
  33587. + short hw_plcp_len;
  33588. + short plcp_preamble_mode;
  33589. +
  33590. + spinlock_t irq_lock;
  33591. +// spinlock_t irq_th_lock;
  33592. + spinlock_t tx_lock;
  33593. +//by amy for ps
  33594. + spinlock_t rf_ps_lock;
  33595. +//by amy for ps
  33596. +
  33597. + u16 irq_mask;
  33598. +// short irq_enabled;
  33599. + struct net_device *dev;
  33600. + short chan;
  33601. + short sens;
  33602. + short max_sens;
  33603. + u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
  33604. + u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
  33605. + u8 cck_txpwr_base;
  33606. + u8 ofdm_txpwr_base;
  33607. + u8 challow[15]; //channels from 1 to 14, 0 not used
  33608. + short up;
  33609. + short crcmon; //if 1 allow bad crc frame reception in monitor mode
  33610. +// short prism_hdr;
  33611. +
  33612. +// struct timer_list scan_timer;
  33613. + /*short scanpending;
  33614. + short stopscan;*/
  33615. +// spinlock_t scan_lock;
  33616. +// u8 active_probe;
  33617. + //u8 active_scan_num;
  33618. + struct semaphore wx_sem;
  33619. + struct semaphore set_chan_sem;
  33620. +// short hw_wep;
  33621. +
  33622. +// short digphy;
  33623. +// short antb;
  33624. +// short diversity;
  33625. +// u8 cs_treshold;
  33626. +// short rcr_csense;
  33627. + short rf_chip;
  33628. +// u32 key0[4];
  33629. + short (*rf_set_sens)(struct net_device *dev,short sens);
  33630. + void (*rf_set_chan)(struct net_device *dev,short ch);
  33631. + void (*rf_close)(struct net_device *dev);
  33632. + void (*rf_init)(struct net_device *dev);
  33633. + //short rate;
  33634. + short promisc;
  33635. + /*stats*/
  33636. + struct Stats stats;
  33637. + struct _link_detect_t link_detect; //added on 1016.2008
  33638. + struct iw_statistics wstats;
  33639. + struct proc_dir_entry *dir_dev;
  33640. +
  33641. + /*RX stuff*/
  33642. +// u32 *rxring;
  33643. +// u32 *rxringtail;
  33644. +// dma_addr_t rxringdma;
  33645. + struct urb **rx_urb;
  33646. +#ifdef THOMAS_BEACON
  33647. + unsigned long *oldaddr; //lzm for 64bit CPU crash
  33648. +#endif
  33649. +
  33650. +#ifdef THOMAS_TASKLET
  33651. + atomic_t irt_counter;//count for irq_rx_tasklet
  33652. +#endif
  33653. +#ifdef JACKSON_NEW_RX
  33654. + struct sk_buff **pp_rxskb;
  33655. + int rx_inx;
  33656. +#endif
  33657. +
  33658. + short tx_urb_index;
  33659. +
  33660. + //struct buffer *rxbuffer;
  33661. + //struct buffer *rxbufferhead;
  33662. + //int rxringcount;
  33663. + //u16 rxbuffersize;
  33664. +
  33665. + //struct sk_buff *rx_skb;
  33666. +
  33667. + //short rx_skb_complete;
  33668. +
  33669. + //u32 rx_prevlen;
  33670. + //atomic_t tx_lp_pending;
  33671. + //atomic_t tx_np_pending;
  33672. + atomic_t tx_pending[0x10];//UART_PRIORITY+1
  33673. +
  33674. +#if 0
  33675. + /*TX stuff*/
  33676. + u32 *txlpring;
  33677. + u32 *txhpring;
  33678. + u32 *txnpring;
  33679. + dma_addr_t txlpringdma;
  33680. + dma_addr_t txhpringdma;
  33681. + dma_addr_t txnpringdma;
  33682. + u32 *txlpringtail;
  33683. + u32 *txhpringtail;
  33684. + u32 *txnpringtail;
  33685. + u32 *txlpringhead;
  33686. + u32 *txhpringhead;
  33687. + u32 *txnpringhead;
  33688. + struct buffer *txlpbufs;
  33689. + struct buffer *txhpbufs;
  33690. + struct buffer *txnpbufs;
  33691. + struct buffer *txlpbufstail;
  33692. + struct buffer *txhpbufstail;
  33693. + struct buffer *txnpbufstail;
  33694. + int txringcount;
  33695. + int txbuffsize;
  33696. +
  33697. + //struct tx_pendingbuf txnp_pending;
  33698. + struct tasklet_struct irq_tx_tasklet;
  33699. +#endif
  33700. + struct tasklet_struct irq_rx_tasklet;
  33701. + struct urb *rxurb_task;
  33702. +// u8 dma_poll_mask;
  33703. + //short tx_suspend;
  33704. +
  33705. + /* adhoc/master mode stuff */
  33706. +#if 0
  33707. + u32 *txbeacontail;
  33708. + dma_addr_t txbeaconringdma;
  33709. + u32 *txbeaconring;
  33710. + int txbeaconcount;
  33711. +#endif
  33712. +// struct ieee_tx_beacon *beacon_buf;
  33713. + //char *master_essid;
  33714. +// dma_addr_t beacondmabuf;
  33715. + //u16 master_beaconinterval;
  33716. +// u32 master_beaconsize;
  33717. + //u16 beacon_interval;
  33718. +
  33719. + //2 Tx Related variables
  33720. + u16 ShortRetryLimit;
  33721. + u16 LongRetryLimit;
  33722. + u32 TransmitConfig;
  33723. + u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27.
  33724. +
  33725. + //2 Rx Related variables
  33726. + u16 EarlyRxThreshold;
  33727. + u32 ReceiveConfig;
  33728. + u8 AcmControl;
  33729. +
  33730. + u8 RFProgType;
  33731. +
  33732. + u8 retry_data;
  33733. + u8 retry_rts;
  33734. + u16 rts;
  33735. +
  33736. +//by amy
  33737. + long LastSignalStrengthInPercent;
  33738. + long SignalStrength;
  33739. + long SignalQuality;
  33740. + u8 antenna_flag;
  33741. + bool flag_beacon;
  33742. +//by amy
  33743. +//by amy for rate adaptive
  33744. + struct timer_list rateadapter_timer;
  33745. + u16 LastRetryCnt;
  33746. + u16 LastRetryRate;
  33747. + unsigned long LastTxokCnt;
  33748. + unsigned long LastRxokCnt;
  33749. + u16 CurrRetryCnt;
  33750. + long RecvSignalPower;
  33751. + unsigned long LastTxOKBytes;
  33752. + u8 LastFailTxRate;
  33753. + long LastFailTxRateSS;
  33754. + u8 FailTxRateCount;
  33755. + u32 LastTxThroughput;
  33756. + unsigned long txokbytestotal;
  33757. + //for up rate
  33758. + unsigned short bTryuping;
  33759. + u8 CurrTxRate; //the rate before up
  33760. + u16 CurrRetryRate;
  33761. + u16 TryupingCount;
  33762. + u8 TryDownCountLowData;
  33763. + u8 TryupingCountNoData;
  33764. +
  33765. + u8 CurrentOperaRate;
  33766. +//by amy for rate adaptive
  33767. +//by amy for power save
  33768. + struct timer_list watch_dog_timer;
  33769. + bool bInactivePs;
  33770. + bool bSwRfProcessing;
  33771. + RT_RF_POWER_STATE eInactivePowerState;
  33772. + RT_RF_POWER_STATE eRFPowerState;
  33773. + u32 RfOffReason;
  33774. + bool RFChangeInProgress;
  33775. + bool bInHctTest;
  33776. + bool SetRFPowerStateInProgress;
  33777. + //u8 RFProgType;
  33778. + bool bLeisurePs;
  33779. + RT_PS_MODE dot11PowerSaveMode;
  33780. + u32 NumRxOkInPeriod;
  33781. + u32 NumTxOkInPeriod;
  33782. + u8 RegThreeWireMode;
  33783. + bool ps_mode;
  33784. +//by amy for power save
  33785. +//by amy for DIG
  33786. + bool bDigMechanism;
  33787. + bool bCCKThMechanism;
  33788. + u8 InitialGain;
  33789. + u8 StageCCKTh;
  33790. + u8 RegBModeGainStage;
  33791. + u8 RegDigOfdmFaUpTh; //added by david, 2008.3.6
  33792. + u8 DIG_NumberFallbackVote;
  33793. + u8 DIG_NumberUpgradeVote;
  33794. + u16 CCKUpperTh;
  33795. + u16 CCKLowerTh;
  33796. + u32 FalseAlarmRegValue; //added by david, 2008.3.6
  33797. +//by amy for DIG
  33798. +//{ added by david for high power, 2008.3.11
  33799. + int UndecoratedSmoothedSS;
  33800. + bool bRegHighPowerMechanism;
  33801. + bool bToUpdateTxPwr;
  33802. + u8 Z2HiPwrUpperTh;
  33803. + u8 Z2HiPwrLowerTh;
  33804. + u8 Z2RSSIHiPwrUpperTh;
  33805. + u8 Z2RSSIHiPwrLowerTh;
  33806. + // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
  33807. + u8 CurCCKRSSI;
  33808. + bool bCurCCKPkt;
  33809. + u32 wMacRegRfPinsOutput;
  33810. + u32 wMacRegRfPinsSelect;
  33811. + TR_SWITCH_STATE TrSwitchState;
  33812. +//}
  33813. +//{added by david for radio on/off
  33814. + u8 radion;
  33815. +//}
  33816. + struct ChnlAccessSetting ChannelAccessSetting;
  33817. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  33818. + struct work_struct reset_wq;
  33819. +#else
  33820. + struct tq_struct reset_wq;
  33821. +#endif
  33822. +
  33823. +#ifdef _RTL8187_EXT_PATCH_
  33824. + struct mshclass *mshobj;
  33825. +#endif
  33826. +
  33827. +#ifdef LED
  33828. + /* add for led controll */
  33829. + u8 EEPROMCustomerID;
  33830. + RT_CID_TYPE CustomerID;
  33831. + LED_8187 Gpio0Led;
  33832. + LED_8187 SwLed0;
  33833. + LED_8187 SwLed1;
  33834. + u8 bEnableLedCtrl;
  33835. + LED_STRATEGY_8187 LedStrategy;
  33836. + u8 PsrValue;
  33837. + struct work_struct Gpio0LedWorkItem;
  33838. + struct work_struct SwLed0WorkItem;
  33839. + struct work_struct SwLed1WorkItem;
  33840. +#endif
  33841. + u8 driver_upping;
  33842. +#ifdef CPU_64BIT
  33843. + u8 *usb_buf;
  33844. + struct dma_pool *usb_pool;
  33845. +#endif
  33846. +
  33847. +
  33848. +#ifdef SW_ANTE_DIVERSITY
  33849. +
  33850. +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  33851. +// struct delayed_work SwAntennaWorkItem;
  33852. +//#else
  33853. +// struct work_struct SwAntennaWorkItem;
  33854. +//#endif
  33855. +
  33856. + bool bAntennaDiversityTimerIssued;
  33857. + short antb;
  33858. + short diversity;
  33859. + bool AutoloadFailFlag;
  33860. + u16 EEPROMVersion;
  33861. + u8 EEPROMAntennaDiversity;
  33862. + u16 EEPROMCSThreshold;
  33863. + u8 EEPROMDefaultAntennaB;
  33864. + u8 EEPROMDigitalPhy;
  33865. + u32 EEPROMCSMethod;
  33866. + u8 EEPROMGEPRFOffState;
  33867. + // For HW antenna diversity, added by Roger, 2008.01.30.
  33868. + u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
  33869. + u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
  33870. + bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
  33871. + u8 EEPROMSwAntennaDiversity;
  33872. + bool EEPROMDefaultAntenna1;
  33873. + u8 RegSwAntennaDiversityMechanism;// 0:default from EEPROM, 1: disable, 2: enable.
  33874. + bool bSwAntennaDiverity;
  33875. + u8 RegDefaultAntenna;// 0: default from EEPROM, 1: main, 2: aux. Added by Roger, 2007.11.05.
  33876. + bool bDefaultAntenna1;
  33877. + //long SignalStrength;
  33878. + long Stats_SignalStrength;
  33879. + //long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
  33880. + //long SignalQuality; // in 0-100 index.
  33881. + long Stats_SignalQuality;
  33882. + //long RecvSignalPower; // in dBm.
  33883. + long Stats_RecvSignalPower;
  33884. + u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
  33885. + u32 AdRxOkCnt;
  33886. + long AdRxSignalStrength; // Rx signal strength for Antenna Diversity, which had been smoothing, its valid range is [0,100].
  33887. + u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
  33888. + u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
  33889. + u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
  33890. + u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
  33891. + u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
  33892. + long AdRxSsThreshold; // Signal strength threshold to switch antenna.
  33893. + long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
  33894. + bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
  33895. + long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
  33896. + struct timer_list SwAntennaDiversityTimer;
  33897. +#endif
  33898. + u8 commit;
  33899. +
  33900. +//#ifdef ENABLE_DOT11D
  33901. + u8 channel_plan;
  33902. +//#endif
  33903. + u8 EEPROMSelectNewGPIO;
  33904. +}r8180_priv;
  33905. +
  33906. +// for rtl8187
  33907. +// now mirging to rtl8187B
  33908. +/*
  33909. +typedef enum{
  33910. + LOW_PRIORITY = 0x02,
  33911. + NORM_PRIORITY
  33912. + } priority_t;
  33913. +*/
  33914. +//for rtl8187B
  33915. +typedef enum{
  33916. + BULK_PRIORITY = 0x01,
  33917. + //RSVD0,
  33918. + //RSVD1,
  33919. + LOW_PRIORITY,
  33920. + NORM_PRIORITY,
  33921. + VO_PRIORITY,
  33922. + VI_PRIORITY, //0x05
  33923. + BE_PRIORITY,
  33924. + BK_PRIORITY,
  33925. + RSVD2,
  33926. + RSVD3,
  33927. + BEACON_PRIORITY, //0x0A
  33928. + HIGH_PRIORITY,
  33929. + MANAGE_PRIORITY,
  33930. + RSVD4,
  33931. + RSVD5,
  33932. + UART_PRIORITY //0x0F
  33933. +} priority_t;
  33934. +
  33935. +typedef enum{
  33936. + NIC_8187 = 1,
  33937. + NIC_8187B
  33938. + } nic_t;
  33939. +
  33940. +
  33941. +typedef u32 AC_CODING;
  33942. +#define AC0_BE 0 // ACI: 0x00 // Best Effort
  33943. +#define AC1_BK 1 // ACI: 0x01 // Background
  33944. +#define AC2_VI 2 // ACI: 0x10 // Video
  33945. +#define AC3_VO 3 // ACI: 0x11 // Voice
  33946. +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
  33947. +
  33948. +//
  33949. +// ECWmin/ECWmax field.
  33950. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
  33951. +//
  33952. +typedef union _ECW{
  33953. + u8 charData;
  33954. + struct
  33955. + {
  33956. + u8 ECWmin:4;
  33957. + u8 ECWmax:4;
  33958. + }f; // Field
  33959. +}ECW, *PECW;
  33960. +
  33961. +//
  33962. +// ACI/AIFSN Field.
  33963. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
  33964. +//
  33965. +typedef union _ACI_AIFSN{
  33966. + u8 charData;
  33967. +
  33968. + struct
  33969. + {
  33970. + u8 AIFSN:4;
  33971. + u8 ACM:1;
  33972. + u8 ACI:2;
  33973. + u8 Reserved:1;
  33974. + }f; // Field
  33975. +}ACI_AIFSN, *PACI_AIFSN;
  33976. +
  33977. +//
  33978. +// AC Parameters Record Format.
  33979. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
  33980. +//
  33981. +typedef union _AC_PARAM{
  33982. + u32 longData;
  33983. + u8 charData[4];
  33984. +
  33985. + struct
  33986. + {
  33987. + ACI_AIFSN AciAifsn;
  33988. + ECW Ecw;
  33989. + u16 TXOPLimit;
  33990. + }f; // Field
  33991. +}AC_PARAM, *PAC_PARAM;
  33992. +
  33993. +#ifdef JOHN_HWSEC
  33994. +struct ssid_thread {
  33995. + struct net_device *dev;
  33996. + u8 name[IW_ESSID_MAX_SIZE + 1];
  33997. +};
  33998. +#endif
  33999. +
  34000. +short rtl8180_tx(struct net_device *dev,u32* skbuf, int len,priority_t priority,short morefrag,short rate);
  34001. +
  34002. +#ifdef JOHN_TKIP
  34003. +u32 read_cam(struct net_device *dev, u8 addr);
  34004. +void write_cam(struct net_device *dev, u8 addr, u32 data);
  34005. +#endif
  34006. +u8 read_nic_byte(struct net_device *dev, int x);
  34007. +u8 read_nic_byte_E(struct net_device *dev, int x);
  34008. +u32 read_nic_dword(struct net_device *dev, int x);
  34009. +u16 read_nic_word(struct net_device *dev, int x) ;
  34010. +void write_nic_byte(struct net_device *dev, int x,u8 y);
  34011. +void write_nic_byte_E(struct net_device *dev, int x,u8 y);
  34012. +void write_nic_word(struct net_device *dev, int x,u16 y);
  34013. +void write_nic_dword(struct net_device *dev, int x,u32 y);
  34014. +void force_pci_posting(struct net_device *dev);
  34015. +
  34016. +void rtl8180_rtx_disable(struct net_device *);
  34017. +void rtl8180_rx_enable(struct net_device *);
  34018. +void rtl8180_tx_enable(struct net_device *);
  34019. +
  34020. +void rtl8180_disassociate(struct net_device *dev);
  34021. +//void fix_rx_fifo(struct net_device *dev);
  34022. +void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
  34023. +
  34024. +void rtl8180_set_anaparam(struct net_device *dev,u32 a);
  34025. +void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
  34026. +void rtl8180_update_msr(struct net_device *dev);
  34027. +int rtl8180_down(struct net_device *dev);
  34028. +int rtl8180_up(struct net_device *dev);
  34029. +void rtl8180_commit(struct net_device *dev);
  34030. +void rtl8180_set_chan(struct net_device *dev,short ch);
  34031. +void write_phy(struct net_device *dev, u8 adr, u8 data);
  34032. +void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
  34033. +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
  34034. +void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
  34035. +void rtl8187_set_rxconf(struct net_device *dev);
  34036. +bool MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource);
  34037. +void IPSEnter(struct net_device *dev);
  34038. +void IPSLeave(struct net_device *dev);
  34039. +int r8187b_rfkill_init(struct net_device *dev);
  34040. +void r8187b_rfkill_exit(void);
  34041. +int r8187b_wifi_report_state(r8180_priv *priv);
  34042. +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet);
  34043. +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
  34044. +void rtl8180_patch_ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  34045. +#ifdef _RTL8187_EXT_PATCH_
  34046. +extern int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  34047. +#endif
  34048. +#ifdef JOHN_TKIP
  34049. +void EnableHWSecurityConfig8187(struct net_device *dev);
  34050. +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
  34051. +
  34052. +#endif
  34053. +
  34054. +#endif
  34055. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.c
  34056. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.c 1970-01-01 01:00:00.000000000 +0100
  34057. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.c 2010-03-06 16:43:22.000000000 +0100
  34058. @@ -0,0 +1,1629 @@
  34059. +/*++
  34060. +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
  34061. +
  34062. +Module Name:
  34063. + r8187_led.c
  34064. +
  34065. +Abstract:
  34066. + RTL8187 LED control functions
  34067. +
  34068. +Major Change History:
  34069. + When Who What
  34070. + ---------- --------------- -------------------------------
  34071. + 2006-09-07 Xiong Created
  34072. +
  34073. +Notes:
  34074. +
  34075. +--*/
  34076. +
  34077. +/*--------------------------Include File------------------------------------*/
  34078. +#include "ieee80211/ieee80211.h"
  34079. +#include "r8180_hw.h"
  34080. +#include "r8187.h"
  34081. +#include "r8180_93cx6.h"
  34082. +#include "r8187_led.h"
  34083. +
  34084. +/**
  34085. +*
  34086. +* Initialization function for Sw Leds controll.
  34087. +*
  34088. +* \param dev The net device for this driver.
  34089. +* \return void.
  34090. +*
  34091. +* Note:
  34092. +*
  34093. +*/
  34094. +
  34095. +void
  34096. +InitSwLeds(
  34097. + struct net_device *dev
  34098. + )
  34099. +{
  34100. +
  34101. + struct r8180_priv *priv = ieee80211_priv(dev);
  34102. + u16 usValue;
  34103. +// printk("========>%s()\n", __FUNCTION__);
  34104. +
  34105. +// priv->CustomerID = RT_CID_87B_DELL; //by lizhaoming for DELL 2008.6.3
  34106. + priv->CustomerID = RT_CID_DEFAULT; //just set to default now
  34107. + priv->bEnableLedCtrl = 1;
  34108. + priv->PsrValue = read_nic_byte(dev, PSR);
  34109. + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET >> 1);
  34110. + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
  34111. + DMESG("EEPROM Customer ID: %02X", priv->EEPROMCustomerID);
  34112. +
  34113. + if(priv->CustomerID == RT_CID_DEFAULT)
  34114. + { // If we have not yet change priv->CustomerID in register,
  34115. + // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko.
  34116. + switch(priv->EEPROMCustomerID)
  34117. + {
  34118. + case EEPROM_CID_RSVD0:
  34119. + case EEPROM_CID_RSVD1:
  34120. + priv->CustomerID = RT_CID_DEFAULT;
  34121. + break;
  34122. +
  34123. + case EEPROM_CID_ALPHA0:
  34124. + priv->CustomerID = RT_CID_8187_ALPHA0;
  34125. + break;
  34126. +
  34127. + case EEPROM_CID_SERCOMM_PS:
  34128. + priv->CustomerID = RT_CID_8187_SERCOMM_PS;
  34129. + break;
  34130. +
  34131. + case EEPROM_CID_HW_LED:
  34132. + priv->CustomerID = RT_CID_8187_HW_LED;
  34133. + break;
  34134. +
  34135. + case EEPROM_CID_QMI:
  34136. + priv->CustomerID = RT_CID_87B_QMI;
  34137. + break;
  34138. +
  34139. + case EEPROM_CID_DELL:
  34140. + priv->CustomerID = RT_CID_87B_DELL;
  34141. + break;
  34142. +
  34143. + default:
  34144. + // Invalid value, so, we use default value instead.
  34145. + priv->CustomerID = RT_CID_DEFAULT;
  34146. + break;
  34147. + }
  34148. + }
  34149. + switch(priv->CustomerID)
  34150. + {
  34151. + case RT_CID_DEFAULT:
  34152. + priv->LedStrategy = SW_LED_MODE0;
  34153. + break;
  34154. +
  34155. + case RT_CID_8187_ALPHA0:
  34156. + priv->LedStrategy = SW_LED_MODE1;
  34157. + break;
  34158. +
  34159. + case RT_CID_8187_SERCOMM_PS:
  34160. + priv->LedStrategy = SW_LED_MODE3;
  34161. + break;
  34162. +
  34163. + case RT_CID_87B_QMI:
  34164. + priv->LedStrategy = SW_LED_MODE4;
  34165. + break;
  34166. +
  34167. + case RT_CID_87B_DELL:
  34168. + priv->LedStrategy = SW_LED_MODE5;
  34169. + break;
  34170. +
  34171. + case RT_CID_8187_HW_LED:
  34172. + priv->LedStrategy = HW_LED;
  34173. + break;
  34174. +
  34175. + default:
  34176. + priv->LedStrategy = SW_LED_MODE0;
  34177. + break;
  34178. + }
  34179. +
  34180. + InitLed8187(dev,
  34181. + &(priv->Gpio0Led),
  34182. + LED_PIN_GPIO0,
  34183. + Gpio0LedBlinkTimerCallback);
  34184. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  34185. + INIT_WORK(&priv->Gpio0LedWorkItem,
  34186. + (void(*)(void*))Gpio0LedWorkItemCallback, dev);
  34187. +
  34188. + InitLed8187(dev,
  34189. + &(priv->SwLed0),
  34190. + LED_PIN_LED0,
  34191. + SwLed0BlinkTimerCallback);
  34192. + INIT_WORK(&priv->SwLed0WorkItem,
  34193. + (void(*)(void*))SwLed0WorkItemCallback, dev);
  34194. +
  34195. + InitLed8187(dev,
  34196. + &(priv->SwLed1),
  34197. + LED_PIN_LED1,
  34198. + SwLed1BlinkTimerCallback);
  34199. + INIT_WORK(&priv->SwLed1WorkItem,
  34200. + (void(*)(void*))SwLed1WorkItemCallback, dev);
  34201. +#else
  34202. +INIT_WORK(&priv->Gpio0LedWorkItem,
  34203. + Gpio0LedWorkItemCallback);
  34204. +
  34205. + InitLed8187(dev,
  34206. + &(priv->SwLed0),
  34207. + LED_PIN_LED0,
  34208. + SwLed0BlinkTimerCallback);
  34209. + INIT_WORK(&priv->SwLed0WorkItem,
  34210. + SwLed0WorkItemCallback);
  34211. +
  34212. + InitLed8187(dev,
  34213. + &(priv->SwLed1),
  34214. + LED_PIN_LED1,
  34215. + SwLed1BlinkTimerCallback);
  34216. + INIT_WORK(&priv->SwLed1WorkItem,
  34217. + SwLed1WorkItemCallback);
  34218. +#endif
  34219. +}
  34220. +
  34221. +void
  34222. +DeInitSwLeds(
  34223. + struct net_device *dev
  34224. + )
  34225. +{
  34226. + struct r8180_priv *priv = ieee80211_priv(dev);
  34227. +
  34228. +// printk("=========>%s In\n", __FUNCTION__);
  34229. + DeInitLed8187(dev, &(priv->Gpio0Led));
  34230. + DeInitLed8187(dev, &(priv->SwLed0));
  34231. + DeInitLed8187(dev, &(priv->SwLed1));
  34232. +}
  34233. +
  34234. +void
  34235. +InitLed8187(
  34236. + struct net_device *dev,
  34237. + PLED_8187 pLed,
  34238. + LED_PIN_8187 LedPin,
  34239. + void * BlinkCallBackFunc)
  34240. +{
  34241. +// printk("=========>%s In\n", __FUNCTION__);
  34242. + pLed->LedPin = LedPin;
  34243. +
  34244. + pLed->bLedOn = 0;
  34245. + pLed->CurrLedState = LED_OFF;
  34246. +
  34247. + pLed->bLedBlinkInProgress = 0;
  34248. + pLed->BlinkTimes = 0;
  34249. + pLed->BlinkingLedState = LED_OFF;
  34250. +
  34251. + init_timer(&(pLed->BlinkTimer));
  34252. + pLed->BlinkTimer.data = (unsigned long)dev;
  34253. + pLed->BlinkTimer.function = BlinkCallBackFunc;
  34254. + //PlatformInitializeTimer(dev, &(pLed->BlinkTimer), BlinkCallBackFunc);
  34255. +}
  34256. +
  34257. +void
  34258. +DeInitLed8187(
  34259. + struct net_device *dev,
  34260. + PLED_8187 pLed)
  34261. +{
  34262. + //printk("=========>%s In\n", __FUNCTION__);
  34263. + //PlatformCancelTimer(dev, &(pLed->BlinkTimer));
  34264. + del_timer_sync(&(pLed->BlinkTimer));
  34265. + // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko.
  34266. + pLed->bLedBlinkInProgress = 0;
  34267. +}
  34268. +
  34269. +void
  34270. +LedControl8187(
  34271. + struct net_device *dev,
  34272. + LED_CTL_MODE LedAction
  34273. +)
  34274. +{
  34275. + struct r8180_priv *priv = ieee80211_priv(dev);
  34276. +// printk("=========>%s In\n", __FUNCTION__);
  34277. + if( priv->bEnableLedCtrl == 0)
  34278. + return;
  34279. +
  34280. +
  34281. + if( priv->eRFPowerState != eRfOn &&
  34282. + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
  34283. + LedAction == LED_CTL_SITE_SURVEY ||
  34284. + LedAction == LED_CTL_LINK ||
  34285. + LedAction == LED_CTL_NO_LINK) )
  34286. + {
  34287. + return;
  34288. + }
  34289. +
  34290. +
  34291. + switch(priv->LedStrategy)
  34292. + {
  34293. + case SW_LED_MODE0:
  34294. + SwLedControlMode0(dev, LedAction);
  34295. + break;
  34296. +
  34297. + case SW_LED_MODE1:
  34298. + SwLedControlMode1(dev, LedAction);
  34299. + break;
  34300. +
  34301. + case SW_LED_MODE2:
  34302. + SwLedControlMode2(dev, LedAction);
  34303. + break;
  34304. +
  34305. + case SW_LED_MODE3:
  34306. + SwLedControlMode3(dev, LedAction);
  34307. + break;
  34308. + case SW_LED_MODE4:
  34309. + SwLedControlMode4(dev, LedAction);
  34310. + break;
  34311. +
  34312. + case SW_LED_MODE5:
  34313. + SwLedControlMode5(dev, LedAction);
  34314. + break;
  34315. +
  34316. + default:
  34317. + break;
  34318. + }
  34319. +}
  34320. +
  34321. +
  34322. +//
  34323. +// Description:
  34324. +// Implement each led action for SW_LED_MODE0.
  34325. +// This is default strategy.
  34326. +//
  34327. +void
  34328. +SwLedControlMode0(
  34329. + struct net_device *dev,
  34330. + LED_CTL_MODE LedAction
  34331. +)
  34332. +{
  34333. + struct r8180_priv *priv = ieee80211_priv(dev);
  34334. + PLED_8187 pLed = &(priv->Gpio0Led);
  34335. +
  34336. +// printk("===+++++++++++++++======>%s In\n", __FUNCTION__);
  34337. + // Decide led state
  34338. + switch(LedAction)
  34339. + {
  34340. + case LED_CTL_TX:
  34341. + case LED_CTL_RX:
  34342. + if( pLed->bLedBlinkInProgress == 0 )
  34343. + {
  34344. + pLed->CurrLedState = LED_BLINK_NORMAL;
  34345. + pLed->BlinkTimes = 2;
  34346. + // printk("===========>LED_CTL_TX/RX \n");
  34347. + }
  34348. + else
  34349. + {
  34350. + return;
  34351. + }
  34352. + break;
  34353. +
  34354. + case LED_CTL_SITE_SURVEY:
  34355. + if( pLed->bLedBlinkInProgress == 0 )
  34356. + {
  34357. + pLed->CurrLedState = LED_BLINK_SLOWLY;
  34358. + // pLed->BlinkTimes = 10;
  34359. + //printk("===========>LED_CTL_SURVEY \n");
  34360. + }
  34361. + else
  34362. + {
  34363. + return;
  34364. + }
  34365. + break;
  34366. +
  34367. + case LED_CTL_LINK:
  34368. + // printk("===========>associate commplite LED_CTL_LINK\n");
  34369. + pLed->CurrLedState = LED_ON;
  34370. + break;
  34371. +
  34372. + case LED_CTL_NO_LINK:
  34373. + pLed->CurrLedState = LED_OFF;
  34374. + break;
  34375. +
  34376. + case LED_CTL_POWER_ON:
  34377. + // printk("===========>LED_CTL_POWER_ON\n");
  34378. + pLed->CurrLedState = LED_POWER_ON_BLINK;
  34379. + break;
  34380. +
  34381. + case LED_CTL_POWER_OFF:
  34382. + pLed->CurrLedState = LED_OFF;
  34383. + break;
  34384. +
  34385. + default:
  34386. + return;
  34387. + break;
  34388. + }
  34389. +
  34390. + // Change led state.
  34391. + switch(pLed->CurrLedState)
  34392. + {
  34393. + case LED_ON:
  34394. + if( pLed->bLedBlinkInProgress == 0 )
  34395. + {
  34396. + SwLedOn(dev, pLed);
  34397. + }
  34398. + break;
  34399. +
  34400. + case LED_OFF://modified by lizhaoming 2008.6.23
  34401. + // if( pLed->bLedBlinkInProgress == 0 )
  34402. + // {
  34403. + // SwLedOff(dev, pLed);
  34404. + // }
  34405. +
  34406. + if(pLed->bLedBlinkInProgress )/////////lizhaoming
  34407. + {
  34408. + del_timer_sync(&(pLed->BlinkTimer));
  34409. + pLed->bLedBlinkInProgress = FALSE;
  34410. + }
  34411. + SwLedOff(dev, pLed);
  34412. + break;
  34413. +
  34414. + case LED_BLINK_NORMAL:
  34415. + if( pLed->bLedBlinkInProgress == 0 )
  34416. + {
  34417. + pLed->bLedBlinkInProgress = 1;
  34418. + if( pLed->bLedOn )
  34419. + pLed->BlinkingLedState = LED_OFF;
  34420. + else
  34421. + pLed->BlinkingLedState = LED_ON;
  34422. +
  34423. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34424. + //add_timer(&(pLed->BlinkTimer));
  34425. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34426. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  34427. + }
  34428. + break;
  34429. +
  34430. + case LED_BLINK_SLOWLY:
  34431. + if( pLed->bLedBlinkInProgress == 0 )
  34432. + {
  34433. + //printk("=======>%s SLOWLY\n", __func__);
  34434. + pLed->bLedBlinkInProgress = 1;
  34435. + // if( pLed->bLedOn )
  34436. + pLed->BlinkingLedState = LED_OFF;//for LED_SHIN is LED on
  34437. + // else
  34438. + // pLed->BlinkingLedState = LED_ON;
  34439. +
  34440. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  34441. + }
  34442. + break;
  34443. +
  34444. + case LED_POWER_ON_BLINK:
  34445. + SwLedOn(dev, pLed);
  34446. +#ifdef LED_SHIN
  34447. + mdelay(100);
  34448. + SwLedOff(dev, pLed);
  34449. +#endif
  34450. + break;
  34451. +
  34452. + default:
  34453. + break;
  34454. + }
  34455. +}
  34456. +
  34457. +//
  34458. +// Description:
  34459. +// Implement each led action for SW_LED_MODE1.
  34460. +// For example, this is applied by ALPHA.
  34461. +//
  34462. +void
  34463. +SwLedControlMode1(
  34464. + struct net_device *dev,
  34465. + LED_CTL_MODE LedAction
  34466. +)
  34467. +{
  34468. + struct r8180_priv *priv = ieee80211_priv(dev);
  34469. + PLED_8187 pLed0 = &(priv->SwLed0);
  34470. + PLED_8187 pLed1 = &(priv->SwLed1);
  34471. +// printk("=====++++++++++++++++++++++====>%s In\n", __FUNCTION__);
  34472. +
  34473. + switch(LedAction)
  34474. + {
  34475. + case LED_CTL_TX:
  34476. + if( pLed0->bLedBlinkInProgress == 0 )
  34477. + {
  34478. + pLed0->CurrLedState = LED_BLINK_NORMAL;
  34479. + pLed0->BlinkTimes = 2;
  34480. + pLed0->bLedBlinkInProgress = 1;
  34481. + if( pLed0->bLedOn )
  34482. + pLed0->BlinkingLedState = LED_OFF;
  34483. + else
  34484. + pLed0->BlinkingLedState = LED_ON;
  34485. +
  34486. + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34487. + //add_timer(&(pLed0->BlinkTimer));
  34488. + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34489. + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  34490. + }
  34491. + break;
  34492. +
  34493. + case LED_CTL_LINK:
  34494. + pLed0->CurrLedState = LED_ON;
  34495. + if( pLed0->bLedBlinkInProgress == 0 )
  34496. + {
  34497. + SwLedOn(dev, pLed0);
  34498. + }
  34499. + break;
  34500. +
  34501. + case LED_CTL_NO_LINK:
  34502. + pLed0->CurrLedState = LED_OFF;
  34503. + if( pLed0->bLedBlinkInProgress == 0 )
  34504. + {
  34505. + SwLedOff(dev, pLed0);
  34506. + }
  34507. + break;
  34508. +
  34509. + case LED_CTL_POWER_ON:
  34510. + pLed0->CurrLedState = LED_OFF;
  34511. + SwLedOff(dev, pLed0);
  34512. +
  34513. + pLed1->CurrLedState = LED_ON;
  34514. + SwLedOn(dev, pLed1);
  34515. +
  34516. + break;
  34517. +
  34518. + case LED_CTL_POWER_OFF:
  34519. + pLed0->CurrLedState = LED_OFF;
  34520. + SwLedOff(dev, pLed0);
  34521. +
  34522. + pLed1->CurrLedState = LED_OFF;
  34523. + SwLedOff(dev, pLed1);
  34524. + break;
  34525. +
  34526. + case LED_CTL_SITE_SURVEY:
  34527. + if( pLed0->bLedBlinkInProgress == 0 )
  34528. + {
  34529. + pLed0->CurrLedState = LED_BLINK_SLOWLY;;
  34530. + pLed0->BlinkTimes = 10;
  34531. + pLed0->bLedBlinkInProgress = 1;
  34532. + if( pLed0->bLedOn )
  34533. + pLed0->BlinkingLedState = LED_OFF;
  34534. + else
  34535. + pLed0->BlinkingLedState = LED_ON;
  34536. +
  34537. + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  34538. + //add_timer(&(pLed0->BlinkTimer));
  34539. + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  34540. + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  34541. + }
  34542. + break;
  34543. +
  34544. + default:
  34545. + break;
  34546. + }
  34547. +}
  34548. +
  34549. +//
  34550. +// Description:
  34551. +// Implement each led action for SW_LED_MODE2,
  34552. +// which is customized for AzWave 8187 minicard.
  34553. +// 2006.04.03, by rcnjko.
  34554. +//
  34555. +void
  34556. +SwLedControlMode2(
  34557. + struct net_device *dev,
  34558. + LED_CTL_MODE LedAction
  34559. +)
  34560. +{
  34561. + struct r8180_priv *priv = ieee80211_priv(dev);
  34562. + PLED_8187 pLed = &(priv->Gpio0Led);
  34563. +
  34564. +// printk("====+++++++++++++++++++++=====>%s In\n", __FUNCTION__);
  34565. + // Decide led state
  34566. + switch(LedAction)
  34567. + {
  34568. + case LED_CTL_TX:
  34569. + case LED_CTL_RX:
  34570. + if( pLed->bLedBlinkInProgress == 0 )
  34571. + {
  34572. + pLed->bLedBlinkInProgress = 1;
  34573. +
  34574. + pLed->CurrLedState = LED_BLINK_NORMAL;
  34575. + pLed->BlinkTimes = 2;
  34576. +
  34577. + if( pLed->bLedOn )
  34578. + pLed->BlinkingLedState = LED_OFF;
  34579. + else
  34580. + pLed->BlinkingLedState = LED_ON;
  34581. +
  34582. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34583. + //add_timer(&(pLed->BlinkTimer));
  34584. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34585. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  34586. + }
  34587. + break;
  34588. +
  34589. + case LED_CTL_SITE_SURVEY:
  34590. + if( pLed->bLedBlinkInProgress == 0 )
  34591. + {
  34592. + pLed->bLedBlinkInProgress = 1;
  34593. +
  34594. + //if( dev->MgntInfo.mAssoc ||
  34595. + // dev->MgntInfo.mIbss )
  34596. + //{
  34597. + pLed->CurrLedState = LED_SCAN_BLINK;
  34598. + pLed->BlinkTimes = 4;
  34599. + //}
  34600. + //else
  34601. + //{
  34602. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  34603. + // pLed->BlinkTimes = 24;
  34604. + //}
  34605. +
  34606. + if( pLed->bLedOn )
  34607. + {
  34608. + pLed->BlinkingLedState = LED_OFF;
  34609. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  34610. + //add_timer(&(pLed->BlinkTimer));
  34611. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  34612. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  34613. + }
  34614. + else
  34615. + {
  34616. + pLed->BlinkingLedState = LED_ON;
  34617. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  34618. + //add_timer(&(pLed->BlinkTimer));
  34619. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  34620. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  34621. + }
  34622. + }
  34623. + else
  34624. + {
  34625. + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
  34626. + {
  34627. + pLed->CurrLedState = LED_SCAN_BLINK;
  34628. + /*
  34629. + if( dev->MgntInfo.mAssoc ||
  34630. + dev->MgntInfo.mIbss )
  34631. + {
  34632. + pLed->CurrLedState = LED_SCAN_BLINK;
  34633. + }
  34634. + else
  34635. + {
  34636. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  34637. + }
  34638. + */
  34639. + }
  34640. + }
  34641. + break;
  34642. +
  34643. + case LED_CTL_NO_LINK:
  34644. + if( pLed->bLedBlinkInProgress == 0 )
  34645. + {
  34646. + pLed->bLedBlinkInProgress = 1;
  34647. +
  34648. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  34649. + pLed->BlinkTimes = 24;
  34650. +
  34651. + if( pLed->bLedOn )
  34652. + {
  34653. + pLed->BlinkingLedState = LED_OFF;
  34654. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  34655. + //add_timer(&(pLed->BlinkTimer));
  34656. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  34657. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  34658. + }
  34659. + else
  34660. + {
  34661. + pLed->BlinkingLedState = LED_ON;
  34662. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  34663. + //add_timer(&(pLed->BlinkTimer));
  34664. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  34665. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  34666. + }
  34667. + }
  34668. + else
  34669. + {
  34670. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  34671. + }
  34672. + break;
  34673. +
  34674. + case LED_CTL_LINK:
  34675. + pLed->CurrLedState = LED_ON;
  34676. + if( pLed->bLedBlinkInProgress == 0 )
  34677. + {
  34678. + SwLedOn(dev, pLed);
  34679. + }
  34680. + break;
  34681. +
  34682. + case LED_CTL_POWER_OFF:
  34683. + pLed->CurrLedState = LED_OFF;
  34684. + if( pLed->bLedBlinkInProgress == 0 )
  34685. + {
  34686. + SwLedOff(dev, pLed);
  34687. + }
  34688. + break;
  34689. +
  34690. + default:
  34691. + break;
  34692. + }
  34693. +}
  34694. +
  34695. +
  34696. +//
  34697. +// Description:
  34698. +// Implement each led action for SW_LED_MODE3,
  34699. +// which is customized for Sercomm Printer Server case.
  34700. +// 2006.04.21, by rcnjko.
  34701. +//
  34702. +void
  34703. +SwLedControlMode3(
  34704. + struct net_device *dev,
  34705. + LED_CTL_MODE LedAction
  34706. +)
  34707. +{
  34708. + struct r8180_priv *priv = ieee80211_priv(dev);
  34709. + PLED_8187 pLed = &(priv->Gpio0Led);
  34710. +
  34711. +// printk("=====+++++++++++++++++++====>%s In\n", __FUNCTION__);
  34712. + // Decide led state
  34713. + switch(LedAction)
  34714. + {
  34715. + case LED_CTL_TX:
  34716. + case LED_CTL_RX:
  34717. + if( pLed->bLedBlinkInProgress == 0 )
  34718. + {
  34719. + pLed->bLedBlinkInProgress = 1;
  34720. +
  34721. + pLed->CurrLedState = LED_BLINK_CM3;
  34722. + pLed->BlinkTimes = 2;
  34723. +
  34724. + if( pLed->bLedOn )
  34725. + pLed->BlinkingLedState = LED_OFF;
  34726. + else
  34727. + pLed->BlinkingLedState = LED_ON;
  34728. +
  34729. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  34730. + //add_timer(&(pLed->BlinkTimer));
  34731. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  34732. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  34733. + }
  34734. + break;
  34735. +
  34736. + case LED_CTL_SITE_SURVEY:
  34737. + if( pLed->bLedBlinkInProgress == 0 )
  34738. + {
  34739. + pLed->bLedBlinkInProgress = 1;
  34740. +
  34741. + pLed->CurrLedState = LED_BLINK_CM3;
  34742. + pLed->BlinkTimes = 10;
  34743. +
  34744. + if( pLed->bLedOn )
  34745. + pLed->BlinkingLedState = LED_OFF;
  34746. + else
  34747. + pLed->BlinkingLedState = LED_ON;
  34748. +
  34749. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  34750. + //add_timer(&(pLed->BlinkTimer));
  34751. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  34752. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  34753. + }
  34754. + break;
  34755. +
  34756. + case LED_CTL_LINK:
  34757. + pLed->CurrLedState = LED_ON;
  34758. + if( pLed->bLedBlinkInProgress == 0 )
  34759. + {
  34760. + SwLedOn(dev, pLed);
  34761. + }
  34762. + break;
  34763. +
  34764. + case LED_CTL_NO_LINK:
  34765. + pLed->CurrLedState = LED_OFF;
  34766. + if( pLed->bLedBlinkInProgress == 0 )
  34767. + {
  34768. + SwLedOff(dev, pLed);
  34769. + }
  34770. + break;
  34771. +
  34772. + case LED_CTL_POWER_ON:
  34773. + pLed->CurrLedState = LED_POWER_ON_BLINK;
  34774. + SwLedOn(dev, pLed);
  34775. + mdelay(100);
  34776. + SwLedOff(dev, pLed);
  34777. + break;
  34778. +
  34779. + case LED_CTL_POWER_OFF:
  34780. + pLed->CurrLedState = LED_OFF;
  34781. + if( pLed->bLedBlinkInProgress == 0 )
  34782. + {
  34783. + SwLedOff(dev, pLed);
  34784. + }
  34785. + break;
  34786. +
  34787. + default:
  34788. + break;
  34789. + }
  34790. +}
  34791. +
  34792. +// added by lizhaoming 2008.6.2
  34793. +//
  34794. +// Description:
  34795. +// Implement each led action for SW_LED_MODE4,
  34796. +// which is customized for QMI 8187B minicard.
  34797. +// 2008.04.21, by chiyokolin.
  34798. +//
  34799. +void
  34800. +SwLedControlMode4(
  34801. + struct net_device *dev,
  34802. + LED_CTL_MODE LedAction
  34803. + )
  34804. +{
  34805. + struct r8180_priv *priv = ieee80211_priv(dev);
  34806. + PLED_8187 pLed = &(priv->Gpio0Led);
  34807. +
  34808. + //printk("=====+++++++++++++++++++++====>%s In\n", __FUNCTION__);
  34809. + // Decide led state
  34810. + switch(LedAction)
  34811. + {
  34812. + case LED_CTL_TX:
  34813. + case LED_CTL_RX:
  34814. + //if( pLed->bLedBlinkInProgress == false && !priv->bScanInProgress)//?????
  34815. + if( pLed->bLedBlinkInProgress == 0)
  34816. + {
  34817. + pLed->bLedBlinkInProgress = 1;
  34818. +
  34819. + pLed->CurrLedState = LED_BLINK_NORMAL;
  34820. + pLed->BlinkTimes = 2;
  34821. +
  34822. + if( pLed->bLedOn )
  34823. + pLed->BlinkingLedState = LED_OFF;
  34824. + else
  34825. + pLed->BlinkingLedState = LED_ON;
  34826. +
  34827. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34828. + //add_timer(&(pLed->BlinkTimer));
  34829. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34830. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  34831. + }
  34832. + else
  34833. + //printk("----->LED_CTL_RX/TX bLedBlinkInProgress\n");
  34834. +
  34835. + break;
  34836. +
  34837. + case LED_CTL_SITE_SURVEY:
  34838. + if( pLed->bLedBlinkInProgress == 0 )
  34839. + {
  34840. +
  34841. + pLed->bLedBlinkInProgress = 1;
  34842. + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//////////??????
  34843. + //{
  34844. + pLed->CurrLedState = LED_SCAN_BLINK;
  34845. + pLed->BlinkTimes = 10;
  34846. +
  34847. + pLed->BlinkingLedState = LED_ON;
  34848. +
  34849. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34850. + //add_timer(&(pLed->BlinkTimer));
  34851. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34852. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  34853. + //}
  34854. + //else
  34855. + //{
  34856. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  34857. + // pLed->BlinkTimes = 24;
  34858. + //
  34859. + // if( pLed->bLedOn )
  34860. + // {
  34861. + // pLed->BlinkingLedState = LED_OFF;
  34862. + //
  34863. + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  34864. + // add_timer(&(pLed->BlinkTimer));
  34865. + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  34866. + // }
  34867. + // else
  34868. + // {
  34869. + // pLed->BlinkingLedState = LED_ON;
  34870. +
  34871. + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  34872. + // add_timer(&(pLed->BlinkTimer));
  34873. + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  34874. + // }
  34875. + //}
  34876. + }
  34877. + else
  34878. + {
  34879. + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
  34880. + {
  34881. + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//???????????
  34882. + //{
  34883. + //}
  34884. + //else
  34885. + //{
  34886. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  34887. + //}
  34888. + }
  34889. +
  34890. + //printk("----->LED_CTL_SITE_SURVEY bLedBlinkInProgress\n");
  34891. + }
  34892. + break;
  34893. +
  34894. + case LED_CTL_NO_LINK:
  34895. + if( pLed->bLedBlinkInProgress == 0 )
  34896. + {
  34897. + pLed->bLedBlinkInProgress = 1;
  34898. +
  34899. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  34900. + pLed->BlinkTimes = 24;
  34901. +
  34902. + if( pLed->bLedOn )
  34903. + {
  34904. + pLed->BlinkingLedState = LED_OFF;
  34905. +
  34906. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  34907. + //add_timer(&(pLed->BlinkTimer));
  34908. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  34909. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  34910. + }
  34911. + else
  34912. + {
  34913. + pLed->BlinkingLedState = LED_ON;
  34914. +
  34915. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  34916. + //add_timer(&(pLed->BlinkTimer));
  34917. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
  34918. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  34919. + }
  34920. + }
  34921. + else
  34922. + {
  34923. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  34924. + //printk("----->LED_CTL_NO_LINK bLedBlinkInProgress\n");
  34925. + }
  34926. + break;
  34927. +
  34928. + case LED_CTL_LINK:
  34929. + pLed->CurrLedState = LED_ON;
  34930. + if( pLed->bLedBlinkInProgress == 0)
  34931. + {
  34932. + SwLedOn(dev, pLed);
  34933. + }
  34934. + else
  34935. + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
  34936. +
  34937. + break;
  34938. +
  34939. + case LED_CTL_POWER_OFF:
  34940. + pLed->CurrLedState = LED_OFF;
  34941. + if(pLed->bLedBlinkInProgress)
  34942. + {
  34943. + printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
  34944. +
  34945. + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
  34946. + del_timer_sync(&(pLed->BlinkTimer));
  34947. + pLed->bLedBlinkInProgress = 0;
  34948. + }
  34949. + SwLedOff(dev, pLed);
  34950. + break;
  34951. +
  34952. + default:
  34953. + break;
  34954. + }
  34955. +}
  34956. +
  34957. +
  34958. +
  34959. +//added by lizhaoming 2008.6.3
  34960. +//
  34961. +// Description:
  34962. +// Implement each led action for SW_LED_MODE5,
  34963. +// which is customized for DELL 8187B minicard.
  34964. +// 2008.04.24, by chiyokolin.
  34965. +//
  34966. +void
  34967. +SwLedControlMode5(
  34968. + struct net_device *dev,
  34969. + LED_CTL_MODE LedAction
  34970. + )
  34971. +{
  34972. + struct r8180_priv *priv = ieee80211_priv(dev);
  34973. + PLED_8187 pLed = &(priv->Gpio0Led);
  34974. +
  34975. + // Decide led state
  34976. + //printk("====++++++++++++++++++++++=====>%s In\n", __FUNCTION__);
  34977. + switch(LedAction)
  34978. + {
  34979. + case LED_CTL_TX:
  34980. + case LED_CTL_RX:
  34981. + case LED_CTL_SITE_SURVEY:
  34982. + case LED_CTL_POWER_ON:
  34983. + case LED_CTL_NO_LINK:
  34984. + case LED_CTL_LINK:
  34985. + pLed->CurrLedState = LED_ON;
  34986. + if( pLed->bLedBlinkInProgress == 0 )
  34987. + {
  34988. + pLed->bLedBlinkInProgress = 1;
  34989. + if(! pLed->bLedOn )
  34990. + pLed->BlinkingLedState = LED_ON;
  34991. + else
  34992. + break;
  34993. +
  34994. + //printk("====++++++++++++++++++++++=====>%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
  34995. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  34996. + //add_timer(&(pLed->BlinkTimer));
  34997. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  34998. + // SwLedOn(dev, pLed);
  34999. + }
  35000. + else
  35001. + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
  35002. +
  35003. + break;
  35004. +
  35005. + case LED_CTL_POWER_OFF:
  35006. + pLed->CurrLedState = LED_OFF;
  35007. + // printk("<====++++++++++++++++++++++=====%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
  35008. + if(pLed->bLedBlinkInProgress)
  35009. + {
  35010. + // printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
  35011. +
  35012. + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
  35013. + del_timer_sync(&(pLed->BlinkTimer));
  35014. + pLed->bLedBlinkInProgress = 0;
  35015. + }
  35016. + SwLedOff(dev, pLed);
  35017. + break;
  35018. +
  35019. + default:
  35020. + break;
  35021. + }
  35022. +}
  35023. +
  35024. +//
  35025. +// Callback fuction of the timer, Gpio0Led.BlinkTimer.
  35026. +//
  35027. +void
  35028. +Gpio0LedBlinkTimerCallback(
  35029. + unsigned long data
  35030. + )
  35031. +{
  35032. + struct net_device *dev = (struct net_device *)data;
  35033. + struct r8180_priv *priv = ieee80211_priv(dev);
  35034. +
  35035. +// printk("=========>%s In\n", __FUNCTION__);
  35036. + PlatformSwLedBlink(dev, &(priv->Gpio0Led));
  35037. +}
  35038. +
  35039. +
  35040. +
  35041. +//
  35042. +// Callback fuction of the timer, SwLed0.BlinkTimer.
  35043. +//
  35044. +void
  35045. +SwLed0BlinkTimerCallback(
  35046. + unsigned long data
  35047. + )
  35048. +{
  35049. + struct net_device *dev = (struct net_device *)data;
  35050. + struct r8180_priv *priv = ieee80211_priv(dev);
  35051. +
  35052. +// printk("=========>%s In\n", __FUNCTION__);
  35053. + PlatformSwLedBlink(dev, &(priv->SwLed0));
  35054. +}
  35055. +
  35056. +
  35057. +
  35058. +//
  35059. +// Callback fuction of the timer, SwLed1.BlinkTimer.
  35060. +//
  35061. +void
  35062. +SwLed1BlinkTimerCallback(
  35063. + unsigned long data
  35064. + )
  35065. +{
  35066. + struct net_device *dev = (struct net_device *)data;
  35067. + struct r8180_priv *priv = ieee80211_priv(dev);
  35068. +
  35069. +// printk("=========>%s In\n", __FUNCTION__);
  35070. + PlatformSwLedBlink(dev, &(priv->SwLed1));
  35071. +}
  35072. +
  35073. +void
  35074. +PlatformSwLedBlink(
  35075. + struct net_device *dev,
  35076. + PLED_8187 pLed
  35077. + )
  35078. +{
  35079. + struct r8180_priv *priv = ieee80211_priv(dev);
  35080. +
  35081. +// printk("=========>%s In\n", __FUNCTION__);
  35082. + switch(pLed->LedPin)
  35083. + {
  35084. + case LED_PIN_GPIO0:
  35085. + schedule_work(&(priv->Gpio0LedWorkItem));
  35086. + break;
  35087. +
  35088. + case LED_PIN_LED0:
  35089. + schedule_work(&(priv->SwLed0WorkItem));
  35090. + break;
  35091. +
  35092. + case LED_PIN_LED1:
  35093. + schedule_work(&(priv->SwLed1WorkItem));
  35094. + break;
  35095. +
  35096. + default:
  35097. + break;
  35098. + }
  35099. +}
  35100. +
  35101. +//
  35102. +// Callback fucntion of the workitem for SW LEDs.
  35103. +// 2006.03.01, by rcnjko.
  35104. +//
  35105. +
  35106. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  35107. +void Gpio0LedWorkItemCallback(struct work_struct *work)
  35108. +{
  35109. + struct r8180_priv *priv = container_of(work, struct r8180_priv,Gpio0LedWorkItem);
  35110. + struct net_device *dev = priv->ieee80211->dev;
  35111. +#else
  35112. +void
  35113. +Gpio0LedWorkItemCallback(
  35114. + void * Context
  35115. + )
  35116. +{
  35117. + struct net_device *dev = (struct net_device *)Context;
  35118. + struct r8180_priv *priv = ieee80211_priv(dev);
  35119. +#endif
  35120. + PLED_8187 pLed = &(priv->Gpio0Led);
  35121. + if (priv == NULL || dev == NULL){
  35122. +// printk("=========>%s In\n", __FUNCTION__);
  35123. + //printk("ft=====================>%s()\n", __FUNCTION__);
  35124. + }
  35125. +
  35126. +#if 0 // by lizahoming 2008.6.3
  35127. + if(priv->LedStrategy == SW_LED_MODE2)
  35128. + SwLedCm2Blink(dev, pLed);
  35129. + else
  35130. + SwLedBlink(dev, pLed);
  35131. +#endif
  35132. +
  35133. +#if 1 // by lizahoming 2008.6.3
  35134. + switch(priv->LedStrategy)
  35135. + {
  35136. + case SW_LED_MODE2:
  35137. + SwLedCm2Blink(dev, pLed);
  35138. + break;
  35139. + case SW_LED_MODE4:
  35140. + SwLedCm4Blink(dev, pLed);
  35141. + break;
  35142. + default:
  35143. + SwLedBlink(dev, pLed);
  35144. + break;
  35145. + }
  35146. +#endif
  35147. +
  35148. + //LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) );
  35149. +}
  35150. +
  35151. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  35152. +void SwLed0WorkItemCallback(struct work_struct *work)
  35153. +{
  35154. + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem);
  35155. + //struct net_device *dev = priv->dev;
  35156. +#else
  35157. +void SwLed0WorkItemCallback(void * Context)
  35158. +{
  35159. + //struct net_device *dev = (struct net_device *)Context;
  35160. + //struct r8180_priv *priv = ieee80211_priv(dev);
  35161. +#endif
  35162. + //SwLedBlink(dev, &(priv->SwLed0));
  35163. +// printk("=========>%s In\n", __FUNCTION__);
  35164. +
  35165. + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) );
  35166. +}
  35167. +
  35168. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  35169. +void SwLed1WorkItemCallback(struct work_struct *work)
  35170. +{
  35171. + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem);
  35172. +// struct net_device *dev = priv->dev;
  35173. +#else
  35174. +void
  35175. +SwLed1WorkItemCallback(
  35176. + void * Context
  35177. + )
  35178. +{
  35179. + //struct net_device *dev = (struct net_device *)Context;
  35180. + //struct r8180_priv *priv = ieee80211_priv(dev);
  35181. +#endif
  35182. +// printk("=========>%s In\n", __FUNCTION__);
  35183. + //SwLedBlink(dev, &(priv->SwLed1));
  35184. +
  35185. + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) );
  35186. +}
  35187. +
  35188. +//
  35189. +// Implementation of LED blinking behavior.
  35190. +// It toggle off LED and schedule corresponding timer if necessary.
  35191. +//
  35192. +void
  35193. +SwLedBlink(
  35194. + struct net_device *dev,
  35195. + PLED_8187 pLed
  35196. + )
  35197. +{
  35198. + u8 bStopBlinking = 0;
  35199. +
  35200. + //printk("=========>%s In state:%d\n", __FUNCTION__, pLed->CurrLedState);
  35201. + // Change LED according to BlinkingLedState specified.
  35202. + if( pLed->BlinkingLedState == LED_ON )
  35203. + {
  35204. + SwLedOn(dev, pLed);
  35205. +// printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  35206. + }
  35207. + else
  35208. + {
  35209. + SwLedOff(dev, pLed);
  35210. +// printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  35211. + }
  35212. +
  35213. + // Determine if we shall change LED state again.
  35214. +//by lizhaoming for LED BLINK SLOWLY
  35215. + if(pLed->CurrLedState == LED_BLINK_SLOWLY)
  35216. + {
  35217. + bStopBlinking = 0;
  35218. + } else {
  35219. + pLed->BlinkTimes--;
  35220. + if( pLed->BlinkTimes == 0 )
  35221. + {
  35222. + bStopBlinking = 1;
  35223. + }
  35224. + else
  35225. + {
  35226. + if( pLed->CurrLedState != LED_BLINK_NORMAL &&
  35227. + pLed->CurrLedState != LED_BLINK_SLOWLY &&
  35228. + pLed->CurrLedState != LED_BLINK_CM3 )
  35229. + {
  35230. + bStopBlinking = 1;
  35231. + }
  35232. + }
  35233. + }
  35234. +
  35235. + if(bStopBlinking)
  35236. + {
  35237. + if( pLed->CurrLedState == LED_ON && pLed->bLedOn == 0)
  35238. + {
  35239. + SwLedOn(dev, pLed);
  35240. + }
  35241. + else if(pLed->CurrLedState == LED_OFF && pLed->bLedOn == 1)
  35242. + {
  35243. + SwLedOff(dev, pLed);
  35244. + }
  35245. +
  35246. + pLed->BlinkTimes = 0;
  35247. + pLed->bLedBlinkInProgress = 0;
  35248. + }
  35249. + else
  35250. + {
  35251. + // Assign LED state to toggle.
  35252. + if( pLed->BlinkingLedState == LED_ON )
  35253. + pLed->BlinkingLedState = LED_OFF;
  35254. + else
  35255. + pLed->BlinkingLedState = LED_ON;
  35256. +
  35257. + // Schedule a timer to toggle LED state.
  35258. + switch( pLed->CurrLedState )
  35259. + {
  35260. + case LED_BLINK_NORMAL:
  35261. + //printk("LED_BLINK_NORMAL:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  35262. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  35263. + //add_timer(&(pLed->BlinkTimer));
  35264. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  35265. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  35266. + break;
  35267. +
  35268. + case LED_BLINK_SLOWLY:
  35269. + if( pLed->bLedOn == 1 )
  35270. + {
  35271. + //printk("LED_BLINK_SLOWLY:turn off\n");
  35272. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL+50;//for pcie mini card spec page 33, 250ms
  35273. + //add_timer(&(pLed->BlinkTimer));
  35274. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL+50));
  35275. + pLed->BlinkingLedState = LED_OFF;
  35276. + } else {
  35277. + //printk("LED_BLINK_SLOWLY:turn on\n");
  35278. + //pLed->BlinkTimer.expires = jiffies + 5000;//for pcie mini card spec page 33, 5s
  35279. + //add_timer(&(pLed->BlinkTimer));
  35280. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(5000));
  35281. + pLed->BlinkingLedState = LED_ON;
  35282. + }
  35283. + break;
  35284. +
  35285. + case LED_BLINK_CM3:
  35286. + //printk("LED_BLINK_CM3:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  35287. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  35288. + //add_timer(&(pLed->BlinkTimer));
  35289. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  35290. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  35291. + break;
  35292. +
  35293. + default:
  35294. + //printk("LED_BLINK_default:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  35295. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  35296. + //add_timer(&(pLed->BlinkTimer));
  35297. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  35298. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  35299. + break;
  35300. + }
  35301. + }
  35302. +}
  35303. +
  35304. +
  35305. +
  35306. +//
  35307. +// Implementation of LED blinking behavior for SwLedControlMode2.
  35308. +//
  35309. +void
  35310. +SwLedCm2Blink(
  35311. + struct net_device *dev,
  35312. + PLED_8187 pLed
  35313. + )
  35314. +{
  35315. + struct r8180_priv *priv = ieee80211_priv(dev);
  35316. + //PMGNT_INFO priv = &(dev->MgntInfo);
  35317. + u8 bStopBlinking = 0;
  35318. +
  35319. + //printk("========+++++++++++++=>%s In\n", __FUNCTION__);
  35320. + //To avoid LED blinking when rf is off, add by lizhaoming 2008.6.2
  35321. + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
  35322. + {
  35323. + SwLedOff(dev, pLed);
  35324. +
  35325. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  35326. + //add_timer(&(pLed->BlinkTimer));
  35327. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  35328. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  35329. + //printk(" Hw/Soft Radio Off, turn off Led\n");
  35330. + return;
  35331. + }
  35332. +
  35333. + // Change LED according to BlinkingLedState specified.
  35334. + if( pLed->BlinkingLedState == LED_ON )
  35335. + {
  35336. + SwLedOn(dev, pLed);
  35337. + //DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  35338. + }
  35339. + else
  35340. + {
  35341. + SwLedOff(dev, pLed);
  35342. + //DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  35343. + }
  35344. +
  35345. + //Add by lizhaoming for avoid BlinkTimers <0, 2008.6.2
  35346. + if(pLed->BlinkTimes > 0)
  35347. + {//by lizhaoming 2008.6.2
  35348. + // Determine if we shall change LED state again.
  35349. + pLed->BlinkTimes--;
  35350. + }//by lizhaoming 2008.6.2
  35351. +
  35352. + switch(pLed->CurrLedState)
  35353. + {
  35354. + case LED_BLINK_NORMAL:
  35355. + if(pLed->BlinkTimes == 0)
  35356. + {
  35357. + bStopBlinking = 1;
  35358. + }
  35359. + break;
  35360. +/* CM2 scan blink and no link blind now not be supported
  35361. + case LED_SCAN_BLINK:
  35362. + if( (priv->mAssoc || priv->mIbss) && // Linked.
  35363. + (!priv->bScanInProgress) && // Not in scan stage.
  35364. + (pLed->BlinkTimes % 2 == 0)) // Even
  35365. + {
  35366. + bStopBlinking = 1;
  35367. + }
  35368. + break;
  35369. +
  35370. + case LED_NO_LINK_BLINK:
  35371. + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
  35372. + //if( (priv->mAssoc || priv->mIbss) ) // Linked.
  35373. + if( priv->mAssoc)
  35374. + {
  35375. + bStopBlinking = 1;
  35376. + }
  35377. + else if(priv->mIbss && priv->bMediaConnect )
  35378. + {
  35379. + bStopBlinking = 1;
  35380. + }
  35381. + break;
  35382. +*/
  35383. + default:
  35384. + bStopBlinking = 1;
  35385. + break;
  35386. + }
  35387. +
  35388. + if(bStopBlinking)
  35389. + {
  35390. +/*
  35391. + if( priv->eRFPowerState != eRfOn )
  35392. + {
  35393. + SwLedOff(dev, pLed);
  35394. + }
  35395. + else if( priv->bMediaConnect == 1 && pLed->bLedOn == 0)
  35396. + {
  35397. + SwLedOn(dev, pLed);
  35398. + }
  35399. + else if( priv->bMediaConnect == 0 && pLed->bLedOn == 1)
  35400. + {
  35401. + SwLedOff(dev, pLed);
  35402. + }
  35403. +*/
  35404. + pLed->BlinkTimes = 0;
  35405. + pLed->bLedBlinkInProgress = 0;
  35406. + }
  35407. + else
  35408. + {
  35409. + // Assign LED state to toggle.
  35410. + if( pLed->BlinkingLedState == LED_ON )
  35411. + pLed->BlinkingLedState = LED_OFF;
  35412. + else
  35413. + pLed->BlinkingLedState = LED_ON;
  35414. +
  35415. + // Schedule a timer to toggle LED state.
  35416. + switch( pLed->CurrLedState )
  35417. + {
  35418. + case LED_BLINK_NORMAL:
  35419. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  35420. + //add_timer(&(pLed->BlinkTimer));
  35421. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  35422. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  35423. + break;
  35424. +
  35425. + case LED_BLINK_SLOWLY:
  35426. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  35427. + //add_timer(&(pLed->BlinkTimer));
  35428. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  35429. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  35430. + break;
  35431. +
  35432. + case LED_SCAN_BLINK:
  35433. + case LED_NO_LINK_BLINK:
  35434. + if( pLed->bLedOn ) {
  35435. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  35436. + //add_timer(&(pLed->BlinkTimer));
  35437. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  35438. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  35439. + } else {
  35440. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  35441. + //add_timer(&(pLed->BlinkTimer));
  35442. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  35443. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  35444. + }
  35445. + break;
  35446. +
  35447. + default:
  35448. + //RT_ASSERT(0, ("SwLedCm2Blink(): unexpected state!\n"));
  35449. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  35450. + //add_timer(&(pLed->BlinkTimer));
  35451. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  35452. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  35453. + break;
  35454. + }
  35455. + }
  35456. +}
  35457. +
  35458. +// added by lizhaoming 2008.6.2
  35459. +//
  35460. +// Description:
  35461. +// Implement LED blinking behavior for SW_LED_MODE4.
  35462. +//
  35463. +void
  35464. +SwLedCm4Blink(
  35465. + struct net_device *dev,
  35466. + PLED_8187 pLed
  35467. + )
  35468. +{
  35469. + struct r8180_priv *priv = ieee80211_priv(dev);
  35470. + u8 bStopBlinking = 0;
  35471. +
  35472. + printk("======++++++++++++++++++======>%s In\n", __FUNCTION__);
  35473. + //To avoid LED blinking when rf is off, add by Maddest 20080307
  35474. + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
  35475. + {
  35476. + SwLedOff(dev, pLed);
  35477. +
  35478. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  35479. + //add_timer(&(pLed->BlinkTimer));
  35480. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  35481. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  35482. + printk(" Hw/Soft Radio Off, turn off Led\n");
  35483. + return;
  35484. + }
  35485. + // Change LED according to BlinkingLedState specified.
  35486. + if( pLed->BlinkingLedState == LED_ON )
  35487. + {
  35488. + if(!pLed->bLedOn)
  35489. + {
  35490. + SwLedOn(dev, pLed);
  35491. + }
  35492. + printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  35493. + }
  35494. + else
  35495. + {
  35496. + SwLedOff(dev, pLed);
  35497. + printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  35498. + }
  35499. +
  35500. + //Add by Maddest for avoid BlinkTimers <0, 20080307;
  35501. + if(pLed->BlinkTimes > 0)
  35502. + {
  35503. + // Determine if we shall change LED state again.
  35504. + pLed->BlinkTimes--;
  35505. + }
  35506. + printk("pLed->CurrLedState %d pLed->BlinkTimes %d\n", pLed->CurrLedState,pLed->BlinkTimes);
  35507. + switch(pLed->CurrLedState)
  35508. + {
  35509. + case LED_BLINK_NORMAL:
  35510. + if(pLed->BlinkTimes == 0)
  35511. + {
  35512. + bStopBlinking = 1;
  35513. + }
  35514. + break;
  35515. +
  35516. +/* CM2 scan blink and no link blind now not be supported
  35517. + case LED_SCAN_BLINK:
  35518. + if( (priv->mAssoc || priv->mIbss) && // Linked.//????????????
  35519. + (!priv->bScanInProgress) && // Not in scan stage.//????????????
  35520. + (pLed->BlinkTimes % 2 == 0)) // Even
  35521. + {
  35522. + bStopBlinking = 1;
  35523. + }
  35524. + break;
  35525. +
  35526. + case LED_NO_LINK_BLINK:
  35527. + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
  35528. + //if( (pMgntInfo->mAssoc || pMgntInfo->mIbss) ) // Linked.
  35529. + if( priv->mAssoc) //????????????
  35530. + {
  35531. + bStopBlinking = 1;
  35532. + }
  35533. + else if(priv->mIbss && priv->bMediaConnect )//????????????
  35534. + {
  35535. + bStopBlinking = 1;
  35536. + }
  35537. + break;
  35538. +*/
  35539. +
  35540. + default:
  35541. + bStopBlinking = 1;
  35542. + break;
  35543. + }
  35544. +
  35545. + if(bStopBlinking)
  35546. + {
  35547. + /*
  35548. + if( priv->eRFPowerState != eRfOn )
  35549. + {
  35550. + SwLedOff(dev, pLed);
  35551. + }
  35552. + else if( priv->bMediaConnect == true && pLed->bLedOn == false)//????????????
  35553. + {
  35554. + SwLedOn(dev, pLed);
  35555. + }
  35556. + else if( priv->bMediaConnect == false && pLed->bLedOn == true)//????????????
  35557. + {
  35558. + SwLedOff(dev, pLed);
  35559. + }
  35560. + */
  35561. +
  35562. + pLed->BlinkTimes = 0;
  35563. + pLed->bLedBlinkInProgress = 0;
  35564. + }
  35565. + else
  35566. + {
  35567. + // Assign LED state to toggle.
  35568. + if( pLed->BlinkingLedState == LED_ON )
  35569. + pLed->BlinkingLedState = LED_OFF;
  35570. + else
  35571. + pLed->BlinkingLedState = LED_ON;
  35572. +
  35573. + // Schedule a timer to toggle LED state.
  35574. + switch( pLed->CurrLedState )
  35575. + {
  35576. + case LED_BLINK_NORMAL:
  35577. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  35578. + //add_timer(&(pLed->BlinkTimer));
  35579. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  35580. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  35581. + break;
  35582. +
  35583. + case LED_BLINK_SLOWLY:
  35584. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  35585. + //add_timer(&(pLed->BlinkTimer));
  35586. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  35587. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  35588. + break;
  35589. +
  35590. + case LED_SCAN_BLINK:
  35591. + pLed->BlinkingLedState = LED_ON;
  35592. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  35593. + //add_timer(&(pLed->BlinkTimer));
  35594. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  35595. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  35596. +
  35597. + case LED_NO_LINK_BLINK:
  35598. + if( pLed->bLedOn ){
  35599. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  35600. + //add_timer(&(pLed->BlinkTimer));
  35601. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  35602. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  35603. + }else{
  35604. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  35605. + //add_timer(&(pLed->BlinkTimer));
  35606. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
  35607. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  35608. + }
  35609. + break;
  35610. +
  35611. + default:
  35612. + printk("SwLedCm2Blink(): unexpected state!\n");
  35613. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  35614. + //add_timer(&(pLed->BlinkTimer));
  35615. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  35616. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  35617. + break;
  35618. + }
  35619. + }
  35620. +}
  35621. +
  35622. +void
  35623. +SwLedOn(
  35624. + struct net_device *dev,
  35625. + PLED_8187 pLed
  35626. +)
  35627. +{
  35628. + struct r8180_priv *priv = ieee80211_priv(dev);
  35629. +// printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
  35630. + switch(pLed->LedPin)
  35631. + {
  35632. + case LED_PIN_GPIO0:
  35633. + write_nic_byte(dev,0x0091,0x01);
  35634. + write_nic_byte(dev,0x0090,0x00); // write 0 : LED on
  35635. + break;
  35636. +
  35637. + case LED_PIN_LED0:
  35638. + priv->PsrValue &= ~(0x01 << 4);
  35639. + write_nic_byte(dev, PSR, priv->PsrValue);
  35640. + break;
  35641. +
  35642. + case LED_PIN_LED1:
  35643. + priv->PsrValue &= ~(0x01 << 5);
  35644. + write_nic_byte(dev, PSR, priv->PsrValue);
  35645. + break;
  35646. +
  35647. + default:
  35648. + break;
  35649. + }
  35650. +
  35651. + pLed->bLedOn = 1;
  35652. +}
  35653. +
  35654. +void
  35655. +SwLedOff(
  35656. + struct net_device *dev,
  35657. + PLED_8187 pLed
  35658. +)
  35659. +{
  35660. + struct r8180_priv *priv = ieee80211_priv(dev);
  35661. +
  35662. +
  35663. + //printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
  35664. + switch(pLed->LedPin)
  35665. + {
  35666. + case LED_PIN_GPIO0:
  35667. + write_nic_byte(dev,0x0091,0x01);
  35668. + write_nic_byte(dev,0x0090,0x01); // write 1 : LED off
  35669. + break;
  35670. +
  35671. + case LED_PIN_LED0:
  35672. + priv->PsrValue |= (0x01 << 4);
  35673. + write_nic_byte(dev, PSR, priv->PsrValue);
  35674. + break;
  35675. +
  35676. + case LED_PIN_LED1:
  35677. + priv->PsrValue |= (0x01 << 5);
  35678. + write_nic_byte(dev, PSR, priv->PsrValue);
  35679. + break;
  35680. +
  35681. + default:
  35682. + break;
  35683. + }
  35684. +
  35685. + pLed->bLedOn = 0;
  35686. +}
  35687. +
  35688. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.h linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.h
  35689. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.h 1970-01-01 01:00:00.000000000 +0100
  35690. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.h 2010-03-06 16:43:22.000000000 +0100
  35691. @@ -0,0 +1,276 @@
  35692. +/*++
  35693. +
  35694. +Copyright (c) Microsoft Corporation. All rights reserved.
  35695. +
  35696. +Module Name:
  35697. + r8187_led.h
  35698. +
  35699. +Abstract:
  35700. + definitions and stuctures for rtl8187 led control.
  35701. +
  35702. +Major Change History:
  35703. + When Who What
  35704. + ---------- ------ ----------------------------------------------
  35705. + 2006-09-07 Xiong Created
  35706. +
  35707. +Notes:
  35708. +
  35709. +--*/
  35710. +
  35711. +#ifndef R8187_LED_H
  35712. +#define R8187_LED_H
  35713. +
  35714. +#include <linux/types.h>
  35715. +#include <linux/timer.h>
  35716. +
  35717. +
  35718. +/*--------------------------Define -------------------------------------------*/
  35719. +//
  35720. +// 0x7E-0x7F is reserved for SW customization. 2006.04.21, by rcnjko.
  35721. +//
  35722. +// BIT[0-7] is for CustomerID where value 0x00 and 0xFF is reserved for Realtek.
  35723. +#define EEPROM_SW_REVD_OFFSET 0x7E
  35724. +
  35725. +#define EEPROM_CID_MASK 0x00FF
  35726. +#define EEPROM_CID_RSVD0 0x00
  35727. +#define EEPROM_CID_RSVD1 0xFF
  35728. +#define EEPROM_CID_ALPHA0 0x01
  35729. +#define EEPROM_CID_SERCOMM_PS 0x02
  35730. +#define EEPROM_CID_HW_LED 0x03
  35731. +
  35732. +#define EEPROM_CID_QMI 0x07 //Added by lizhaoming 2008.6.3
  35733. +#define EEPROM_CID_DELL 0x08 //Added by lizhaoming 2008.6.3
  35734. +
  35735. +#define LED_BLINK_NORMAL_INTERVAL 100 //by lizhaoming 50 -> 100
  35736. +#define LED_BLINK_SLOWLY_INTERVAL 200
  35737. +
  35738. +// Customized for AzWave, 2006.04.03, by rcnjko.
  35739. +#define LED_CM2_BLINK_ON_INTERVAL 250
  35740. +#define LED_CM2_BLINK_OFF_INTERVAL 4750
  35741. +//
  35742. +
  35743. +// Customized for Sercomm Printer Server case, 2006.04.21, by rcnjko.
  35744. +#define LED_CM3_BLINK_INTERVAL 1500
  35745. +
  35746. +// by lizhaoming 2008.6.3: Customized for QMI.
  35747. +//
  35748. +#define LED_CM4_BLINK_ON_INTERVAL 500
  35749. +#define LED_CM4_BLINK_OFF_INTERVAL 4500
  35750. +
  35751. +
  35752. +/*--------------------------Define MACRO--------------------------------------*/
  35753. +
  35754. +
  35755. +/*------------------------------Define Struct---------------------------------*/
  35756. +typedef enum _LED_STATE_8187{
  35757. + LED_UNKNOWN = 0,
  35758. + LED_ON = 1,
  35759. + LED_OFF = 2,
  35760. + LED_BLINK_NORMAL = 3,
  35761. + LED_BLINK_SLOWLY = 4,
  35762. + LED_POWER_ON_BLINK = 5,
  35763. + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning.
  35764. + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state.
  35765. + LED_BLINK_CM3 = 8, // Customzied for Sercomm Printer Server case
  35766. +}LED_STATE_8187;
  35767. +
  35768. +typedef enum _RT_CID_TYPE {
  35769. + RT_CID_DEFAULT,
  35770. + RT_CID_8187_ALPHA0,
  35771. + RT_CID_8187_SERCOMM_PS,
  35772. + RT_CID_8187_HW_LED,
  35773. +
  35774. + RT_CID_87B_QMI , //Added by lizhaoming 2008.6.3
  35775. + RT_CID_87B_DELL, //Added by lizhaoming 2008.6.3
  35776. +
  35777. +} RT_CID_TYPE;
  35778. +
  35779. +typedef enum _LED_STRATEGY_8187{
  35780. + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
  35781. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA.
  35782. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard.
  35783. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case.
  35784. + SW_LED_MODE4, //added by lizhaoming for bluetooth 2008.6.3
  35785. + SW_LED_MODE5, //added by lizhaoming for bluetooth 2008.6.3
  35786. + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.)
  35787. +}LED_STRATEGY_8187, *PLED_STRATEGY_8187;
  35788. +
  35789. +typedef enum _LED_PIN_8187{
  35790. + LED_PIN_GPIO0,
  35791. + LED_PIN_LED0,
  35792. + LED_PIN_LED1
  35793. +}LED_PIN_8187;
  35794. +
  35795. +//by lizhaoming for LED 2008.6.23 into ieee80211.h
  35796. +//typedef enum _LED_CTL_MODE {
  35797. +// LED_CTL_POWER_ON,
  35798. +// LED_CTL_POWER_OFF,
  35799. +// LED_CTL_LINK,
  35800. +// LED_CTL_NO_LINK,
  35801. +// LED_CTL_TX,
  35802. +// LED_CTL_RX,
  35803. +// LED_CTL_SITE_SURVEY,
  35804. +//} LED_CTL_MODE;
  35805. +
  35806. +typedef struct _LED_8187{
  35807. + LED_PIN_8187 LedPin; // Identify how to implement this SW led.
  35808. +
  35809. + LED_STATE_8187 CurrLedState; // Current LED state.
  35810. + u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF.
  35811. +
  35812. + u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w..
  35813. + u32 BlinkTimes; // Number of times to toggle led state for blinking.
  35814. + LED_STATE_8187 BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are.
  35815. + struct timer_list BlinkTimer; // Timer object for led blinking.
  35816. +} LED_8187, *PLED_8187;
  35817. +
  35818. +
  35819. +
  35820. +/*------------------------Export global variable------------------------------*/
  35821. +
  35822. +
  35823. +/*------------------------------Funciton declaration--------------------------*/
  35824. +void
  35825. +InitSwLeds(
  35826. + struct net_device *dev
  35827. + );
  35828. +
  35829. +void
  35830. +DeInitSwLeds(
  35831. + struct net_device *dev
  35832. + );
  35833. +
  35834. +void
  35835. +InitLed8187(
  35836. + struct net_device *dev,
  35837. + PLED_8187 pLed,
  35838. + LED_PIN_8187 LedPin,
  35839. + void * BlinkCallBackFunc);
  35840. +
  35841. +void
  35842. +DeInitLed8187(
  35843. + struct net_device *dev,
  35844. + PLED_8187 pLed);
  35845. +
  35846. +void
  35847. +LedControl8187(
  35848. + struct net_device *dev,
  35849. + LED_CTL_MODE LedAction
  35850. +);
  35851. +
  35852. +void
  35853. +SwLedControlMode0(
  35854. + struct net_device *dev,
  35855. + LED_CTL_MODE LedAction
  35856. +);
  35857. +
  35858. +void
  35859. +SwLedControlMode1(
  35860. + struct net_device *dev,
  35861. + LED_CTL_MODE LedAction
  35862. +);
  35863. +
  35864. +void
  35865. +SwLedControlMode2(
  35866. + struct net_device *dev,
  35867. + LED_CTL_MODE LedAction
  35868. +);
  35869. +
  35870. +void
  35871. +SwLedControlMode3(
  35872. + struct net_device *dev,
  35873. + LED_CTL_MODE LedAction
  35874. +);
  35875. +
  35876. +
  35877. +void
  35878. +SwLedControlMode4(
  35879. + struct net_device *dev,
  35880. + LED_CTL_MODE LedAction
  35881. +);
  35882. +
  35883. +
  35884. +void
  35885. +SwLedControlMode5(
  35886. + struct net_device *dev,
  35887. + LED_CTL_MODE LedAction
  35888. +);
  35889. +
  35890. +void
  35891. +Gpio0LedBlinkTimerCallback(
  35892. + unsigned long data
  35893. + );
  35894. +
  35895. +void
  35896. +SwLed0BlinkTimerCallback(
  35897. + unsigned long data
  35898. + );
  35899. +
  35900. +void
  35901. +SwLed1BlinkTimerCallback(
  35902. + unsigned long data
  35903. + );
  35904. +
  35905. +void
  35906. +PlatformSwLedBlink(
  35907. + struct net_device *dev,
  35908. + PLED_8187 pLed
  35909. + );
  35910. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  35911. +void
  35912. +Gpio0LedWorkItemCallback(
  35913. + void * Context
  35914. + );
  35915. +
  35916. +void
  35917. +SwLed0WorkItemCallback(
  35918. + void * Context
  35919. + );
  35920. +
  35921. +void
  35922. +SwLed1WorkItemCallback(
  35923. + void * Context
  35924. + );
  35925. +#else
  35926. +void
  35927. +Gpio0LedWorkItemCallback(struct work_struct *work);
  35928. +
  35929. +void
  35930. +SwLed0WorkItemCallback(struct work_struct *work);
  35931. +
  35932. +void
  35933. +SwLed1WorkItemCallback(struct work_struct *work);
  35934. +
  35935. +#endif
  35936. +void
  35937. +SwLedBlink(
  35938. + struct net_device *dev,
  35939. + PLED_8187 pLed
  35940. + );
  35941. +
  35942. +void
  35943. +SwLedCm2Blink(
  35944. + struct net_device *dev,
  35945. + PLED_8187 pLed
  35946. + );
  35947. +
  35948. +void
  35949. +SwLedCm4Blink(
  35950. + struct net_device *dev,
  35951. + PLED_8187 pLed
  35952. + );
  35953. +
  35954. +void
  35955. +SwLedOn(
  35956. + struct net_device *dev,
  35957. + PLED_8187 pLed
  35958. +);
  35959. +
  35960. +void
  35961. +SwLedOff(
  35962. + struct net_device *dev,
  35963. + PLED_8187 pLed
  35964. +);
  35965. +
  35966. +
  35967. +#endif
  35968. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_rfkill.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_rfkill.c
  35969. --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_rfkill.c 1970-01-01 01:00:00.000000000 +0100
  35970. +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_rfkill.c 2010-03-06 16:43:22.000000000 +0100
  35971. @@ -0,0 +1,157 @@
  35972. +/*
  35973. + * rtl8187b specific rfkill support
  35974. + *
  35975. + * NOTE: we only concern about two states
  35976. + * eRfOff: RFKILL_STATE_SOFT_BLOCKED
  35977. + * eRfOn: RFKILL_STATE_UNBLOCKED
  35978. + * TODO: move led controlling source code to rfkill framework
  35979. + *
  35980. + * Copyright (C) 2009 Lemote Inc.
  35981. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  35982. + */
  35983. +
  35984. +#include <linux/module.h>
  35985. +#include <linux/rfkill.h>
  35986. +#include <linux/device.h>
  35987. +
  35988. +/* LED macros are defined in r8187.h and rfkill.h, we not use any of them here
  35989. + * just avoid compiling erros here.
  35990. + */
  35991. +#undef LED
  35992. +
  35993. +#include "r8187.h"
  35994. +#include "ieee80211/ieee80211.h"
  35995. +#include "linux/netdevice.h"
  35996. +
  35997. +static struct rfkill *r8187b_rfkill;
  35998. +static struct work_struct r8187b_rfkill_task;
  35999. +static int initialized;
  36000. +/* turn off by default */
  36001. +int r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
  36002. +struct net_device *r8187b_dev = NULL;
  36003. +RT_RF_POWER_STATE eRfPowerStateToSet;
  36004. +
  36005. +/* These two mutexes are used to ensure the relative rfkill status are accessed
  36006. + * by different tasks exclusively */
  36007. +DEFINE_MUTEX(statetoset_lock);
  36008. +DEFINE_MUTEX(state_lock);
  36009. +
  36010. +static void r8187b_wifi_rfkill_task(struct work_struct *work)
  36011. +{
  36012. + if (r8187b_dev) {
  36013. + mutex_lock(&statetoset_lock);
  36014. + r8187b_wifi_change_rfkill_state(r8187b_dev, eRfPowerStateToSet);
  36015. + mutex_unlock(&statetoset_lock);
  36016. + }
  36017. +}
  36018. +
  36019. +static int r8187b_wifi_update_rfkill_state(int status)
  36020. +{
  36021. + /* ensure r8187b_rfkill is initialized if dev is not initialized, means
  36022. + * wifi driver is not start, the status is eRfOff be default.
  36023. + */
  36024. + if (!r8187b_dev)
  36025. + return eRfOff;
  36026. +
  36027. + if (initialized == 0) {
  36028. + /* init the rfkill work task */
  36029. + INIT_WORK(&r8187b_rfkill_task, r8187b_wifi_rfkill_task);
  36030. + initialized = 1;
  36031. + }
  36032. +
  36033. + mutex_lock(&statetoset_lock);
  36034. + if (status == 1)
  36035. + eRfPowerStateToSet = eRfOn;
  36036. + else if (status == 0)
  36037. + eRfPowerStateToSet = eRfOff;
  36038. + else if (status == 2) {
  36039. + /* if the KEY_WLAN is pressed, just switch it! */
  36040. + mutex_lock(&state_lock);
  36041. + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
  36042. + eRfPowerStateToSet = eRfOff;
  36043. + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
  36044. + eRfPowerStateToSet = eRfOn;
  36045. + mutex_unlock(&state_lock);
  36046. + }
  36047. + mutex_unlock(&statetoset_lock);
  36048. +
  36049. + schedule_work(&r8187b_rfkill_task);
  36050. +
  36051. + return eRfPowerStateToSet;
  36052. +}
  36053. +
  36054. +static int r8187b_rfkill_set(void *data, bool blocked)
  36055. +{
  36056. + r8187b_wifi_update_rfkill_state(!blocked);
  36057. +
  36058. + return 0;
  36059. +}
  36060. +
  36061. +static void r8187b_rfkill_query(struct rfkill *rfkill, void *data)
  36062. +{
  36063. + static bool blocked;
  36064. +
  36065. + mutex_lock(&state_lock);
  36066. + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
  36067. + blocked = 0;
  36068. + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
  36069. + blocked = 1;
  36070. + mutex_unlock(&state_lock);
  36071. +
  36072. + rfkill_set_hw_state(rfkill, blocked);
  36073. +}
  36074. +
  36075. +int r8187b_wifi_report_state(r8180_priv *priv)
  36076. +{
  36077. + mutex_lock(&state_lock);
  36078. + r8187b_rfkill_state = RFKILL_USER_STATE_UNBLOCKED;
  36079. + if (priv->ieee80211->bHwRadioOff && priv->eRFPowerState == eRfOff)
  36080. + r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
  36081. + mutex_unlock(&state_lock);
  36082. +
  36083. + r8187b_rfkill_query(r8187b_rfkill, NULL);
  36084. +
  36085. + return 0;
  36086. +}
  36087. +
  36088. +static const struct rfkill_ops r8187b_rfkill_ops = {
  36089. + .set_block = r8187b_rfkill_set,
  36090. + .query = r8187b_rfkill_query,
  36091. +};
  36092. +
  36093. +int r8187b_rfkill_init(struct net_device *dev)
  36094. +{
  36095. + int ret;
  36096. +
  36097. + /* init the r8187b device */
  36098. + r8187b_dev = dev;
  36099. +
  36100. + /* init the rfkill struct */
  36101. + r8187b_rfkill = rfkill_alloc("r8187b-wifi", &dev->dev,
  36102. + RFKILL_TYPE_WLAN, &r8187b_rfkill_ops,
  36103. + (void *)1);
  36104. +
  36105. + if (!r8187b_rfkill) {
  36106. + rfkill_destroy(r8187b_rfkill);
  36107. + printk(KERN_WARNING "r8187b: Unable to allocate rfkill\n");
  36108. + return -ENOMEM;
  36109. + }
  36110. + ret = rfkill_register(r8187b_rfkill);
  36111. + if (ret) {
  36112. + rfkill_destroy(r8187b_rfkill);
  36113. + return ret;
  36114. + }
  36115. +
  36116. + /* The default status is passed to the rfkill module */
  36117. +
  36118. + return 0;
  36119. +}
  36120. +
  36121. +void r8187b_rfkill_exit(void)
  36122. +{
  36123. + if (r8187b_rfkill) {
  36124. + rfkill_unregister(r8187b_rfkill);
  36125. + rfkill_destroy(r8187b_rfkill);
  36126. + }
  36127. + r8187b_rfkill = NULL;
  36128. +}
  36129. diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/readme linux-lemote/drivers/net/wireless/rtl8187b/readme
  36130. --- linux-2.6.33/drivers/net/wireless/rtl8187b/readme 1970-01-01 01:00:00.000000000 +0100
  36131. +++ linux-lemote/drivers/net/wireless/rtl8187b/readme 2010-03-06 16:43:22.000000000 +0100
  36132. @@ -0,0 +1,124 @@
  36133. +rtl8187 Linux kernel driver
  36134. +Released under the terms of GNU General Public Licence (GPL)
  36135. +Copyright(c) Andrea Merello - 2004,2005
  36136. +
  36137. +Portions of this driver are based on other projects, please see the notes
  36138. +in the source files for detail.
  36139. +A special thanks go to Realtek corp for their support and to David Young
  36140. +------------------------------------------------------------------------------
  36141. +
  36142. +This is an attempt to write somethig that can make rtl8187 usb dongle wifi card
  36143. +on Linux using only opensource stuff.
  36144. +The rtl8225 radio is supported.
  36145. +
  36146. +It's in early development stage so don't expect too much from it
  36147. +(also use it at your own risk!)
  36148. +This should be considered just a fragment of code.. using it on your(any)
  36149. +system is at your own risk! Please note that I never supported the idea to
  36150. +use it in any way, so i cannot be considered responsible in any way for
  36151. +anything deriving by it usage.
  36152. +
  36153. +Anyway for now we have monitor mode and managed mode
  36154. +basically working! This isn't necessary stable, but seems to work..
  36155. +
  36156. +This driver is still under development and very far from perfect. It should work on x86,
  36157. +Other archs are untested..
  36158. +
  36159. +To compile the driver simply run make.
  36160. +
  36161. +The driver contains also the ieee80211.h and ieee80211_crypt.h from the ieee stack.
  36162. +Note that for some reasons this stack is NOT the same that will be included in newer
  36163. +2.6 kernel. I will try to port to this stack as soon as it will have enought features
  36164. +to support 8187 cards.
  36165. +Please note that you will have to make sure the two .h files are the same of the ieee
  36166. +stack.
  36167. +In other words when you download from the CVS this driver and the ieee80211 stack a good
  36168. +idea is to copy the ieee80211.h and ieee80211_crypt.h from the ieee directory to the drv
  36169. +directory
  36170. +
  36171. +Warning during compile are OK
  36172. +
  36173. +To wake up the nic run:
  36174. +
  36175. + ifconfig <ifacename> up
  36176. +
  36177. +(where <ifacename> is your network device for wlan card).
  36178. +
  36179. +Please note that the default interface name is wlanX.
  36180. +
  36181. +Please note thet this will take several seconds..
  36182. +
  36183. +If you would like to set the interface name to something else you may use the
  36184. +'devname=' module parameter. For example:
  36185. +
  36186. + insmod r8187.ko ifname=eth%d
  36187. +
  36188. +will set the interface name of this device to something like eth0.
  36189. +
  36190. +Once the nic is up it can be put in a monitor mode by running:
  36191. +
  36192. + iwconfig <ifacename> mode monitor
  36193. +
  36194. +and channel number may be changed by running:
  36195. +
  36196. + iwconfig <ifacename> channel XX
  36197. +
  36198. +
  36199. +In monitor mode a choice may be made via iwpriv if the nic should pass packets
  36200. +with bad crc or drop them.
  36201. +
  36202. +To put the nic in managed mode run:
  36203. +
  36204. + iwconfig <ifacename> mode managed
  36205. +
  36206. +In managed mode there is support for
  36207. +
  36208. + iwlist scan
  36209. +
  36210. +that should report the currently available networks.
  36211. +Please note that in managed mode channels cannot be changed manually.
  36212. +
  36213. +To associate with a network
  36214. +
  36215. + iwconfig <ifacename> essid XXXXX
  36216. +
  36217. +where XXXXX is the network essid (name) reported by 'iwlist scan'. Please
  36218. +note that essid is case sensitive.
  36219. +
  36220. +If your network is not broadcasting the ESSID, then you need to specify *also*
  36221. +the AP MAC address
  36222. +
  36223. + iwconfig <ifacename> ap XX:XX:XX:XX:XX:XX
  36224. +
  36225. +The driver accepts another boolean parameter: hwseqnum
  36226. +If set to 1 it lets the card HW take care of the sequence number of the TXed
  36227. +frames. Altought in managed mode I can't see an important reason to use HW to
  36228. +do that, when we'll start to TX beacons in master (AP) and ad-hoc modes most
  36229. +probably it will be extremely useful (since most probably we will use two HW
  36230. +queues).
  36231. +
  36232. +I'm unsure if it will work correctly on all NICs.. reports are *VERY, VERY* apreciated..
  36233. +
  36234. +
  36235. + WEP
  36236. + ===
  36237. +
  36238. +WEP encryption should work. For now it's done by host, not by the nic. Key can be set with:
  36239. +Key can be set with
  36240. +
  36241. + iwconfig <ifacename> key 12345...
  36242. +
  36243. +WEP is supported via software thanks to the ipw stack.
  36244. +
  36245. +Shared and open authentication are supported
  36246. +
  36247. + IWPRIV
  36248. + ======
  36249. +
  36250. +This driver supports some private handlers:
  36251. +-badcrc: let you choose to kill or to pass to the upper layer frames with bad crc in monitor mode
  36252. +-activescan: if 0 the driver will avoid to send probe requests, sanning will be only on beacon basis
  36253. +
  36254. +
  36255. +If you have some question/comments please feel free to write me.
  36256. +
  36257. diff -Nur linux-2.6.33/drivers/platform/Kconfig linux-lemote/drivers/platform/Kconfig
  36258. --- linux-2.6.33/drivers/platform/Kconfig 2010-02-24 19:52:17.000000000 +0100
  36259. +++ linux-lemote/drivers/platform/Kconfig 2010-03-06 16:43:22.000000000 +0100
  36260. @@ -1,3 +1,7 @@
  36261. if X86
  36262. source "drivers/platform/x86/Kconfig"
  36263. endif
  36264. +
  36265. +if MIPS
  36266. +source "drivers/platform/mips/Kconfig"
  36267. +endif
  36268. diff -Nur linux-2.6.33/drivers/platform/Makefile linux-lemote/drivers/platform/Makefile
  36269. --- linux-2.6.33/drivers/platform/Makefile 2010-02-24 19:52:17.000000000 +0100
  36270. +++ linux-lemote/drivers/platform/Makefile 2010-03-06 16:43:22.000000000 +0100
  36271. @@ -3,3 +3,4 @@
  36272. #
  36273. obj-$(CONFIG_X86) += x86/
  36274. +obj-$(CONFIG_MIPS) += mips/
  36275. diff -Nur linux-2.6.33/drivers/platform/mips/Kconfig linux-lemote/drivers/platform/mips/Kconfig
  36276. --- linux-2.6.33/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
  36277. +++ linux-lemote/drivers/platform/mips/Kconfig 2010-03-06 16:43:22.000000000 +0100
  36278. @@ -0,0 +1,43 @@
  36279. +#
  36280. +# MIPS Platform Specific Drivers
  36281. +#
  36282. +
  36283. +menuconfig MIPS_PLATFORM_DEVICES
  36284. + bool "MIPS Platform Specific Device Drivers"
  36285. + default y
  36286. + help
  36287. + Say Y here to get to see options for device drivers of various
  36288. + MIPS platforms, including vendor-specific netbook/laptop/pc extension
  36289. + drivers. This option alone does not add any kernel code.
  36290. +
  36291. + If you say N, all options in this submenu will be skipped and disabled.
  36292. +
  36293. +if MIPS_PLATFORM_DEVICES
  36294. +
  36295. +config LEMOTE_YEELOONG2F
  36296. + tristate "Lemote YeeLoong Laptop"
  36297. + depends on LEMOTE_MACH2F
  36298. + select BACKLIGHT_CLASS_DEVICE
  36299. + select POWER_SUPPLY
  36300. + select HWMON
  36301. + select VIDEO_OUTPUT_CONTROL
  36302. + select INPUT_SPARSEKMAP
  36303. + depends on INPUT
  36304. + help
  36305. + YeeLoong netbook is a mini laptop made by Lemote, which is basically
  36306. + compatible to FuLoong2F mini PC, but it has an extra Embedded
  36307. + Controller(kb3310b) for battery, hotkey, backlight, temperature and
  36308. + fan management.
  36309. +
  36310. +config LEMOTE_LYNLOONG2F
  36311. + tristate "Lemote LynLoong PC"
  36312. + depends on LEMOTE_MACH2F
  36313. + select BACKLIGHT_CLASS_DEVICE
  36314. + select VIDEO_OUTPUT_CONTROL
  36315. + help
  36316. + LynLoong PC is an AllINONE machine made by Lemote, which is basically
  36317. + compatible to FuLoong2F Mini PC, the only difference is that it has a
  36318. + size-fixed screen: 1360x768 with sisfb video driver. and also, it has
  36319. + its own specific suspend support.
  36320. +
  36321. +endif # MIPS_PLATFORM_DEVICES
  36322. diff -Nur linux-2.6.33/drivers/platform/mips/lynloong_pc.c linux-lemote/drivers/platform/mips/lynloong_pc.c
  36323. --- linux-2.6.33/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
  36324. +++ linux-lemote/drivers/platform/mips/lynloong_pc.c 2010-03-06 16:43:22.000000000 +0100
  36325. @@ -0,0 +1,511 @@
  36326. +/*
  36327. + * Driver for LynLoong PC extras
  36328. + *
  36329. + * Copyright (C) 2009 Lemote Inc.
  36330. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>
  36331. + *
  36332. + * This program is free software; you can redistribute it and/or modify
  36333. + * it under the terms of the GNU General Public License version 2 as
  36334. + * published by the Free Software Foundation.
  36335. + */
  36336. +
  36337. +#include <linux/err.h>
  36338. +#include <linux/platform_device.h>
  36339. +#include <linux/backlight.h> /* for backlight subdriver */
  36340. +#include <linux/fb.h>
  36341. +#include <linux/video_output.h> /* for video output subdriver */
  36342. +#include <linux/delay.h> /* for suspend support */
  36343. +
  36344. +#include <cs5536/cs5536.h>
  36345. +#include <cs5536/cs5536_mfgpt.h>
  36346. +
  36347. +#include <loongson.h>
  36348. +
  36349. +static u32 gpio_base, mfgpt_base;
  36350. +
  36351. +static void set_gpio_reg_high(int gpio, int reg)
  36352. +{
  36353. + u32 val;
  36354. +
  36355. + val = inl(gpio_base + reg);
  36356. + val |= (1 << gpio);
  36357. + val &= ~(1 << (16 + gpio));
  36358. + outl(val, gpio_base + reg);
  36359. + mmiowb();
  36360. +}
  36361. +
  36362. +static void set_gpio_reg_low(int gpio, int reg)
  36363. +{
  36364. + u32 val;
  36365. +
  36366. + val = inl(gpio_base + reg);
  36367. + val |= (1 << (16 + gpio));
  36368. + val &= ~(1 << gpio);
  36369. + outl(val, gpio_base + reg);
  36370. + mmiowb();
  36371. +}
  36372. +
  36373. +static void set_gpio_output_low(int gpio)
  36374. +{
  36375. + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
  36376. + set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
  36377. +}
  36378. +
  36379. +static void set_gpio_output_high(int gpio)
  36380. +{
  36381. + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
  36382. + set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
  36383. +}
  36384. +
  36385. +/* backlight subdriver */
  36386. +
  36387. +#define MAX_BRIGHTNESS 100
  36388. +#define DEFAULT_BRIGHTNESS 50
  36389. +#define MIN_BRIGHTNESS 0
  36390. +static unsigned int level;
  36391. +
  36392. +DEFINE_SPINLOCK(backlight_lock);
  36393. +/* Tune the brightness */
  36394. +static void setup_mfgpt2(void)
  36395. +{
  36396. + unsigned long flags;
  36397. +
  36398. + spin_lock_irqsave(&backlight_lock, flags);
  36399. +
  36400. + /* Set MFGPT2 comparator 1,2 */
  36401. + outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
  36402. + outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
  36403. + /* Clear MFGPT2 UP COUNTER */
  36404. + outw(0, MFGPT2_CNT);
  36405. + /* Enable counter, compare mode, 32k */
  36406. + outw(0x8280, MFGPT2_SETUP);
  36407. +
  36408. + spin_unlock_irqrestore(&backlight_lock, flags);
  36409. +}
  36410. +
  36411. +static int lynloong_set_brightness(struct backlight_device *bd)
  36412. +{
  36413. + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
  36414. + bd->props.power == FB_BLANK_UNBLANK) ?
  36415. + bd->props.brightness : 0;
  36416. +
  36417. + if (level > MAX_BRIGHTNESS)
  36418. + level = MAX_BRIGHTNESS;
  36419. + else if (level < MIN_BRIGHTNESS)
  36420. + level = MIN_BRIGHTNESS;
  36421. +
  36422. + setup_mfgpt2();
  36423. +
  36424. + return 0;
  36425. +}
  36426. +
  36427. +static int lynloong_get_brightness(struct backlight_device *bd)
  36428. +{
  36429. + return level;
  36430. +}
  36431. +
  36432. +static struct backlight_ops backlight_ops = {
  36433. + .get_brightness = lynloong_get_brightness,
  36434. + .update_status = lynloong_set_brightness,
  36435. +};
  36436. +
  36437. +static struct backlight_device *lynloong_backlight_dev;
  36438. +
  36439. +static int lynloong_backlight_init(void)
  36440. +{
  36441. + int ret;
  36442. + u32 hi;
  36443. +
  36444. + /* Get gpio_base */
  36445. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
  36446. + /* Get mfgpt_base */
  36447. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
  36448. + /* Get gpio_base */
  36449. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
  36450. +
  36451. + /* Select for mfgpt */
  36452. + set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
  36453. + /* Enable brightness controlling */
  36454. + set_gpio_output_high(7);
  36455. +
  36456. + lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
  36457. + NULL, &backlight_ops);
  36458. +
  36459. + if (IS_ERR(lynloong_backlight_dev)) {
  36460. + ret = PTR_ERR(lynloong_backlight_dev);
  36461. + return ret;
  36462. + }
  36463. +
  36464. + lynloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
  36465. + lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
  36466. + backlight_update_status(lynloong_backlight_dev);
  36467. +
  36468. + return 0;
  36469. +}
  36470. +
  36471. +static void lynloong_backlight_exit(void)
  36472. +{
  36473. + if (lynloong_backlight_dev) {
  36474. + backlight_device_unregister(lynloong_backlight_dev);
  36475. + lynloong_backlight_dev = NULL;
  36476. + }
  36477. + /* Disable brightness controlling */
  36478. + set_gpio_output_low(7);
  36479. +}
  36480. +
  36481. +/* video output driver */
  36482. +static int vo_status = 1;
  36483. +
  36484. +static int lcd_video_output_get(struct output_device *od)
  36485. +{
  36486. + return vo_status;
  36487. +}
  36488. +
  36489. +static int lcd_video_output_set(struct output_device *od)
  36490. +{
  36491. + int i;
  36492. + unsigned long status;
  36493. +
  36494. + status = !!od->request_state;
  36495. +
  36496. + if (status == 0) {
  36497. + /* Set the current status as off */
  36498. + vo_status = 0;
  36499. + /* Turn off the backlight */
  36500. + set_gpio_output_low(11);
  36501. + for (i = 0; i < 0x500; i++)
  36502. + delay();
  36503. + /* Turn off the LCD */
  36504. + set_gpio_output_high(8);
  36505. + } else {
  36506. + /* Turn on the LCD */
  36507. + set_gpio_output_low(8);
  36508. + for (i = 0; i < 0x500; i++)
  36509. + delay();
  36510. + /* Turn on the backlight */
  36511. + set_gpio_output_high(11);
  36512. + /* Set the current status as on */
  36513. + vo_status = 1;
  36514. + }
  36515. +
  36516. + return 0;
  36517. +}
  36518. +
  36519. +static struct output_properties lcd_output_properties = {
  36520. + .set_state = lcd_video_output_set,
  36521. + .get_status = lcd_video_output_get,
  36522. +};
  36523. +
  36524. +static struct output_device *lcd_output_dev;
  36525. +
  36526. +static void lynloong_lcd_vo_set(int status)
  36527. +{
  36528. + lcd_output_dev->request_state = status;
  36529. + lcd_video_output_set(lcd_output_dev);
  36530. +}
  36531. +
  36532. +static int lynloong_vo_init(void)
  36533. +{
  36534. + int ret;
  36535. +
  36536. + /* Register video output device: lcd */
  36537. + lcd_output_dev = video_output_register("LCD", NULL, NULL,
  36538. + &lcd_output_properties);
  36539. +
  36540. + if (IS_ERR(lcd_output_dev)) {
  36541. + ret = PTR_ERR(lcd_output_dev);
  36542. + lcd_output_dev = NULL;
  36543. + return ret;
  36544. + }
  36545. + /* Ensure LCD is on by default */
  36546. + lynloong_lcd_vo_set(1);
  36547. +
  36548. + return 0;
  36549. +}
  36550. +
  36551. +static void lynloong_vo_exit(void)
  36552. +{
  36553. + if (lcd_output_dev) {
  36554. + video_output_unregister(lcd_output_dev);
  36555. + lcd_output_dev = NULL;
  36556. + }
  36557. +}
  36558. +
  36559. +/* suspend support */
  36560. +
  36561. +#ifdef CONFIG_PM
  36562. +
  36563. +static u32 smb_base;
  36564. +
  36565. +/* I2C operations */
  36566. +
  36567. +static int i2c_wait(void)
  36568. +{
  36569. + char c;
  36570. + int i;
  36571. +
  36572. + udelay(1000);
  36573. + for (i = 0; i < 20; i++) {
  36574. + c = inb(smb_base | SMB_STS);
  36575. + if (c & (SMB_STS_BER | SMB_STS_NEGACK))
  36576. + return -1;
  36577. + if (c & SMB_STS_SDAST)
  36578. + return 0;
  36579. + udelay(100);
  36580. + }
  36581. + return -2;
  36582. +}
  36583. +
  36584. +static void i2c_read_single(int addr, int regNo, char *value)
  36585. +{
  36586. + unsigned char c;
  36587. +
  36588. + /* Start condition */
  36589. + c = inb(smb_base | SMB_CTRL1);
  36590. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  36591. + i2c_wait();
  36592. +
  36593. + /* Send slave address */
  36594. + outb(addr & 0xfe, smb_base | SMB_SDA);
  36595. + i2c_wait();
  36596. +
  36597. + /* Acknowledge smbus */
  36598. + c = inb(smb_base | SMB_CTRL1);
  36599. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  36600. +
  36601. + /* Send register index */
  36602. + outb(regNo, smb_base | SMB_SDA);
  36603. + i2c_wait();
  36604. +
  36605. + /* Acknowledge smbus */
  36606. + c = inb(smb_base | SMB_CTRL1);
  36607. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  36608. +
  36609. + /* Start condition again */
  36610. + c = inb(smb_base | SMB_CTRL1);
  36611. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  36612. + i2c_wait();
  36613. +
  36614. + /* Send salve address again */
  36615. + outb(1 | addr, smb_base | SMB_SDA);
  36616. + i2c_wait();
  36617. +
  36618. + /* Acknowledge smbus */
  36619. + c = inb(smb_base | SMB_CTRL1);
  36620. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  36621. +
  36622. + /* Read data */
  36623. + *value = inb(smb_base | SMB_SDA);
  36624. +
  36625. + /* Stop condition */
  36626. + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
  36627. + i2c_wait();
  36628. +}
  36629. +
  36630. +static void i2c_write_single(int addr, int regNo, char value)
  36631. +{
  36632. + unsigned char c;
  36633. +
  36634. + /* Start condition */
  36635. + c = inb(smb_base | SMB_CTRL1);
  36636. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  36637. + i2c_wait();
  36638. + /* Send slave address */
  36639. + outb(addr & 0xfe, smb_base | SMB_SDA);
  36640. + i2c_wait();;
  36641. +
  36642. + /* Send register index */
  36643. + outb(regNo, smb_base | SMB_SDA);
  36644. + i2c_wait();
  36645. +
  36646. + /* Write data */
  36647. + outb(value, smb_base | SMB_SDA);
  36648. + i2c_wait();
  36649. + /* Stop condition */
  36650. + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
  36651. + i2c_wait();
  36652. +}
  36653. +
  36654. +static void stop_clock(int clk_reg, int clk_sel)
  36655. +{
  36656. + u8 value;
  36657. +
  36658. + i2c_read_single(0xd3, clk_reg, &value);
  36659. + value &= ~(1 << clk_sel);
  36660. + i2c_write_single(0xd2, clk_reg, value);
  36661. +}
  36662. +
  36663. +static void enable_clock(int clk_reg, int clk_sel)
  36664. +{
  36665. + u8 value;
  36666. +
  36667. + i2c_read_single(0xd3, clk_reg, &value);
  36668. + value |= (1 << clk_sel);
  36669. + i2c_write_single(0xd2, clk_reg, value);
  36670. +}
  36671. +
  36672. +static char cached_clk_freq;
  36673. +static char cached_pci_fixed_freq;
  36674. +
  36675. +static void decrease_clk_freq(void)
  36676. +{
  36677. + char value;
  36678. +
  36679. + i2c_read_single(0xd3, 1, &value);
  36680. + cached_clk_freq = value;
  36681. +
  36682. + /* Select frequency by software */
  36683. + value |= (1 << 1);
  36684. + /* CPU, 3V66, PCI : 100, 66, 33(1) */
  36685. + value |= (1 << 2);
  36686. + i2c_write_single(0xd2, 1, value);
  36687. +
  36688. + /* Cache the pci frequency */
  36689. + i2c_read_single(0xd3, 14, &value);
  36690. + cached_pci_fixed_freq = value;
  36691. +
  36692. + /* Enable PCI fix mode */
  36693. + value |= (1 << 5);
  36694. + /* 3V66, PCI : 64MHz, 32MHz */
  36695. + value |= (1 << 3);
  36696. + i2c_write_single(0xd2, 14, value);
  36697. +
  36698. +}
  36699. +
  36700. +static void resume_clk_freq(void)
  36701. +{
  36702. + i2c_write_single(0xd2, 1, cached_clk_freq);
  36703. + i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
  36704. +}
  36705. +
  36706. +static void stop_clocks(void)
  36707. +{
  36708. + /* CPU Clock Register */
  36709. + stop_clock(2, 5); /* not used */
  36710. + stop_clock(2, 6); /* not used */
  36711. + stop_clock(2, 7); /* not used */
  36712. +
  36713. + /* PCI Clock Register */
  36714. + stop_clock(3, 1); /* 8100 */
  36715. + stop_clock(3, 5); /* SIS */
  36716. + stop_clock(3, 0); /* not used */
  36717. + stop_clock(3, 6); /* not used */
  36718. +
  36719. + /* PCI 48M Clock Register */
  36720. + stop_clock(4, 6); /* USB grounding */
  36721. + stop_clock(4, 5); /* REF(5536_14M) */
  36722. +
  36723. + /* 3V66 Control Register */
  36724. + stop_clock(5, 0); /* VCH_CLK..., grounding */
  36725. +}
  36726. +
  36727. +static void enable_clocks(void)
  36728. +{
  36729. + enable_clock(3, 1); /* 8100 */
  36730. + enable_clock(3, 5); /* SIS */
  36731. +
  36732. + enable_clock(4, 6);
  36733. + enable_clock(4, 5); /* REF(5536_14M) */
  36734. +
  36735. + enable_clock(5, 0); /* VCH_CLOCK, grounding */
  36736. +}
  36737. +
  36738. +static int lynloong_suspend(struct device *dev)
  36739. +{
  36740. + /* Disable AMP */
  36741. + set_gpio_output_high(6);
  36742. + /* Turn off LCD */
  36743. + lynloong_lcd_vo_set(0);
  36744. +
  36745. + /* Stop the clocks of some devices */
  36746. + stop_clocks();
  36747. +
  36748. + /* Decrease the external clock frequency */
  36749. + decrease_clk_freq();
  36750. +
  36751. + return 0;
  36752. +}
  36753. +
  36754. +static int lynloong_resume(struct device *dev)
  36755. +{
  36756. + /* Turn on the LCD */
  36757. + lynloong_lcd_vo_set(1);
  36758. +
  36759. + /* Resume clock frequency, enable the relative clocks */
  36760. + resume_clk_freq();
  36761. + enable_clocks();
  36762. +
  36763. + /* Enable AMP */
  36764. + set_gpio_output_low(6);
  36765. +
  36766. + return 0;
  36767. +}
  36768. +
  36769. +static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,
  36770. + lynloong_resume);
  36771. +#endif /* !CONFIG_PM */
  36772. +
  36773. +static struct platform_device_id platform_device_ids[] = {
  36774. + {
  36775. + .name = "lynloong_pc",
  36776. + },
  36777. + {}
  36778. +};
  36779. +
  36780. +MODULE_DEVICE_TABLE(platform, platform_device_ids);
  36781. +
  36782. +static struct platform_driver platform_driver = {
  36783. + .driver = {
  36784. + .name = "lynloong_pc",
  36785. + .owner = THIS_MODULE,
  36786. +#ifdef CONFIG_PM
  36787. + .pm = &lynloong_pm_ops,
  36788. +#endif
  36789. + },
  36790. + .id_table = platform_device_ids,
  36791. +};
  36792. +
  36793. +static int __init lynloong_init(void)
  36794. +{
  36795. + int ret;
  36796. +
  36797. + pr_info("Load LynLoong Platform Specific Driver.\n");
  36798. +
  36799. + /* Register platform stuff */
  36800. + ret = platform_driver_register(&platform_driver);
  36801. + if (ret) {
  36802. + pr_err("Fail to register lynloong platform driver.\n");
  36803. + return ret;
  36804. + }
  36805. +
  36806. + ret = lynloong_backlight_init();
  36807. + if (ret) {
  36808. + pr_err("Fail to register lynloong backlight driver.\n");
  36809. + return ret;
  36810. + }
  36811. +
  36812. + ret = lynloong_vo_init();
  36813. + if (ret) {
  36814. + pr_err("Fail to register lynloong backlight driver.\n");
  36815. + lynloong_vo_exit();
  36816. + return ret;
  36817. + }
  36818. +
  36819. + return 0;
  36820. +}
  36821. +
  36822. +static void __exit lynloong_exit(void)
  36823. +{
  36824. + lynloong_vo_exit();
  36825. + lynloong_backlight_exit();
  36826. + platform_driver_unregister(&platform_driver);
  36827. +
  36828. + pr_info("Unload LynLoong Platform Specific Driver.\n");
  36829. +}
  36830. +
  36831. +module_init(lynloong_init);
  36832. +module_exit(lynloong_exit);
  36833. +
  36834. +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");
  36835. +MODULE_DESCRIPTION("LynLoong PC driver");
  36836. +MODULE_LICENSE("GPL");
  36837. diff -Nur linux-2.6.33/drivers/platform/mips/Makefile linux-lemote/drivers/platform/mips/Makefile
  36838. --- linux-2.6.33/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
  36839. +++ linux-lemote/drivers/platform/mips/Makefile 2010-03-06 16:43:22.000000000 +0100
  36840. @@ -0,0 +1,7 @@
  36841. +#
  36842. +# Makefile for MIPS Platform-Specific Drivers
  36843. +#
  36844. +
  36845. +obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong_laptop.o
  36846. +
  36847. +obj-$(CONFIG_LEMOTE_LYNLOONG2F) += lynloong_pc.o
  36848. diff -Nur linux-2.6.33/drivers/platform/mips/yeeloong_ecrom.c linux-lemote/drivers/platform/mips/yeeloong_ecrom.c
  36849. --- linux-2.6.33/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
  36850. +++ linux-lemote/drivers/platform/mips/yeeloong_ecrom.c 2010-03-06 16:43:22.000000000 +0100
  36851. @@ -0,0 +1,943 @@
  36852. +/*
  36853. + * Driver for flushing/dumping ROM of EC on YeeLoong laptop
  36854. + *
  36855. + * Copyright (C) 2009 Lemote Inc.
  36856. + * Author: liujl <liujl@lemote.com>
  36857. + *
  36858. + * NOTE :
  36859. + * The EC resources accessing and programming are supported.
  36860. + */
  36861. +
  36862. +#include <linux/proc_fs.h>
  36863. +#include <linux/miscdevice.h>
  36864. +#include <linux/init.h>
  36865. +#include <linux/delay.h>
  36866. +
  36867. +#include <ec_kb3310b.h>
  36868. +
  36869. +#define EC_MISC_DEV "ec_misc"
  36870. +#define EC_IOC_MAGIC 'E'
  36871. +
  36872. +/* ec registers range */
  36873. +#define EC_MAX_REGADDR 0xFFFF
  36874. +#define EC_MIN_REGADDR 0xF000
  36875. +#define EC_RAM_ADDR 0xF800
  36876. +
  36877. +/* version burned address */
  36878. +#define VER_ADDR 0xf7a1
  36879. +#define VER_MAX_SIZE 7
  36880. +#define EC_ROM_MAX_SIZE 0x10000
  36881. +
  36882. +/* ec internal register */
  36883. +#define REG_POWER_MODE 0xF710
  36884. +#define FLAG_NORMAL_MODE 0x00
  36885. +#define FLAG_IDLE_MODE 0x01
  36886. +#define FLAG_RESET_MODE 0x02
  36887. +
  36888. +/* ec update program flag */
  36889. +#define PROGRAM_FLAG_NONE 0x00
  36890. +#define PROGRAM_FLAG_IE 0x01
  36891. +#define PROGRAM_FLAG_ROM 0x02
  36892. +
  36893. +/* XBI relative registers */
  36894. +#define REG_XBISEG0 0xFEA0
  36895. +#define REG_XBISEG1 0xFEA1
  36896. +#define REG_XBIRSV2 0xFEA2
  36897. +#define REG_XBIRSV3 0xFEA3
  36898. +#define REG_XBIRSV4 0xFEA4
  36899. +#define REG_XBICFG 0xFEA5
  36900. +#define REG_XBICS 0xFEA6
  36901. +#define REG_XBIWE 0xFEA7
  36902. +#define REG_XBISPIA0 0xFEA8
  36903. +#define REG_XBISPIA1 0xFEA9
  36904. +#define REG_XBISPIA2 0xFEAA
  36905. +#define REG_XBISPIDAT 0xFEAB
  36906. +#define REG_XBISPICMD 0xFEAC
  36907. +#define REG_XBISPICFG 0xFEAD
  36908. +#define REG_XBISPIDATR 0xFEAE
  36909. +#define REG_XBISPICFG2 0xFEAF
  36910. +
  36911. +/* commands definition for REG_XBISPICMD */
  36912. +#define SPICMD_WRITE_STATUS 0x01
  36913. +#define SPICMD_BYTE_PROGRAM 0x02
  36914. +#define SPICMD_READ_BYTE 0x03
  36915. +#define SPICMD_WRITE_DISABLE 0x04
  36916. +#define SPICMD_READ_STATUS 0x05
  36917. +#define SPICMD_WRITE_ENABLE 0x06
  36918. +#define SPICMD_HIGH_SPEED_READ 0x0B
  36919. +#define SPICMD_POWER_DOWN 0xB9
  36920. +#define SPICMD_SST_EWSR 0x50
  36921. +#define SPICMD_SST_SEC_ERASE 0x20
  36922. +#define SPICMD_SST_BLK_ERASE 0x52
  36923. +#define SPICMD_SST_CHIP_ERASE 0x60
  36924. +#define SPICMD_FRDO 0x3B
  36925. +#define SPICMD_SEC_ERASE 0xD7
  36926. +#define SPICMD_BLK_ERASE 0xD8
  36927. +#define SPICMD_CHIP_ERASE 0xC7
  36928. +
  36929. +/* bits definition for REG_XBISPICFG */
  36930. +#define SPICFG_AUTO_CHECK 0x01
  36931. +#define SPICFG_SPI_BUSY 0x02
  36932. +#define SPICFG_DUMMY_READ 0x04
  36933. +#define SPICFG_EN_SPICMD 0x08
  36934. +#define SPICFG_LOW_SPICS 0x10
  36935. +#define SPICFG_EN_SHORT_READ 0x20
  36936. +#define SPICFG_EN_OFFSET_READ 0x40
  36937. +#define SPICFG_EN_FAST_READ 0x80
  36938. +
  36939. +/* watchdog timer registers */
  36940. +#define REG_WDTCFG 0xfe80
  36941. +#define REG_WDTPF 0xfe81
  36942. +#define REG_WDT 0xfe82
  36943. +
  36944. +/* lpc configure register */
  36945. +#define REG_LPCCFG 0xfe95
  36946. +
  36947. +/* 8051 reg */
  36948. +#define REG_PXCFG 0xff14
  36949. +
  36950. +/* Fan register in KB3310 */
  36951. +#define REG_ECFAN_SPEED_LEVEL 0xf4e4
  36952. +#define REG_ECFAN_SWITCH 0xf4d2
  36953. +
  36954. +/* the ec flash rom id number */
  36955. +#define EC_ROM_PRODUCT_ID_SPANSION 0x01
  36956. +#define EC_ROM_PRODUCT_ID_MXIC 0xC2
  36957. +#define EC_ROM_PRODUCT_ID_AMIC 0x37
  36958. +#define EC_ROM_PRODUCT_ID_EONIC 0x1C
  36959. +
  36960. +/* misc ioctl operations */
  36961. +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
  36962. +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
  36963. +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
  36964. +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
  36965. +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
  36966. +
  36967. +/* start address for programming of EC content or IE */
  36968. +/* ec running code start address */
  36969. +#define EC_START_ADDR 0x00000000
  36970. +/* ec information element storing address */
  36971. +#define IE_START_ADDR 0x00020000
  36972. +
  36973. +/* EC state */
  36974. +#define EC_STATE_IDLE 0x00 /* ec in idle state */
  36975. +#define EC_STATE_BUSY 0x01 /* ec in busy state */
  36976. +
  36977. +/* timeout value for programming */
  36978. +#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
  36979. +/* command checkout timeout including cmd to port or state flag check */
  36980. +#define EC_CMD_TIMEOUT 0x1000
  36981. +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
  36982. +#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
  36983. +#define SPI_FINISH_WAIT_TIME 10
  36984. +/* EC content max size */
  36985. +#define EC_CONTENT_MAX_SIZE (64 * 1024)
  36986. +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
  36987. +
  36988. +/* the register operation access struct */
  36989. +struct ec_reg {
  36990. + u32 addr; /* the address of kb3310 registers */
  36991. + u8 val; /* the register value */
  36992. +};
  36993. +
  36994. +struct ec_info {
  36995. + u32 start_addr;
  36996. + u32 size;
  36997. + u8 *buf;
  36998. +};
  36999. +
  37000. +/* open for using rom protection action */
  37001. +#define EC_ROM_PROTECTION
  37002. +
  37003. +/* enable the chip reset mode */
  37004. +static int ec_init_reset_mode(void)
  37005. +{
  37006. + int timeout;
  37007. + unsigned char status = 0;
  37008. + int ret = 0;
  37009. +
  37010. + /* make chip goto reset mode */
  37011. + ret = ec_query_seq(CMD_INIT_RESET_MODE);
  37012. + if (ret < 0) {
  37013. + printk(KERN_ERR "ec init reset mode failed.\n");
  37014. + goto out;
  37015. + }
  37016. +
  37017. + /* make the action take active */
  37018. + timeout = EC_CMD_TIMEOUT;
  37019. + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
  37020. + while (timeout--) {
  37021. + if (status) {
  37022. + udelay(EC_REG_DELAY);
  37023. + break;
  37024. + }
  37025. + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
  37026. + udelay(EC_REG_DELAY);
  37027. + }
  37028. + if (timeout <= 0) {
  37029. + printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
  37030. + ret = -EINVAL;
  37031. + } else
  37032. + printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
  37033. + EC_CMD_TIMEOUT - timeout, status);
  37034. +
  37035. + /* set MCU to reset mode */
  37036. + udelay(EC_REG_DELAY);
  37037. + status = ec_read(REG_PXCFG);
  37038. + status |= (1 << 0);
  37039. + ec_write(REG_PXCFG, status);
  37040. + udelay(EC_REG_DELAY);
  37041. +
  37042. + /* disable FWH/LPC */
  37043. + udelay(EC_REG_DELAY);
  37044. + status = ec_read(REG_LPCCFG);
  37045. + status &= ~(1 << 7);
  37046. + ec_write(REG_LPCCFG, status);
  37047. + udelay(EC_REG_DELAY);
  37048. +
  37049. + printk(KERN_INFO "entering reset mode ok..............\n");
  37050. +
  37051. + out:
  37052. + return ret;
  37053. +}
  37054. +
  37055. +/* make ec exit from reset mode */
  37056. +static void ec_exit_reset_mode(void)
  37057. +{
  37058. + unsigned char regval;
  37059. +
  37060. + udelay(EC_REG_DELAY);
  37061. + regval = ec_read(REG_LPCCFG);
  37062. + regval |= (1 << 7);
  37063. + ec_write(REG_LPCCFG, regval);
  37064. + regval = ec_read(REG_PXCFG);
  37065. + regval &= ~(1 << 0);
  37066. + ec_write(REG_PXCFG, regval);
  37067. + printk(KERN_INFO "exit reset mode ok..................\n");
  37068. +
  37069. + return;
  37070. +}
  37071. +
  37072. +/* make ec disable WDD */
  37073. +static void ec_disable_WDD(void)
  37074. +{
  37075. + unsigned char status;
  37076. +
  37077. + udelay(EC_REG_DELAY);
  37078. + status = ec_read(REG_WDTCFG);
  37079. + ec_write(REG_WDTPF, 0x03);
  37080. + ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
  37081. + printk(KERN_INFO "Disable WDD ok..................\n");
  37082. +
  37083. + return;
  37084. +}
  37085. +
  37086. +/* make ec enable WDD */
  37087. +static void ec_enable_WDD(void)
  37088. +{
  37089. + unsigned char status;
  37090. +
  37091. + udelay(EC_REG_DELAY);
  37092. + status = ec_read(REG_WDTCFG);
  37093. + ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
  37094. + ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
  37095. + printk(KERN_INFO "Enable WDD ok..................\n");
  37096. +
  37097. + return;
  37098. +}
  37099. +
  37100. +/* make ec goto idle mode */
  37101. +static int ec_init_idle_mode(void)
  37102. +{
  37103. + int timeout;
  37104. + unsigned char status = 0;
  37105. + int ret = 0;
  37106. +
  37107. + ec_query_seq(CMD_INIT_IDLE_MODE);
  37108. +
  37109. + /* make the action take active */
  37110. + timeout = EC_CMD_TIMEOUT;
  37111. + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
  37112. + while (timeout--) {
  37113. + if (status) {
  37114. + udelay(EC_REG_DELAY);
  37115. + break;
  37116. + }
  37117. + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
  37118. + udelay(EC_REG_DELAY);
  37119. + }
  37120. + if (timeout <= 0) {
  37121. + printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
  37122. + ret = -EINVAL;
  37123. + } else
  37124. + printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
  37125. + EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
  37126. +
  37127. + printk(KERN_INFO "entering idle mode ok...................\n");
  37128. +
  37129. + return ret;
  37130. +}
  37131. +
  37132. +/* make ec exit from idle mode */
  37133. +static int ec_exit_idle_mode(void)
  37134. +{
  37135. +
  37136. + ec_query_seq(CMD_EXIT_IDLE_MODE);
  37137. +
  37138. + printk(KERN_INFO "exit idle mode ok...................\n");
  37139. +
  37140. + return 0;
  37141. +}
  37142. +
  37143. +static int ec_instruction_cycle(void)
  37144. +{
  37145. + unsigned long timeout;
  37146. + int ret = 0;
  37147. +
  37148. + timeout = EC_FLASH_TIMEOUT;
  37149. + while (timeout-- >= 0) {
  37150. + if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
  37151. + break;
  37152. + }
  37153. + if (timeout <= 0) {
  37154. + printk(KERN_ERR
  37155. + "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
  37156. + ret = -EINVAL;
  37157. + goto out;
  37158. + }
  37159. +
  37160. + out:
  37161. + return ret;
  37162. +}
  37163. +
  37164. +/* To see if the ec is in busy state or not. */
  37165. +static inline int ec_flash_busy(unsigned long timeout)
  37166. +{
  37167. + /* assurance the first command be going to rom */
  37168. + if (ec_instruction_cycle() < 0)
  37169. + return EC_STATE_BUSY;
  37170. +#if 1
  37171. + timeout = timeout / EC_MAX_DELAY_UNIT;
  37172. + while (timeout-- > 0) {
  37173. + /* check the rom's status of busy flag */
  37174. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  37175. + if (ec_instruction_cycle() < 0)
  37176. + return EC_STATE_BUSY;
  37177. + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
  37178. + return EC_STATE_IDLE;
  37179. + udelay(EC_MAX_DELAY_UNIT);
  37180. + }
  37181. + if (timeout <= 0) {
  37182. + printk(KERN_ERR
  37183. + "EC_FLASH_BUSY : timeout for check rom flag.\n");
  37184. + return EC_STATE_BUSY;
  37185. + }
  37186. +#else
  37187. + /* check the rom's status of busy flag */
  37188. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  37189. + if (ec_instruction_cycle() < 0)
  37190. + return EC_STATE_BUSY;
  37191. +
  37192. + timeout = timeout / EC_MAX_DELAY_UNIT;
  37193. + while (timeout-- > 0) {
  37194. + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
  37195. + return EC_STATE_IDLE;
  37196. + udelay(EC_MAX_DELAY_UNIT);
  37197. + }
  37198. + if (timeout <= 0) {
  37199. + printk(KERN_ERR
  37200. + "EC_FLASH_BUSY : timeout for check rom flag.\n");
  37201. + return EC_STATE_BUSY;
  37202. + }
  37203. +#endif
  37204. +
  37205. + return EC_STATE_IDLE;
  37206. +}
  37207. +
  37208. +static int rom_instruction_cycle(unsigned char cmd)
  37209. +{
  37210. + unsigned long timeout = 0;
  37211. +
  37212. + switch (cmd) {
  37213. + case SPICMD_READ_STATUS:
  37214. + case SPICMD_WRITE_ENABLE:
  37215. + case SPICMD_WRITE_DISABLE:
  37216. + case SPICMD_READ_BYTE:
  37217. + case SPICMD_HIGH_SPEED_READ:
  37218. + timeout = 0;
  37219. + break;
  37220. + case SPICMD_WRITE_STATUS:
  37221. + timeout = 300 * 1000;
  37222. + break;
  37223. + case SPICMD_BYTE_PROGRAM:
  37224. + timeout = 5 * 1000;
  37225. + break;
  37226. + case SPICMD_SST_SEC_ERASE:
  37227. + case SPICMD_SEC_ERASE:
  37228. + timeout = 1000 * 1000;
  37229. + break;
  37230. + case SPICMD_SST_BLK_ERASE:
  37231. + case SPICMD_BLK_ERASE:
  37232. + timeout = 3 * 1000 * 1000;
  37233. + break;
  37234. + case SPICMD_SST_CHIP_ERASE:
  37235. + case SPICMD_CHIP_ERASE:
  37236. + timeout = 20 * 1000 * 1000;
  37237. + break;
  37238. + default:
  37239. + timeout = EC_SPICMD_STANDARD_TIMEOUT;
  37240. + }
  37241. + if (timeout == 0)
  37242. + return ec_instruction_cycle();
  37243. + if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
  37244. + timeout = EC_SPICMD_STANDARD_TIMEOUT;
  37245. +
  37246. + return ec_flash_busy(timeout);
  37247. +}
  37248. +
  37249. +/* delay for start/stop action */
  37250. +static void delay_spi(int n)
  37251. +{
  37252. + while (n--)
  37253. + inb(EC_IO_PORT_HIGH);
  37254. +}
  37255. +
  37256. +/* start the action to spi rom function */
  37257. +static void ec_start_spi(void)
  37258. +{
  37259. + unsigned char val;
  37260. +
  37261. + delay_spi(SPI_FINISH_WAIT_TIME);
  37262. + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
  37263. + ec_write(REG_XBISPICFG, val);
  37264. + delay_spi(SPI_FINISH_WAIT_TIME);
  37265. +}
  37266. +
  37267. +/* stop the action to spi rom function */
  37268. +static void ec_stop_spi(void)
  37269. +{
  37270. + unsigned char val;
  37271. +
  37272. + delay_spi(SPI_FINISH_WAIT_TIME);
  37273. + val =
  37274. + ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
  37275. + ec_write(REG_XBISPICFG, val);
  37276. + delay_spi(SPI_FINISH_WAIT_TIME);
  37277. +}
  37278. +
  37279. +/* read one byte from xbi interface */
  37280. +static int ec_read_byte(unsigned int addr, unsigned char *byte)
  37281. +{
  37282. + int ret = 0;
  37283. +
  37284. + /* enable spicmd writing. */
  37285. + ec_start_spi();
  37286. +
  37287. + /* enable write spi flash */
  37288. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  37289. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  37290. + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
  37291. + ret = -EINVAL;
  37292. + goto out;
  37293. + }
  37294. +
  37295. + /* write the address */
  37296. + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
  37297. + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
  37298. + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
  37299. + /* start action */
  37300. + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
  37301. + if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
  37302. + printk(KERN_ERR
  37303. + "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
  37304. + ret = -EINVAL;
  37305. + goto out;
  37306. + }
  37307. +
  37308. + *byte = ec_read(REG_XBISPIDAT);
  37309. +
  37310. + out:
  37311. + /* disable spicmd writing. */
  37312. + ec_stop_spi();
  37313. +
  37314. + return ret;
  37315. +}
  37316. +
  37317. +/* write one byte to ec rom */
  37318. +static int ec_write_byte(unsigned int addr, unsigned char byte)
  37319. +{
  37320. + int ret = 0;
  37321. +
  37322. + /* enable spicmd writing. */
  37323. + ec_start_spi();
  37324. +
  37325. + /* enable write spi flash */
  37326. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  37327. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  37328. + printk(KERN_ERR
  37329. + "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
  37330. + ret = -EINVAL;
  37331. + goto out;
  37332. + }
  37333. +
  37334. + /* write the address */
  37335. + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
  37336. + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
  37337. + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
  37338. + ec_write(REG_XBISPIDAT, byte);
  37339. + /* start action */
  37340. + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
  37341. + if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
  37342. + printk(KERN_ERR
  37343. + "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
  37344. + ret = -EINVAL;
  37345. + goto out;
  37346. + }
  37347. +
  37348. + out:
  37349. + /* disable spicmd writing. */
  37350. + ec_stop_spi();
  37351. +
  37352. + return ret;
  37353. +}
  37354. +
  37355. +/* unprotect SPI ROM */
  37356. +/* EC_ROM_unprotect function code */
  37357. +static int EC_ROM_unprotect(void)
  37358. +{
  37359. + unsigned char status;
  37360. +
  37361. + /* enable write spi flash */
  37362. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  37363. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  37364. + printk(KERN_ERR
  37365. + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
  37366. + return 1;
  37367. + }
  37368. +
  37369. + /* unprotect the status register of rom */
  37370. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  37371. + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
  37372. + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
  37373. + return 1;
  37374. + }
  37375. + status = ec_read(REG_XBISPIDAT);
  37376. + ec_write(REG_XBISPIDAT, status & 0x02);
  37377. + if (ec_instruction_cycle() < 0) {
  37378. + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
  37379. + return 1;
  37380. + }
  37381. +
  37382. + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
  37383. + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
  37384. + printk(KERN_ERR
  37385. + "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
  37386. + return 1;
  37387. + }
  37388. +
  37389. + /* enable write spi flash */
  37390. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  37391. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  37392. + printk(KERN_ERR
  37393. + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
  37394. + return 1;
  37395. + }
  37396. +
  37397. + return 0;
  37398. +}
  37399. +
  37400. +/* erase one block or chip or sector as needed */
  37401. +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
  37402. +{
  37403. + unsigned char status;
  37404. + int ret = 0, i = 0;
  37405. + int unprotect_count = 3;
  37406. + int check_flag = 0;
  37407. +
  37408. + /* enable spicmd writing. */
  37409. + ec_start_spi();
  37410. +
  37411. +#ifdef EC_ROM_PROTECTION
  37412. + /* added for re-check SPICMD_READ_STATUS */
  37413. + while (unprotect_count-- > 0) {
  37414. + if (EC_ROM_unprotect()) {
  37415. + ret = -EINVAL;
  37416. + goto out;
  37417. + }
  37418. +
  37419. + /* first time:500ms --> 5.5sec -->10.5sec */
  37420. + for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
  37421. + udelay(50000);
  37422. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  37423. + if (rom_instruction_cycle(SPICMD_READ_STATUS)
  37424. + == EC_STATE_BUSY) {
  37425. + printk(KERN_ERR
  37426. + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
  37427. + } else {
  37428. + status = ec_read(REG_XBISPIDAT);
  37429. + printk(KERN_INFO "Read unprotect status : 0x%x\n",
  37430. + status);
  37431. + if ((status & 0x1C) == 0x00) {
  37432. + printk(KERN_INFO
  37433. + "Read unprotect status OK1 : 0x%x\n",
  37434. + status & 0x1C);
  37435. + check_flag = 1;
  37436. + break;
  37437. + }
  37438. + }
  37439. + }
  37440. +
  37441. + if (!check_flag) {
  37442. + printk(KERN_INFO "SPI ROM unprotect fail.\n");
  37443. + return 1;
  37444. + }
  37445. +#endif
  37446. +
  37447. + /* block address fill */
  37448. + if (erase_cmd == SPICMD_BLK_ERASE) {
  37449. + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
  37450. + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
  37451. + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
  37452. + }
  37453. +
  37454. + /* erase the whole chip first */
  37455. + ec_write(REG_XBISPICMD, erase_cmd);
  37456. + if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
  37457. + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
  37458. + ret = -EINVAL;
  37459. + goto out;
  37460. + }
  37461. +
  37462. + out:
  37463. + /* disable spicmd writing. */
  37464. + ec_stop_spi();
  37465. +
  37466. + return ret;
  37467. +}
  37468. +
  37469. +/* update the whole rom content with H/W mode
  37470. + * PLEASE USING ec_unit_erase() FIRSTLY
  37471. + */
  37472. +static int ec_program_rom(struct ec_info *info, int flag)
  37473. +{
  37474. + unsigned int addr = 0;
  37475. + unsigned long size = 0;
  37476. + unsigned char *ptr = NULL;
  37477. + unsigned char data;
  37478. + unsigned char val = 0;
  37479. + int ret = 0;
  37480. + int i, j;
  37481. + unsigned char status;
  37482. +
  37483. + /* modify for program serial No.
  37484. + * set IE_START_ADDR & use idle mode,
  37485. + * disable WDD
  37486. + */
  37487. + if (flag == PROGRAM_FLAG_ROM) {
  37488. + ret = ec_init_reset_mode();
  37489. + addr = info->start_addr + EC_START_ADDR;
  37490. + printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
  37491. + } else if (flag == PROGRAM_FLAG_IE) {
  37492. + ret = ec_init_idle_mode();
  37493. + ec_disable_WDD();
  37494. + addr = info->start_addr + IE_START_ADDR;
  37495. + printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
  37496. + } else {
  37497. + return 0;
  37498. + }
  37499. +
  37500. + if (ret < 0) {
  37501. + if (flag == PROGRAM_FLAG_IE)
  37502. + ec_enable_WDD();
  37503. + return ret;
  37504. + }
  37505. +
  37506. + size = info->size;
  37507. + ptr = info->buf;
  37508. + printk(KERN_INFO "starting update ec ROM..............\n");
  37509. +
  37510. + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
  37511. + if (ret) {
  37512. + printk(KERN_ERR "program ec : erase block failed.\n");
  37513. + goto out;
  37514. + }
  37515. + printk(KERN_ERR "program ec : erase block OK.\n");
  37516. +
  37517. + i = 0;
  37518. + while (i < size) {
  37519. + data = *(ptr + i);
  37520. + ec_write_byte(addr, data);
  37521. + ec_read_byte(addr, &val);
  37522. + if (val != data) {
  37523. + ec_write_byte(addr, data);
  37524. + ec_read_byte(addr, &val);
  37525. + if (val != data) {
  37526. + printk(KERN_INFO
  37527. + "EC : Second flash program failed at:\t");
  37528. + printk(KERN_INFO
  37529. + "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
  37530. + addr, data, val);
  37531. + printk(KERN_INFO "This should not happen... STOP\n");
  37532. + break;
  37533. + }
  37534. + }
  37535. + i++;
  37536. + addr++;
  37537. + }
  37538. +
  37539. +#ifdef EC_ROM_PROTECTION
  37540. + /* we should start spi access firstly */
  37541. + ec_start_spi();
  37542. +
  37543. + /* enable write spi flash */
  37544. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  37545. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  37546. + printk(KERN_ERR
  37547. + "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
  37548. + goto out1;
  37549. + }
  37550. +
  37551. + /* protect the status register of rom */
  37552. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  37553. + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
  37554. + printk(KERN_ERR
  37555. + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
  37556. + goto out1;
  37557. + }
  37558. + status = ec_read(REG_XBISPIDAT);
  37559. +
  37560. + ec_write(REG_XBISPIDAT, status | 0x1C);
  37561. + if (ec_instruction_cycle() < 0) {
  37562. + printk(KERN_ERR
  37563. + "EC_PROGRAM_ROM : write status value failed.\n");
  37564. + goto out1;
  37565. + }
  37566. +
  37567. + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
  37568. + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
  37569. + printk(KERN_ERR
  37570. + "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
  37571. + goto out1;
  37572. + }
  37573. +#endif
  37574. +
  37575. + /* disable the write action to spi rom */
  37576. + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
  37577. + if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
  37578. + printk(KERN_ERR
  37579. + "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
  37580. + goto out1;
  37581. + }
  37582. +
  37583. + out1:
  37584. + /* we should stop spi access firstly */
  37585. + ec_stop_spi();
  37586. + out:
  37587. + /* for security */
  37588. + for (j = 0; j < 2000; j++)
  37589. + udelay(1000);
  37590. +
  37591. + /* modify for program serial No.
  37592. + * after program No exit idle mode
  37593. + * and enable WDD
  37594. + */
  37595. + if (flag == PROGRAM_FLAG_ROM) {
  37596. + /* exit from the reset mode */
  37597. + ec_exit_reset_mode();
  37598. + } else {
  37599. + /* ec exit from idle mode */
  37600. + ret = ec_exit_idle_mode();
  37601. + ec_enable_WDD();
  37602. + if (ret < 0)
  37603. + return ret;
  37604. + }
  37605. +
  37606. + return 0;
  37607. +}
  37608. +
  37609. +/* ioctl */
  37610. +static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
  37611. + u_long arg)
  37612. +{
  37613. + struct ec_info ecinfo;
  37614. + void __user *ptr = (void __user *)arg;
  37615. + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
  37616. + int ret = 0;
  37617. +
  37618. + switch (cmd) {
  37619. + case IOCTL_RDREG:
  37620. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  37621. + if (ret) {
  37622. + printk(KERN_ERR "reg read : copy from user error.\n");
  37623. + return -EFAULT;
  37624. + }
  37625. + if ((ecreg->addr > EC_MAX_REGADDR)
  37626. + || (ecreg->addr < EC_MIN_REGADDR)) {
  37627. + printk(KERN_ERR
  37628. + "reg read : out of register address range.\n");
  37629. + return -EINVAL;
  37630. + }
  37631. + ecreg->val = ec_read(ecreg->addr);
  37632. + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
  37633. + if (ret) {
  37634. + printk(KERN_ERR "reg read : copy to user error.\n");
  37635. + return -EFAULT;
  37636. + }
  37637. + break;
  37638. + case IOCTL_WRREG:
  37639. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  37640. + if (ret) {
  37641. + printk(KERN_ERR "reg write : copy from user error.\n");
  37642. + return -EFAULT;
  37643. + }
  37644. + if ((ecreg->addr > EC_MAX_REGADDR)
  37645. + || (ecreg->addr < EC_MIN_REGADDR)) {
  37646. + printk(KERN_ERR
  37647. + "reg write : out of register address range.\n");
  37648. + return -EINVAL;
  37649. + }
  37650. + ec_write(ecreg->addr, ecreg->val);
  37651. + break;
  37652. + case IOCTL_READ_EC:
  37653. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  37654. + if (ret) {
  37655. + printk(KERN_ERR "spi read : copy from user error.\n");
  37656. + return -EFAULT;
  37657. + }
  37658. + if ((ecreg->addr > EC_RAM_ADDR)
  37659. + && (ecreg->addr < EC_MAX_REGADDR)) {
  37660. + printk(KERN_ERR
  37661. + "spi read : out of register address range.\n");
  37662. + return -EINVAL;
  37663. + }
  37664. + ec_read_byte(ecreg->addr, &(ecreg->val));
  37665. + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
  37666. + if (ret) {
  37667. + printk(KERN_ERR "spi read : copy to user error.\n");
  37668. + return -EFAULT;
  37669. + }
  37670. + break;
  37671. + case IOCTL_PROGRAM_IE:
  37672. + ecinfo.start_addr = EC_START_ADDR;
  37673. + ecinfo.size = EC_CONTENT_MAX_SIZE;
  37674. + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
  37675. + if (ecinfo.buf == NULL) {
  37676. + printk(KERN_ERR "program ie : kmalloc failed.\n");
  37677. + return -ENOMEM;
  37678. + }
  37679. + ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
  37680. + if (ret) {
  37681. + printk(KERN_ERR "program ie : copy from user error.\n");
  37682. + kfree(ecinfo.buf);
  37683. + ecinfo.buf = NULL;
  37684. + return -EFAULT;
  37685. + }
  37686. +
  37687. + /* use ec_program_rom to write serial No */
  37688. + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
  37689. +
  37690. + kfree(ecinfo.buf);
  37691. + ecinfo.buf = NULL;
  37692. + break;
  37693. + case IOCTL_PROGRAM_EC:
  37694. + ecinfo.start_addr = EC_START_ADDR;
  37695. + if (get_user((ecinfo.size), (u32 *) ptr)) {
  37696. + printk(KERN_ERR "program ec : get user error.\n");
  37697. + return -EFAULT;
  37698. + }
  37699. + if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
  37700. + printk(KERN_ERR "program ec : size out of limited.\n");
  37701. + return -EINVAL;
  37702. + }
  37703. + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
  37704. + if (ecinfo.buf == NULL) {
  37705. + printk(KERN_ERR "program ec : kmalloc failed.\n");
  37706. + return -ENOMEM;
  37707. + }
  37708. + ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
  37709. + if (ret) {
  37710. + printk(KERN_ERR "program ec : copy from user error.\n");
  37711. + kfree(ecinfo.buf);
  37712. + ecinfo.buf = NULL;
  37713. + return -EFAULT;
  37714. + }
  37715. +
  37716. + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
  37717. +
  37718. + kfree(ecinfo.buf);
  37719. + ecinfo.buf = NULL;
  37720. + break;
  37721. +
  37722. + default:
  37723. + break;
  37724. + }
  37725. +
  37726. + return 0;
  37727. +}
  37728. +
  37729. +static long misc_compat_ioctl(struct file *file, unsigned int cmd,
  37730. + unsigned long arg)
  37731. +{
  37732. + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
  37733. +}
  37734. +
  37735. +static int misc_open(struct inode *inode, struct file *filp)
  37736. +{
  37737. + struct ec_reg *ecreg = NULL;
  37738. + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
  37739. + if (ecreg)
  37740. + filp->private_data = ecreg;
  37741. +
  37742. + return ecreg ? 0 : -ENOMEM;
  37743. +}
  37744. +
  37745. +static int misc_release(struct inode *inode, struct file *filp)
  37746. +{
  37747. + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
  37748. +
  37749. + filp->private_data = NULL;
  37750. + kfree(ecreg);
  37751. +
  37752. + return 0;
  37753. +}
  37754. +
  37755. +static const struct file_operations ecmisc_fops = {
  37756. + .open = misc_open,
  37757. + .release = misc_release,
  37758. + .read = NULL,
  37759. + .write = NULL,
  37760. +#ifdef CONFIG_64BIT
  37761. + .compat_ioctl = misc_compat_ioctl,
  37762. +#else
  37763. + .ioctl = misc_ioctl,
  37764. +#endif
  37765. +};
  37766. +
  37767. +static struct miscdevice ecmisc_device = {
  37768. + .minor = MISC_DYNAMIC_MINOR,
  37769. + .name = EC_MISC_DEV,
  37770. + .fops = &ecmisc_fops
  37771. +};
  37772. +
  37773. +static int __init ecmisc_init(void)
  37774. +{
  37775. + int ret;
  37776. +
  37777. + printk(KERN_INFO "EC misc device init.\n");
  37778. + ret = misc_register(&ecmisc_device);
  37779. +
  37780. + return ret;
  37781. +}
  37782. +
  37783. +static void __exit ecmisc_exit(void)
  37784. +{
  37785. + printk(KERN_INFO "EC misc device exit.\n");
  37786. + misc_deregister(&ecmisc_device);
  37787. +}
  37788. +
  37789. +module_init(ecmisc_init);
  37790. +module_exit(ecmisc_exit);
  37791. +
  37792. +MODULE_AUTHOR("liujl <liujl@lemote.com>");
  37793. +MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
  37794. +MODULE_LICENSE("GPL");
  37795. diff -Nur linux-2.6.33/drivers/platform/mips/yeeloong_laptop.c linux-lemote/drivers/platform/mips/yeeloong_laptop.c
  37796. --- linux-2.6.33/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
  37797. +++ linux-lemote/drivers/platform/mips/yeeloong_laptop.c 2010-03-06 16:43:22.000000000 +0100
  37798. @@ -0,0 +1,1194 @@
  37799. +/*
  37800. + * Driver for YeeLoong laptop extras
  37801. + *
  37802. + * Copyright (C) 2009 Lemote Inc.
  37803. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>
  37804. + *
  37805. + * This program is free software; you can redistribute it and/or modify
  37806. + * it under the terms of the GNU General Public License version 2 as
  37807. + * published by the Free Software Foundation.
  37808. + */
  37809. +
  37810. +#include <linux/err.h>
  37811. +#include <linux/platform_device.h>
  37812. +#include <linux/backlight.h> /* for backlight subdriver */
  37813. +#include <linux/fb.h>
  37814. +#include <linux/hwmon.h> /* for hwmon subdriver */
  37815. +#include <linux/hwmon-sysfs.h>
  37816. +#include <linux/video_output.h> /* for video output subdriver */
  37817. +#include <linux/input.h> /* for hotkey subdriver */
  37818. +#include <linux/input/sparse-keymap.h>
  37819. +#include <linux/interrupt.h>
  37820. +#include <linux/delay.h>
  37821. +#include <linux/power_supply.h> /* for AC & Battery subdriver */
  37822. +
  37823. +#include <cs5536/cs5536.h>
  37824. +
  37825. +#include <loongson.h> /* for loongson_cmdline */
  37826. +#include <ec_kb3310b.h>
  37827. +
  37828. +/* common function */
  37829. +#define EC_VER_LEN 64
  37830. +
  37831. +static int ec_ver_small_than(char *version)
  37832. +{
  37833. + char *p, ec_ver[EC_VER_LEN];
  37834. +
  37835. + p = strstr(loongson_cmdline, "EC_VER=");
  37836. + if (!p)
  37837. + memset(ec_ver, 0, EC_VER_LEN);
  37838. + else {
  37839. + strncpy(ec_ver, p, EC_VER_LEN);
  37840. + p = strstr(ec_ver, " ");
  37841. + if (p)
  37842. + *p = '\0';
  37843. + }
  37844. +
  37845. + /* Seems EC(>=PQ1D26) does this job for us, we can not do it again,
  37846. + * otherwise, the brightness will not resume to the normal level! */
  37847. + if (strncasecmp(ec_ver, version, 64) < 0)
  37848. + return 1;
  37849. + return 0;
  37850. +}
  37851. +
  37852. +/* backlight subdriver */
  37853. +#define MAX_BRIGHTNESS 8
  37854. +
  37855. +static int yeeloong_set_brightness(struct backlight_device *bd)
  37856. +{
  37857. + unsigned int level, current_level;
  37858. + static unsigned int old_level;
  37859. +
  37860. + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
  37861. + bd->props.power == FB_BLANK_UNBLANK) ?
  37862. + bd->props.brightness : 0;
  37863. +
  37864. + level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);
  37865. +
  37866. + /* Avoid to modify the brightness when EC is tuning it */
  37867. + if (old_level != level) {
  37868. + current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
  37869. + if (old_level == current_level)
  37870. + ec_write(REG_DISPLAY_BRIGHTNESS, level);
  37871. + old_level = level;
  37872. + }
  37873. +
  37874. + return 0;
  37875. +}
  37876. +
  37877. +static int yeeloong_get_brightness(struct backlight_device *bd)
  37878. +{
  37879. + return ec_read(REG_DISPLAY_BRIGHTNESS);
  37880. +}
  37881. +
  37882. +static struct backlight_ops backlight_ops = {
  37883. + .get_brightness = yeeloong_get_brightness,
  37884. + .update_status = yeeloong_set_brightness,
  37885. +};
  37886. +
  37887. +static struct backlight_device *yeeloong_backlight_dev;
  37888. +
  37889. +static int yeeloong_backlight_init(void)
  37890. +{
  37891. + int ret;
  37892. +
  37893. + yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
  37894. + NULL, &backlight_ops);
  37895. +
  37896. + if (IS_ERR(yeeloong_backlight_dev)) {
  37897. + ret = PTR_ERR(yeeloong_backlight_dev);
  37898. + yeeloong_backlight_dev = NULL;
  37899. + return ret;
  37900. + }
  37901. +
  37902. + yeeloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
  37903. + yeeloong_backlight_dev->props.brightness =
  37904. + yeeloong_get_brightness(yeeloong_backlight_dev);
  37905. + backlight_update_status(yeeloong_backlight_dev);
  37906. +
  37907. + return 0;
  37908. +}
  37909. +
  37910. +static void yeeloong_backlight_exit(void)
  37911. +{
  37912. + if (yeeloong_backlight_dev) {
  37913. + backlight_device_unregister(yeeloong_backlight_dev);
  37914. + yeeloong_backlight_dev = NULL;
  37915. + }
  37916. +}
  37917. +
  37918. +/* AC & Battery subdriver */
  37919. +
  37920. +static struct power_supply yeeloong_ac, yeeloong_bat;
  37921. +
  37922. +#define AC_OFFLINE 0
  37923. +#define AC_ONLINE 1
  37924. +
  37925. +static int yeeloong_get_ac_props(struct power_supply *psy,
  37926. + enum power_supply_property psp,
  37927. + union power_supply_propval *val)
  37928. +{
  37929. + switch (psp) {
  37930. + case POWER_SUPPLY_PROP_ONLINE:
  37931. + val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?
  37932. + AC_ONLINE : AC_OFFLINE;
  37933. + break;
  37934. + default:
  37935. + return -EINVAL;
  37936. + }
  37937. +
  37938. + return 0;
  37939. +}
  37940. +
  37941. +static enum power_supply_property yeeloong_ac_props[] = {
  37942. + POWER_SUPPLY_PROP_ONLINE,
  37943. +};
  37944. +
  37945. +static struct power_supply yeeloong_ac = {
  37946. + .name = "yeeloong-ac",
  37947. + .type = POWER_SUPPLY_TYPE_MAINS,
  37948. + .properties = yeeloong_ac_props,
  37949. + .num_properties = ARRAY_SIZE(yeeloong_ac_props),
  37950. + .get_property = yeeloong_get_ac_props,
  37951. +};
  37952. +
  37953. +#define BAT_CAP_CRITICAL 5
  37954. +#define BAT_CAP_HIGH 99
  37955. +
  37956. +#define get_bat_info(type) \
  37957. + ((ec_read(REG_BAT_##type##_HIGH) << 8) | \
  37958. + (ec_read(REG_BAT_##type##_LOW)))
  37959. +
  37960. +static int yeeloong_bat_get_ex_property(enum power_supply_property psp,
  37961. + union power_supply_propval *val)
  37962. +{
  37963. + int bat_in, curr_cap, cap_level, status, charge, health;
  37964. +
  37965. + status = ec_read(REG_BAT_STATUS);
  37966. + bat_in = status & BIT_BAT_STATUS_IN;
  37967. + curr_cap = get_bat_info(RELATIVE_CAP);
  37968. + if (status & BIT_BAT_STATUS_FULL)
  37969. + curr_cap = 100;
  37970. +
  37971. + switch (psp) {
  37972. + case POWER_SUPPLY_PROP_PRESENT:
  37973. + val->intval = bat_in;
  37974. + break;
  37975. + case POWER_SUPPLY_PROP_CAPACITY:
  37976. + val->intval = curr_cap;
  37977. + break;
  37978. + case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
  37979. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
  37980. + if (status & BIT_BAT_STATUS_LOW) {
  37981. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
  37982. + if (curr_cap <= BAT_CAP_CRITICAL)
  37983. + cap_level =
  37984. + POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
  37985. + } else if (status & BIT_BAT_STATUS_FULL) {
  37986. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
  37987. + if (curr_cap >= BAT_CAP_HIGH)
  37988. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
  37989. + } else if (status & BIT_BAT_STATUS_DESTROY)
  37990. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
  37991. + val->intval = cap_level;
  37992. + break;
  37993. + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
  37994. + /* seconds */
  37995. + val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 00;
  37996. + break;
  37997. + case POWER_SUPPLY_PROP_STATUS:
  37998. + if (!bat_in)
  37999. + charge = POWER_SUPPLY_STATUS_UNKNOWN;
  38000. + else {
  38001. + if (status & BIT_BAT_STATUS_FULL) {
  38002. + val->intval = POWER_SUPPLY_STATUS_FULL;
  38003. + break;
  38004. + }
  38005. +
  38006. + charge = ec_read(REG_BAT_CHARGE);
  38007. + if (charge & FLAG_BAT_CHARGE_DISCHARGE)
  38008. + charge = POWER_SUPPLY_STATUS_DISCHARGING;
  38009. + else if (charge & FLAG_BAT_CHARGE_CHARGE)
  38010. + charge = POWER_SUPPLY_STATUS_CHARGING;
  38011. + else
  38012. + charge = POWER_SUPPLY_STATUS_NOT_CHARGING;
  38013. + }
  38014. + val->intval = charge;
  38015. + break;
  38016. + case POWER_SUPPLY_PROP_HEALTH:
  38017. + if (!bat_in) /* no battery present */
  38018. + health = POWER_SUPPLY_HEALTH_UNKNOWN;
  38019. + else { /* Assume it is good */
  38020. + health = POWER_SUPPLY_HEALTH_GOOD;
  38021. + if (status &
  38022. + (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))
  38023. + health = POWER_SUPPLY_HEALTH_DEAD;
  38024. + if (ec_read(REG_BAT_CHARGE_STATUS) &
  38025. + BIT_BAT_CHARGE_STATUS_OVERTEMP)
  38026. + health = POWER_SUPPLY_HEALTH_OVERHEAT;
  38027. + }
  38028. + val->intval = health;
  38029. + break;
  38030. + default:
  38031. + return -EINVAL;
  38032. + }
  38033. + return 0;
  38034. +}
  38035. +
  38036. +static int get_battery_temp(void)
  38037. +{
  38038. + int value;
  38039. +
  38040. + value = get_bat_info(TEMPERATURE);
  38041. +
  38042. + return value * 1000;
  38043. +}
  38044. +
  38045. +static int get_battery_current(void)
  38046. +{
  38047. + s16 value;
  38048. +
  38049. + value = get_bat_info(CURRENT);
  38050. +
  38051. + return -value;
  38052. +}
  38053. +
  38054. +static int get_battery_voltage(void)
  38055. +{
  38056. + int value;
  38057. +
  38058. + value = get_bat_info(VOLTAGE);
  38059. +
  38060. + return value;
  38061. +}
  38062. +
  38063. +static int yeeloong_get_bat_props(struct power_supply *psy,
  38064. + enum power_supply_property psp,
  38065. + union power_supply_propval *val)
  38066. +{
  38067. + switch (psp) {
  38068. + /* Fixed information */
  38069. + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  38070. + val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mV -> 繕V */
  38071. + break;
  38072. + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
  38073. + val->intval = get_bat_info(DESIGN_VOL) * 1000; /* mA -> 繕A */
  38074. + break;
  38075. + case POWER_SUPPLY_PROP_CHARGE_FULL:
  38076. + val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* 繕A */
  38077. + break;
  38078. + case POWER_SUPPLY_PROP_MANUFACTURER:
  38079. + val->strval = (ec_read(REG_BAT_VENDOR) ==
  38080. + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";
  38081. + break;
  38082. + /* Dynamic information */
  38083. + case POWER_SUPPLY_PROP_CURRENT_NOW:
  38084. + val->intval = get_battery_current() * 1000; /* mA -> 繕A */
  38085. + break;
  38086. + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  38087. + val->intval = get_battery_voltage() * 1000; /* mV -> 繕V */
  38088. + break;
  38089. + case POWER_SUPPLY_PROP_TEMP:
  38090. + val->intval = get_battery_temp(); /* Celcius */
  38091. + break;
  38092. + /* Dynamic but related information */
  38093. + default:
  38094. + return yeeloong_bat_get_ex_property(psp, val);
  38095. + }
  38096. +
  38097. + return 0;
  38098. +}
  38099. +
  38100. +static enum power_supply_property yeeloong_bat_props[] = {
  38101. + POWER_SUPPLY_PROP_STATUS,
  38102. + POWER_SUPPLY_PROP_PRESENT,
  38103. + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  38104. + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  38105. + POWER_SUPPLY_PROP_CURRENT_NOW,
  38106. + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  38107. + POWER_SUPPLY_PROP_HEALTH,
  38108. + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
  38109. + POWER_SUPPLY_PROP_CAPACITY,
  38110. + POWER_SUPPLY_PROP_CAPACITY_LEVEL,
  38111. + POWER_SUPPLY_PROP_TEMP,
  38112. + POWER_SUPPLY_PROP_MANUFACTURER,
  38113. +};
  38114. +
  38115. +static struct power_supply yeeloong_bat = {
  38116. + .name = "yeeloong-bat",
  38117. + .type = POWER_SUPPLY_TYPE_BATTERY,
  38118. + .properties = yeeloong_bat_props,
  38119. + .num_properties = ARRAY_SIZE(yeeloong_bat_props),
  38120. + .get_property = yeeloong_get_bat_props,
  38121. +};
  38122. +
  38123. +static int ac_bat_initialized;
  38124. +
  38125. +static int yeeloong_bat_init(void)
  38126. +{
  38127. + int ret;
  38128. +
  38129. + ret = power_supply_register(NULL, &yeeloong_ac);
  38130. + if (ret)
  38131. + return ret;
  38132. + ret = power_supply_register(NULL, &yeeloong_bat);
  38133. + if (ret) {
  38134. + power_supply_unregister(&yeeloong_ac);
  38135. + return ret;
  38136. + }
  38137. + ac_bat_initialized = 1;
  38138. +
  38139. + return 0;
  38140. +}
  38141. +
  38142. +static void yeeloong_bat_exit(void)
  38143. +{
  38144. + ac_bat_initialized = 0;
  38145. +
  38146. + power_supply_unregister(&yeeloong_ac);
  38147. + power_supply_unregister(&yeeloong_bat);
  38148. +}
  38149. +/* hwmon subdriver */
  38150. +
  38151. +#define MIN_FAN_SPEED 0
  38152. +#define MAX_FAN_SPEED 3
  38153. +
  38154. +static int get_fan_pwm_enable(void)
  38155. +{
  38156. + int level, mode;
  38157. +
  38158. + level = ec_read(REG_FAN_SPEED_LEVEL);
  38159. + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
  38160. +
  38161. + if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
  38162. + mode = 0;
  38163. + else if (mode == BIT_FAN_MANUAL)
  38164. + mode = 1;
  38165. + else
  38166. + mode = 2;
  38167. +
  38168. + return mode;
  38169. +}
  38170. +
  38171. +static void set_fan_pwm_enable(int mode)
  38172. +{
  38173. + switch (mode) {
  38174. + case 0:
  38175. + /* fullspeed */
  38176. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
  38177. + ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
  38178. + break;
  38179. + case 1:
  38180. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
  38181. + break;
  38182. + case 2:
  38183. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
  38184. + break;
  38185. + default:
  38186. + break;
  38187. + }
  38188. +}
  38189. +
  38190. +static int get_fan_pwm(void)
  38191. +{
  38192. + return ec_read(REG_FAN_SPEED_LEVEL);
  38193. +}
  38194. +
  38195. +static void set_fan_pwm(int value)
  38196. +{
  38197. + int mode;
  38198. +
  38199. + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
  38200. + if (mode != BIT_FAN_MANUAL)
  38201. + return;
  38202. +
  38203. + value = SENSORS_LIMIT(value, 0, 3);
  38204. +
  38205. + /* We must ensure the fan is on */
  38206. + if (value > 0)
  38207. + ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
  38208. +
  38209. + ec_write(REG_FAN_SPEED_LEVEL, value);
  38210. +}
  38211. +
  38212. +static int get_fan_rpm(void)
  38213. +{
  38214. + int value;
  38215. +
  38216. + value = FAN_SPEED_DIVIDER /
  38217. + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
  38218. + ec_read(REG_FAN_SPEED_LOW));
  38219. +
  38220. + return value;
  38221. +}
  38222. +
  38223. +static int get_cpu_temp(void)
  38224. +{
  38225. + s8 value;
  38226. +
  38227. + value = ec_read(REG_TEMPERATURE_VALUE);
  38228. +
  38229. + return value * 1000;
  38230. +}
  38231. +
  38232. +static int get_cpu_temp_max(void)
  38233. +{
  38234. + return 60 * 1000;
  38235. +}
  38236. +
  38237. +static int get_battery_temp_alarm(void)
  38238. +{
  38239. + int status;
  38240. +
  38241. + status = (ec_read(REG_BAT_CHARGE_STATUS) &
  38242. + BIT_BAT_CHARGE_STATUS_OVERTEMP);
  38243. +
  38244. + return !!status;
  38245. +}
  38246. +
  38247. +static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
  38248. +{
  38249. + int ret;
  38250. + unsigned long value;
  38251. +
  38252. + if (!count)
  38253. + return 0;
  38254. +
  38255. + ret = strict_strtoul(buf, 10, &value);
  38256. + if (ret)
  38257. + return ret;
  38258. +
  38259. + set(value);
  38260. +
  38261. + return count;
  38262. +}
  38263. +
  38264. +static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
  38265. +{
  38266. + return sprintf(buf, "%d\n", get());
  38267. +}
  38268. +
  38269. +#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
  38270. + static ssize_t show_##_name(struct device *dev, \
  38271. + struct device_attribute *attr, \
  38272. + char *buf) \
  38273. + { \
  38274. + return show_sys_hwmon(_set, buf); \
  38275. + } \
  38276. + static ssize_t store_##_name(struct device *dev, \
  38277. + struct device_attribute *attr, \
  38278. + const char *buf, size_t count) \
  38279. + { \
  38280. + return store_sys_hwmon(_get, buf, count); \
  38281. + } \
  38282. + static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
  38283. +
  38284. +CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
  38285. +CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
  38286. +CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
  38287. + set_fan_pwm_enable);
  38288. +CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
  38289. +CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);
  38290. +CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
  38291. +CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);
  38292. +CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
  38293. +CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
  38294. +
  38295. +static ssize_t
  38296. +show_name(struct device *dev, struct device_attribute *attr, char *buf)
  38297. +{
  38298. + return sprintf(buf, "yeeloong\n");
  38299. +}
  38300. +
  38301. +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
  38302. +
  38303. +static struct attribute *hwmon_attributes[] = {
  38304. + &sensor_dev_attr_pwm1.dev_attr.attr,
  38305. + &sensor_dev_attr_pwm1_enable.dev_attr.attr,
  38306. + &sensor_dev_attr_fan1_input.dev_attr.attr,
  38307. + &sensor_dev_attr_temp1_input.dev_attr.attr,
  38308. + &sensor_dev_attr_temp1_max.dev_attr.attr,
  38309. + &sensor_dev_attr_temp2_input.dev_attr.attr,
  38310. + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
  38311. + &sensor_dev_attr_curr1_input.dev_attr.attr,
  38312. + &sensor_dev_attr_in1_input.dev_attr.attr,
  38313. + &sensor_dev_attr_name.dev_attr.attr,
  38314. + NULL
  38315. +};
  38316. +
  38317. +static struct attribute_group hwmon_attribute_group = {
  38318. + .attrs = hwmon_attributes
  38319. +};
  38320. +
  38321. +static struct device *yeeloong_hwmon_dev;
  38322. +
  38323. +static int yeeloong_hwmon_init(void)
  38324. +{
  38325. + int ret;
  38326. +
  38327. + yeeloong_hwmon_dev = hwmon_device_register(NULL);
  38328. + if (IS_ERR(yeeloong_hwmon_dev)) {
  38329. + pr_err("Fail to register yeeloong hwmon device\n");
  38330. + yeeloong_hwmon_dev = NULL;
  38331. + return PTR_ERR(yeeloong_hwmon_dev);
  38332. + }
  38333. + ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
  38334. + &hwmon_attribute_group);
  38335. + if (ret) {
  38336. + hwmon_device_unregister(yeeloong_hwmon_dev);
  38337. + yeeloong_hwmon_dev = NULL;
  38338. + return ret;
  38339. + }
  38340. + /* ensure fan is set to auto mode */
  38341. + set_fan_pwm_enable(2);
  38342. +
  38343. + return 0;
  38344. +}
  38345. +
  38346. +static void yeeloong_hwmon_exit(void)
  38347. +{
  38348. + if (yeeloong_hwmon_dev) {
  38349. + sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
  38350. + &hwmon_attribute_group);
  38351. + hwmon_device_unregister(yeeloong_hwmon_dev);
  38352. + yeeloong_hwmon_dev = NULL;
  38353. + }
  38354. +}
  38355. +
  38356. +/* video output subdriver */
  38357. +
  38358. +static int lcd_video_output_get(struct output_device *od)
  38359. +{
  38360. + return ec_read(REG_DISPLAY_LCD);
  38361. +}
  38362. +
  38363. +#define LCD 0
  38364. +#define CRT 1
  38365. +
  38366. +static void display_vo_set(int display, int on)
  38367. +{
  38368. + int addr;
  38369. + unsigned long value;
  38370. +
  38371. + addr = (display == LCD) ? 0x31 : 0x21;
  38372. +
  38373. + outb(addr, 0x3c4);
  38374. + value = inb(0x3c5);
  38375. +
  38376. + if (display == LCD)
  38377. + value |= (on ? 0x03 : 0x02);
  38378. + else {
  38379. + if (on)
  38380. + clear_bit(7, &value);
  38381. + else
  38382. + set_bit(7, &value);
  38383. + }
  38384. +
  38385. + outb(addr, 0x3c4);
  38386. + outb(value, 0x3c5);
  38387. +}
  38388. +
  38389. +static int lcd_video_output_set(struct output_device *od)
  38390. +{
  38391. + unsigned long status;
  38392. +
  38393. + status = !!od->request_state;
  38394. +
  38395. + display_vo_set(LCD, status);
  38396. + ec_write(REG_BACKLIGHT_CTRL, status);
  38397. +
  38398. + return 0;
  38399. +}
  38400. +
  38401. +static struct output_properties lcd_output_properties = {
  38402. + .set_state = lcd_video_output_set,
  38403. + .get_status = lcd_video_output_get,
  38404. +};
  38405. +
  38406. +static int crt_video_output_get(struct output_device *od)
  38407. +{
  38408. + return ec_read(REG_CRT_DETECT);
  38409. +}
  38410. +
  38411. +static int crt_video_output_set(struct output_device *od)
  38412. +{
  38413. + unsigned long status;
  38414. +
  38415. + status = !!od->request_state;
  38416. +
  38417. + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)
  38418. + display_vo_set(CRT, status);
  38419. +
  38420. + return 0;
  38421. +}
  38422. +
  38423. +static struct output_properties crt_output_properties = {
  38424. + .set_state = crt_video_output_set,
  38425. + .get_status = crt_video_output_get,
  38426. +};
  38427. +
  38428. +static struct output_device *lcd_output_dev, *crt_output_dev;
  38429. +
  38430. +static void yeeloong_lcd_vo_set(int status)
  38431. +{
  38432. + if (ec_ver_small_than("EC_VER=PQ1D27")) {
  38433. + lcd_output_dev->request_state = status;
  38434. + lcd_video_output_set(lcd_output_dev);
  38435. + }
  38436. +}
  38437. +
  38438. +static void yeeloong_crt_vo_set(int status)
  38439. +{
  38440. + crt_output_dev->request_state = status;
  38441. + crt_video_output_set(crt_output_dev);
  38442. +}
  38443. +
  38444. +static int yeeloong_vo_init(void)
  38445. +{
  38446. + int ret;
  38447. +
  38448. + /* Register video output device: lcd, crt */
  38449. + lcd_output_dev = video_output_register("LCD", NULL, NULL,
  38450. + &lcd_output_properties);
  38451. +
  38452. + if (IS_ERR(lcd_output_dev)) {
  38453. + ret = PTR_ERR(lcd_output_dev);
  38454. + lcd_output_dev = NULL;
  38455. + return ret;
  38456. + }
  38457. + /* Ensure LCD is on by default */
  38458. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38459. +
  38460. + crt_output_dev = video_output_register("CRT", NULL, NULL,
  38461. + &crt_output_properties);
  38462. +
  38463. + if (IS_ERR(crt_output_dev)) {
  38464. + ret = PTR_ERR(crt_output_dev);
  38465. + crt_output_dev = NULL;
  38466. + return ret;
  38467. + }
  38468. +
  38469. + /* Turn off CRT by default, and will be enabled when the CRT
  38470. + * connectting event reported by SCI */
  38471. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  38472. +
  38473. + return 0;
  38474. +}
  38475. +
  38476. +static void yeeloong_vo_exit(void)
  38477. +{
  38478. + if (lcd_output_dev) {
  38479. + video_output_unregister(lcd_output_dev);
  38480. + lcd_output_dev = NULL;
  38481. + }
  38482. + if (crt_output_dev) {
  38483. + video_output_unregister(crt_output_dev);
  38484. + crt_output_dev = NULL;
  38485. + }
  38486. +}
  38487. +
  38488. +/* hotkey subdriver */
  38489. +
  38490. +static struct input_dev *yeeloong_hotkey_dev;
  38491. +
  38492. +static const struct key_entry yeeloong_keymap[] = {
  38493. + {KE_SW, EVENT_LID, { SW_LID } },
  38494. + {KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */
  38495. + {KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */
  38496. + {KE_KEY, EVENT_DISPLAY_TOGGLE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */
  38497. + {KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */
  38498. + {KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */
  38499. + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */
  38500. + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */
  38501. + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */
  38502. + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */
  38503. + {KE_END, 0}
  38504. +};
  38505. +
  38506. +static struct key_entry *get_event_key_entry(int event, int status)
  38507. +{
  38508. + struct key_entry *ke;
  38509. + static int old_brightness_status = -1;
  38510. + static int old_volume_status = -1;
  38511. +
  38512. + ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);
  38513. + if (!ke)
  38514. + return NULL;
  38515. +
  38516. + switch (event) {
  38517. + case EVENT_DISPLAY_BRIGHTNESS:
  38518. + /* current status > old one, means up */
  38519. + if ((status < old_brightness_status) || (0 == status))
  38520. + ke++;
  38521. + old_brightness_status = status;
  38522. + break;
  38523. + case EVENT_AUDIO_VOLUME:
  38524. + if ((status < old_volume_status) || (0 == status))
  38525. + ke++;
  38526. + old_volume_status = status;
  38527. + break;
  38528. + default:
  38529. + break;
  38530. + }
  38531. +
  38532. + return ke;
  38533. +}
  38534. +
  38535. +static int report_lid_switch(int status)
  38536. +{
  38537. + input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
  38538. + input_sync(yeeloong_hotkey_dev);
  38539. +
  38540. + return status;
  38541. +}
  38542. +
  38543. +static int crt_detect_handler(int status)
  38544. +{
  38545. + if (status) {
  38546. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  38547. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  38548. + } else {
  38549. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38550. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  38551. + }
  38552. + return status;
  38553. +}
  38554. +
  38555. +static int black_screen_handler(int status)
  38556. +{
  38557. + if (ec_ver_small_than("EC_VER=PQ1D26"))
  38558. + yeeloong_lcd_vo_set(status);
  38559. +
  38560. + return status;
  38561. +}
  38562. +
  38563. +static int display_toggle_handler(int status)
  38564. +{
  38565. + static int video_output_status;
  38566. +
  38567. + /* Only enable switch video output button
  38568. + * when CRT is connected */
  38569. + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
  38570. + return 0;
  38571. + /* 0. no CRT connected: LCD on, CRT off
  38572. + * 1. BOTH on
  38573. + * 2. LCD off, CRT on
  38574. + * 3. BOTH off
  38575. + * 4. LCD on, CRT off
  38576. + */
  38577. + video_output_status++;
  38578. + if (video_output_status > 4)
  38579. + video_output_status = 1;
  38580. +
  38581. + switch (video_output_status) {
  38582. + case 1:
  38583. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38584. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  38585. + break;
  38586. + case 2:
  38587. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  38588. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  38589. + break;
  38590. + case 3:
  38591. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  38592. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  38593. + break;
  38594. + case 4:
  38595. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38596. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  38597. + break;
  38598. + default:
  38599. + /* Ensure LCD is on */
  38600. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38601. + break;
  38602. + }
  38603. + return video_output_status;
  38604. +}
  38605. +
  38606. +static int camera_handler(int status)
  38607. +{
  38608. + int value;
  38609. +
  38610. + value = ec_read(REG_CAMERA_CONTROL);
  38611. + ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
  38612. +
  38613. + return status;
  38614. +}
  38615. +
  38616. +static int usb2_handler(int status)
  38617. +{
  38618. + pr_emerg("USB2 Over Current occurred\n");
  38619. +
  38620. + return status;
  38621. +}
  38622. +
  38623. +static int usb0_handler(int status)
  38624. +{
  38625. + pr_emerg("USB0 Over Current occurred\n");
  38626. +
  38627. + return status;
  38628. +}
  38629. +
  38630. +static int ac_bat_handler(int status)
  38631. +{
  38632. + if (ac_bat_initialized) {
  38633. + power_supply_changed(&yeeloong_ac);
  38634. + power_supply_changed(&yeeloong_bat);
  38635. + }
  38636. + return status;
  38637. +}
  38638. +
  38639. +static void do_event_action(int event)
  38640. +{
  38641. + sci_handler handler;
  38642. + int reg, status;
  38643. + struct key_entry *ke;
  38644. +
  38645. + reg = 0;
  38646. + handler = NULL;
  38647. +
  38648. + switch (event) {
  38649. + case EVENT_LID:
  38650. + reg = REG_LID_DETECT;
  38651. + break;
  38652. + case EVENT_DISPLAY_TOGGLE:
  38653. + handler = display_toggle_handler;
  38654. + break;
  38655. + case EVENT_CRT_DETECT:
  38656. + reg = REG_CRT_DETECT;
  38657. + handler = crt_detect_handler;
  38658. + break;
  38659. + case EVENT_CAMERA:
  38660. + reg = REG_CAMERA_STATUS;
  38661. + handler = camera_handler;
  38662. + break;
  38663. + case EVENT_USB_OC2:
  38664. + reg = REG_USB2_FLAG;
  38665. + handler = usb2_handler;
  38666. + break;
  38667. + case EVENT_USB_OC0:
  38668. + reg = REG_USB0_FLAG;
  38669. + handler = usb0_handler;
  38670. + break;
  38671. + case EVENT_BLACK_SCREEN:
  38672. + reg = REG_DISPLAY_LCD;
  38673. + handler = black_screen_handler;
  38674. + break;
  38675. + case EVENT_AUDIO_MUTE:
  38676. + reg = REG_AUDIO_MUTE;
  38677. + break;
  38678. + case EVENT_DISPLAY_BRIGHTNESS:
  38679. + reg = REG_DISPLAY_BRIGHTNESS;
  38680. + break;
  38681. + case EVENT_AUDIO_VOLUME:
  38682. + reg = REG_AUDIO_VOLUME;
  38683. + break;
  38684. + case EVENT_AC_BAT:
  38685. + handler = ac_bat_handler;
  38686. + break;
  38687. + default:
  38688. + break;
  38689. + }
  38690. +
  38691. + if (reg != 0)
  38692. + status = ec_read(reg);
  38693. +
  38694. + if (handler != NULL)
  38695. + status = handler(status);
  38696. +
  38697. + pr_info("%s: event: %d status: %d\n", __func__, event, status);
  38698. +
  38699. + /* Report current key to user-space */
  38700. + ke = get_event_key_entry(event, status);
  38701. + if (ke) {
  38702. + if (ke->keycode == SW_LID)
  38703. + report_lid_switch(status);
  38704. + else
  38705. + sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,
  38706. + true);
  38707. + }
  38708. +}
  38709. +
  38710. +/*
  38711. + * SCI(system control interrupt) main interrupt routine
  38712. + *
  38713. + * We will do the query and get event number together so the interrupt routine
  38714. + * should be longer than 120us now at least 3ms elpase for it.
  38715. + */
  38716. +static irqreturn_t sci_irq_handler(int irq, void *dev_id)
  38717. +{
  38718. + int ret, event;
  38719. +
  38720. + if (SCI_IRQ_NUM != irq)
  38721. + return IRQ_NONE;
  38722. +
  38723. + /* Query the event number */
  38724. + ret = ec_query_event_num();
  38725. + if (ret < 0)
  38726. + return IRQ_NONE;
  38727. +
  38728. + event = ec_get_event_num();
  38729. + if (event < EVENT_START || event > EVENT_END)
  38730. + return IRQ_NONE;
  38731. +
  38732. + /* Execute corresponding actions */
  38733. + do_event_action(event);
  38734. +
  38735. + return IRQ_HANDLED;
  38736. +}
  38737. +
  38738. +/*
  38739. + * Config and init some msr and gpio register properly.
  38740. + */
  38741. +static int sci_irq_init(void)
  38742. +{
  38743. + u32 hi, lo;
  38744. + u32 gpio_base;
  38745. + unsigned long flags;
  38746. + int ret;
  38747. +
  38748. + /* Get gpio base */
  38749. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
  38750. + gpio_base = lo & 0xff00;
  38751. +
  38752. + /* Filter the former kb3310 interrupt for security */
  38753. + ret = ec_query_event_num();
  38754. + if (ret)
  38755. + return ret;
  38756. +
  38757. + /* For filtering next number interrupt */
  38758. + udelay(10000);
  38759. +
  38760. + /* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN
  38761. + * gpio :
  38762. + * input, pull-up, no-invert, event-count and value 0,
  38763. + * no-filter, no edge mode
  38764. + * gpio27 map to Virtual gpio0
  38765. + * msr :
  38766. + * no primary and lpc
  38767. + * Unrestricted Z input to IG10 from Virtual gpio 0.
  38768. + */
  38769. + local_irq_save(flags);
  38770. + _rdmsr(0x80000024, &hi, &lo);
  38771. + lo &= ~(1 << 10);
  38772. + _wrmsr(0x80000024, hi, lo);
  38773. + _rdmsr(0x80000025, &hi, &lo);
  38774. + lo &= ~(1 << 10);
  38775. + _wrmsr(0x80000025, hi, lo);
  38776. + _rdmsr(0x80000023, &hi, &lo);
  38777. + lo |= (0x0a << 0);
  38778. + _wrmsr(0x80000023, hi, lo);
  38779. + local_irq_restore(flags);
  38780. +
  38781. + /* Set gpio27 as sci interrupt
  38782. + *
  38783. + * input, pull-up, no-fliter, no-negedge, invert
  38784. + * the sci event is just about 120us
  38785. + */
  38786. + asm(".set noreorder\n");
  38787. + /* input enable */
  38788. + outl(0x00000800, (gpio_base | 0xA0));
  38789. + /* revert the input */
  38790. + outl(0x00000800, (gpio_base | 0xA4));
  38791. + /* event-int enable */
  38792. + outl(0x00000800, (gpio_base | 0xB8));
  38793. + asm(".set reorder\n");
  38794. +
  38795. + return 0;
  38796. +}
  38797. +
  38798. +static struct irqaction sci_irqaction = {
  38799. + .handler = sci_irq_handler,
  38800. + .name = "sci",
  38801. + .flags = IRQF_SHARED,
  38802. +};
  38803. +
  38804. +static int yeeloong_hotkey_init(void)
  38805. +{
  38806. + int ret;
  38807. +
  38808. + ret = sci_irq_init();
  38809. + if (ret)
  38810. + return -EFAULT;
  38811. +
  38812. + ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);
  38813. + if (ret)
  38814. + return -EFAULT;
  38815. +
  38816. + yeeloong_hotkey_dev = input_allocate_device();
  38817. +
  38818. + if (!yeeloong_hotkey_dev) {
  38819. + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
  38820. + return -ENOMEM;
  38821. + }
  38822. +
  38823. + yeeloong_hotkey_dev->name = "HotKeys";
  38824. + yeeloong_hotkey_dev->phys = "button/input0";
  38825. + yeeloong_hotkey_dev->id.bustype = BUS_HOST;
  38826. + yeeloong_hotkey_dev->dev.parent = NULL;
  38827. +
  38828. + ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);
  38829. + if (ret) {
  38830. + pr_err("Fail to setup input device keymap\n");
  38831. + input_free_device(yeeloong_hotkey_dev);
  38832. + return ret;
  38833. + }
  38834. +
  38835. + ret = input_register_device(yeeloong_hotkey_dev);
  38836. + if (ret) {
  38837. + sparse_keymap_free(yeeloong_hotkey_dev);
  38838. + input_free_device(yeeloong_hotkey_dev);
  38839. + return ret;
  38840. + }
  38841. +
  38842. + /* Update the current status of LID */
  38843. + report_lid_switch(BIT_LID_DETECT_ON);
  38844. +
  38845. +#ifdef CONFIG_LOONGSON_SUSPEND
  38846. + /* Install the real yeeloong_report_lid_status for pm.c */
  38847. + yeeloong_report_lid_status = report_lid_switch;
  38848. +#endif
  38849. +
  38850. + return 0;
  38851. +}
  38852. +
  38853. +static void yeeloong_hotkey_exit(void)
  38854. +{
  38855. + /* Free irq */
  38856. + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
  38857. +
  38858. +#ifdef CONFIG_LOONGSON_SUSPEND
  38859. + /* Uninstall yeeloong_report_lid_status for pm.c */
  38860. + if (yeeloong_report_lid_status == report_lid_switch)
  38861. + yeeloong_report_lid_status = NULL;
  38862. +#endif
  38863. +
  38864. + if (yeeloong_hotkey_dev) {
  38865. + sparse_keymap_free(yeeloong_hotkey_dev);
  38866. + input_unregister_device(yeeloong_hotkey_dev);
  38867. + yeeloong_hotkey_dev = NULL;
  38868. + }
  38869. +}
  38870. +
  38871. +#ifdef CONFIG_PM
  38872. +static void usb_ports_set(int status)
  38873. +{
  38874. + status = !!status;
  38875. +
  38876. + ec_write(REG_USB0_FLAG, status);
  38877. + ec_write(REG_USB1_FLAG, status);
  38878. + ec_write(REG_USB2_FLAG, status);
  38879. +}
  38880. +
  38881. +static int yeeloong_suspend(struct device *dev)
  38882. +
  38883. +{
  38884. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  38885. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  38886. + usb_ports_set(BIT_USB_FLAG_OFF);
  38887. +
  38888. + return 0;
  38889. +}
  38890. +
  38891. +static int yeeloong_resume(struct device *dev)
  38892. +{
  38893. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  38894. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  38895. + usb_ports_set(BIT_USB_FLAG_ON);
  38896. +
  38897. + return 0;
  38898. +}
  38899. +
  38900. +static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,
  38901. + yeeloong_resume);
  38902. +#endif
  38903. +
  38904. +static struct platform_device_id platform_device_ids[] = {
  38905. + {
  38906. + .name = "yeeloong_laptop",
  38907. + },
  38908. + {}
  38909. +};
  38910. +
  38911. +MODULE_DEVICE_TABLE(platform, platform_device_ids);
  38912. +
  38913. +static struct platform_driver platform_driver = {
  38914. + .driver = {
  38915. + .name = "yeeloong_laptop",
  38916. + .owner = THIS_MODULE,
  38917. +#ifdef CONFIG_PM
  38918. + .pm = &yeeloong_pm_ops,
  38919. +#endif
  38920. + },
  38921. + .id_table = platform_device_ids,
  38922. +};
  38923. +
  38924. +static int __init yeeloong_init(void)
  38925. +{
  38926. + int ret;
  38927. +
  38928. + pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");
  38929. +
  38930. + /* Register platform stuff */
  38931. + ret = platform_driver_register(&platform_driver);
  38932. + if (ret) {
  38933. + pr_err("Fail to register yeeloong platform driver.\n");
  38934. + return ret;
  38935. + }
  38936. +
  38937. + ret = yeeloong_backlight_init();
  38938. + if (ret) {
  38939. + pr_err("Fail to register yeeloong backlight driver.\n");
  38940. + yeeloong_backlight_exit();
  38941. + return ret;
  38942. + }
  38943. +
  38944. + ret = yeeloong_bat_init();
  38945. + if (ret) {
  38946. + pr_err("Fail to register yeeloong battery driver.\n");
  38947. + yeeloong_bat_exit();
  38948. + return ret;
  38949. + }
  38950. +
  38951. + ret = yeeloong_hwmon_init();
  38952. + if (ret) {
  38953. + pr_err("Fail to register yeeloong hwmon driver.\n");
  38954. + yeeloong_hwmon_exit();
  38955. + return ret;
  38956. + }
  38957. +
  38958. + ret = yeeloong_vo_init();
  38959. + if (ret) {
  38960. + pr_err("Fail to register yeeloong video output driver.\n");
  38961. + yeeloong_vo_exit();
  38962. + return ret;
  38963. + }
  38964. +
  38965. + ret = yeeloong_hotkey_init();
  38966. + if (ret) {
  38967. + pr_err("Fail to register yeeloong hotkey driver.\n");
  38968. + yeeloong_hotkey_exit();
  38969. + return ret;
  38970. + }
  38971. +
  38972. + return 0;
  38973. +}
  38974. +
  38975. +static void __exit yeeloong_exit(void)
  38976. +{
  38977. + yeeloong_hotkey_exit();
  38978. + yeeloong_vo_exit();
  38979. + yeeloong_hwmon_exit();
  38980. + yeeloong_bat_exit();
  38981. + yeeloong_backlight_exit();
  38982. + platform_driver_unregister(&platform_driver);
  38983. +
  38984. + pr_info("Unload YeeLoong Platform Specific Driver.\n");
  38985. +}
  38986. +
  38987. +module_init(yeeloong_init);
  38988. +module_exit(yeeloong_exit);
  38989. +
  38990. +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");
  38991. +MODULE_DESCRIPTION("YeeLoong laptop driver");
  38992. +MODULE_LICENSE("GPL");
  38993. diff -Nur linux-2.6.33/drivers/rtc/rtc-cmos.c linux-lemote/drivers/rtc/rtc-cmos.c
  38994. --- linux-2.6.33/drivers/rtc/rtc-cmos.c 2010-02-24 19:52:17.000000000 +0100
  38995. +++ linux-lemote/drivers/rtc/rtc-cmos.c 2010-03-06 16:43:22.000000000 +0100
  38996. @@ -752,9 +752,8 @@
  38997. /* FIXME teach the alarm code how to handle binary mode;
  38998. * <asm-generic/rtc.h> doesn't know 12-hour mode either.
  38999. */
  39000. - if (is_valid_irq(rtc_irq) &&
  39001. - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
  39002. - dev_dbg(dev, "only 24-hr BCD mode supported\n");
  39003. + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
  39004. + dev_dbg(dev, "only 24-hr supported\n");
  39005. retval = -ENXIO;
  39006. goto cleanup1;
  39007. }
  39008. diff -Nur linux-2.6.33/drivers/staging/sm7xx/Kconfig linux-lemote/drivers/staging/sm7xx/Kconfig
  39009. --- linux-2.6.33/drivers/staging/sm7xx/Kconfig 2010-02-24 19:52:17.000000000 +0100
  39010. +++ linux-lemote/drivers/staging/sm7xx/Kconfig 2010-03-06 16:43:30.000000000 +0100
  39011. @@ -6,10 +6,3 @@
  39012. select FB_CFB_IMAGEBLIT
  39013. help
  39014. Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
  39015. -
  39016. -config FB_SM7XX_ACCEL
  39017. - bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
  39018. - depends on FB_SM7XX && EXPERIMENTAL
  39019. - help
  39020. - This will compile the Trident frame buffer device with
  39021. - acceleration functions.
  39022. diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtc2d.c linux-lemote/drivers/staging/sm7xx/smtc2d.c
  39023. --- linux-2.6.33/drivers/staging/sm7xx/smtc2d.c 2010-02-24 19:52:17.000000000 +0100
  39024. +++ linux-lemote/drivers/staging/sm7xx/smtc2d.c 1970-01-01 01:00:00.000000000 +0100
  39025. @@ -1,979 +0,0 @@
  39026. -/*
  39027. - * Silicon Motion SM7XX 2D drawing engine functions.
  39028. - *
  39029. - * Copyright (C) 2006 Silicon Motion Technology Corp.
  39030. - * Author: Boyod boyod.yang@siliconmotion.com.cn
  39031. - *
  39032. - * Copyright (C) 2009 Lemote, Inc.
  39033. - * Author: Wu Zhangjin, wuzj@lemote.com
  39034. - *
  39035. - * This file is subject to the terms and conditions of the GNU General Public
  39036. - * License. See the file COPYING in the main directory of this archive for
  39037. - * more details.
  39038. - *
  39039. - * Version 0.10.26192.21.01
  39040. - * - Add PowerPC support
  39041. - * - Add 2D support for Lynx -
  39042. - * Verified on 2.6.19.2
  39043. - * Boyod.yang <boyod.yang@siliconmotion.com.cn>
  39044. - */
  39045. -
  39046. -unsigned char smtc_de_busy;
  39047. -
  39048. -void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
  39049. -{
  39050. - writel(nData, smtc_2DBaseAddress + nOffset);
  39051. -}
  39052. -
  39053. -unsigned long SMTC_read2Dreg(unsigned long nOffset)
  39054. -{
  39055. - return readl(smtc_2DBaseAddress + nOffset);
  39056. -}
  39057. -
  39058. -void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
  39059. -{
  39060. - writel(nData, smtc_2Ddataport + nOffset);
  39061. -}
  39062. -
  39063. -/**********************************************************************
  39064. - *
  39065. - * deInit
  39066. - *
  39067. - * Purpose
  39068. - * Drawing engine initialization.
  39069. - *
  39070. - **********************************************************************/
  39071. -
  39072. -void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
  39073. - unsigned int bpp)
  39074. -{
  39075. - /* Get current power configuration. */
  39076. - unsigned char clock;
  39077. - clock = smtc_seqr(0x21);
  39078. -
  39079. - /* initialize global 'mutex lock' variable */
  39080. - smtc_de_busy = 0;
  39081. -
  39082. - /* Enable 2D Drawing Engine */
  39083. - smtc_seqw(0x21, clock & 0xF8);
  39084. -
  39085. - SMTC_write2Dreg(DE_CLIP_TL,
  39086. - FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
  39087. - FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
  39088. - FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
  39089. - FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
  39090. -
  39091. - if (bpp >= 24) {
  39092. - SMTC_write2Dreg(DE_PITCH,
  39093. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39094. - nModeWidth * 3) | FIELD_VALUE(0,
  39095. - DE_PITCH,
  39096. - SOURCE,
  39097. - nModeWidth
  39098. - * 3));
  39099. - } else {
  39100. - SMTC_write2Dreg(DE_PITCH,
  39101. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39102. - nModeWidth) | FIELD_VALUE(0,
  39103. - DE_PITCH,
  39104. - SOURCE,
  39105. - nModeWidth));
  39106. - }
  39107. -
  39108. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39109. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39110. - nModeWidth) | FIELD_VALUE(0,
  39111. - DE_WINDOW_WIDTH,
  39112. - SOURCE,
  39113. - nModeWidth));
  39114. -
  39115. - switch (bpp) {
  39116. - case 8:
  39117. - SMTC_write2Dreg(DE_STRETCH_FORMAT,
  39118. - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
  39119. - NORMAL) | FIELD_VALUE(0,
  39120. - DE_STRETCH_FORMAT,
  39121. - PATTERN_Y,
  39122. - 0) |
  39123. - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
  39124. - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
  39125. - PIXEL_FORMAT,
  39126. - 8) | FIELD_SET(0,
  39127. - DE_STRETCH_FORMAT,
  39128. - ADDRESSING,
  39129. - XY) |
  39130. - FIELD_VALUE(0, DE_STRETCH_FORMAT,
  39131. - SOURCE_HEIGHT, 3));
  39132. - break;
  39133. - case 24:
  39134. - SMTC_write2Dreg(DE_STRETCH_FORMAT,
  39135. - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
  39136. - NORMAL) | FIELD_VALUE(0,
  39137. - DE_STRETCH_FORMAT,
  39138. - PATTERN_Y,
  39139. - 0) |
  39140. - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
  39141. - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
  39142. - PIXEL_FORMAT,
  39143. - 24) | FIELD_SET(0,
  39144. - DE_STRETCH_FORMAT,
  39145. - ADDRESSING,
  39146. - XY) |
  39147. - FIELD_VALUE(0, DE_STRETCH_FORMAT,
  39148. - SOURCE_HEIGHT, 3));
  39149. - break;
  39150. - case 16:
  39151. - default:
  39152. - SMTC_write2Dreg(DE_STRETCH_FORMAT,
  39153. - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
  39154. - NORMAL) | FIELD_VALUE(0,
  39155. - DE_STRETCH_FORMAT,
  39156. - PATTERN_Y,
  39157. - 0) |
  39158. - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
  39159. - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
  39160. - PIXEL_FORMAT,
  39161. - 16) | FIELD_SET(0,
  39162. - DE_STRETCH_FORMAT,
  39163. - ADDRESSING,
  39164. - XY) |
  39165. - FIELD_VALUE(0, DE_STRETCH_FORMAT,
  39166. - SOURCE_HEIGHT, 3));
  39167. - break;
  39168. - }
  39169. -
  39170. - SMTC_write2Dreg(DE_MASKS,
  39171. - FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
  39172. - FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
  39173. - SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
  39174. - FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
  39175. - 0xFFFFFF));
  39176. - SMTC_write2Dreg(DE_COLOR_COMPARE,
  39177. - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
  39178. -}
  39179. -
  39180. -void deVerticalLine(unsigned long dst_base,
  39181. - unsigned long dst_pitch,
  39182. - unsigned long nX,
  39183. - unsigned long nY,
  39184. - unsigned long dst_height, unsigned long nColor)
  39185. -{
  39186. - deWaitForNotBusy();
  39187. -
  39188. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39189. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
  39190. - dst_base));
  39191. -
  39192. - SMTC_write2Dreg(DE_PITCH,
  39193. - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
  39194. - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
  39195. -
  39196. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39197. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39198. - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
  39199. - SOURCE,
  39200. - dst_pitch));
  39201. -
  39202. - SMTC_write2Dreg(DE_FOREGROUND,
  39203. - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
  39204. -
  39205. - SMTC_write2Dreg(DE_DESTINATION,
  39206. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39207. - FIELD_VALUE(0, DE_DESTINATION, X, nX) |
  39208. - FIELD_VALUE(0, DE_DESTINATION, Y, nY));
  39209. -
  39210. - SMTC_write2Dreg(DE_DIMENSION,
  39211. - FIELD_VALUE(0, DE_DIMENSION, X, 1) |
  39212. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
  39213. -
  39214. - SMTC_write2Dreg(DE_CONTROL,
  39215. - FIELD_SET(0, DE_CONTROL, STATUS, START) |
  39216. - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
  39217. - FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
  39218. - FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
  39219. - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
  39220. - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
  39221. - FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
  39222. - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
  39223. - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
  39224. -
  39225. - smtc_de_busy = 1;
  39226. -}
  39227. -
  39228. -void deHorizontalLine(unsigned long dst_base,
  39229. - unsigned long dst_pitch,
  39230. - unsigned long nX,
  39231. - unsigned long nY,
  39232. - unsigned long dst_width, unsigned long nColor)
  39233. -{
  39234. - deWaitForNotBusy();
  39235. -
  39236. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39237. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
  39238. - dst_base));
  39239. -
  39240. - SMTC_write2Dreg(DE_PITCH,
  39241. - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
  39242. - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
  39243. -
  39244. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39245. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39246. - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
  39247. - SOURCE,
  39248. - dst_pitch));
  39249. - SMTC_write2Dreg(DE_FOREGROUND,
  39250. - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
  39251. - SMTC_write2Dreg(DE_DESTINATION,
  39252. - FIELD_SET(0, DE_DESTINATION, WRAP,
  39253. - DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
  39254. - nX) | FIELD_VALUE(0,
  39255. - DE_DESTINATION,
  39256. - Y,
  39257. - nY));
  39258. - SMTC_write2Dreg(DE_DIMENSION,
  39259. - FIELD_VALUE(0, DE_DIMENSION, X,
  39260. - dst_width) | FIELD_VALUE(0, DE_DIMENSION,
  39261. - Y_ET, 1));
  39262. - SMTC_write2Dreg(DE_CONTROL,
  39263. - FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
  39264. - DE_CONTROL,
  39265. - DIRECTION,
  39266. - RIGHT_TO_LEFT)
  39267. - | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
  39268. - DE_CONTROL,
  39269. - STEP_X,
  39270. - POSITIVE)
  39271. - | FIELD_SET(0, DE_CONTROL, STEP_Y,
  39272. - NEGATIVE) | FIELD_SET(0, DE_CONTROL,
  39273. - LAST_PIXEL,
  39274. - OFF) | FIELD_SET(0,
  39275. - DE_CONTROL,
  39276. - COMMAND,
  39277. - SHORT_STROKE)
  39278. - | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
  39279. - ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
  39280. - 0x0C));
  39281. -
  39282. - smtc_de_busy = 1;
  39283. -}
  39284. -
  39285. -void deLine(unsigned long dst_base,
  39286. - unsigned long dst_pitch,
  39287. - unsigned long nX1,
  39288. - unsigned long nY1,
  39289. - unsigned long nX2, unsigned long nY2, unsigned long nColor)
  39290. -{
  39291. - unsigned long nCommand =
  39292. - FIELD_SET(0, DE_CONTROL, STATUS, START) |
  39293. - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
  39294. - FIELD_SET(0, DE_CONTROL, MAJOR, X) |
  39295. - FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
  39296. - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
  39297. - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
  39298. - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
  39299. - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
  39300. - unsigned long DeltaX;
  39301. - unsigned long DeltaY;
  39302. -
  39303. - /* Calculate delta X */
  39304. - if (nX1 <= nX2)
  39305. - DeltaX = nX2 - nX1;
  39306. - else {
  39307. - DeltaX = nX1 - nX2;
  39308. - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
  39309. - }
  39310. -
  39311. - /* Calculate delta Y */
  39312. - if (nY1 <= nY2)
  39313. - DeltaY = nY2 - nY1;
  39314. - else {
  39315. - DeltaY = nY1 - nY2;
  39316. - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
  39317. - }
  39318. -
  39319. - /* Determine the major axis */
  39320. - if (DeltaX < DeltaY)
  39321. - nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
  39322. -
  39323. - /* Vertical line? */
  39324. - if (nX1 == nX2)
  39325. - deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
  39326. -
  39327. - /* Horizontal line? */
  39328. - else if (nY1 == nY2)
  39329. - deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
  39330. - DeltaX, nColor);
  39331. -
  39332. - /* Diagonal line? */
  39333. - else if (DeltaX == DeltaY) {
  39334. - deWaitForNotBusy();
  39335. -
  39336. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39337. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
  39338. - ADDRESS, dst_base));
  39339. -
  39340. - SMTC_write2Dreg(DE_PITCH,
  39341. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39342. - dst_pitch) | FIELD_VALUE(0,
  39343. - DE_PITCH,
  39344. - SOURCE,
  39345. - dst_pitch));
  39346. -
  39347. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39348. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39349. - dst_pitch) | FIELD_VALUE(0,
  39350. - DE_WINDOW_WIDTH,
  39351. - SOURCE,
  39352. - dst_pitch));
  39353. -
  39354. - SMTC_write2Dreg(DE_FOREGROUND,
  39355. - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
  39356. -
  39357. - SMTC_write2Dreg(DE_DESTINATION,
  39358. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39359. - FIELD_VALUE(0, DE_DESTINATION, X, 1) |
  39360. - FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
  39361. -
  39362. - SMTC_write2Dreg(DE_DIMENSION,
  39363. - FIELD_VALUE(0, DE_DIMENSION, X, 1) |
  39364. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
  39365. -
  39366. - SMTC_write2Dreg(DE_CONTROL,
  39367. - FIELD_SET(nCommand, DE_CONTROL, COMMAND,
  39368. - SHORT_STROKE));
  39369. - }
  39370. -
  39371. - /* Generic line */
  39372. - else {
  39373. - unsigned int k1, k2, et, w;
  39374. - if (DeltaX < DeltaY) {
  39375. - k1 = 2 * DeltaX;
  39376. - et = k1 - DeltaY;
  39377. - k2 = et - DeltaY;
  39378. - w = DeltaY + 1;
  39379. - } else {
  39380. - k1 = 2 * DeltaY;
  39381. - et = k1 - DeltaX;
  39382. - k2 = et - DeltaX;
  39383. - w = DeltaX + 1;
  39384. - }
  39385. -
  39386. - deWaitForNotBusy();
  39387. -
  39388. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39389. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
  39390. - ADDRESS, dst_base));
  39391. -
  39392. - SMTC_write2Dreg(DE_PITCH,
  39393. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39394. - dst_pitch) | FIELD_VALUE(0,
  39395. - DE_PITCH,
  39396. - SOURCE,
  39397. - dst_pitch));
  39398. -
  39399. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39400. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39401. - dst_pitch) | FIELD_VALUE(0,
  39402. - DE_WINDOW_WIDTH,
  39403. - SOURCE,
  39404. - dst_pitch));
  39405. -
  39406. - SMTC_write2Dreg(DE_FOREGROUND,
  39407. - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
  39408. -
  39409. - SMTC_write2Dreg(DE_SOURCE,
  39410. - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
  39411. - FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
  39412. - FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
  39413. -
  39414. - SMTC_write2Dreg(DE_DESTINATION,
  39415. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39416. - FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
  39417. - FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
  39418. -
  39419. - SMTC_write2Dreg(DE_DIMENSION,
  39420. - FIELD_VALUE(0, DE_DIMENSION, X, w) |
  39421. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
  39422. -
  39423. - SMTC_write2Dreg(DE_CONTROL,
  39424. - FIELD_SET(nCommand, DE_CONTROL, COMMAND,
  39425. - LINE_DRAW));
  39426. - }
  39427. -
  39428. - smtc_de_busy = 1;
  39429. -}
  39430. -
  39431. -void deFillRect(unsigned long dst_base,
  39432. - unsigned long dst_pitch,
  39433. - unsigned long dst_X,
  39434. - unsigned long dst_Y,
  39435. - unsigned long dst_width,
  39436. - unsigned long dst_height, unsigned long nColor)
  39437. -{
  39438. - deWaitForNotBusy();
  39439. -
  39440. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39441. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
  39442. - dst_base));
  39443. -
  39444. - if (dst_pitch) {
  39445. - SMTC_write2Dreg(DE_PITCH,
  39446. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39447. - dst_pitch) | FIELD_VALUE(0,
  39448. - DE_PITCH,
  39449. - SOURCE,
  39450. - dst_pitch));
  39451. -
  39452. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39453. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39454. - dst_pitch) | FIELD_VALUE(0,
  39455. - DE_WINDOW_WIDTH,
  39456. - SOURCE,
  39457. - dst_pitch));
  39458. - }
  39459. -
  39460. - SMTC_write2Dreg(DE_FOREGROUND,
  39461. - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
  39462. -
  39463. - SMTC_write2Dreg(DE_DESTINATION,
  39464. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39465. - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
  39466. - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
  39467. -
  39468. - SMTC_write2Dreg(DE_DIMENSION,
  39469. - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
  39470. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
  39471. -
  39472. - SMTC_write2Dreg(DE_CONTROL,
  39473. - FIELD_SET(0, DE_CONTROL, STATUS, START) |
  39474. - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
  39475. - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
  39476. - FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
  39477. - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
  39478. - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
  39479. -
  39480. - smtc_de_busy = 1;
  39481. -}
  39482. -
  39483. -/**********************************************************************
  39484. - *
  39485. - * deRotatePattern
  39486. - *
  39487. - * Purpose
  39488. - * Rotate the given pattern if necessary
  39489. - *
  39490. - * Parameters
  39491. - * [in]
  39492. - * pPattern - Pointer to DE_SURFACE structure containing
  39493. - * pattern attributes
  39494. - * patternX - X position (0-7) of pattern origin
  39495. - * patternY - Y position (0-7) of pattern origin
  39496. - *
  39497. - * [out]
  39498. - * pattern_dstaddr - Pointer to pre-allocated buffer containing
  39499. - * rotated pattern
  39500. - *
  39501. - **********************************************************************/
  39502. -void deRotatePattern(unsigned char *pattern_dstaddr,
  39503. - unsigned long pattern_src_addr,
  39504. - unsigned long pattern_BPP,
  39505. - unsigned long pattern_stride, int patternX, int patternY)
  39506. -{
  39507. - unsigned int i;
  39508. - unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
  39509. - unsigned int x, y;
  39510. - unsigned char *pjPatByte;
  39511. -
  39512. - if (pattern_dstaddr != NULL) {
  39513. - deWaitForNotBusy();
  39514. -
  39515. - if (patternX || patternY) {
  39516. - /* Rotate pattern */
  39517. - pjPatByte = (unsigned char *)pattern;
  39518. -
  39519. - switch (pattern_BPP) {
  39520. - case 8:
  39521. - {
  39522. - for (y = 0; y < 8; y++) {
  39523. - unsigned char *pjBuffer =
  39524. - pattern_dstaddr +
  39525. - ((patternY + y) & 7) * 8;
  39526. - for (x = 0; x < 8; x++) {
  39527. - pjBuffer[(patternX +
  39528. - x) & 7] =
  39529. - pjPatByte[x];
  39530. - }
  39531. - pjPatByte += pattern_stride;
  39532. - }
  39533. - break;
  39534. - }
  39535. -
  39536. - case 16:
  39537. - {
  39538. - for (y = 0; y < 8; y++) {
  39539. - unsigned short *pjBuffer =
  39540. - (unsigned short *)
  39541. - pattern_dstaddr +
  39542. - ((patternY + y) & 7) * 8;
  39543. - for (x = 0; x < 8; x++) {
  39544. - pjBuffer[(patternX +
  39545. - x) & 7] =
  39546. - ((unsigned short *)
  39547. - pjPatByte)[x];
  39548. - }
  39549. - pjPatByte += pattern_stride;
  39550. - }
  39551. - break;
  39552. - }
  39553. -
  39554. - case 32:
  39555. - {
  39556. - for (y = 0; y < 8; y++) {
  39557. - unsigned long *pjBuffer =
  39558. - (unsigned long *)
  39559. - pattern_dstaddr +
  39560. - ((patternY + y) & 7) * 8;
  39561. - for (x = 0; x < 8; x++) {
  39562. - pjBuffer[(patternX +
  39563. - x) & 7] =
  39564. - ((unsigned long *)
  39565. - pjPatByte)[x];
  39566. - }
  39567. - pjPatByte += pattern_stride;
  39568. - }
  39569. - break;
  39570. - }
  39571. - }
  39572. - } else {
  39573. - /*Don't rotate,just copy pattern into pattern_dstaddr*/
  39574. - for (i = 0; i < (pattern_BPP * 2); i++) {
  39575. - ((unsigned long *)pattern_dstaddr)[i] =
  39576. - pattern[i];
  39577. - }
  39578. - }
  39579. -
  39580. - }
  39581. -}
  39582. -
  39583. -/**********************************************************************
  39584. - *
  39585. - * deCopy
  39586. - *
  39587. - * Purpose
  39588. - * Copy a rectangular area of the source surface to a destination surface
  39589. - *
  39590. - * Remarks
  39591. - * Source bitmap must have the same color depth (BPP) as the destination
  39592. - * bitmap.
  39593. - *
  39594. -**********************************************************************/
  39595. -void deCopy(unsigned long dst_base,
  39596. - unsigned long dst_pitch,
  39597. - unsigned long dst_BPP,
  39598. - unsigned long dst_X,
  39599. - unsigned long dst_Y,
  39600. - unsigned long dst_width,
  39601. - unsigned long dst_height,
  39602. - unsigned long src_base,
  39603. - unsigned long src_pitch,
  39604. - unsigned long src_X,
  39605. - unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
  39606. -{
  39607. - unsigned long nDirection = 0;
  39608. - unsigned long nTransparent = 0;
  39609. - /* Direction of ROP2 operation:
  39610. - * 1 = Left to Right,
  39611. - * (-1) = Right to Left
  39612. - */
  39613. - unsigned long opSign = 1;
  39614. - /* xWidth is in pixels */
  39615. - unsigned long xWidth = 192 / (dst_BPP / 8);
  39616. - unsigned long de_ctrl = 0;
  39617. -
  39618. - deWaitForNotBusy();
  39619. -
  39620. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
  39621. - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
  39622. - dst_base));
  39623. -
  39624. - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
  39625. - FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
  39626. - src_base));
  39627. -
  39628. - if (dst_pitch && src_pitch) {
  39629. - SMTC_write2Dreg(DE_PITCH,
  39630. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39631. - dst_pitch) | FIELD_VALUE(0,
  39632. - DE_PITCH,
  39633. - SOURCE,
  39634. - src_pitch));
  39635. -
  39636. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39637. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39638. - dst_pitch) | FIELD_VALUE(0,
  39639. - DE_WINDOW_WIDTH,
  39640. - SOURCE,
  39641. - src_pitch));
  39642. - }
  39643. -
  39644. - /* Set transparent bits if necessary */
  39645. - if (pTransp != NULL) {
  39646. - nTransparent =
  39647. - pTransp->match | pTransp->select | pTransp->control;
  39648. -
  39649. - /* Set color compare register */
  39650. - SMTC_write2Dreg(DE_COLOR_COMPARE,
  39651. - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
  39652. - pTransp->color));
  39653. - }
  39654. -
  39655. - /* Determine direction of operation */
  39656. - if (src_Y < dst_Y) {
  39657. - /* +----------+
  39658. - |S |
  39659. - | +----------+
  39660. - | | | |
  39661. - | | | |
  39662. - +---|------+ |
  39663. - | D |
  39664. - +----------+ */
  39665. -
  39666. - nDirection = BOTTOM_TO_TOP;
  39667. - } else if (src_Y > dst_Y) {
  39668. - /* +----------+
  39669. - |D |
  39670. - | +----------+
  39671. - | | | |
  39672. - | | | |
  39673. - +---|------+ |
  39674. - | S |
  39675. - +----------+ */
  39676. -
  39677. - nDirection = TOP_TO_BOTTOM;
  39678. - } else {
  39679. - /* src_Y == dst_Y */
  39680. -
  39681. - if (src_X <= dst_X) {
  39682. - /* +------+---+------+
  39683. - |S | | D|
  39684. - | | | |
  39685. - | | | |
  39686. - | | | |
  39687. - +------+---+------+ */
  39688. -
  39689. - nDirection = RIGHT_TO_LEFT;
  39690. - } else {
  39691. - /* src_X > dst_X */
  39692. -
  39693. - /* +------+---+------+
  39694. - |D | | S|
  39695. - | | | |
  39696. - | | | |
  39697. - | | | |
  39698. - +------+---+------+ */
  39699. -
  39700. - nDirection = LEFT_TO_RIGHT;
  39701. - }
  39702. - }
  39703. -
  39704. - if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
  39705. - src_X += dst_width - 1;
  39706. - src_Y += dst_height - 1;
  39707. - dst_X += dst_width - 1;
  39708. - dst_Y += dst_height - 1;
  39709. - opSign = (-1);
  39710. - }
  39711. -
  39712. - if (dst_BPP >= 24) {
  39713. - src_X *= 3;
  39714. - src_Y *= 3;
  39715. - dst_X *= 3;
  39716. - dst_Y *= 3;
  39717. - dst_width *= 3;
  39718. - if ((nDirection == BOTTOM_TO_TOP)
  39719. - || (nDirection == RIGHT_TO_LEFT)) {
  39720. - src_X += 2;
  39721. - dst_X += 2;
  39722. - }
  39723. - }
  39724. -
  39725. - /* Workaround for 192 byte hw bug */
  39726. - if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
  39727. - /*
  39728. - * Perform the ROP2 operation in chunks of (xWidth *
  39729. - * dst_height)
  39730. - */
  39731. - while (1) {
  39732. - deWaitForNotBusy();
  39733. -
  39734. - SMTC_write2Dreg(DE_SOURCE,
  39735. - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
  39736. - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
  39737. - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
  39738. -
  39739. - SMTC_write2Dreg(DE_DESTINATION,
  39740. - FIELD_SET(0, DE_DESTINATION, WRAP,
  39741. - DISABLE) | FIELD_VALUE(0,
  39742. - DE_DESTINATION,
  39743. - X,
  39744. - dst_X)
  39745. - | FIELD_VALUE(0, DE_DESTINATION, Y,
  39746. - dst_Y));
  39747. -
  39748. - SMTC_write2Dreg(DE_DIMENSION,
  39749. - FIELD_VALUE(0, DE_DIMENSION, X,
  39750. - xWidth) | FIELD_VALUE(0,
  39751. - DE_DIMENSION,
  39752. - Y_ET,
  39753. - dst_height));
  39754. -
  39755. - de_ctrl =
  39756. - FIELD_VALUE(0, DE_CONTROL, ROP,
  39757. - nROP2) | nTransparent | FIELD_SET(0,
  39758. - DE_CONTROL,
  39759. - ROP_SELECT,
  39760. - ROP2)
  39761. - | FIELD_SET(0, DE_CONTROL, COMMAND,
  39762. - BITBLT) | ((nDirection ==
  39763. - 1) ? FIELD_SET(0,
  39764. - DE_CONTROL,
  39765. - DIRECTION,
  39766. - RIGHT_TO_LEFT)
  39767. - : FIELD_SET(0, DE_CONTROL,
  39768. - DIRECTION,
  39769. - LEFT_TO_RIGHT)) |
  39770. - FIELD_SET(0, DE_CONTROL, STATUS, START);
  39771. -
  39772. - SMTC_write2Dreg(DE_CONTROL, de_ctrl);
  39773. -
  39774. - src_X += (opSign * xWidth);
  39775. - dst_X += (opSign * xWidth);
  39776. - dst_width -= xWidth;
  39777. -
  39778. - if (dst_width <= 0) {
  39779. - /* ROP2 operation is complete */
  39780. - break;
  39781. - }
  39782. -
  39783. - if (xWidth > dst_width)
  39784. - xWidth = dst_width;
  39785. - }
  39786. - } else {
  39787. - deWaitForNotBusy();
  39788. - SMTC_write2Dreg(DE_SOURCE,
  39789. - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
  39790. - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
  39791. - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
  39792. -
  39793. - SMTC_write2Dreg(DE_DESTINATION,
  39794. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39795. - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
  39796. - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
  39797. -
  39798. - SMTC_write2Dreg(DE_DIMENSION,
  39799. - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
  39800. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
  39801. -
  39802. - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
  39803. - nTransparent |
  39804. - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
  39805. - FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
  39806. - ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
  39807. - RIGHT_TO_LEFT)
  39808. - : FIELD_SET(0, DE_CONTROL, DIRECTION,
  39809. - LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
  39810. - STATUS, START);
  39811. - SMTC_write2Dreg(DE_CONTROL, de_ctrl);
  39812. - }
  39813. -
  39814. - smtc_de_busy = 1;
  39815. -}
  39816. -
  39817. -/*
  39818. - * This function sets the pixel format that will apply to the 2D Engine.
  39819. - */
  39820. -void deSetPixelFormat(unsigned long bpp)
  39821. -{
  39822. - unsigned long de_format;
  39823. -
  39824. - de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
  39825. -
  39826. - switch (bpp) {
  39827. - case 8:
  39828. - de_format =
  39829. - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
  39830. - break;
  39831. - default:
  39832. - case 16:
  39833. - de_format =
  39834. - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
  39835. - break;
  39836. - case 32:
  39837. - de_format =
  39838. - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
  39839. - break;
  39840. - }
  39841. -
  39842. - SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
  39843. -}
  39844. -
  39845. -/*
  39846. - * System memory to Video memory monochrome expansion.
  39847. - *
  39848. - * Source is monochrome image in system memory. This function expands the
  39849. - * monochrome data to color image in video memory.
  39850. - */
  39851. -
  39852. -long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
  39853. - long srcDelta,
  39854. - unsigned long startBit,
  39855. - unsigned long dBase,
  39856. - unsigned long dPitch,
  39857. - unsigned long bpp,
  39858. - unsigned long dx, unsigned long dy,
  39859. - unsigned long width, unsigned long height,
  39860. - unsigned long fColor,
  39861. - unsigned long bColor,
  39862. - unsigned long rop2) {
  39863. - unsigned long bytePerPixel;
  39864. - unsigned long ulBytesPerScan;
  39865. - unsigned long ul4BytesPerScan;
  39866. - unsigned long ulBytesRemain;
  39867. - unsigned long de_ctrl = 0;
  39868. - unsigned char ajRemain[4];
  39869. - long i, j;
  39870. -
  39871. - bytePerPixel = bpp / 8;
  39872. -
  39873. - /* Just make sure the start bit is within legal range */
  39874. - startBit &= 7;
  39875. -
  39876. - ulBytesPerScan = (width + startBit + 7) / 8;
  39877. - ul4BytesPerScan = ulBytesPerScan & ~3;
  39878. - ulBytesRemain = ulBytesPerScan & 3;
  39879. -
  39880. - if (smtc_de_busy)
  39881. - deWaitForNotBusy();
  39882. -
  39883. - /*
  39884. - * 2D Source Base. Use 0 for HOST Blt.
  39885. - */
  39886. -
  39887. - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
  39888. -
  39889. - /*
  39890. - * 2D Destination Base.
  39891. - *
  39892. - * It is an address offset (128 bit aligned) from the beginning of
  39893. - * frame buffer.
  39894. - */
  39895. -
  39896. - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
  39897. -
  39898. - if (dPitch) {
  39899. -
  39900. - /*
  39901. - * Program pitch (distance between the 1st points of two
  39902. - * adjacent lines).
  39903. - *
  39904. - * Note that input pitch is BYTE value, but the 2D Pitch
  39905. - * register uses pixel values. Need Byte to pixel convertion.
  39906. - */
  39907. -
  39908. - SMTC_write2Dreg(DE_PITCH,
  39909. - FIELD_VALUE(0, DE_PITCH, DESTINATION,
  39910. - dPitch /
  39911. - bytePerPixel) | FIELD_VALUE(0,
  39912. - DE_PITCH,
  39913. - SOURCE,
  39914. - dPitch /
  39915. - bytePerPixel));
  39916. -
  39917. - /* Screen Window width in Pixels.
  39918. - *
  39919. - * 2D engine uses this value to calculate the linear address in
  39920. - * frame buffer for a given point.
  39921. - */
  39922. -
  39923. - SMTC_write2Dreg(DE_WINDOW_WIDTH,
  39924. - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
  39925. - (dPitch /
  39926. - bytePerPixel)) | FIELD_VALUE(0,
  39927. - DE_WINDOW_WIDTH,
  39928. - SOURCE,
  39929. - (dPitch
  39930. - /
  39931. - bytePerPixel)));
  39932. - }
  39933. - /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
  39934. - * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
  39935. - */
  39936. -
  39937. - SMTC_write2Dreg(DE_SOURCE,
  39938. - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
  39939. - FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
  39940. - FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
  39941. -
  39942. - SMTC_write2Dreg(DE_DESTINATION,
  39943. - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
  39944. - FIELD_VALUE(0, DE_DESTINATION, X, dx) |
  39945. - FIELD_VALUE(0, DE_DESTINATION, Y, dy));
  39946. -
  39947. - SMTC_write2Dreg(DE_DIMENSION,
  39948. - FIELD_VALUE(0, DE_DIMENSION, X, width) |
  39949. - FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
  39950. -
  39951. - SMTC_write2Dreg(DE_FOREGROUND, fColor);
  39952. - SMTC_write2Dreg(DE_BACKGROUND, bColor);
  39953. -
  39954. - if (bpp)
  39955. - deSetPixelFormat(bpp);
  39956. - /* Set the pixel format of the destination */
  39957. -
  39958. - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
  39959. - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
  39960. - FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
  39961. - FIELD_SET(0, DE_CONTROL, HOST, MONO) |
  39962. - FIELD_SET(0, DE_CONTROL, STATUS, START);
  39963. -
  39964. - SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
  39965. -
  39966. - /* Write MONO data (line by line) to 2D Engine data port */
  39967. - for (i = 0; i < height; i++) {
  39968. - /* For each line, send the data in chunks of 4 bytes */
  39969. - for (j = 0; j < (ul4BytesPerScan / 4); j++)
  39970. - SMTC_write2Ddataport(0,
  39971. - *(unsigned long *)(pSrcbuf +
  39972. - (j * 4)));
  39973. -
  39974. - if (ulBytesRemain) {
  39975. - memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
  39976. - ulBytesRemain);
  39977. - SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
  39978. - }
  39979. -
  39980. - pSrcbuf += srcDelta;
  39981. - }
  39982. - smtc_de_busy = 1;
  39983. -
  39984. - return 0;
  39985. -}
  39986. -
  39987. -/*
  39988. - * This function gets the transparency status from DE_CONTROL register.
  39989. - * It returns a double word with the transparent fields properly set,
  39990. - * while other fields are 0.
  39991. - */
  39992. -unsigned long deGetTransparency(void)
  39993. -{
  39994. - unsigned long de_ctrl;
  39995. -
  39996. - de_ctrl = SMTC_read2Dreg(DE_CONTROL);
  39997. -
  39998. - de_ctrl &=
  39999. - FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
  40000. - FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
  40001. - FIELD_MASK(DE_CONTROL_TRANSPARENCY);
  40002. -
  40003. - return de_ctrl;
  40004. -}
  40005. diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtc2d.h linux-lemote/drivers/staging/sm7xx/smtc2d.h
  40006. --- linux-2.6.33/drivers/staging/sm7xx/smtc2d.h 2010-02-24 19:52:17.000000000 +0100
  40007. +++ linux-lemote/drivers/staging/sm7xx/smtc2d.h 1970-01-01 01:00:00.000000000 +0100
  40008. @@ -1,530 +0,0 @@
  40009. -/*
  40010. - * Silicon Motion SM712 2D drawing engine functions.
  40011. - *
  40012. - * Copyright (C) 2006 Silicon Motion Technology Corp.
  40013. - * Author: Ge Wang, gewang@siliconmotion.com
  40014. - *
  40015. - * Copyright (C) 2009 Lemote, Inc.
  40016. - * Author: Wu Zhangjin, wuzj@lemote.com
  40017. - *
  40018. - * This file is subject to the terms and conditions of the GNU General Public
  40019. - * License. See the file COPYING in the main directory of this archive for
  40020. - * more details.
  40021. - */
  40022. -
  40023. -#ifndef NULL
  40024. -#define NULL 0
  40025. -#endif
  40026. -
  40027. -/* Internal macros */
  40028. -
  40029. -#define _F_START(f) (0 ? f)
  40030. -#define _F_END(f) (1 ? f)
  40031. -#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
  40032. -#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
  40033. -#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
  40034. -#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
  40035. -
  40036. -/* Global macros */
  40037. -
  40038. -#define FIELD_GET(x, reg, field) \
  40039. -( \
  40040. - _F_NORMALIZE((x), reg ## _ ## field) \
  40041. -)
  40042. -
  40043. -#define FIELD_SET(x, reg, field, value) \
  40044. -( \
  40045. - (x & ~_F_MASK(reg ## _ ## field)) \
  40046. - | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
  40047. -)
  40048. -
  40049. -#define FIELD_VALUE(x, reg, field, value) \
  40050. -( \
  40051. - (x & ~_F_MASK(reg ## _ ## field)) \
  40052. - | _F_DENORMALIZE(value, reg ## _ ## field) \
  40053. -)
  40054. -
  40055. -#define FIELD_CLEAR(reg, field) \
  40056. -( \
  40057. - ~_F_MASK(reg ## _ ## field) \
  40058. -)
  40059. -
  40060. -/* Field Macros */
  40061. -
  40062. -#define FIELD_START(field) (0 ? field)
  40063. -#define FIELD_END(field) (1 ? field)
  40064. -#define FIELD_SIZE(field) \
  40065. - (1 + FIELD_END(field) - FIELD_START(field))
  40066. -
  40067. -#define FIELD_MASK(field) \
  40068. - (((1 << (FIELD_SIZE(field)-1)) \
  40069. - | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
  40070. - << FIELD_START(field))
  40071. -
  40072. -#define FIELD_NORMALIZE(reg, field) \
  40073. - (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
  40074. -
  40075. -#define FIELD_DENORMALIZE(field, value) \
  40076. - (((value) << FIELD_START(field)) & FIELD_MASK(field))
  40077. -
  40078. -#define FIELD_INIT(reg, field, value) \
  40079. - FIELD_DENORMALIZE(reg ## _ ## field, \
  40080. - reg ## _ ## field ## _ ## value)
  40081. -
  40082. -#define FIELD_INIT_VAL(reg, field, value) \
  40083. - (FIELD_DENORMALIZE(reg ## _ ## field, value))
  40084. -
  40085. -#define FIELD_VAL_SET(x, r, f, v) ({ \
  40086. - x = (x & ~FIELD_MASK(r ## _ ## f)) \
  40087. - | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
  40088. -})
  40089. -
  40090. -#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
  40091. -
  40092. -/* Transparent info definition */
  40093. -typedef struct {
  40094. - unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
  40095. - unsigned long select; /* Transparency controlled by SRC/DST */
  40096. - unsigned long control; /* ENABLE/DISABLE transparency */
  40097. - unsigned long color; /* Transparent color */
  40098. -} Transparent, *pTransparent;
  40099. -
  40100. -#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
  40101. -#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
  40102. -#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
  40103. -#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
  40104. -#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
  40105. -#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
  40106. -
  40107. -#define PATTERN_WIDTH 8
  40108. -#define PATTERN_HEIGHT 8
  40109. -
  40110. -#define TOP_TO_BOTTOM 0
  40111. -#define BOTTOM_TO_TOP 1
  40112. -#define RIGHT_TO_LEFT BOTTOM_TO_TOP
  40113. -#define LEFT_TO_RIGHT TOP_TO_BOTTOM
  40114. -
  40115. -/* Constants used in Transparent structure */
  40116. -#define MATCH_OPAQUE 0x00000000
  40117. -#define MATCH_TRANSPARENT 0x00000400
  40118. -#define SOURCE 0x00000000
  40119. -#define DESTINATION 0x00000200
  40120. -
  40121. -/* 2D registers. */
  40122. -
  40123. -#define DE_SOURCE 0x000000
  40124. -#define DE_SOURCE_WRAP 31 : 31
  40125. -#define DE_SOURCE_WRAP_DISABLE 0
  40126. -#define DE_SOURCE_WRAP_ENABLE 1
  40127. -#define DE_SOURCE_X_K1 29 : 16
  40128. -#define DE_SOURCE_Y_K2 15 : 0
  40129. -
  40130. -#define DE_DESTINATION 0x000004
  40131. -#define DE_DESTINATION_WRAP 31 : 31
  40132. -#define DE_DESTINATION_WRAP_DISABLE 0
  40133. -#define DE_DESTINATION_WRAP_ENABLE 1
  40134. -#define DE_DESTINATION_X 28 : 16
  40135. -#define DE_DESTINATION_Y 15 : 0
  40136. -
  40137. -#define DE_DIMENSION 0x000008
  40138. -#define DE_DIMENSION_X 28 : 16
  40139. -#define DE_DIMENSION_Y_ET 15 : 0
  40140. -
  40141. -#define DE_CONTROL 0x00000C
  40142. -#define DE_CONTROL_STATUS 31 : 31
  40143. -#define DE_CONTROL_STATUS_STOP 0
  40144. -#define DE_CONTROL_STATUS_START 1
  40145. -#define DE_CONTROL_PATTERN 30 : 30
  40146. -#define DE_CONTROL_PATTERN_MONO 0
  40147. -#define DE_CONTROL_PATTERN_COLOR 1
  40148. -#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
  40149. -#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
  40150. -#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
  40151. -#define DE_CONTROL_QUICK_START 28 : 28
  40152. -#define DE_CONTROL_QUICK_START_DISABLE 0
  40153. -#define DE_CONTROL_QUICK_START_ENABLE 1
  40154. -#define DE_CONTROL_DIRECTION 27 : 27
  40155. -#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
  40156. -#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
  40157. -#define DE_CONTROL_MAJOR 26 : 26
  40158. -#define DE_CONTROL_MAJOR_X 0
  40159. -#define DE_CONTROL_MAJOR_Y 1
  40160. -#define DE_CONTROL_STEP_X 25 : 25
  40161. -#define DE_CONTROL_STEP_X_POSITIVE 1
  40162. -#define DE_CONTROL_STEP_X_NEGATIVE 0
  40163. -#define DE_CONTROL_STEP_Y 24 : 24
  40164. -#define DE_CONTROL_STEP_Y_POSITIVE 1
  40165. -#define DE_CONTROL_STEP_Y_NEGATIVE 0
  40166. -#define DE_CONTROL_STRETCH 23 : 23
  40167. -#define DE_CONTROL_STRETCH_DISABLE 0
  40168. -#define DE_CONTROL_STRETCH_ENABLE 1
  40169. -#define DE_CONTROL_HOST 22 : 22
  40170. -#define DE_CONTROL_HOST_COLOR 0
  40171. -#define DE_CONTROL_HOST_MONO 1
  40172. -#define DE_CONTROL_LAST_PIXEL 21 : 21
  40173. -#define DE_CONTROL_LAST_PIXEL_OFF 0
  40174. -#define DE_CONTROL_LAST_PIXEL_ON 1
  40175. -#define DE_CONTROL_COMMAND 20 : 16
  40176. -#define DE_CONTROL_COMMAND_BITBLT 0
  40177. -#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
  40178. -#define DE_CONTROL_COMMAND_DE_TILE 2
  40179. -#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
  40180. -#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
  40181. -#define DE_CONTROL_COMMAND_RLE_STRIP 5
  40182. -#define DE_CONTROL_COMMAND_SHORT_STROKE 6
  40183. -#define DE_CONTROL_COMMAND_LINE_DRAW 7
  40184. -#define DE_CONTROL_COMMAND_HOST_WRITE 8
  40185. -#define DE_CONTROL_COMMAND_HOST_READ 9
  40186. -#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
  40187. -#define DE_CONTROL_COMMAND_ROTATE 11
  40188. -#define DE_CONTROL_COMMAND_FONT 12
  40189. -#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
  40190. -#define DE_CONTROL_ROP_SELECT 15 : 15
  40191. -#define DE_CONTROL_ROP_SELECT_ROP3 0
  40192. -#define DE_CONTROL_ROP_SELECT_ROP2 1
  40193. -#define DE_CONTROL_ROP2_SOURCE 14 : 14
  40194. -#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
  40195. -#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
  40196. -#define DE_CONTROL_MONO_DATA 13 : 12
  40197. -#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
  40198. -#define DE_CONTROL_MONO_DATA_8_PACKED 1
  40199. -#define DE_CONTROL_MONO_DATA_16_PACKED 2
  40200. -#define DE_CONTROL_MONO_DATA_32_PACKED 3
  40201. -#define DE_CONTROL_REPEAT_ROTATE 11 : 11
  40202. -#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
  40203. -#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
  40204. -#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
  40205. -#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
  40206. -#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
  40207. -#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
  40208. -#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
  40209. -#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
  40210. -#define DE_CONTROL_TRANSPARENCY 8 : 8
  40211. -#define DE_CONTROL_TRANSPARENCY_DISABLE 0
  40212. -#define DE_CONTROL_TRANSPARENCY_ENABLE 1
  40213. -#define DE_CONTROL_ROP 7 : 0
  40214. -
  40215. -/* Pseudo fields. */
  40216. -
  40217. -#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
  40218. -#define DE_CONTROL_SHORT_STROKE_DIR_225 0
  40219. -#define DE_CONTROL_SHORT_STROKE_DIR_135 1
  40220. -#define DE_CONTROL_SHORT_STROKE_DIR_315 2
  40221. -#define DE_CONTROL_SHORT_STROKE_DIR_45 3
  40222. -#define DE_CONTROL_SHORT_STROKE_DIR_270 4
  40223. -#define DE_CONTROL_SHORT_STROKE_DIR_90 5
  40224. -#define DE_CONTROL_SHORT_STROKE_DIR_180 8
  40225. -#define DE_CONTROL_SHORT_STROKE_DIR_0 10
  40226. -#define DE_CONTROL_ROTATION 25 : 24
  40227. -#define DE_CONTROL_ROTATION_0 0
  40228. -#define DE_CONTROL_ROTATION_270 1
  40229. -#define DE_CONTROL_ROTATION_90 2
  40230. -#define DE_CONTROL_ROTATION_180 3
  40231. -
  40232. -#define DE_PITCH 0x000010
  40233. -#define DE_PITCH_DESTINATION 28 : 16
  40234. -#define DE_PITCH_SOURCE 12 : 0
  40235. -
  40236. -#define DE_FOREGROUND 0x000014
  40237. -#define DE_FOREGROUND_COLOR 31 : 0
  40238. -
  40239. -#define DE_BACKGROUND 0x000018
  40240. -#define DE_BACKGROUND_COLOR 31 : 0
  40241. -
  40242. -#define DE_STRETCH_FORMAT 0x00001C
  40243. -#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
  40244. -#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
  40245. -#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
  40246. -#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
  40247. -#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
  40248. -#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
  40249. -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
  40250. -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
  40251. -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
  40252. -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
  40253. -#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
  40254. -#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
  40255. -#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
  40256. -#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
  40257. -
  40258. -#define DE_COLOR_COMPARE 0x000020
  40259. -#define DE_COLOR_COMPARE_COLOR 23 : 0
  40260. -
  40261. -#define DE_COLOR_COMPARE_MASK 0x000024
  40262. -#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
  40263. -
  40264. -#define DE_MASKS 0x000028
  40265. -#define DE_MASKS_BYTE_MASK 31 : 16
  40266. -#define DE_MASKS_BIT_MASK 15 : 0
  40267. -
  40268. -#define DE_CLIP_TL 0x00002C
  40269. -#define DE_CLIP_TL_TOP 31 : 16
  40270. -#define DE_CLIP_TL_STATUS 13 : 13
  40271. -#define DE_CLIP_TL_STATUS_DISABLE 0
  40272. -#define DE_CLIP_TL_STATUS_ENABLE 1
  40273. -#define DE_CLIP_TL_INHIBIT 12 : 12
  40274. -#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
  40275. -#define DE_CLIP_TL_INHIBIT_INSIDE 1
  40276. -#define DE_CLIP_TL_LEFT 11 : 0
  40277. -
  40278. -#define DE_CLIP_BR 0x000030
  40279. -#define DE_CLIP_BR_BOTTOM 31 : 16
  40280. -#define DE_CLIP_BR_RIGHT 12 : 0
  40281. -
  40282. -#define DE_MONO_PATTERN_LOW 0x000034
  40283. -#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
  40284. -
  40285. -#define DE_MONO_PATTERN_HIGH 0x000038
  40286. -#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
  40287. -
  40288. -#define DE_WINDOW_WIDTH 0x00003C
  40289. -#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
  40290. -#define DE_WINDOW_WIDTH_SOURCE 12 : 0
  40291. -
  40292. -#define DE_WINDOW_SOURCE_BASE 0x000040
  40293. -#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
  40294. -#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
  40295. -#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
  40296. -#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
  40297. -#define DE_WINDOW_SOURCE_BASE_CS_0 0
  40298. -#define DE_WINDOW_SOURCE_BASE_CS_1 1
  40299. -#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
  40300. -
  40301. -#define DE_WINDOW_DESTINATION_BASE 0x000044
  40302. -#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
  40303. -#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
  40304. -#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
  40305. -#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
  40306. -#define DE_WINDOW_DESTINATION_BASE_CS_0 0
  40307. -#define DE_WINDOW_DESTINATION_BASE_CS_1 1
  40308. -#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
  40309. -
  40310. -#define DE_ALPHA 0x000048
  40311. -#define DE_ALPHA_VALUE 7 : 0
  40312. -
  40313. -#define DE_WRAP 0x00004C
  40314. -#define DE_WRAP_X 31 : 16
  40315. -#define DE_WRAP_Y 15 : 0
  40316. -
  40317. -#define DE_STATUS 0x000050
  40318. -#define DE_STATUS_CSC 1 : 1
  40319. -#define DE_STATUS_CSC_CLEAR 0
  40320. -#define DE_STATUS_CSC_NOT_ACTIVE 0
  40321. -#define DE_STATUS_CSC_ACTIVE 1
  40322. -#define DE_STATUS_2D 0 : 0
  40323. -#define DE_STATUS_2D_CLEAR 0
  40324. -#define DE_STATUS_2D_NOT_ACTIVE 0
  40325. -#define DE_STATUS_2D_ACTIVE 1
  40326. -
  40327. -/* Color Space Conversion registers. */
  40328. -
  40329. -#define CSC_Y_SOURCE_BASE 0x0000C8
  40330. -#define CSC_Y_SOURCE_BASE_EXT 27 : 27
  40331. -#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
  40332. -#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
  40333. -#define CSC_Y_SOURCE_BASE_CS 26 : 26
  40334. -#define CSC_Y_SOURCE_BASE_CS_0 0
  40335. -#define CSC_Y_SOURCE_BASE_CS_1 1
  40336. -#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
  40337. -
  40338. -#define CSC_CONSTANTS 0x0000CC
  40339. -#define CSC_CONSTANTS_Y 31 : 24
  40340. -#define CSC_CONSTANTS_R 23 : 16
  40341. -#define CSC_CONSTANTS_G 15 : 8
  40342. -#define CSC_CONSTANTS_B 7 : 0
  40343. -
  40344. -#define CSC_Y_SOURCE_X 0x0000D0
  40345. -#define CSC_Y_SOURCE_X_INTEGER 26 : 16
  40346. -#define CSC_Y_SOURCE_X_FRACTION 15 : 3
  40347. -
  40348. -#define CSC_Y_SOURCE_Y 0x0000D4
  40349. -#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
  40350. -#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
  40351. -
  40352. -#define CSC_U_SOURCE_BASE 0x0000D8
  40353. -#define CSC_U_SOURCE_BASE_EXT 27 : 27
  40354. -#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
  40355. -#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
  40356. -#define CSC_U_SOURCE_BASE_CS 26 : 26
  40357. -#define CSC_U_SOURCE_BASE_CS_0 0
  40358. -#define CSC_U_SOURCE_BASE_CS_1 1
  40359. -#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
  40360. -
  40361. -#define CSC_V_SOURCE_BASE 0x0000DC
  40362. -#define CSC_V_SOURCE_BASE_EXT 27 : 27
  40363. -#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
  40364. -#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
  40365. -#define CSC_V_SOURCE_BASE_CS 26 : 26
  40366. -#define CSC_V_SOURCE_BASE_CS_0 0
  40367. -#define CSC_V_SOURCE_BASE_CS_1 1
  40368. -#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
  40369. -
  40370. -#define CSC_SOURCE_DIMENSION 0x0000E0
  40371. -#define CSC_SOURCE_DIMENSION_X 31 : 16
  40372. -#define CSC_SOURCE_DIMENSION_Y 15 : 0
  40373. -
  40374. -#define CSC_SOURCE_PITCH 0x0000E4
  40375. -#define CSC_SOURCE_PITCH_Y 31 : 16
  40376. -#define CSC_SOURCE_PITCH_UV 15 : 0
  40377. -
  40378. -#define CSC_DESTINATION 0x0000E8
  40379. -#define CSC_DESTINATION_WRAP 31 : 31
  40380. -#define CSC_DESTINATION_WRAP_DISABLE 0
  40381. -#define CSC_DESTINATION_WRAP_ENABLE 1
  40382. -#define CSC_DESTINATION_X 27 : 16
  40383. -#define CSC_DESTINATION_Y 11 : 0
  40384. -
  40385. -#define CSC_DESTINATION_DIMENSION 0x0000EC
  40386. -#define CSC_DESTINATION_DIMENSION_X 31 : 16
  40387. -#define CSC_DESTINATION_DIMENSION_Y 15 : 0
  40388. -
  40389. -#define CSC_DESTINATION_PITCH 0x0000F0
  40390. -#define CSC_DESTINATION_PITCH_X 31 : 16
  40391. -#define CSC_DESTINATION_PITCH_Y 15 : 0
  40392. -
  40393. -#define CSC_SCALE_FACTOR 0x0000F4
  40394. -#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
  40395. -#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
  40396. -
  40397. -#define CSC_DESTINATION_BASE 0x0000F8
  40398. -#define CSC_DESTINATION_BASE_EXT 27 : 27
  40399. -#define CSC_DESTINATION_BASE_EXT_LOCAL 0
  40400. -#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
  40401. -#define CSC_DESTINATION_BASE_CS 26 : 26
  40402. -#define CSC_DESTINATION_BASE_CS_0 0
  40403. -#define CSC_DESTINATION_BASE_CS_1 1
  40404. -#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
  40405. -
  40406. -#define CSC_CONTROL 0x0000FC
  40407. -#define CSC_CONTROL_STATUS 31 : 31
  40408. -#define CSC_CONTROL_STATUS_STOP 0
  40409. -#define CSC_CONTROL_STATUS_START 1
  40410. -#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
  40411. -#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
  40412. -#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
  40413. -#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
  40414. -#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
  40415. -#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
  40416. -#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
  40417. -#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
  40418. -#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
  40419. -#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
  40420. -#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
  40421. -#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
  40422. -#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
  40423. -#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
  40424. -#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
  40425. -#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
  40426. -#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
  40427. -#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
  40428. -#define CSC_CONTROL_BYTE_ORDER 23 : 23
  40429. -#define CSC_CONTROL_BYTE_ORDER_YUYV 0
  40430. -#define CSC_CONTROL_BYTE_ORDER_UYVY 1
  40431. -
  40432. -#define DE_DATA_PORT_501 0x110000
  40433. -#define DE_DATA_PORT_712 0x400000
  40434. -#define DE_DATA_PORT_722 0x6000
  40435. -
  40436. -/* point to virtual Memory Map IO starting address */
  40437. -extern char *smtc_RegBaseAddress;
  40438. -/* point to virtual video memory starting address */
  40439. -extern char *smtc_VRAMBaseAddress;
  40440. -extern unsigned char smtc_de_busy;
  40441. -
  40442. -extern unsigned long memRead32(unsigned long nOffset);
  40443. -extern void memWrite32(unsigned long nOffset, unsigned long nData);
  40444. -extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
  40445. -
  40446. -/* 2D functions */
  40447. -extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
  40448. - unsigned int bpp);
  40449. -
  40450. -extern void deWaitForNotBusy(void);
  40451. -
  40452. -extern void deVerticalLine(unsigned long dst_base,
  40453. - unsigned long dst_pitch,
  40454. - unsigned long nX,
  40455. - unsigned long nY,
  40456. - unsigned long dst_height,
  40457. - unsigned long nColor);
  40458. -
  40459. -extern void deHorizontalLine(unsigned long dst_base,
  40460. - unsigned long dst_pitch,
  40461. - unsigned long nX,
  40462. - unsigned long nY,
  40463. - unsigned long dst_width,
  40464. - unsigned long nColor);
  40465. -
  40466. -extern void deLine(unsigned long dst_base,
  40467. - unsigned long dst_pitch,
  40468. - unsigned long nX1,
  40469. - unsigned long nY1,
  40470. - unsigned long nX2,
  40471. - unsigned long nY2,
  40472. - unsigned long nColor);
  40473. -
  40474. -extern void deFillRect(unsigned long dst_base,
  40475. - unsigned long dst_pitch,
  40476. - unsigned long dst_X,
  40477. - unsigned long dst_Y,
  40478. - unsigned long dst_width,
  40479. - unsigned long dst_height,
  40480. - unsigned long nColor);
  40481. -
  40482. -extern void deRotatePattern(unsigned char *pattern_dstaddr,
  40483. - unsigned long pattern_src_addr,
  40484. - unsigned long pattern_BPP,
  40485. - unsigned long pattern_stride,
  40486. - int patternX,
  40487. - int patternY);
  40488. -
  40489. -extern void deCopy(unsigned long dst_base,
  40490. - unsigned long dst_pitch,
  40491. - unsigned long dst_BPP,
  40492. - unsigned long dst_X,
  40493. - unsigned long dst_Y,
  40494. - unsigned long dst_width,
  40495. - unsigned long dst_height,
  40496. - unsigned long src_base,
  40497. - unsigned long src_pitch,
  40498. - unsigned long src_X,
  40499. - unsigned long src_Y,
  40500. - pTransparent pTransp,
  40501. - unsigned char nROP2);
  40502. -
  40503. -/*
  40504. - * System memory to Video memory monochrome expansion.
  40505. - *
  40506. - * Source is monochrome image in system memory. This function expands the
  40507. - * monochrome data to color image in video memory.
  40508. - *
  40509. - * @pSrcbuf: pointer to start of source buffer in system memory
  40510. - * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
  40511. - * down and -ive mean button up
  40512. - * @startBit: Mono data can start at any bit in a byte, this value should
  40513. - * be 0 to 7
  40514. - * @dBase: Address of destination : offset in frame buffer
  40515. - * @dPitch: Pitch value of destination surface in BYTE
  40516. - * @bpp: Color depth of destination surface
  40517. - * @dx, dy: Starting coordinate of destination surface
  40518. - * @width, height: width and height of rectange in pixel value
  40519. - * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
  40520. - * the monochrome data)
  40521. - * @rop2: ROP value
  40522. - */
  40523. -
  40524. -extern long deSystemMem2VideoMemMonoBlt(
  40525. - const char *pSrcbuf,
  40526. - long srcDelta,
  40527. - unsigned long startBit,
  40528. - unsigned long dBase,
  40529. - unsigned long dPitch,
  40530. - unsigned long bpp,
  40531. - unsigned long dx, unsigned long dy,
  40532. - unsigned long width, unsigned long height,
  40533. - unsigned long fColor,
  40534. - unsigned long bColor,
  40535. - unsigned long rop2);
  40536. -
  40537. -extern unsigned long deGetTransparency(void);
  40538. -extern void deSetPixelFormat(unsigned long bpp);
  40539. diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtcfb.c linux-lemote/drivers/staging/sm7xx/smtcfb.c
  40540. --- linux-2.6.33/drivers/staging/sm7xx/smtcfb.c 2010-02-24 19:52:17.000000000 +0100
  40541. +++ linux-lemote/drivers/staging/sm7xx/smtcfb.c 2010-03-06 16:43:30.000000000 +0100
  40542. @@ -6,12 +6,14 @@
  40543. * Boyod boyod.yang@siliconmotion.com.cn
  40544. *
  40545. * Copyright (C) 2009 Lemote, Inc.
  40546. - * Author: Wu Zhangjin, wuzj@lemote.com
  40547. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  40548. *
  40549. * This file is subject to the terms and conditions of the GNU General Public
  40550. * License. See the file COPYING in the main directory of this archive for
  40551. * more details.
  40552. *
  40553. + * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
  40554. + *
  40555. * Version 0.10.26192.21.01
  40556. * - Add PowerPC/Big endian support
  40557. * - Add 2D support for Lynx
  40558. @@ -45,7 +47,6 @@
  40559. struct screen_info smtc_screen_info;
  40560. #include "smtcfb.h"
  40561. -#include "smtc2d.h"
  40562. #ifdef DEBUG
  40563. #define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
  40564. @@ -107,6 +108,7 @@
  40565. {"0x307", 1280, 1024, 8},
  40566. {"0x311", 640, 480, 16},
  40567. + {"0x313", 800, 480, 16},
  40568. {"0x314", 800, 600, 16},
  40569. {"0x317", 1024, 768, 16},
  40570. {"0x31A", 1280, 1024, 16},
  40571. @@ -120,10 +122,6 @@
  40572. char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
  40573. char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
  40574. -char *smtc_2DBaseAddress; /* 2D engine starting address */
  40575. -char *smtc_2Ddataport; /* 2D data port offset */
  40576. -short smtc_2Dacceleration;
  40577. -
  40578. static u32 colreg[17];
  40579. static struct par_info hw; /* hardware information */
  40580. @@ -135,16 +133,6 @@
  40581. #define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
  40582. -void deWaitForNotBusy(void)
  40583. -{
  40584. - unsigned long i = 0x1000000;
  40585. - while (i--) {
  40586. - if ((smtc_seqr(0x16) & 0x18) == 0x10)
  40587. - break;
  40588. - }
  40589. - smtc_de_busy = 0;
  40590. -}
  40591. -
  40592. static void sm712_set_timing(struct smtcfb_info *sfb,
  40593. struct par_info *ppar_info)
  40594. {
  40595. @@ -324,7 +312,7 @@
  40596. return chan << bf->offset;
  40597. }
  40598. -static int smtcfb_blank(int blank_mode, struct fb_info *info)
  40599. +static int cfb_blank(int blank_mode, struct fb_info *info)
  40600. {
  40601. /* clear DPMS setting */
  40602. switch (blank_mode) {
  40603. @@ -622,93 +610,13 @@
  40604. }
  40605. #endif /* ! __BIG_ENDIAN */
  40606. -#include "smtc2d.c"
  40607. -
  40608. -void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
  40609. -{
  40610. - struct par_info *p = (struct par_info *)info->par;
  40611. -
  40612. - if (smtc_2Dacceleration) {
  40613. - if (!area->width || !area->height)
  40614. - return;
  40615. -
  40616. - deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
  40617. - area->dx, area->dy, area->width, area->height,
  40618. - p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
  40619. -
  40620. - } else
  40621. - cfb_copyarea(info, area);
  40622. -}
  40623. -
  40624. -void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
  40625. -{
  40626. - struct par_info *p = (struct par_info *)info->par;
  40627. -
  40628. - if (smtc_2Dacceleration) {
  40629. - if (!rect->width || !rect->height)
  40630. - return;
  40631. - if (info->var.bits_per_pixel >= 24)
  40632. - deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
  40633. - rect->dy * 3, rect->width * 3, rect->height,
  40634. - rect->color);
  40635. - else
  40636. - deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
  40637. - rect->width, rect->height, rect->color);
  40638. - } else
  40639. - cfb_fillrect(info, rect);
  40640. -}
  40641. -
  40642. -void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
  40643. -{
  40644. - struct par_info *p = (struct par_info *)info->par;
  40645. - u32 bg_col = 0, fg_col = 0;
  40646. -
  40647. - if ((smtc_2Dacceleration) && (image->depth == 1)) {
  40648. - if (smtc_de_busy)
  40649. - deWaitForNotBusy();
  40650. -
  40651. - switch (info->var.bits_per_pixel) {
  40652. - case 8:
  40653. - bg_col = image->bg_color;
  40654. - fg_col = image->fg_color;
  40655. - break;
  40656. - case 16:
  40657. - bg_col =
  40658. - ((u32 *) (info->pseudo_palette))[image->bg_color];
  40659. - fg_col =
  40660. - ((u32 *) (info->pseudo_palette))[image->fg_color];
  40661. - break;
  40662. - case 32:
  40663. - bg_col =
  40664. - ((u32 *) (info->pseudo_palette))[image->bg_color];
  40665. - fg_col =
  40666. - ((u32 *) (info->pseudo_palette))[image->fg_color];
  40667. - break;
  40668. - }
  40669. -
  40670. - deSystemMem2VideoMemMonoBlt(
  40671. - image->data,
  40672. - image->width / 8,
  40673. - 0,
  40674. - p->BaseAddressInVRAM,
  40675. - 0,
  40676. - 0,
  40677. - image->dx, image->dy,
  40678. - image->width, image->height,
  40679. - fg_col, bg_col,
  40680. - 0x0C);
  40681. -
  40682. - } else
  40683. - cfb_imageblit(info, image);
  40684. -}
  40685. -
  40686. static struct fb_ops smtcfb_ops = {
  40687. .owner = THIS_MODULE,
  40688. .fb_setcolreg = smtc_setcolreg,
  40689. - .fb_blank = smtcfb_blank,
  40690. - .fb_fillrect = smtcfb_fillrect,
  40691. - .fb_imageblit = smtcfb_imageblit,
  40692. - .fb_copyarea = smtcfb_copyarea,
  40693. + .fb_blank = cfb_blank,
  40694. + .fb_fillrect = cfb_fillrect,
  40695. + .fb_imageblit = cfb_imageblit,
  40696. + .fb_copyarea = cfb_copyarea,
  40697. #ifdef __BIG_ENDIAN
  40698. .fb_read = smtcfb_read,
  40699. .fb_write = smtcfb_write,
  40700. @@ -772,12 +680,6 @@
  40701. hw.height = sfb->fb.var.yres;
  40702. hw.hz = 60;
  40703. smtc_set_timing(sfb, &hw);
  40704. - if (smtc_2Dacceleration) {
  40705. - printk("2D acceleration enabled!\n");
  40706. - /* Init smtc drawing engine */
  40707. - deInit(sfb->fb.var.xres, sfb->fb.var.yres,
  40708. - sfb->fb.var.bits_per_pixel);
  40709. - }
  40710. }
  40711. /*
  40712. @@ -1004,9 +906,7 @@
  40713. #endif
  40714. hw.m_pMMIO = (smtc_RegBaseAddress =
  40715. smtc_VRAMBaseAddress + 0x00700000);
  40716. - smtc_2DBaseAddress = (hw.m_pDPR =
  40717. - smtc_VRAMBaseAddress + 0x00408000);
  40718. - smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
  40719. + hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
  40720. hw.m_pVPR = hw.m_pLFB + 0x0040c000;
  40721. #ifdef __BIG_ENDIAN
  40722. if (sfb->fb.var.bits_per_pixel == 32) {
  40723. @@ -1035,27 +935,21 @@
  40724. if (sfb->fb.var.bits_per_pixel == 32)
  40725. smtc_seqw(0x17, 0x30);
  40726. #endif
  40727. -#ifdef CONFIG_FB_SM7XX_ACCEL
  40728. - smtc_2Dacceleration = 1;
  40729. -#endif
  40730. break;
  40731. case 0x720:
  40732. sfb->fb.fix.mmio_start = pFramebufferPhysical;
  40733. sfb->fb.fix.mmio_len = 0x00200000;
  40734. smem_size = SM722_VIDEOMEMORYSIZE;
  40735. - smtc_2DBaseAddress = (hw.m_pDPR =
  40736. - ioremap(pFramebufferPhysical, 0x00a00000));
  40737. + hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
  40738. hw.m_pLFB = (smtc_VRAMBaseAddress =
  40739. - smtc_2DBaseAddress + 0x00200000);
  40740. + hw.m_pDPR + 0x00200000);
  40741. hw.m_pMMIO = (smtc_RegBaseAddress =
  40742. - smtc_2DBaseAddress + 0x000c0000);
  40743. - smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
  40744. - hw.m_pVPR = smtc_2DBaseAddress + 0x800;
  40745. + hw.m_pDPR + 0x000c0000);
  40746. + hw.m_pVPR = hw.m_pDPR + 0x800;
  40747. smtc_seqw(0x62, 0xff);
  40748. smtc_seqw(0x6a, 0x0d);
  40749. smtc_seqw(0x6b, 0x02);
  40750. - smtc_2Dacceleration = 0;
  40751. break;
  40752. default:
  40753. printk(KERN_INFO
  40754. diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtcfb.h linux-lemote/drivers/staging/sm7xx/smtcfb.h
  40755. --- linux-2.6.33/drivers/staging/sm7xx/smtcfb.h 2010-02-24 19:52:17.000000000 +0100
  40756. +++ linux-lemote/drivers/staging/sm7xx/smtcfb.h 2010-03-06 16:43:30.000000000 +0100
  40757. @@ -6,7 +6,7 @@
  40758. * Boyod boyod.yang@siliconmotion.com.cn
  40759. *
  40760. * Copyright (C) 2009 Lemote, Inc.
  40761. - * Author: Wu Zhangjin, wuzj@lemote.com
  40762. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  40763. *
  40764. * This file is subject to the terms and conditions of the GNU General Public
  40765. * License. See the file COPYING in the main directory of this archive for
  40766. diff -Nur linux-2.6.33/drivers/staging/sm7xx/TODO linux-lemote/drivers/staging/sm7xx/TODO
  40767. --- linux-2.6.33/drivers/staging/sm7xx/TODO 2010-02-24 19:52:17.000000000 +0100
  40768. +++ linux-lemote/drivers/staging/sm7xx/TODO 2010-03-06 16:43:30.000000000 +0100
  40769. @@ -1,5 +1,6 @@
  40770. TODO:
  40771. - Dual head support
  40772. +- 2D acceleration support
  40773. - use kernel coding style
  40774. - checkpatch.pl clean
  40775. - refine the code and remove unused code
  40776. diff -Nur linux-2.6.33/drivers/usb/host/ohci-hcd.c linux-lemote/drivers/usb/host/ohci-hcd.c
  40777. --- linux-2.6.33/drivers/usb/host/ohci-hcd.c 2010-02-24 19:52:17.000000000 +0100
  40778. +++ linux-lemote/drivers/usb/host/ohci-hcd.c 2010-03-06 16:43:31.000000000 +0100
  40779. @@ -832,9 +832,13 @@
  40780. }
  40781. if (ints & OHCI_INTR_WDH) {
  40782. - spin_lock (&ohci->lock);
  40783. - dl_done_list (ohci);
  40784. - spin_unlock (&ohci->lock);
  40785. + if (ohci->hcca->done_head == 0) {
  40786. + ints &= ~OHCI_INTR_WDH;
  40787. + } else {
  40788. + spin_lock (&ohci->lock);
  40789. + dl_done_list (ohci);
  40790. + spin_unlock (&ohci->lock);
  40791. + }
  40792. }
  40793. if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {